Migration Guide sdk v2.2.0 to v3.0.0

Prev Next

This guide helps you migrate your Python applications from MachineLogic SDK v2.2.0 to v3.0.0. The v3.0.0 release introduces significant changes to our robot programming SDK.


Table of Contents

  1. Breaking Changes Overview

  2. Robot API Changes    

  3. RobotState Changes

  4. Sequence Builder Changes

  5. Callback Management Changes

  6. Migration Examples

  7. Quick Reference Table


Breaking Changes Overview

Category

Change Type

v2.2.0

v3.0.0

Robot States

Breaking

Previous enums

New enums (different values)

Teach Mode

Removed

robot.teach_mode() context manager

Use set_to_freedrive() + set_to_normal()

Set Payload

Breaking

set_payload(weight) → bool

set_payload(weight, center_of_mass, inertia?) → None

Timestamp

Breaking

Custom Timestamp type

Standard Python datetime

Sequence Return

Breaking

execute_sequence() → bool

execute_sequence() → None

Wait for Motion

Breaking

wait_for_motion_completion(timeout?) → bool

wait_for_motion_completion() → None

Digital I/O

Removed

robot.set_tool_digital_output()

Removed

Velocity Limits

Deprecated

Returns actual limits

Returns default values (250.0 mm/s, 120.0 deg/s)


Robot API Changes

Operational State Enum Changes

The RobotOperationalState enum has been completely redesigned. Both the names and values have changed.

v2.2.0

from machinelogic.ivention.irobot import RobotOperationalState

        # Old enum values
        RobotOperationalState.OFFLINE # = 0
        RobotOperationalState.NON_OPERATIONAL # = 1
        RobotOperationalState.FREEDRIVE # = 2
        RobotOperationalState.NORMAL # = 3
        RobotOperationalState.UNKNOWN # = 4
        RobotOperationalState.NEED_MANUAL_INTERVENTION # = 5

v3.0.0

from machinelogic.types import RobotOperationalState

        # New enum values
        RobotOperationalState.UNKNOWN # = 0 (value changed from 4)
        RobotOperationalState.IDLE # = 1 ✨ NEW
        RobotOperationalState.RUNNING # = 2 ✨ NEW
        RobotOperationalState.JOGGING # = 3 ✨ NEW
        RobotOperationalState.FREEDRIVE # = 4 (value changed from 2)
        RobotOperationalState.STOPPING # = 5 ✨ NEW
        RobotOperationalState.NON_OPERATIONAL # = 6 (value changed from 1)

Migration Notes

Old State (v2.2.0)

New State (v3.0.0)

Action Required

OFFLINE = 0

❌ Removed

Check for NON_OPERATIONAL instead

NON_OPERATIONAL = 1

NON_OPERATIONAL = 6

Update value comparisons

FREEDRIVE = 2

FREEDRIVE = 4

Update value comparisons

NORMAL = 3

❌ Removed

Use IDLE or RUNNING instead

UNKNOWN = 4

UNKNOWN = 0

Update value comparisons

NEED_MANUAL_INTERVENTION = 5

❌ Removed

Handle via safety states

-

IDLE = 1

Robot ready but not moving

-

RUNNING = 2

Robot executing trajectory

-

JOGGING = 3

Robot in jog mode

-

STOPPING = 5

Robot stopping motion

Before (v2.2.0):

if robot.state.operational_state == RobotOperationalState.NORMAL:
        print("Robot ready")

After (v3.0.0):

if robot.state.operational_state == RobotOperationalState.IDLE:
        print("Robot ready")

        # Or check for running state
        if robot.state.operational_state == RobotOperationalState.RUNNING:
        print("Robot is executing a trajectory")

Safety State Enum Changes

The RobotSafetyState enum has also been updated.

v2.2.0

RobotSafetyState.NORMAL # = 0
        RobotSafetyState.EMERGENCY_STOP # = 2
        RobotSafetyState.REDUCED_SPEED # = 3
        RobotSafetyState.SAFEGUARD_STOP # = 4
        RobotSafetyState.UNKNOWN # = 5

v3.0.0

