Exercise 2.4 question - working with messages and ros1_bridge

So far I’m following without much trouble. But I cant so far see how you get from the information you can get from the shells to write " RCLCPP_INFO(this->get_logger(), “I heard: ‘%d’”, msg->pose.pose.position.x);

I mean, I understand how you get to:
“user:~$ ros2 interface show geometry_msgs/msg/PoseWithCovariance” which gives you:

# This represents a pose in free space with uncertainty.

Pose pose

# Row-major representation of the 6x6 covariance matrix
# The orientation parameters use a fixed-axis representation.
# In order, the parameters are:
# (x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis)
float64[36] covariance

But how do you go from that info to know that you have to type it “pose.pose.position.x”?

In the explanation you say one can see the whole Odometry message to understand how to access the info and give a link:

" So here, you can have a look at the whole structure of the Odometry message in order to better understand how to properly access the different levels of the message (which is shown in the code)."

But that link goes nowhere or it doesnt work for me at least.

I should also mention that I do have ros bridge running, all shells sourced, but if i issue "ros2 topic list i only get 2 topics. This is an issue others have mentioned in the forum. ( here) But apparently you guys have not yet found an official solution to the problem or made the necessary clarifications/changes.

I can see the topic if I issue: rostopic list tho. Is just the ros2 command doesnt get the whole list of topics?

If you issue : “ros2 topic echo /odom nav_msgs/msg/Odometry” as you suggest in the solution, from a ros2 sourced shell nothing happens or sometimes it throws the following message:

user:~$ ros2 topic echo /odom nav_msgs/msg/Odometry
Traceback (most recent call last):
File “/opt/ros/foxy/bin/ros2”, line 11, in
load_entry_point(‘ros2cli==0.9.7’, ‘console_scripts’, ‘ros2’)()
File “/opt/ros/foxy/lib/python3.8/site-packages/ros2cli/cli.py”, line 67, in main
rc = extension.main(parser=parser, args=args)
File “/opt/ros/foxy/lib/python3.8/site-packages/ros2topic/command/topic.py”, line 41, in main
return extension.main(args=args)
File “/opt/ros/foxy/lib/python3.8/site-packages/ros2topic/verb/echo.py”, line 81, in main
return main(args)
File “/opt/ros/foxy/lib/python3.8/site-packages/ros2topic/verb/echo.py”, line 97, in main
message_type = get_message(args.message_type)
File “/opt/ros/foxy/lib/python3.8/site-packages/rosidl_runtime_py/utilities.py”, line 30, in get_message
raise ValueError(“Expected the full name of a message, got ‘{}’”.format(identifier))
ValueError: Expected the full name of a message, got ‘nav_msgs/msg/Odometry’

To summarize:
1.- Could you please explain/clarify how to get the proper information on how to access the different levels of the Odometry messages in order to write the code “msg->pose.pose.position.x”
2.- Could you explain/look into why even with sourced shells commands like “ros2 topic list” dont show all the topics? and why “ros2 topic echo /odom nav_msgs/msg/Odometry” doesnt work?

Granted being the absolute beginner i am i might have messed up something while trying to find a solution so please explain it considering im new to this. Thanks.

B

Hi,

  1. To access the levels of the odometry messages, you need to know what type of message odometry is. From this you can quickly figure out which fields it has. Like you said, there are parameters pertaining to pose and twist. Pose is position, and twist velocity. That is why you access to the x field of the odometry. If you wanted to see how fast you are going, you would do something like msg->pose.twist.velocity.x, for example.

  2. This is probably because the ROS bridge isn’t working correctly. Can you see any output from the bridge when you launch it?

Hey there. Thanks for replying.

I think I understand so far how to see the components of a message. For example, if I do a > rostopic echo /odom ( in a ros1 sourced shell) i get the whole message. But how do i extract the correct nomenclature/syntax to a particular element in the message?

I get for example:

user:~$ rostopic echo /odom

header:
seq: 34771
stamp:
secs: 1738
nsecs: 747000000
frame_id: “odom”
child_frame_id: “base_footprint”
pose:
pose:
position:
x: 0.01557208025804135
y: 0.00023436732522432775
z: -0.0002467784029049347
orientation:
x: 0.00039292977908080197
y: -0.007209945653598375
z: 0.0008363202951627082
w: 0.9999735810801328
covariance: [1e-05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1e-05, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000000000000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.001]
twist:
twist:
linear:
x: -0.00014899969784919686
y: -3.135810273773937e-05
z: 0.0
angular:
x: 0.0
y: 0.0
z: -6.400556547483302e-05
covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

