With the help of responses from this topic (see https://forum.coppeliarobotics.com/view ... hp?t=10791), I can now create a AddFourInts.srv service message and use it in a Coppelia python threaded script.
Code: Select all
def sysCall_init():
sim = require('sim')
simROS2 = require('simROS2')
global srv
sim.addLog(sim.verbosity_msgs, 'Thread started')
# Create the ROS2 service
srv = simROS2.createService('/add_four_ints', 'tutorial_interfaces/srv/AddFourInts', srv_callback)
def sysCall_thread():
while not sim.getSimulationStopping():
# Keep the thread alive
sim.wait(0.01) # Wait for 10ms before the next iteration
def srv_callback(req):
sim.addLog(sim.verbosity_msgs, f'Service called: {req}')
# Create the response
resp = simROS2.createInterface('tutorial_interfaces/srv/AddFourIntsResponse')
resp['sum'] = req['a'] + req['b'] + req['c'] + req['d']
return resp
def sysCall_cleanup():
# Shutdown the ROS2 service
simROS2.shutdownService(srv)
sim.addLog(sim.verbosity_msgs, 'Thread finished')
Code: Select all
ros2 service call /add_four_ints tutorial_interfaces/srv/AddFourInts "{a: 2, b: 3, c: 4, d: 5}"
requester: making request: tutorial_interfaces.srv.AddFourInts_Request(a=2, b=3, c=4, d=5)
response:
tutorial_interfaces.srv.AddFourInts_Response(sum=14)
So,I've added, in the tutorial_interfaces/src folder, the file MyImage.srv :
Code: Select all
---
sensor_msgs/Image image
Code: Select all
find_package(sensor_msgs REQUIRED)
Code: Select all
<depend>sensor_msgs</depend>
Code: Select all
ros2 interface show tutorial_interfaces/srv/MyImage
---
sensor_msgs/Image image
std_msgs/Header header #
builtin_interfaces/Time stamp
int32 sec
uint32 nanosec
string frame_id
# Header frame_id should be optical frame of camera
# origin of frame should be optical center of cameara
# +x should point to the right in the image
# +y should point down in the image
# +z should point into to plane of the image
# If the frame_id here and the frame_id of the CameraInfo
# message associated with the image conflict
# the behavior is undefined
uint32 height #
uint32 width #
string encoding #
# taken from the list of strings in include/sensor_msgs/image_encodings.hpp
uint8 is_bigendian #
uint32 step #
uint8[] data #
Code: Select all
tutorial_interfaces/srv/MyImage
Now, I've created a new threaded python script with a service called
Code: Select all
/vision_sensor
Code: Select all
# Ensure that this script is added as a threaded child script in CoppeliaSim
# Set the script's interpreter to Python
from sensor_msgs.msg import Image
def sysCall_init():
sim = require('sim')
simROS2 = require('simROS2')
self.visionSensor = sim.getObject('/visionSensor')
global srv
sim.addLog(sim.verbosity_msgs, 'Thread started')
# Create the ROS2 service
srv = simROS2.createService('/vision_sensor', 'tutorial_interfaces/srv/MyImage', srv_callback)
def sysCall_thread():
while not sim.getSimulationStopping():
# Keep the thread alive
sim.wait(0.01) # Wait for 10ms before the next iteration
def srv_callback(req):
sim.addLog(sim.verbosity_msgs, f'Service called: {req}')
# Create the response
resp = simROS2.createInterface('tutorial_interfaces/srv/MyImageResponse')
print('==================')
data, resolution = sim.getVisionSensorImg(self.visionSensor)
resp['image'] = Image()
#resp['image'].header.stamp = ??
resp['image'].height = resolution[1]
resp['image'].width = resolution[0]
resp['image'].encoding = 'rgb8'
resp['image'].is_bigendian = 1
resp['image'].step = resolution[0] * 3
#resp['image'].data = data
print('image generated')
return resp
def sysCall_cleanup():
# Shutdown the ROS2 service
simROS2.shutdownService(srv)
sim.addLog(sim.verbosity_msgs, 'Thread finished')
Code: Select all
ros2 service call /vision_sensor tutorial_interfaces/srv/MyImage
Code: Select all
requester: making request: tutorial_interfaces.srv.MyImage_Request()
response:
tutorial_interfaces.srv.MyImage_Response(image=sensor_msgs.msg.Image(header=std_msgs.msg.Header(stamp=builtin_interfaces.msg.Time(sec=0, nanosec=0), frame_id=''), height=0, width=0, encoding='', is_bigendian=0, step=0, data=[]))
but on the Coppelia console, I can see :
Code: Select all
[/scriptCamera:info] Thread started
[/scriptCamera:info] Service called: {}
==================
image generated
[/scriptCamera:warning] Received non-serializable data: {'image': sensor_msgs.msg.Image(header=std_msgs.msg.Header(stamp=builtin_interfaces.msg.Time(sec=0, nanosec=0), frame_id=''), height=256, width=256, encoding='rgb8', is_bigendian=1, step=768, data=[])}
Why?
Do you have any example of how to use service with custom message with Coppelia?
Philippe