RobotSafetyState.UNKNOWN # = 0 (value changed from 5)
        RobotSafetyState.NORMAL # = 1 (value changed from 0)
        RobotSafetyState.EMERGENCY_STOP # = 2 (unchanged)
        RobotSafetyState.REDUCED_SPEED # = 3 (unchanged)
        RobotSafetyState.RECOVERABLE_FAULT # = 4 ✨ NEW (replaces SAFEGUARD_STOP)

Migration Notes

Old State (v2.2.0)

New State (v3.0.0)

Action Required

NORMAL = 0

NORMAL = 1

Update value comparisons

SAFEGUARD_STOP = 4

❌ Removed

Use RECOVERABLE_FAULT instead

UNKNOWN = 5

UNKNOWN = 0

Update value comparisons

-

RECOVERABLE_FAULT = 4

Handle recoverable faults


Removed Methods

The following methods have been removed in v3.0.0:

robot.teach_mode() - Context Manager for Freedrive

v2.2.0:

with my_robot.teach_mode():
        print("Robot is in teach mode for 5 seconds")
        time.sleep(5)
        # Robot automatically returns to normal mode

v3.0.0:

my_robot.set_to_freedrive()
        print("Robot is in freedrive mode for 5 seconds")
        time.sleep(5)
        my_robot.set_to_normal()

robot.set_tool_digital_output(pin, value)

This method has been removed. Tool digital outputs are no longer managed through the Robot class.

v2.2.0:

my_robot.set_tool_digital_output(pin=1, value=1)

v3.0.0:

This functionality is no longer available through the SDK.

robot.state.get_digital_input_value(pin)

v2.2.0:

value = my_robot.state.get_digital_input_value(pin=1)

v3.0.0:

This method has been removed.

robot.state.cartesian_position and robot.state.joint_angles

These deprecated properties have been removed. Use cartesian_position_data and joint_angles_data instead.

v2.2.0:

# These were already deprecated in v1.14.0
        position = my_robot.state.cartesian_position
        angles = my_robot.state.joint_angles

v3.0.0:

position, timestamp = my_robot.state.cartesian_position_data
        angles, timestamp = my_robot.state.joint_angles_data

Changed Method Signatures

robot.set_payload()

v2.2.0:

def set_payload(self, payload: Kilograms) -> bool:
        ...

        # Usage
        success = my_robot.set_payload(2.76)
        if success:
        print("Payload set")

v3.0.0:

def set_payload(
        self,
        payload: Kilograms,
        center_of_mass: Vector, # Required: [x, y, z] in mm
        inertia: Inertia | None = None # Optional: [ixx, ixy, ixz, iyy, iyz, izz] in kg·mm²
        ) -> None:
        ...

        # Usage
        my_robot.set_payload(2.76, center_of_mass=[10, 10, 10])
        print("Payload set")

        # With inertia (optional)
        my_robot.set_payload(
        2.76,
        center_of_mass=[10, 10, 10],
        inertia=[100, 0, 0, 100, 0, 100]
        )

robot.execute_sequence() and robot.execute_sequence_async()

v2.2.0:

def execute_sequence(self, sequence: ISequenceBuilder) -> bool:
        ...

        # Usage
        success = my_robot.execute_sequence(seq)
        if not success:
        print("Sequence execution failed")

v3.0.0:

def execute_sequence(self, sequence: IRobotMoveSequence) -> None:
        ...

        # Usage - raises exception on failure
        my_robot.execute_sequence(seq)

robot.wait_for_motion_completion()

v2.2.0:

def wait_for_motion_completion(self, timeout: float | None = None) -> bool:
        ...

        # Usage
        success = my_robot.wait_for_motion_completion(timeout=30.0)

v3.0.0:

def wait_for_motion_completion(self) -> None:
        ...

        # Usage - timeout parameter removed
        my_robot.wait_for_motion_completion()

robot.reset()robot.set_to_normal() (Deprecated)

v2.2.0:

success = my_robot.reset()

v3.0.0:

# reset() is deprecated, use set_to_normal() instead
        my_robot.set_to_normal()

        # reset() still works but is deprecated
        success = my_robot.reset() # Deprecated

New Methods

robot.set_to_normal()