Should I assume then, that x, is an element of “position”, which is an element of “pose”, which is an element of “pose”. And therefore i must write it as “pose.pose.position.x” with no capitals because thats how i see it in the “echo” of the topic?

If I do a:
user:~$ rosmsg show nav_msgs/Odometry
std_msgs/Header header

  • uint32 seq*
  • time stamp*
  • string frame_id*
    string child_frame_id
    geometry_msgs/PoseWithCovariance pose
  • geometry_msgs/Pose pose*
  • geometry_msgs/Point position*
  •  float64 x*
    

Then Seems a bit more clear that the tree is “pose.pose.position.x”

you wrote " you would do something like msg->pose.twist.velocity.x , for example.", but i see that twist is an element of twist. So shouldnt I have to write it as “msg->twist.twist.linear.x”??

But if I do a $ ros2 interface show geometry_msgs/msg/PoseWithCovariance then i get this: ( which would be the command for ros2)

$ ros2 interface show geometry_msgs/msg/PoseWithCovariance
#This represents a pose in free space with uncertainty.

Pose pose

#Row-major representation of the 6x6 covariance matrix
#The orientation parameters use a fixed-axis representation.
#In order, the parameters are:
#(x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis)
float64[36] covariance

But i dont see the tree directly there… Also it shows one pose with capital, the other without capital, how would i know how to use the right one when writing the code?
And it doesnt even mention “position” and i can’t see how I would deduce that x, is of position, that is of pose, that in turn is of pose…

Sorry if this is obvious… but for me as a newby is not apparent and a bit confusing.

On the second subject of ros bridge.

I have sourced all shells. Bridge is running and the “talker” demo works fine. If I launch my topic sub it launches and it reads from /odom so to that end it appears bridge works. But if I do a $ ros2 topic list then I only get 2 topics;

user:~$ ros2 topic list
/parameter_events
/rosout

And if a do a $ ros2 topic echo /odom, then i get:

user:~$ ros2 topic echo /odom
WARNING: topic [/odom] does not appear to be published yet
Could not determine the type for the passed topic
user:~$

but if I do a $rostopic echo /odom then i get the full echo of the topic. So the topic definitely has info in it.

I should not that after running my topic sub, ros bridge shows the following:

reated 1to2 bridge for topic ‘/odom’ with ROS 1 type ‘nav_msgs/Odometry’ and ROS 2 type ‘nav_msgs/msg/Odometry’
[INFO] [1620413016.576852486] [ros_bridge]: Passing message from ROS 1 nav_msgs/Odometry to ROS 2 nav_msgs/msg/Odometry (showing msg only once per type)
removed 1to2 bridge for topic ‘/odom’

So it it normal that bridge is only active while a ros2 sub is actually using the topic? seems like it kills the connection as soon as the ros2 sub is stopped.
That would mean actually that I will have to keep issuing commands on ROS1 in order to work with ROS2 as to read the “echo” of a ROS1 topic etc…

I hope to understand this clearly before i move forward with the rest of the course.

Thank you.

B

Hello @bernard.arriagada ,

Yes, with the current configuration, the bridge only creates the connection when it detects a subscriber in the topic. You have the option though to bridge all the topics with this command:

ros2 run ros1_bridge dynamic_bridge --bridge-all-topics

However, this mode takes more resources obviously.

With the regular configuration (without bridging all the topics), though, you can subscribe to the /odom topic with the following command:

ros2 topic echo /odom nav_msgs/Odometry

As for how to get the structure of a message, let me try to clarify it up. First of all, yes, you are right. To access the twist you would write msg->twist.twist.linear.x Can you point me out where we said it’s msg->pose.twist.velocity.x so that I can modify it?

Also, in ROS2, the structure of the message is not directly shown with the ros2 interface show command as you point out, which makes it a bit trickier. However, you can see the full structure of the message by subscribing it to it with the ros2 topic echo command. The other option is to check each message contained in the main message. For instance:

ros2 interface show nav_msgs/msg/Odometry
ros2 interface show geometry_msgs/msg/PoseWithCovariance

and so on… Then, if you find the following structure:

Pose pose

The Pose in capitals is an interface (ros2 interface show geometry_msgs/msg/Pose), and the other pose is the name of the variable (the name you would use to access the value).

Does it make sense?

1 Like

Hi, I’m sorry, you’re right I made a mistake, it should be msg->twist.twist.linear.x

Thank you very much man, that helped a lot. Although there are still a few things I’d appreciate some help with. If you dont mind i’ll quote your response to make it clearer.

"Yes, with the current configuration, the bridge only creates the connection when it detects a subscriber in the topic. You have the option though to bridge all the topics with this command:

ros2 run ros1_bridge dynamic_bridge --bridge-all-topics

However, this mode takes more resources obviously."

I’d suggest you guys add a little section explaining this in the Bridge section of the course since I believe it can lend it self for confusion.

The exercise requires that we figure out the messages used in /odom. So one would do a $ ros2 topic list, to make sure we see /odom but that wont show us /odom because we havent created any sub to keep the bridge active yet (since thats what we are trying to do). If one would directly assume to do a $ ros2 topic info /odom, that wont work because we haven’t created the subscriber yet, so since there’s no active sub… then bridge wont create the connection and we will get the error
“Uknown topic ‘/odom’”. Chicken and the egg kinda situation here i think.

So then I figured I’ll just issue ros1 commands. So I went and issued $ rostopic info /odom on a ros1 sourced shell. that gives me that the message to use is nav_msgs/Odomoetry. But I dont think this course is assuming im familiar with ros1 commands…

So now I have the msg for /odom. But if i do $ ros2 interface show nav_msgs/Odometry, which i got from rostopic info ( issuing ros1 commands)… then i get an error: Could not find the interface ‘/opt/ros/foxy/share/nav_msgs/Odometry.idl’

How did you know you had to add “msg” between ‘nav_msgs’ and ‘Odometry’? ( as to get $ ros2 interface show nav_msgs/msg/Odometry in your explanation)

Because although "$ ros2 topic echo /odom nav_msgs/Odometry " works and it gives me the info I need, i believe ( unless i absolutelly missed it, and i admit is possible) so far in the course I was never told I could echo a particular message of a topic I dont even see listed after doing a $ ros2 topic list. since this last command only shows me 2 topics.

So, lets assume I understand how why to add nav_msgs/msg/Odometry. If i issue that i get: geometry_msgs/PoseWithCovariance pose. But again to see it I need to add the “MSG” between geometry_msgs and PoseWith…
So lets Assume i understand again i have to add the msg and issue " ros2 interface show geometry_msgs/msg/PoseWithCovariance" . Ill get the Pose pose and that the parameters are “(x, y, z, rotation about X axis, rotation about Y axis, rotation about Z axis)” etc…
But in that result i dont see the “position” element in order to write pose.pose.position.x

Man im sorry im hard headed and don’t understand this, but i trully don’t think is so obvious if you are doing this course as a newbie which i think is supposed to be made for. I just want to know i really understand the logic behind the process.

For example, in the solution you see:

So now, you can keep checking how this message types are composed. For instance, you could check the geometry_msgs/PoseWithCovariance message with the following command: ros2 interface show geometry_msgs/msg/PoseWithCovariance

He just adds the msg part even tho it was not in the previous part. did i really miss it in the course? because i can’t find it :confused: ( not saying i didn’t miss it, its possible)

So far it seems you can “echo” it without the msg part: “$ ros2 topic echo /odom nav_msgs/Odometry”

but you need to interface show WITH the msg part…: $ ros2 interface show nav_msgs/msg/Odometry

Thank you for your time

B

No worries man, im just trying to make sure i understand

I understand the confusion @bernard.arriagada . I will update the notebook in order to better clarify this part, probably using the --bridge-all-topics argument to simplify things. For now, just keep in mind that for the interface command, you will always have to specify the interface folder (msg, srv or action).

1 Like

Hola Alberto

its been a long time but im back at learning ros with you guys. So I started all over again to refresh the memory, but now that i’m where I left last time, I see no corrections have been made to this subject, and again I’m trying to understand how I could with only the information of the course, do this properly and keep the bridge active in order to read the /odom topic from ros 2 without using any ros 1 commands. I still dont see any mentions of needing to subscribe to the topic first so the bridge can show me odom etc.
I know you guys are pros at this so seems like you guys are making assumptions about things that should be known, but this course is basics, and people like me that are just learning we dont know a lot of things and we can get lost easily and we cant make jumps in logic if we havent been shown the steps.

Any chance you guys could look into it? I can get the results but only if i use ros 1 commands which shouldnt be required in this course. I still dont see how one can get the results using ONLY ros 2 commands and based ONLY on the info provided in the course.
Hope you guys can make some edits to clarify the subject.

Thanks!

Hello @bernard.arriagada ,

Welcome back! My apologies for not adding these modifications before, as I told you I would. I have just added them now based on the comments of this post.

  • I’ve added a final section in the ROS Bridge chapter
  • I’ve added some extra notes in Exercise 5.2

Please let us know if you think the course needs more clarification in other sections also.

Best,

2 Likes

This topic was automatically closed after 4 days. New replies are no longer allowed.