Exercise 3.1 please explain the python code exercise31.py in detail

I am new to ros. Could you please add more explanation to the Python code of the exercise solution?

Why do you combine publisher and subscriber into one node?

What is the meaning of the Twist message? We know it represents the velocity of three directions but what exactly x, y, z means in terms of a robot? Could you please share a figure? I believe it is different for different robots. It would be nice if you distinguished it instead of just giving us a solution without any explanation.
I searched online, it shows that “For a ground robot, most probably your angular velocity will be in z i.e. robot’s turning speed. And your linear velocity will be mostly in x i.e. robot’s moving straight speed.” However, how can we know setting angular.z to a positive number means turning left instead of right?

In the laser_callback function, how can you know the meaning of the range[359] of the message? WHy does it mean the laser beam of 0 degree?

Hi @min.wang.1997.01.13!

Starting foremost with your inquiry regarding the idea of combining publishers and subcribers, our goal for this exercise is to conduct a control scheme for our robot to essentially be able to stop once it detects a wall. Now, for this, we will need the inclusion of a subscriber and a publisher.

Going foremost into the subscriber, its primary purpose if for us to let the robot acquire information about the distance that has been detected in its frontmost sensor. After this, the question then is what will we do with this information? Based on the premise of the problem, our goal is to have the robot traverse in a circular manner then later on shifting to linear and eventually stopping depending on the distance recorded by the sensor. To do this, we then implement a publisher which will then publish the velocities into the /cmd_vel topic which our robot essentially acquires its movement from.

So overall, our node essentially acquires information (subscriber) and processes that information in order to come up with a command or behavior relating to our desired motion for the robot (publisher).

