Rosbridge Driver
This driver uses the rosbridge_suite with the python client roslibpy to allow topic publishing and subscribing in a running ROS device.
The host needs to run the rosbridge websocket server. Installation instructions can be found at https://wiki.ros.org/rosbridge_suite.
Parameters
Aside from the common parameters described in the communication_driver docs, this driver includes:
Parameter | Default Value | Description |
---|---|---|
host | localhost | ROS host name. |
port | 9090 | Port assigned to ros_bridge. |
channel | 0 | Communication channel. Necessary to use when using the special ROS Message Types. |
Setup Data
The setup data will give values to the parameters required and will specify the topics info. Variables with operation = write
will be configured as publishers, while variables with operation = read
are subscribers.
Two special variable names are reserved and can be used to publish and subscribe to ros topics with message types that are not part of the standard Simumatik data types (bool
, byte
, int
, word
, dword
, qword
, float
, str
). The variables are ros_message_request
which is used to send requests to the Gateway to publish or subscribe to topics, and ros_message_response
which gives updates from the subscribed variables. For more info, see the section about ROS Message types These variables need to be defined as in the example below.
{
"parameters": {
"host": "192.168.1.100",
"port": 9090,
"channel": 0
},
"variables": {
"publisher_00": {
"datatype": "word",
"size": 1,
"operation": "write"
},
"subscriber_00": {
"datatype": "word",
"size": 1,
"operation": "read"
},
"ros_message_request": {
"datatype": "str",
"size": 1,
"operation": "write"
},
"ros_message_response": {
"datatype": "str",
"size": 1,
"operation": "read"
},
}
}
The setup_params in the generic PLC components for rosbridge will need the following format:
{ "host": "192.168.1.100", "port": 9090 }
ROS Message Types
The standard Simumatik data types will be converted to ROS message types in the following way.
{
"bool" : "std_msgs/Bool",
"byte" : "std_msgs/Byte",
"int" : "std_msgs/Int32",
"word" : "std_msgs/UInt16",
"dword" : "std_msgs/UInt32",
"qword" : "std_msgs/UInt64",
"float" : "std_msgs/Float32",
"str" : "std_msgs/String",
"string": "std_msgs/String"
}
For other ROS message types, the ros_message_request
and ros_message_response
telegrams can be used, these variables are explained in the sections below.
When several components in a system are using the special ros_message_request
and ros_message_response
variables, it's important that every component uses a separate communication channel. For example, in a system with 2 components, one component can use channel 0
and the other can use channel 1
.
Subscribing to Messages
# Starts subscribing to the specified topic name
msg = {
'subscribed_topic_name': {
'id': 0,
'msg': 'geometry_msgs/msg/Twist',
'subscribe': True,
},
}
# Write the request message to the communication driver
update_input = json.dumps({
'ros_message_request': json.dumps(msg)
})
# Reading value updates of the subscribed variables
new_output_data = json.loads(update_output)
if 'ros_message_response' in new_output_data:
response_data = json.loads(new_output_data['ros_message_response'])
# The values of the message will be available in the 'payload' dictionary
subscribed_topic_response_data = response_data['subscribed_topic_name']['payload']
linear_x = subscribed_topic_response_data['linear']['x']
Publishing Messages
# Build a dictionary of all topics to publish, where the payload is the contents of the message
msg = {
'topic_1': {
'id': 0,
'msg': 'sensor_msgs/msg/LaserScan',
'subscribe': False,
'payload': {
'header': {
'frame_id': frame_id,
},
'angle_increment': ANGLE_INCREMENT,
'angle_min': -ANGLE_RANGE/2,
'angle_max': ANGLE_RANGE/2,
'range_min': RANGE[0],
'range_max': RANGE[1],
'ranges': ray_data_list,
}
}
}
# Write the dictionary of topics in the request telegram as a json formatted string
update_input = json.dumps({
REQUEST_TELEGRAM_VAR: json.dumps(msg)
})