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
Breaking Changes Overview
Category | Change Type | v2.2.0 | v3.0.0 |
|---|---|---|---|
Robot States | Breaking | Previous enums | New enums (different values) |
Teach Mode | Removed |
| Use |
Set Payload | Breaking |
|
|
Timestamp | Breaking | Custom | Standard Python |
Sequence Return | Breaking |
|
|
Wait for Motion | Breaking |
|
|
Digital I/O | Removed |
| 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 # = 5v3.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 |
|---|---|---|
| ❌ Removed | Check for |
|
| Update value comparisons |
|
| Update value comparisons |
| ❌ Removed | Use |
|
| Update value comparisons |
| ❌ Removed | Handle via safety states |
- |
| Robot ready but not moving |
- |
| Robot executing trajectory |
- |
| Robot in jog mode |
- |
| 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 # = 5v3.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 |
|---|---|---|
|
| Update value comparisons |
| ❌ Removed | Use |
|
| Update value comparisons |
- |
| 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 modev3.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_anglesv3.0.0:
position, timestamp = my_robot.state.cartesian_position_data
angles, timestamp = my_robot.state.joint_angles_dataChanged 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() # DeprecatedNew 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.123456Sequence 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 exitCallback 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 callbackv3.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, RobotSafetyStatev3.0.0:
from machinelogic.types import RobotOperationalState, RobotSafetyStateMigration 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 laterExample 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 modev3.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 waitsExample 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 datetimeQuick Reference Table
Feature | v2.2.0 | v3.0.0 |
|---|---|---|
Import enums |
|
|
Check robot ready |
|
|
Check robot moving |
|
|
Freedrive mode |
|
|
Reset robot |
|
|
Set payload |
|
|
Execute sequence |
|
|
Wait for motion |
|
|
Blend parameter |
|
|
Timestamp type |
|
|
Remove callbacks | Not supported |
|
Deprecated Features
The following features are deprecated in v3.0.0 and will be removed in a future version:
Feature | Status | Replacement |
|---|---|---|
| Deprecated |
|
| Deprecated (since v2.2.0) |
|
| Deprecated | Returns default 250.0 mm/s |
| Deprecated | Returns default 120.0 deg/s |