Now, in terms of the Twist message, you may want to read on the idea of Degrees of Freedom (DOF). Based on my understanding of the linear x, y, and z components, these pertain to essentially the x, y, and z axes of a 3-D plane. So relative to the robot, which in this case would be a turtlebot3, its linear/forward motion may then be described as one that traverses along the x-axis (See image acquired from Making a Mobile Robot #2 - Concept Design URDF | Articulated Robotics)

For the angular components, these then describe the rotations of the robot with respect to that axis. Now, from this premise, the reason why we designated the angular velocity to be that of the cmd.angular.z component is because our robot may only rotate with respect to the z axis (See more about Pitch, Yaw, and Roll); and for the numbers, positive pertains to a counter-clockwise motion as this is how we measure positive angles and negative for clockwise motion.

Lastly, for the laser_callback function, you can see this information when you run an echo on the topic /scan. You will be able to see that it outputs a syntax that begins with “range:” which is then followed by all sensor readings. Now, if you wish to know more about the laser positions, I may also suggest that you refer to the documentation of the turtlebot3. But the idea is there essentially are 360 points scattered around the robot. So given our knowledge that 359 pertains to the frontmost laser, you can also do a little experimentation to determine how the remaining sensors are distributed throughout the turtlebot3!

Hope this helps.


Dear Christian,

Thank you very much for your reply! It helps a lot.

I still feel confused about this one:

  • For the first question about publisher and subscriber:
    When should we separate publisher and subscriber (use 2 nodes and create two pkgs) and when should we combine them (one node, one pkg)? It seems to be the same for me - just two implementations…

The rest is my answer to other two questions:

For the coordinate question and answer, I think it is better to understand it in the following way and I think it should be added to the course content rather than assuming everyone knows it.
In ROS (Robot Operating System), it is a convention to use a right-handed coordinate system. This means:

  • The X-axis typically points forward from the robot, which is considered the direction of forward motion.
  • The Y-axis usually points to the left of the robot, following the right-hand rule.
  • The Z-axis points upwards, perpendicular to the ground if the robot is on a horizontal plane.

As for rotation, ROS follows the right-hand rule, which is a common standard in physics and engineering:

  • If you curl the fingers of your right hand around an axis, with your thumb pointing along the direction of the axis, the direction your fingers curl is the positive direction for angular motion around that axis.
  • Thus, for the Z-axis, a positive angular velocity (cmd.angular.z) means that the robot is rotating counter-clockwise when viewed from above, and a negative value means clockwise rotation.

For the laser_call back function, I think index 359 is not correct. It should be 0 in this case.

To be sure about which index corresponds to the forward direction, we should consult the documentation of your specific laser scanner or inspect the angle_min , angle_max , and angle_increment fields in the LaserScan message to calculate the correct index for the desired direction.
The formula:
index = (angle - min_angle) / angle_increment

according to the log:

  1. Angle Min: 0.0
  2. Angle Max: 6.28 (approximately 2π)
  3. Angle Increment: 0.01749303564429283

This configuration suggests that your laser scanner’s field of view (FoV) covers a full circle (360 degrees or 2π radians), starting from 0 radians and going up to approximately 2π radians. Here’s what this means for your measurements:

Front Direction as 0 Degree (or 0 Radians)

The angle_min value of 0.0 indicates that the scanning starts from 0 radians. In many laser scanners, especially those with a 360-degree range, it’s common for the 0-radian point to be defined as the front direction of the scanner (or the robot it’s mounted on). This is likely why the front direction is being referred to as 0 degrees (or 0 radians) in your setup.

The modified laser_callback function is as follows:

def laser_callback(self, msg):
    # Access the fields from the LaserScan message
    angle_min = msg.angle_min
    angle_max = msg.angle_max
    angle_increment = msg.angle_increment

    # Calculate the index for the specific angle (0 degrees in this case)
    specific_angle = 0.0  # Change this value if you're looking for a different angle
    index = int((specific_angle - angle_min) / angle_increment)
    # Log the angle parameters and the calculated index
    self.get_logger().info(f'Angle Min: {angle_min}')
    self.get_logger().info(f'Angle Max: {angle_max}')
    self.get_logger().info(f'Angle Increment: {angle_increment}')
    self.get_logger().info(f'Specific Angle: {specific_angle}')
    self.get_logger().info(f'Calculated Index: {index}')
    # Ensure the index is within the valid range
    if 0 <= index < len(msg.ranges):
        self.laser_forward = msg.ranges[index]
        self.get_logger().info(f'Laser reading at {specific_angle} degrees: {self.laser_forward}')
        self.get_logger().error(f'Calculated index ({index}) is out of range. Check your laser configuration.')

Hi @min.wang.1997.01.13,

Glad that you were able to gain clarity on your inquiries.

For your question regarding nodes, I think this all boils down to how you want your control schemes to be. For instance, the approach here I believe focuses on the simplicity and practicality of the file – essentially only needing to run one single executable to perform two (2) tasks simultaneously which can be considered less resource-intensive in this regard. Now, one idea that I can emphasize on the notion of packages in ROS is that the scripts within a package must primarily focus on a specific purpose or feature of the robot. Therefore, when you want to create multiple packages, these would then essentially represent the other funtionalities of your robot.

In the case of this exercise, I think there wouldn’t be any issue if you want to create a separate node that would acquire the information and another to process it; however, it would simply be a matter of practicality in this context.

Hope this helps as well!


Thank you Christian!

I am sorry there was a mistake in my previous question- when we separate publisher and subscriber, it just needs to define two nodes and there is no need to create two packages…

Could you clarify the relationship between package, node, publisher, subscriber, etc?

I guess we just need one package for one specific feature of the robot, within the one script of a package, you can define a specific node class, and it can be publisher and subscriber at the same time, right?
If I understand correctly, the Topic (and its interface), publisher, and subscriber are just designed for indirect communication (instead of getting the data from a specific sensor directly). The publisher just means write messages to the interface and the subscriber means read messages.

Honestly, the course content makes it a bit confusing…

What is a node in ros? In what kind of cases do we use more than two nodes?
What is the purpose of a package usually? In the courses, it is usually an exercise. In reality, Isn’t it a module based on functions like navigation/localization or based on the hardware like dealing with Lidar/ IMU, etc?

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.