Sets the robot to normal operational state. This is the preferred replacement for reset().

my_robot.set_to_normal()

robot.set_to_freedrive()

Puts the robot into freedrive mode. Use with set_to_normal() to replace the removed teach_mode() context manager.

my_robot.set_to_freedrive()
        # Robot can be manually moved
        time.sleep(5)
        my_robot.set_to_normal()

robot.remove_log_alarm_callback(callback_id)

Remove a previously registered log alarm callback.

callback_id = my_robot.on_log_alarm(my_callback)
        # Later...
        my_robot.remove_log_alarm_callback(callback_id)

robot.remove_system_state_change_callback(callback_id)

Remove a previously registered system state change callback.

callback_id = my_robot.on_system_state_change(my_callback)
        # Later...
        my_robot.remove_system_state_change_callback(callback_id)

RobotState Changes

Timestamp Type Change

The timestamp returned by cartesian_position_data and joint_angles_data has changed from a custom Timestamp namedtuple to a standard Python datetime object.

v2.2.0:

joint_angles, timestamp = my_robot.state.joint_angles_data

        # timestamp was a custom Timestamp namedtuple with seconds and nanoseconds
        print(f"Timestamp: {timestamp}") # Timestamp(seconds=..., nanoseconds=...)

v3.0.0:

joint_angles, timestamp = my_robot.state.joint_angles_data

        # timestamp is now a standard datetime object
        print(f"Timestamp: {timestamp.isoformat()}") # 2026-02-12T10:30:00.123456

Sequence Builder Changes

Blend Parameter Change

The blend parameter in append_movel and append_movej has changed from a blend_factor (0.0-1.0 scale factor) to a blend_radius (millimeters).

v2.2.0:

seq = my_robot.create_sequence()
        seq.append_movel(target, velocity, acceleration, blend_factor=0.5) # Scale factor
        seq.append_movej(target, velocity, acceleration, blend_factor=0.5)

v3.0.0:

seq = my_robot.create_sequence()
        seq.append_movel(target, velocity, acceleration, blend_radius=5.0) # Millimeters
        seq.append_movej(target, velocity, acceleration, blend_radius=5.0)

Context Manager Support

v3.0.0 adds context manager support for sequences with automatic execution:

# Synchronous execution with context manager
        with my_robot.create_sequence() as seq:
        seq.append_movej(joint_target, velocity=10.0, acceleration=10.0)
        seq.append_movel(cartesian_target, velocity=100.0, acceleration=100.0)
        # Sequence executes automatically on exit

        # Async execution with context manager
        with my_robot.create_sequence().execute_async_on_exit() as seq:
        seq.append_movej(joint_target, velocity=10.0, acceleration=10.0)
        # Sequence starts executing asynchronously on exit

Callback Management Changes

on_system_state_change() Now Returns a Callback ID

v2.2.0:

my_robot.on_system_state_change(handle_state_change)
        # No way to remove the callback

v3.0.0:

callback_id = my_robot.on_system_state_change(handle_state_change)
        # Later, you can remove it:
        my_robot.remove_system_state_change_callback(callback_id)

Import Path for Types

v2.2.0:

from machinelogic.ivention.irobot import RobotOperationalState, RobotSafetyState

v3.0.0:

from machinelogic.types import RobotOperationalState, RobotSafetyState

Migration Examples

Example 1: Basic Robot State Monitoring

v2.2.0:

from machinelogic import Machine
        from machinelogic.ivention.irobot import RobotOperationalState, RobotSafetyState

        machine = Machine()
        robot = machine.get_robot("Robot")

        def handle_state(op_state: RobotOperationalState, safety_state: RobotSafetyState):
        if op_state == RobotOperationalState.NORMAL:
        print("Robot is in normal mode")
        elif op_state == RobotOperationalState.FREEDRIVE:
        print("Robot is in freedrive")

        robot.on_system_state_change(handle_state)

v3.0.0:

