ROS2 commands & Python

I want to use the robot based on ROS2 and python scripts.

Currently, I am trying to set the robot mode - like in Node Red - in order to be allowed to drive. However, I have problems with the format of the service message, both at command line as well as in Python. The reason seems to be the format.

ros2 service call /eduard/orange/set_mode edu_robot/srv/SetMode "{mode: 4, drive_kinematic: 0, feature_mode: 0}"

I also tried:
ros2 service call /eduard/orange/set_mode edu_robot/srv/SetMode “{mode: AUTONOMOUS, drive_kinematic: 0, feature_mode: 0}”

How does the ROS2-cmd-message looks like in order to fullfil the same task as NodeRed? Is there a description in GitHub?

The idea was, that after setting the mode, I can set the speed with another python script. Just like in Node-Red.

Are there any ROS2 examples (in Python) available, how to control the robot with ROS2 directly?

Thanks, Verena

I found out that the service type for setting the mode was wrong:
{“mode”:{“mode”:4,“drive_kinematic”:0,“feature_mode”:0},“disable_feature”:0}

However, I am still not able to produce commands / python code which does the same as the node red flow:

  1. set the drive to automatic mode
  2. write velocity commands which let the robot drive

Which step is missing / or not visible in Node-Red?

Hi Verena,

at the moment I am out of office. I’ll answer your question as soon I am back. This evening or tomorrow morning.

Greetings,

Christian

First command line:

I see the format string is not correct. The mode in the service contains the message type Mode which also contains the filed mode. → Please try “{mode: {mode: 4}}” instead. Btw only values != 0 has to be set. In this case only “mode”.

Second python example:

Below you will find a code snippet with which we have already set the mode in Python.Please note that this is only copied together and that the lines below belong in a function such as main.

import rclpy
from edu_robot.srv import SetMode
from edu_robot.msg import Mode

_srv_set_mode = None

def set_mode_robot(mode) -> None:
    global _srv_set_mode

    set_mode_request = SetMode.Request()
    set_mode_request.mode.mode = mode

    if (_srv_set_mode.service_is_ready() is False):
        print('Service set mode not ready --> cancel operation')
        return

    future = _srv_set_mode.call_async(set_mode_request)
    rclpy.spin_until_future_complete(_node, future)

    if (future.result() is None):
        print("New mode wasn't accepted by the robot.")
    else:
        print("Robot accepted new mode.")

// put below in a function like main()
rclpy.init(args=None)
_node = rclpy.create_node('edu_web_joy')
_srv_set_mode = _node.create_client(SetMode, 'set_mode')
set_mode_robot(Mode.REMOTE_CONTROLLED)
rclpy.spin(_node)
_node.destroy_node()
rclpy.shutdown()

Thank you that is working now. How, can I drive after setting the mode?

I tried that code, it writes on the same node as Node-Red. However, the robot does not drive.

Thanks a lot, Verena

import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
import time
import sys
from rclpy.qos import QoSProfile
from rclpy.qos import QoSProfile, DurabilityPolicy, LivelinessPolicy, ReliabilityPolicy, HistoryPolicy
from rclpy.duration import Duration

def publish_cmd_vel_message(node):
    qos_profile = QoSProfile(
        depth=10,  # Depth setting (UNKNOWN in the provided settings)
            reliability=ReliabilityPolicy.RELIABLE,
            durability=DurabilityPolicy.TRANSIENT_LOCAL,
            lifespan=Duration(seconds=0),  # Infinite in the provided settings
            deadline=Duration(seconds=0),  # Infinite in the provided settings
            liveliness=LivelinessPolicy.AUTOMATIC,
            liveliness_lease_duration=Duration(seconds=0)  # Infinite in the provided settings
    )

    pub = node.create_publisher(Twist, '/eduard/orange/autonomous/cmd_vel', qos_profile)
    msg = Twist()

    # Fill in the message with the desired values
    msg.linear.x = 0.05
    msg.linear.y = 0.0
    msg.linear.z = 0.0
    msg.angular.x = 0.0
    msg.angular.y = 0.0
    msg.angular.z = 0.2

    turn = 0
    while rclpy.ok():
        pub.publish(msg)  # Publish the Twist message
        node.get_logger().info('Published cmd_vel message')
        time.sleep(0.1)  # 0.1 Sekunden Verzögerung zwischen den Wiederholungen
        turn = turn + 1
        # Beenden Sie das Programm nach dem Senden der Nachricht
        if turn >= 10:
            sys.exit(0)

def main(args=None):
    rclpy.init(args=args)
    node = Node('cmd_vel_publisher')
    try:
        publish_cmd_vel_message(node)
    except KeyboardInterrupt:
        pass  # Catch Ctrl+C and continue to the cleanup
    finally:
        node.destroy_node()
        rclpy.shutdown()

if __name__ == '__main__':
    main()

Could somebody please help me. I added the code above. How, can I drive the robot via (Python) Code programmed.

Hi Verena,

I can see that the QoS is wrong. The reliability must be “best effort” and the durability must be Volatile. The rest seems fine to me.

Greetings,

Christian