v-kiniv / rws Goto Github PK
View Code? Open in Web Editor NEWWebSocket gateway for ROS2 topics and services
License: Apache License 2.0
WebSocket gateway for ROS2 topics and services
License: Apache License 2.0
Hi @v-kiniv
The multithreaded executor is not actually using more than one thread. In order to achieve that you need multiple callback groups, see the example at
https://github.com/ros2/examples/blob/95c3b145e4f75c24e1617d97acc3d349ad67e78f/rclcpp/executors/multithreaded_executor/multithreaded_executor.cpp#L78-L81
However, to minimize CPU usage, I suggest testing out the "static" single threaded executor. See ros2/rclcpp#1034 and ros2/rclcpp#873
After switching rclcpp::executors::MultiThreadedExecutor executor;
to rclcpp::executors::StaticSingleThreadedExecutor executor;
I suggest testing to see if CPU usage decreases.
Alright so I'm back at this and I've finally figured out what's going wrong with service calls on humble.
Here's a simple rclpy service I've tested with that prints that it's been called and returns a test string.
self.create_service(Trigger, '/test', self.test)
def test(self, req, res):
self.get_logger().info("Test service called!")
res.success = True
res.message = "Service handler online."
return res
Called from the terminal it returns all as it should:
ros2 service call /test std_srvs/srv/Trigger {}
requester: making request: std_srvs.srv.Trigger_Request()
response:
std_srvs.srv.Trigger_Response(success=True, message='Service handler online.')
And the service reports being called:
[service_handler_node-4] [INFO] [1705673112.498633772] [service_handler_node]: Test service called!
Calling it from Foxglove however, yields a {}
, which I suspect is a client side fix since calling it manually from roslibjs returns undefined
.
What's interesting though is that the services genuinely get called on the ROS side:
[service_handler_node-4] [INFO] [1705673112.498633772] [service_handler_node]: Test service called!
[service_handler_node-4] [INFO] [1705673133.305536556] [service_handler_node]: Test service called!
[service_handler_node-4] [INFO] [1705673333.699421237] [service_handler_node]: Test service called!
[service_handler_node-4] [INFO] [1705673338.410078049] [service_handler_node]: Test service called!
The response just doesn't make it back. So there's some issue in parsing that part. In case it helps tracking the issue down, the errors I'm getting are:
rmw_serialize: invalid data size, at ./src/rmw_node.cpp:1727
and
'Handle's typesupport identifier (rosidl_typesupport_cpp) is not supported by this library, at ./src/type_support_dispatch.hpp:111'
I'm seeing the same behaviour on both cyclone and dynamic fastrtps.
I've noticed a difference in behavior of rws compared to rosbridge when using subscriptions through roslibjs. With rosbridge, if I subscribe to the same topic from two places and unsubscribe once, I still get messages to the remaining subscriber. With rws, this is not the case. It appears rosbridge keeps track of the ids of the subscribers and does not kill the ros subscription until all subscribers of a topic have unsubscribed.
Looking at the ROSLIB.Topic object created it seems it has a concept subscribeId: "subscribe:/echoer/int32:805"
with a number at the end, unique to each subscriber. When calling subscribe, this is passed to the bridge as
{"op":"subscribe","id":"subscribe:/echoer/int32:805","type":"std_msgs/msg/Int32","topic":"/echoer/int32","compression":"none","throttle_rate":0,"queue_length":0}
While one might argue keeping track of this should be done in roslibjs rather than in the bridge, that's how it works today and it would be nice to be able to use roslibjs with rws as is.
Right now, RWS is using websocketpp, asio and nlohmann/json and these 3 libraries will be fetched by CMake during configuration step. Is there a reason they need to be built like this? Can the libraries installable via apt
work?
You can add the following to the package.xml
file
<build_depend>asio</build_depend>
<build_depend>nlohmann-json-dev</build_depend>
<build_depend>libwebsocketpp-dev</build_depend>
Then the rosdep
tool can be used to install the correct packages from apt
. Note that the rosdep tool works for other linux distributions than just Ubuntu.
Maybe you can also change the CMakeLists.txt to attempt to find_package
and if it fails to find a package then fetch and build? I also think that automatic fetching and building should be an option that is disabled by default.
So this is something more of a suggestion than a bug report, I've noticed that there can seemingly only be one client connected to one topic at a time.
If I e.g. open two browser windows that both subscribe to the same long list of topics at roughly the same time, they'll seemingly split the list in two, one receiving some and the other what's left depending on which connection gets there first. I suspect some of the bugs I've seen in the past were made a bit more confusing due to this.
There is the issue of course that mobile browser suspended clients or background windows will pull resources when not actually being used, which serving only the latest one solves, but it also prevents multiple instances of the same app running concurrently. Besides, the watchdog should take care of those instances to some extent, right?
The rosbridge default behaviour is to send all data to all clients, so it would be nice to have parity there.
Hi @v-kiniv
One great benefit that this websocket server can have over a python based on is the ability to run it as a component node in the same process as other c++ nodes to help share memory for ROS messages. So to get the best benefits of using c++ over python, consider exposing the node as a component. See https://docs.ros.org/en/humble/Concepts/About-Composition.html
Hi @v-kiniv
Cool library!
Im trying it out a bit, pub sub works great and some service calls.
But i get a silent crash when i try to call a service with the following interface
/foo/list_parameters
rcl_interfaces/srv/ListParameters
The same goes for other services of rcl_interface types.
The line that seems failing is:
rmw_deserialize(sm, req_ts_hdl_, buf.get());
Any ideas what might cause this issue?
Do all nodes that i spawn run rmw_fastrtps_dynamic_cpp?
Hey, I just wanted to try this out since it seems like a good stopgap replacement for rosbridge, especially given how monumental moving to Foxglove's protocol would be. Unfortunately it seems to be missing some middleware dependencies on Humble? I'm not entirely sure.
I see the repo's been somewhat stale since last year, but in case there's still any maintenance planned I'd be glad to test out any fixes or ideas that may get us closer to one.
Starting >>> rws
--- stderr: rws
CMake Deprecation Warning at /home/ubuntu/colcon_ws/build/rws/_deps/websocketpp-src/CMakeLists.txt:5 (cmake_mini mum_required):
Compatibility with CMake < 2.8.12 will be removed from a future version of
CMake.
Update the VERSION argument <min> value or use a ...<max> suffix to tell
CMake that the project does not need compatibility with older versions.
** websocketpp
=========== Used Build Configuration =============
In file included from /home/ubuntu/colcon_ws/src/rws/include/rws/client_handler.hpp:21,
from /home/ubuntu/colcon_ws/src/rws/src/client_handler.cpp:15:
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp: In constructor ‘rws::topic_params::topic_params()’:
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:40:15: warning: ‘rws::topic_params::type’ will be initi alized after [-Wreorder]
40 | std::string type;
| ^~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:36:8: warning: ‘bool rws::topic_params::latch’ [-Wreo rder]
36 | bool latch; // only for publishers, rws internal
| ^~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:18:3: warning: when initialized here [-Wreorder]
18 | topic_params() : history_depth(10), compression("none"), topic(""), type(""), latch(false) {}
| ^~~~~~~~~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp: In constructor ‘rws::topic_params::topic_params(std::s tring, std::string)’:
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:40:15: warning: ‘rws::topic_params::type’ will be initi alized after [-Wreorder]
40 | std::string type;
| ^~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:36:8: warning: ‘bool rws::topic_params::latch’ [-Wreo rder]
36 | bool latch; // only for publishers, rws internal
| ^~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:19:3: warning: when initialized here [-Wreorder]
19 | topic_params(std::string t, std::string tp)
| ^~~~~~~~~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp: In constructor ‘rws::topic_params::topic_params(std::s tring, std::string, size_t, std::string)’:
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:40:15: warning: ‘rws::topic_params::type’ will be initi alized after [-Wreorder]
40 | std::string type;
| ^~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:36:8: warning: ‘bool rws::topic_params::latch’ [-Wreo rder]
36 | bool latch; // only for publishers, rws internal
| ^~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:23:3: warning: when initialized here [-Wreorder]
23 | topic_params(std::string t, std::string tp, size_t qs, std::string c)
| ^~~~~~~~~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp: In constructor ‘rws::topic_params::topic_params(std::s tring, std::string, size_t, bool)’:
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:40:15: warning: ‘rws::topic_params::type’ will be initi alized after [-Wreorder]
40 | std::string type;
| ^~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:36:8: warning: ‘bool rws::topic_params::latch’ [-Wreo rder]
36 | bool latch; // only for publishers, rws internal
| ^~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:27:3: warning: when initialized here [-Wreorder]
27 | topic_params(std::string t, std::string tp, size_t qs, bool l)
| ^~~~~~~~~~~~
In file included from /home/ubuntu/colcon_ws/src/rws/src/client_handler.cpp:15:
/home/ubuntu/colcon_ws/src/rws/include/rws/client_handler.hpp: In constructor ‘rws::ClientHandler::ClientHandler (int, std::shared_ptr<rws::NodeInterface<> >, std::shared_ptr<rws::Connector<> >, bool, std::function<void(std:: __cxx11::basic_string<char>&)>, std::function<void(std::vector<unsigned char>&)>)’:
/home/ubuntu/colcon_ws/src/rws/include/rws/client_handler.hpp:46:37: warning: ‘rws::ClientHandler::connector_’ w ill be initialized after [-Wreorder]
46 | std::shared_ptr<rws::Connector<>> connector_;
| ^~~~~~~~~~
/home/ubuntu/colcon_ws/src/rws/include/rws/client_handler.hpp:42:8: warning: ‘bool rws::ClientHandler::rosbrid ge_compatible_’ [-Wreorder]
42 | bool rosbridge_compatible_;
| ^~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/colcon_ws/src/rws/src/client_handler.cpp:38:1: warning: when initialized here [-Wreorder]
38 | ClientHandler::ClientHandler(
| ^~~~~~~~~~~~~
In file included from /home/ubuntu/colcon_ws/src/rws/include/rws/node_interface.hpp:6,
from /home/ubuntu/colcon_ws/src/rws/include/rws/connector.hpp:8,
from /home/ubuntu/colcon_ws/src/rws/include/rws/client_handler.hpp:21,
from /home/ubuntu/colcon_ws/src/rws/src/client_handler.cpp:15:
/home/ubuntu/colcon_ws/src/rws/include/rws/generic_client.hpp: In member function ‘rws::GenericClient::SharedFut ure rws::GenericClient::async_send_request(rws::GenericClient::SharedRequest, rws::GenericClient::CallbackType&& )’:
/home/ubuntu/colcon_ws/src/rws/include/rws/generic_client.hpp:145:20: warning: ignoring return value of ‘rmw_ret _t rmw_deserialize(const rmw_serialized_message_t*, const rosidl_message_type_support_t*, void*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
145 | rmw_deserialize(sm, req_ts_hdl_, buf.get());
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/colcon_ws/src/rws/src/serdes.cpp:18:10: fatal error: dds/ddsrt/endian.h: No such file or directory
18 | #include "dds/ddsrt/endian.h"
| ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
gmake[2]: *** [CMakeFiles/rws_server.dir/build.make:90: CMakeFiles/rws_server.dir/src/serdes.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:231: CMakeFiles/rws_server.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
---
Failed <<< rws [3min 35s, exited with code 2]
Summary: 6 packages finished [5min 26s]
1 package failed: rws
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.