from machinelogic import Machine
        from machinelogic.types import RobotOperationalState, RobotSafetyState

        machine = Machine()
        robot = machine.get_robot("Robot")

        def handle_state(op_state: RobotOperationalState, safety_state: RobotSafetyState):
        if op_state == RobotOperationalState.IDLE:
        print("Robot is ready (idle)")
        elif op_state == RobotOperationalState.RUNNING:
        print("Robot is executing a trajectory")
        elif op_state == RobotOperationalState.FREEDRIVE:
        print("Robot is in freedrive")

        callback_id = robot.on_system_state_change(handle_state)
        # Store callback_id if you need to remove the callback later

Example 2: Teach Mode / Freedrive

v2.2.0:

import time
        from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        # Using context manager
        with robot.teach_mode():
        print("Teach mode active")
        time.sleep(10)
        # Automatically exits teach mode

v3.0.0:

import time
        from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        # Manual freedrive control
        robot.set_to_freedrive()
        print("Freedrive active")
        time.sleep(10)
        robot.set_to_normal()
        print("Back to normal")

Example 3: Setting Payload

v2.2.0:

from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        success = robot.set_payload(2.5)
        if success:
        print("Payload configured")
        else:
        print("Failed to set payload")

v3.0.0:

from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        # center_of_mass is now required [x, y, z] in mm
        robot.set_payload(
        payload=2.5,
        center_of_mass=[0, 0, 50], # 50mm above the flange
        inertia=None # Optional
        )
        print("Payload configured")

Example 4: Execute Sequence

v2.2.0:

from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        joint_target = [10, 20, 30, 40, 50, 60]

        seq = robot.create_sequence()
        seq.append_movej(joint_target, 10.0, 10.0, 0.5) # blend_factor

        success = robot.execute_sequence(seq)
        if not success:
        print("Sequence failed")

        success = robot.wait_for_motion_completion(timeout=30.0)

v3.0.0:

from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        joint_target = [10, 20, 30, 40, 50, 60]

        # Option 1: Manual execution
        seq = robot.create_sequence()
        seq.append_movej(joint_target, 10.0, 10.0, 5.0) # blend_radius in mm
        robot.execute_sequence(seq) # Raises on failure, no return value

        # Option 2: Context manager (cleaner)
        with robot.create_sequence() as seq:
        seq.append_movej(joint_target, velocity=10.0, acceleration=10.0, blend_radius=5.0)
        # Automatically executes and waits

Example 5: Reading Position Data

v2.2.0:

from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        angles, timestamp = robot.state.joint_angles_data
        print(f"Joint angles: {angles}")
        print(f"Timestamp seconds: {timestamp.seconds}, ns: {timestamp.nanoseconds}")

v3.0.0:

from machinelogic import Machine

        machine = Machine()
        robot = machine.get_robot("Robot")

        angles, timestamp = robot.state.joint_angles_data
        print(f"Joint angles: {angles}")
        print(f"Timestamp: {timestamp.isoformat()}") # Standard datetime

Quick Reference Table

Feature

v2.2.0

v3.0.0

Import enums

from machinelogic.ivention.irobot import ...

from machinelogic.types import ...

Check robot ready

state == NORMAL

state == IDLE

Check robot moving

state.move_in_progress

state == RUNNING or state.move_in_progress

Freedrive mode

with robot.teach_mode():

robot.set_to_freedrive() / robot.set_to_normal()

Reset robot

robot.reset()

robot.set_to_normal()

Set payload

robot.set_payload(kg)

robot.set_payload(kg, [x,y,z])

Execute sequence

success = robot.execute_sequence(seq)

robot.execute_sequence(seq)

Wait for motion

robot.wait_for_motion_completion(timeout=30)

robot.wait_for_motion_completion()

Blend parameter

blend_factor (0-1)

blend_radius (mm)

Timestamp type

Timestamp(seconds, nanoseconds)

datetime

Remove callbacks

Not supported

robot.remove_system_state_change_callback(id)


Deprecated Features

The following features are deprecated in v3.0.0 and will be removed in a future version:

Feature

Status

Replacement

robot.reset()

Deprecated

robot.set_to_normal()

robot.set_tcp_offset()

Deprecated (since v2.2.0)

robot.set_active_tcp()

robot.configuration.cartesian_velocity_limit

Deprecated

Returns default 250.0 mm/s

robot.configuration.joint_velocity_limit

Deprecated

Returns default 120.0 deg/s