ROS2 Services#
The WMX R2 application provides services for engine management, axis
control, parameter loading, I/O, EtherCAT diagnostics, and gripper operation.
Services use custom types from wmx_r2_message plus standard types from
std_srvs.
Service Name |
Type |
Node |
Category |
|---|---|---|---|
|
|
|
Engine |
|
|
|
Engine |
|
|
|
Engine |
|
|
|
Engine |
|
|
|
Axis Control |
|
|
|
Axis Control |
|
|
|
Axis Control |
|
|
|
Axis Control |
|
|
|
Axis Control |
|
|
|
Axis Control |
|
|
|
Parameters |
|
|
|
Parameters |
|
|
|
I/O |
|
|
|
I/O |
|
|
|
I/O |
|
|
|
I/O |
|
|
|
I/O |
|
|
|
I/O |
|
|
|
EtherCAT |
|
|
|
EtherCAT |
|
|
|
EtherCAT |
|
|
|
EtherCAT |
|
|
|
Gripper |
Custom Service Types#
Before reviewing the services, here are the custom service type definitions
from wmx_r2_message.
wmx_r2_message/srv/SetEngine
# Request
bool data # true = create device, false = close device
string path # Device path (e.g., "/opt/wmx3/")
string name # Device name (e.g., "wmx_r2_general_test")
---
# Response
bool success # true if operation succeeded
string message # Human-readable result description
wmx_r2_message/srv/SetAxis
# Request
int32[] index # Axis indices (e.g., [0, 1, 2, 3, 4, 5])
int32[] data # Per-axis values (meaning depends on service)
---
# Response
bool success # true only if ALL axes succeeded
string message # Concatenated per-axis result messages
wmx_r2_message/srv/SetAxisGearRatio
# Request
int32[] index # Axis indices
float64[] numerator # Gear ratio numerators (encoder counts)
float64[] denominator # Gear ratio denominators (physical units)
---
# Response
bool success # true only if ALL axes succeeded
string message # Concatenated per-axis result messages
wmx_r2_message/srv/LoadWmxParams
# Request
string file_path # absolute path to the WMX3 XML parameter file
---
# Response
bool success
string message
wmx_r2_message/srv/GetWmxParams
# Request
int32[] index # specific axis indices to display parameters for
---
# Response
bool success
string message
string[] params_dump # formatted human-readable string of all parameters
Engine Management Services#
These services manage the WMX engine lifecycle. They are hosted by
wmx_engine_node (source: wmx_engine_node.cpp).
/wmx/engine/set_device#
Service Type |
|
Node |
|
Purpose |
Create or close the WMX device handle |
Field |
Type |
Description |
|---|---|---|
|
|
|
|
|
WMX Runtime installation path (typically |
|
|
Device name assigned via |
Behavior when data=true:
Calls
WMX3Api::CreateDevice(path, DeviceTypeNormal, timeout=10000)Calls
WMX3Api::SetDeviceName(name)On success:
message="Created a device with name: <name>"On error:
success=false,message="Failed to create device. Error=<code> (<description>)"
Behavior when data=false:
Calls
WMX3Api::CloseDevice()On success:
message="Device stopped"On error:
success=false,message="Failed to close device. Error=<code> (<description>)"
Example – Create device:
ros2 service call /wmx/engine/set_device wmx_r2_message/srv/SetEngine \
"{data: true, path: '/opt/wmx3/', name: 'my_device'}"
Example – Close device:
ros2 service call /wmx/engine/set_device wmx_r2_message/srv/SetEngine \
"{data: false, path: '', name: ''}"
/wmx/engine/set_comm#
Service Type |
|
Node |
|
Purpose |
Start or stop EtherCAT real-time communication |
Field |
Type |
Description |
|---|---|---|
|
|
|
Behavior when data=true:
Calls
WMX3Api::StartCommunication(timeout=10000)On success:
message="Communication is started"On error:
success=false,message="Failed to start communication. Error=<code> (<description>)"
Behavior when data=false:
Calls
WMX3Api::StopCommunication(timeout=10000)On success:
message="Communication is stopped"On error:
success=false,message="Failed to stop communication. Error=<code> (<description>)"
Example – Start communication:
ros2 service call /wmx/engine/set_comm std_srvs/srv/SetBool "{data: true}"
Example – Stop communication:
ros2 service call /wmx/engine/set_comm std_srvs/srv/SetBool "{data: false}"
/wmx/engine/get_status#
Service Type |
|
Node |
|
Purpose |
Query the current WMX engine state |
This service takes no request parameters. The response message field
contains one of the following engine states:
State |
Meaning |
|---|---|
|
Engine created but not started |
|
Engine running, no EtherCAT communication |
|
EtherCAT real-time cycle is active (normal operating state) |
|
Engine is shutting down |
|
Unrecognized state code |
|
State code does not match any known value |
The success field is always true (the status query itself does not
fail).
Example:
ros2 service call /wmx/engine/get_status std_srvs/srv/Trigger
Expected response when operating normally:
success: True
message: "Communicating"
/wmx/engine/scan_network#
Service Type |
|
Node |
|
Purpose |
Trigger an EtherCAT network scan to discover connected slave devices |
Calls Ecat::ScanNetwork(masterId=0). Returns success=true and a
summary message on success, or success=false with the WMX error code on
failure.
Example:
ros2 service call /wmx/engine/scan_network std_srvs/srv/Trigger
Axis Control Services#
These services control individual servo axes. They are hosted by
wmx_core_motion_node (source: wmx_core_motion_node.cpp). Operations
are applied per-axis based on the index array in the request. The response
success is true only if all specified axes succeeded.
/wmx/axis/set_on#
Service Type |
|
Node |
|
Purpose |
Enable or disable servo drives |
Field |
Type |
Description |
|---|---|---|
|
|
Axis indices to control (0-5 for a 6-DOF robot) |
|
|
|
Calls CoreMotion::SetServoOn(axis, on_off) for each axis. Response
message is concatenated per-axis (e.g., "Set axis 0 on. Set axis 1 on.").
Example – Enable all 6 servos:
ros2 service call /wmx/axis/set_on wmx_r2_message/srv/SetAxis \
"{index: [0, 1, 2, 3, 4, 5], data: [1, 1, 1, 1, 1, 1]}"
Example – Disable all 6 servos:
ros2 service call /wmx/axis/set_on wmx_r2_message/srv/SetAxis \
"{index: [0, 1, 2, 3, 4, 5], data: [0, 0, 0, 0, 0, 0]}"
/wmx/axis/clear_alarm#
Service Type |
|
Node |
|
Purpose |
Clear amplifier alarm (fault) on specified axes |
Calls CoreMotion::ClearAmpAlarm(axis) for each axis. The data field
is not used – only the index array determines which axes are cleared.
Example – Clear alarms on all axes:
ros2 service call /wmx/axis/clear_alarm wmx_r2_message/srv/SetAxis \
"{index: [0, 1, 2, 3, 4, 5], data: [0, 0, 0, 0, 0, 0]}"
/wmx/axis/set_mode#
Service Type |
|
Node |
|
Purpose |
Set the control mode for each axis |
Calls CoreMotion::SetAxisCommandMode(axis, mode) for each axis.
Value |
Mode |
Description |
|---|---|---|
|
Position ( |
Axis accepts absolute/relative position commands |
|
Velocity ( |
Axis accepts velocity commands |
Invalid mode values are rejected per-axis with the message
"Invalid mode <value> for axis <index>".
Example – Set all axes to position mode:
ros2 service call /wmx/axis/set_mode wmx_r2_message/srv/SetAxis \
"{index: [0, 1, 2, 3, 4, 5], data: [0, 0, 0, 0, 0, 0]}"
Example – Set axis 0 to velocity mode:
ros2 service call /wmx/axis/set_mode wmx_r2_message/srv/SetAxis \
"{index: [0], data: [1]}"
/wmx/axis/set_polarity#
Service Type |
|
Node |
|
Purpose |
Set the rotation direction polarity for each axis |
Calls CoreMotion::SetAxisPolarity(axis, polarity) for each axis.
Value |
Meaning |
|---|---|
|
Normal direction |
|
Reversed direction |
Only 1 and -1 are accepted. Invalid values are rejected per-axis with
the message "Invalid polarity value for axis <index>: <value>".
Warning
Polarity decides which physical direction a positive command produces. The correct value follows from the URDF’s sign convention for that joint and from the motor’s mounting orientation. Change it only with the axis stopped, and re-verify with a low-speed single-axis jog afterwards. This override is not written back to the parameter XML and is lost on the next engine restart — see Robot Parameter Configuration and Validation.
Example – Set axis 1 reversed, axis 0 normal:
ros2 service call /wmx/axis/set_polarity wmx_r2_message/srv/SetAxis \
"{index: [0, 1], data: [1, -1]}"
/wmx/axis/set_gear_ratio#
Service Type |
|
Node |
|
Purpose |
Configure the encoder gear ratio for each axis |
Calls CoreMotion::SetGearRatio(axis, numerator, denominator) for each
axis. The gear ratio maps encoder counts to WMX user units:
position_user_units = encoder_counts * (denominator / numerator). The user
unit is the radian only when denominator is 2π
(6.283185307179586), as every shipped parameter file sets it.
Warning
The numerator is the encoder counts in one revolution of the joint output — encoder counts per motor revolution × the reducer ratio. A numerator that is wrong by the reducer ratio produces motion that is wrong by roughly two orders of magnitude. A denominator other than 2π silently rescales every position, velocity, and acceleration in the ROS 2 interface. Change these only with the axis stopped, and re-verify afterwards; the override is lost on the next engine restart. See Robot Parameter Configuration and Validation.
Example – Set gear ratios for 2 axes:
ros2 service call /wmx/axis/set_gear_ratio \
wmx_r2_message/srv/SetAxisGearRatio \
"{index: [0, 1],
numerator: [8388608.0, 8388608.0],
denominator: [6.28319, 6.28319]}"
/wmx/axis/homing#
Service Type |
|
Node |
|
Purpose |
Set the home (zero) position for specified axes |
For each axis in index, this service:
Reads the current home parameters via
Config::GetHomeParam()Sets
homeTypetoConfig::HomeType::CurrentPosWrites updated parameters via
Config::SetHomeParam()Starts the homing procedure via
CoreMotion::StartHome()Blocks on
CoreMotion::Wait()until homing completes
The data field is not used – only the index array determines which
axes are homed.
Note
This service blocks until all axes complete homing. For multiple axes, each axis is homed sequentially within the callback.
Example – Home all axes at current position:
ros2 service call /wmx/axis/homing wmx_r2_message/srv/SetAxis \
"{index: [0, 1, 2, 3, 4, 5], data: [0, 0, 0, 0, 0, 0]}"
Parameter Services#
These services load and inspect WMX3 axis parameters (gear ratios, polarities,
home settings, etc.). They are hosted by wmx_core_motion_node (source:
wmx_core_motion_node.cpp).
/wmx/params/load#
Service Type |
|
Node |
|
Purpose |
Import axis parameters from a WMX3 XML configuration file |
The request file_path is the absolute path to the WMX3 XML parameter file.
Returns success=true with a confirmation message on success.
Example:
ros2 service call /wmx/params/load wmx_r2_message/srv/LoadWmxParams \
"{file_path: '/opt/wmx3/param/cr3a_params.xml'}"
/wmx/params/get#
Service Type |
|
Node |
|
Purpose |
Retrieve the active axis configuration as human-readable text |
The request index array selects which axes to report. The response
params_dump holds a formatted, human-readable string of the parameters for
each requested axis.
Example – dump parameters for axes 0 and 1:
ros2 service call /wmx/params/get wmx_r2_message/srv/GetWmxParams \
"{index: [0, 1]}"
Gripper Service#
/wmx/set_gripper#
Service Type |
|
Node |
|
Purpose |
Open or close the pneumatic gripper via EtherCAT digital I/O |
Configurable |
Service name set via |
The gripper is controlled through the WMX Io::SetOutBit(0, 0, value)
API, which sets digital output bit 0 on I/O module 0 in the EtherCAT chain.
Field |
Type |
Description |
|---|---|---|
|
|
|
Field |
Type |
Description |
|---|---|---|
|
|
|
|
|
|
Example – Close gripper:
ros2 service call /wmx/set_gripper std_srvs/srv/SetBool "{data: true}"
Example – Open gripper:
ros2 service call /wmx/set_gripper std_srvs/srv/SetBool "{data: false}"
The gripper state is also reflected in the /joint_states topic. The
joint_state_broadcaster node reads the I/O output bit via Io::GetOutBit()
and maps it to the picker_1_joint and picker_2_joint values using
the gripper_open_value and gripper_close_value parameters.
I/O Services#
These services provide direct access to EtherCAT digital I/O. They are hosted
by wmx_io_node (source: wmx_io_node.cpp). The node becomes active
after wmx_engine_node publishes /wmx/engine/ready.
Custom service types used:
wmx_r2_message/srv/GetIoBit
int32 byte # I/O byte address
int32 bit # Bit index within the byte (0–7)
---
bool success # true if read succeeded
int32 value # Bit value: 0 or 1
string message # Response or error description
wmx_r2_message/srv/GetIoBytes
int32 byte # Starting I/O byte address
int32 length # Number of bytes to read (must be > 0)
---
bool success # true if read succeeded
uint8[] data # Byte values read from I/O
string message # Response or error description
wmx_r2_message/srv/SetIoBit
int32 byte # Output I/O byte address
int32 bit # Bit index within the byte (0–7)
int32 value # Bit value to write: 0 or 1
---
bool success # true if write succeeded
string message # Response or error description
wmx_r2_message/srv/SetIoBytes
int32 byte # Starting output I/O byte address
uint8[] data # Byte values to write
---
bool success # true if write succeeded
string message # Response or error description
/wmx/io/get_input_bit#
Read a single bit from an EtherCAT digital input.
Example – Read input bit 3 of byte 0:
ros2 service call /wmx/io/get_input_bit wmx_r2_message/srv/GetIoBit \
"{byte: 0, bit: 3}"
/wmx/io/get_output_bit#
Read the current value of a digital output bit (reads back the commanded output state, not a physical input).
Example:
ros2 service call /wmx/io/get_output_bit wmx_r2_message/srv/GetIoBit \
"{byte: 0, bit: 0}"
/wmx/io/get_input_bytes#
Read a contiguous block of digital input bytes.
Example – Read 4 input bytes starting at address 0:
ros2 service call /wmx/io/get_input_bytes wmx_r2_message/srv/GetIoBytes \
"{byte: 0, length: 4}"
/wmx/io/get_output_bytes#
Read the current values of a contiguous block of digital output bytes.
Example:
ros2 service call /wmx/io/get_output_bytes wmx_r2_message/srv/GetIoBytes \
"{byte: 0, length: 4}"
/wmx/io/set_output_bit#
Set a single digital output bit. The /wmx/set_gripper service uses the
same underlying Io::SetOutBit call (byte=0, bit=0). Use this service for
general-purpose digital outputs.
Example – Set output bit 1 of byte 0 to high:
ros2 service call /wmx/io/set_output_bit wmx_r2_message/srv/SetIoBit \
"{byte: 0, bit: 1, value: 1}"
/wmx/io/set_output_bytes#
Write a block of digital output bytes in a single call.
Example – Write [0x01, 0x00] to output bytes 0–1:
ros2 service call /wmx/io/set_output_bytes wmx_r2_message/srv/SetIoBytes \
"{byte: 0, data: [1, 0]}"
EtherCAT Diagnostic Services#
These services provide low-level EtherCAT diagnostics and are hosted by
wmx_ethercat_node (source: wmx_ethercat_node.cpp). The node becomes
active after wmx_engine_node publishes /wmx/engine/ready.
Custom service types used:
wmx_r2_message/srv/EcatGetNetworkState
int32 master_id
---
bool success
string message
# Master info
int32 master_state # EcStateMachine: 0=None 1=Init 2=Preop 4=Boot 8=Safeop 16=Op
int32 master_mode # EcMasterMode: 0=Cyclic 1=PP 2=Monitor
uint32 comm_period
uint32 total_axes
uint32 packet_loss
uint32 over_cycle
# Per-slave arrays (parallel, one entry per slave)
int32 num_of_slaves
int32[] slave_ids
int32[] slave_states
bool[] slave_offline
bool[] slave_inaccessible
uint32[] slave_vendor_ids
uint32[] slave_product_codes
# (plus additional timing and addressing fields)
wmx_r2_message/srv/EcatRegisterRead
int32 master_id
int32 slave_id
int32 reg_address # valid range: 0x000–0xFFF
int32 length # valid range: 1–4096 bytes
---
bool success
uint8[] data
string message
wmx_r2_message/srv/EcatResetStatistics / EcatStartHotconnect
Both take only int32 master_id in the request and return
bool success + string message.
/wmx/ecat/get_network_state#
Query the complete EtherCAT network state including master and all slave
devices. Useful for verifying that all drives are online and in operational
state (slave_states = 16).
Example:
ros2 service call /wmx/ecat/get_network_state \
wmx_r2_message/srv/EcatGetNetworkState "{master_id: 0}"
/wmx/ecat/register_read#
Read raw EtherCAT register data from a specific slave device. Primarily used for low-level diagnostics.
Example – Read 4 bytes from register 0x0130 of slave 1:
ros2 service call /wmx/ecat/register_read \
wmx_r2_message/srv/EcatRegisterRead \
"{master_id: 0, slave_id: 1, reg_address: 304, length: 4}"
/wmx/ecat/reset_statistics#
Reset EtherCAT packet counters (packet loss, timeout, over-cycle counts). Useful when starting a measurement window.
Example:
ros2 service call /wmx/ecat/reset_statistics \
wmx_r2_message/srv/EcatResetStatistics "{master_id: 0}"
/wmx/ecat/start_hotconnect#
Initiate the EtherCAT hot-connect procedure for dynamic slave addition.
Example:
ros2 service call /wmx/ecat/start_hotconnect \
wmx_r2_message/srv/EcatStartHotconnect "{master_id: 0}"
Service Call Workflow#
For standalone axis control (without MoveIt2), call services in the following order.
Setup phase:
/wmx/engine/set_device– Create the WMX device/wmx/engine/set_comm– Start EtherCAT communication/wmx/axis/set_gear_ratio– Configure encoder mapping/wmx/axis/set_polarity– Set rotation directions/wmx/axis/clear_alarm– Clear any existing faults/wmx/axis/set_mode– Select position or velocity mode/wmx/axis/set_on– Enable servo drives/wmx/axis/homing– Set home position
Motion phase:
Use the motion topics (/wmx/axis/velocity, /wmx/axis/position,
/wmx/axis/position/relative) documented in ROS2 Topics.
Shutdown phase:
/wmx/axis/set_on(data=[0,…]) – Disable servos/wmx/engine/set_comm(data=false) – Stop communication/wmx/engine/set_device(data=false) – Close device
Error Handling#
All services follow a consistent error reporting pattern:
Engine services return
success=falsewith the WMX error code and human-readable description inmessageAxis services apply operations per-axis and return
success=trueonly if all axes succeeded. Themessagefield contains concatenated results for each axis, including error codes for any that failedError format:
"Failed to [operation] axis [N]. Error=[code] ([description])"Gripper service returns
success=falsewith a description if the I/O write fails
See Also#
ROS2 Actions – FollowJointTrajectory action for MoveIt2 integration
ROS2 Topics – Motion command topics and state feedback
wmx_r2_message – Custom message type definitions