jhelovuo / ros2-client

ROS2 client library based on RustDDS
68 stars 15 forks source link

Server not detected by ros2 cli #4

Closed curiousmindflow closed 2 years ago

curiousmindflow commented 2 years ago

Hello,

I'm trying to test the server feature, sadly i'm not able to even see the service through ros2 cli. My example is in my fork

Is the server showing on your side ?

jhelovuo commented 2 years ago

You are wandering into untested territory here. So far I have been making experiments from the client side only.

The server implementation may be e.g. missing something, such as some registration, or topic naming may be wrong, or QoS may be wrong. As stated before, there is very little documentation available on how ROS2 actually implements the services.

Topic naming and QoS mismatches you should be able to see from RustDDS logs, if you increase the verbosity level to activate the debug printouts in the reader and writer

One debugging/reverse-engineering method would be to set up a functioning Python server and trace its communication using Wireshark, then compare that to this implementation. Another method would be to read the sources of various ROS2 libraries and see if you can spot the missing ingredient.

curiousmindflow commented 2 years ago

Exciting !

I was able to let the server available, it was just a little omission. The suffix for the server topic name was not the same as the one used for the client. So, no big thing.

I can now see the server and request it from a python ros2 node. The request is correctly received. The response on the other hand is never received by the client.

I compare with wireshark, as you suggested, the traffic ros2/rustdds, saddly for the Data(p) RTPS packet, there is apparently no clue. Still with wireshark, i noticed a lot of HEARTBEAT RTPS packet for the rustdds server. Almost no one with the ros2 server.

I joined both record in this message wireshark_records.zip .

curiousmindflow commented 2 years ago

I also noticed that for the client (rustdds -> ros2 server), the fn unwrap_response(...) return a r_id full of 0 values.

jhelovuo commented 2 years ago

Good to hear that you got something working and are on the right track. Please make a pull request.

Wireshark knows quite a bit about RTPS: Packets marked DATA(p) are part of the participant discovery protocol SPDP. If you are looking for user data and not DDS discovery messages, you should look for packets marked as "DATA" without parenthesis suffix.

HEARTBEAT (sub)messages are announcements of data availability, not any payload.

curiousmindflow commented 2 years ago

Hmmm... i don't see any packet with just "DATA", no prefix/suffix.

I even wrote a server message based on test_msgs/srv/BasicTypes and wrote a long string just to be sure it will pop very strongly in the wireshark ascii parser.

Still no trace of those messages.

I will make a pull request after some cleaning.

jhelovuo commented 2 years ago

Using a long string as a marker is a good idea, but keep it under 1 kbyte to fit into one UDP packet, as RustDDS does not yet support fragmentation at the RTPS level.

If you are not seeing any user DATA messages in RTPS, then there is a good chance that RTPS readers/writers are not matching each other and therefore not sending anything.

The way to diagnose that is to configure logging and set the "root" level to info or debug. Then you should see the match/mismatch messages output in the reader/writer code linked above. Match indicates that RustDDS reader/writer accepts the other end writer/reader. If there is a mismatch, the other end is seen, but not accepted because of QoS settings. If there is neither, then the reader and writer do not see each other, because e.g. they are not on the same topic or similar.

curiousmindflow commented 2 years ago

I'm able to see all the logs from INFO level, in example ros2_service_server. I didn't use log4rs on my example, but pretty_env_logger, to enable the level you want you have to set RUST_LOG={log_level}

For the client, no issue. This works fine, at least apparently. For the server, there is no error in log, and there is a match between writer and reader and between reader and writer.

Regarding the DATA messages, i don't see them even with the client, who works.

stuck... i continue the search

curiousmindflow commented 2 years ago

I created a custom ros2 idl message as 'marker' message.

Stil not able to see it in wireshark, even the request who is well received (from ros2 cli call command)

jhelovuo commented 2 years ago

Hmm. So you are able to send and receive a request, but Wireshark does not see it?

Maybe this is a multicast problem? Are you running Wireshark on another host? Has it joined the multicast group used by DDS? Are you seeing any messages sent to a multicast address?

My configuration for Wireshark is to set it to capture all UDP packets and then show only RTPS.

curiousmindflow commented 2 years ago

Okay, i'm now able to see the DATA packet. I'm joined two captures.

Those tests are done on one host only. There is no multicast use.

For the exercise, i tried to host the server on my pc and run the client on another. There was multicast involved, but still, the same behavior occurred. The request is well received but no responses rustdds_.zip .

jhelovuo commented 2 years ago

I can confirm your results: Client side works, but server needs work.

When testing the server side against rclpy minimal_client, it looks like data appears on the wire, but ROS2 rcl is not happy with it.

Request for AddTwoInts: a=41, b=1

Note the DATA submessage, field serializedData contains 0x29 and 0x01 as 64-bit ints.

image

And response:

There the serializedPayload contains just 0x2a, again as 64-bit int.

image

I pulled your example code into my repo into branch more_examples.

Is it ok for you if I later merge them?

This needs further investigation. Possibly the response id is not correctly sent, so rclpy (or rcl under that) cannot correlate the response to its request.

curiousmindflow commented 2 years ago

Ok, at least we can be sure that there is an issue with that.

Yes, yes, sure. You are in charge here :) !

I will try to investigate that in the future days, but not sure i will have time immediately.

jhelovuo commented 2 years ago

@curiousmindflow , how about now?

Just merged your branch into master. There were multiple issues with RustDDS, but they should now be fixed in the latest github master branch.

Thanks for the AddTwoInts examples. They should now work both ways against ROS2. Tested with ROS2 Galactic, running both the rclpy and rclcpp examples. ROS2 was run on top of both eProsima FastRTPS and RTI Connext.

The Parameter examples compile, but do not yet work. Maybe you would like to take a shot at those?

Please configure your editor to maintain code indentation at two spaces per level, so it will be easier to merge. I am developing this on Rust stable channel, so I had to revert some of the newer println! syntax to the stable one.