Coder Social home page Coder Social logo

rclcpp's Introduction

rclcpp

This repository contains the source code for the ROS Client Library for C++ package, included with a standard install of any ROS 2 distro.

rclcpp provides the standard C++ API for interacting with ROS 2.

Usage

#include "rclcpp/rclcpp.hpp" allows use of the most common elements of the ROS 2 system.

The link to the latest API documentation can be found on the rclcpp package info page.

Examples

The ROS 2 tutorials Writing a simple publisher and subscriber. and Writing a simple service and client contain some examples of rclcpp APIs in use.

rclcpp's People

Contributors

ahcorde avatar alsora avatar audrow avatar barry-xu-2018 avatar blast545 avatar brawner avatar christophebedard avatar claireyywang avatar clalancette avatar cottsay avatar dabonnie avatar dhood avatar dirk-thomas avatar emersonknapp avatar esteve avatar fujitatomoya avatar gerkey avatar hidmic avatar ivanpauno avatar jacobperron avatar jacquelinekay avatar karsten1987 avatar mauropasse avatar methyldragon avatar mikaelarguedas avatar mjcarroll avatar nuclearsandwich avatar sloretz avatar tfoote avatar wjwwood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rclcpp's Issues

Segfault at: spin_until_future_complete

Short description of my program:
static method A: gets a node passed, accesses a parameter server via an AsyncParametersClient
returns some information gained from the parameter server

static method B:gets a node passed: accesses a service that is hosted somewhere.
returns some information gained from the service

Both methods have somewhere a call to rclcpp::spin_until_future_complete.

Example:
When I call method A, A returns succesfully.
When I call method B, B will give me a segfault

Everytime I'm using a the service call in a static method (that succeeds), I cant do a second service call or a call to a parameter server because of a segfault at: rclcpp::spin_until_future_complete

gdb Backtrace:

#0  0x00000000006747b8 in std::__shared_ptr<std::__future_base::_State_baseV2, (__gnu_cxx::_Lock_policy)2>::operator-> (this=0x0) at /usr/include/c++/5/bits/shared_ptr_base.h:1055
#1  0x00007ffff201e263 in std::promise<std::shared_ptr<rcl_interfaces::srv::GetParameters_Response_<std::allocator<void> > > >::set_value(std::shared_ptr<rcl_interfaces::srv::GetParameters_Response_<std::allocator<void> > > const&) () from /home/firesurfer/workspace/ros2_ws/install/lib/librclcpp.so
#2  0x00007ffff201cfbb in rclcpp::client::Client<rcl_interfaces::srv::GetParameters>::handle_response(std::shared_ptr<void>&, std::shared_ptr<void>&) ()
   from /home/firesurfer/workspace/ros2_ws/install/lib/librclcpp.so
#3  0x00007ffff1fcc7f6 in rclcpp::executor::Executor::execute_client(std::shared_ptr<rclcpp::client::ClientBase>) () from /home/firesurfer/workspace/ros2_ws/install/lib/librclcpp.so
#4  0x00007ffff1fcc193 in rclcpp::executor::Executor::execute_any_executable(std::shared_ptr<rclcpp::executor::AnyExecutable>) () from /home/firesurfer/workspace/ros2_ws/install/lib/librclcpp.so
#5  0x00007ffff1fcbdf9 in rclcpp::executor::Executor::spin_once(std::chrono::duration<long, std::ratio<1l, 1000000000l> >) () from /home/firesurfer/workspace/ros2_ws/install/lib/librclcpp.so
#6  0x000000000069d5a1 in rclcpp::executor::Executor::spin_until_future_complete<std::shared_ptr<ros2_components_msg::srv::ListChilds_Response_<std::allocator<void> > >, std::ratio<1l, 1000l> > (
    this=0x7fffffffd3f0, future=..., timeout=...) at /home/firesurfer/workspace/ros2_ws/install/include/rclcpp/executor.hpp:184
#7  0x000000000068c94d in rclcpp::executors::spin_node_until_future_complete<std::shared_ptr<ros2_components_msg::srv::ListChilds_Response_<std::allocator<void> > >, std::ratio<1l, 1000l> > (executor=..., 
    node_ptr=std::shared_ptr (count 12, weak 1) 0x974440, future=..., timeout=...) at /home/firesurfer/workspace/ros2_ws/install/include/rclcpp/executors.hpp:67
#8  0x0000000000679fe9 in rclcpp::spin_until_future_complete<std::shared_ptr<ros2_components_msg::srv::ListChilds_Response_<std::allocator<void> > >, std::ratio<1l, 1000l> > (
    node_ptr=std::shared_ptr (count 12, weak 1) 0x974440, future=..., timeout=...) at /home/firesurfer/workspace/ros2_ws/install/include/rclcpp/executors.hpp:81

gdb output:

Program received signal SIGSEGV, Segmentation fault.
0x00000000006747b8 in std::__shared_ptr<std::__future_base::_State_baseV2, (__gnu_cxx::_Lock_policy)2>::operator-> (this=0x0) at /usr/include/c++/5/bits/shared_ptr_base.h:1055
1055        return _M_ptr;

Edit: Some further research showed that this behavior occurs every time I create a Client and destroy it. When I'm creating a new client afterwards and want to use it, I get a segfault

Edit2: After digging in the ros2 code I think the solution might be to tell the executor that a certain client doenst exist anymore

Intra-process pipeline between different nodes in same process

In ros2/rmw_connext#76 I complained about nondeterministic startup behavior for 2 nodes communicating in the same process (but this was before the intra-process pipeline was implemented)). It was argued that this is acceptable behavior, since the two nodes are being initialized through DDS and DDS discovery can't make timing guarantees.

I would expect nodes within the same process to be able to avoid this nondeterministic startup behavior if the intra-process pipeline were utilized. This would be an acceptable solution.

However, the intra-process pipeline currently does not work for communication between two different nodes in the same process. I assume because the intra-process manager is a child of the context, not the node, that this feature should be implemented.

In branch multiple_nodes of system_tests, I added a case for publishing messages from one node to another node in the same process:

https://github.com/ros2/system_tests/blob/multiple_nodes/test_rclcpp/test/test_intra_process.cpp#L154

Currently the callback fails to trigger.

This feature is probably not urgent right now, but important for node composability.

move rmw_implementation?

I think it made sense for rmw_implementation to be in the rclcpp repository when it only used by rclcpp, but now I think it probably belongs in rmw.

Thoughts?

management of subscribers/publishers

Not sure if this is the way to make a comment or not, so please forgive.

Why should create_X return a handle for a publisher or subscriber when that information can be managed internally? What flexibility does it provide? Most topics are openend/closed at start/shutdown, with a single type on a single topic. With the current mechanism, there are 3 APIs: node, publish, subscribe. If the Node manages the publishers and subscribers, there would be a single API handling create/read/write, fewer objects for the client to track, and potentially a simpler locking and management scheme in a multi-threaded environment.

Provide CMake infrastructure for creating a node

This is a spin off from ros2/ros2#55.

Basically we need to add some lubrication to the process of making a node which can be loaded as a library into a container or run as a stand-alone executable. This is what I imagine it would look like:

rclcpp_add_node(my_node src/my_node.cpp)
target_link_libraries(my_node ...)
ament_target_dependencies(my_node "rclcpp" ...)
...

The rclcpp_add_node macro would create a target my_node which builds a shared library, and also creates a target which builds an executable (name of this target is an implementation detail) with the output name my_node. This allows the user to link extra libraries and what not to the library containing the node. It would also register this node in the ament index.

The output files will be lib/libmy_node.so, bin/my_node, and share/ament_index/resource_index/nodes/pkg_name/my_node (maybe just share/ament_index/resource_index/nodes/pkg_name with the my_node in the contents of that file).

The user's code is compiled into lib/libmy_node.so.
The executable is a boilerplate main which can load and run the shared library in stand alone mode or, with a cli switch, it can tell a remote container to load and run the library, acting as a surrogate until the node is removed from the container.

The infrastructure has been prototyped here: ros2/demos#18

Making all of this work will require us to figure out the issues surrounding multi vendor support in #48

Refactor to use rcl

rclcpp should be a wrapper around rcl (similar to rclpy).

I am going to start addressing this because I think it will help me understand how to design the rcl parameters API.

Subscribing with a `ConstSharedPtr` in the callback signature/publishing a `ConstSharedPtr`

Nowhere on the master branches of ROS 2 repositories do we subscribe to a topic with a callback signature receiving a MessageT::ConstSharedPtr (shared_ptr<const MessageT>, or publish a ConstSharedPtr.

I tried to do this and there two problems:

  1. AnySubscriptionCallback doesn't have definitions for the ConstSharedPtr type. This is easy to fix and I have an upcoming pull request for it.
  2. The IntraProcessManager receives the published message as a void* in its store_intra_process callback. The compile error is because the publisher template tries to copy the const message into a unique pointer of a const message and pass that to store_intra_proces, but const message cannot be cast to void. Fixing this requires a bit more work to ensure the copy of the message is not const.

Non deterministic double free or corruption on ctrl-c

This has been observed in the talker using opensplice:

$ ./install/bin/talker__ros_middleware_opensplice_cpp
init()
  init() get_instance
create_node()
  create_node() opensplice_static
  create_node() get_instance
  create_node() create_participant in domain 0
  create_node() pass opaque node handle
create_publisher()
create_publisher() opensplice_static
  create_publisher() extract participant from opaque node handle
  create_publisher() invoke register callback
  simple_msgs::type_support::register_type__String()
  create_publisher() create dds publisher
  create_publisher() create topic: chatter
  create_publisher() create data writer
  create_publisher() build opaque publisher handle
Publishing: 'Hello World: 1'
Publishing: 'Hello World: 2'
Publishing: 'Hello World: 3'
^Csignal_handler(2)
*** Error in `./install/bin/talker__ros_middleware_opensplice_cpp': double free or corruption (!prev): 0x00000000016f8ff0 ***

Lock-free executor

How should we expose synchronization primitives to implement a lock-free executor for real-time execution?

Consider renaming rclcpp::ok

Discussed names were:

  • bool rclcpp::is_shutdown and bool rclcpp::is_not_shutdown
  • bool rclcpp::is_shutting_down
  • State rclcpp::state and compare to predefined states
    • e.g. while (rclcpp::state() == rclcpp::RUNNING)
    • or while (rclcpp::state() != rclcpp::SHUTDOWN)

refactor into library

Currently all functions are defined in the header files directly. This makes it impossible to create executables from multiple C++ files since each will include its own version of the symbol and then collide at link time.

timers: consider implementation of timers which uses wait thread

Currently timers are naively implemented using a thread per timer, but it should be possible to implement the timers using a timeout argument to the ros_middleware_interface::wait function. This would potentially be much more efficient and at least more ellegant, as the total number of threads and ros_middleware_interface::GuardConditionHandle's would be significantly reduced. A stepping stone to this, without requiring a timeout in the ros_middleware_interface::wait function, would be to have one thread for all timers which does the same waiting mechanism, but using a sleep function not as a parameter to ros_middleware_interface::wait.

parameter client: pass vectors by reference

I noticed this while combing through the rclcpp library PR, but I wanted to make note of it here: we should pass std::vectors and other potentially large objects by reference. There are a few places where this is not done in parameter_client and possibly elsewhere.

Real-time safe intra-process communication

  • Implement RT allocator and incorporate into examples and demos
  • Implement lock-free synchronization alternative to the mutex in publisher (intra-process_publish_mutex) #77
  • Extract memory allocations from take_intra_process_message and store_intra_process_message for pool alternative (solution: allocator template)
  • Alternative for std::map in IntraProcessManager (solution: allocator template for stdlib data structures)
  • Profiling/testing

Real-time safe services + clients

Make the client/service pipeline safe for real-time execution. It has not yet been vetted for allocations, STL structures which malloc automatically, and nondeterministic blocking.

This will be required for RT-safe node lifecycle, since we plan to use services to transition between states in the lifecycle.

  • abstract out "new" in Service::handle_request
  • abstract out make_shared from async_send_request
  • rt-safe alternatives to std::vector and std::map (maybe just use a custom allocator)
  • example with OS-specific threading abstraction (instead of std::future)
  • testing/profiling

Ordered single-threaded executor

Suggestion from @adolfo-rt:

Currently the ordering of tasks in the single-threaded executor is not exposed to the user. It should be possible to implement a single-threaded executor in which task execution ordering can be specified by the user. This is to further decouple the component topology from its thread execution.

Not a high priority for the current milestone (ROSCon demos) but an eventual goal.

rate.sleep will sometimes return slightly early from a sleep

I was working on the unit tests with @gerkey for rate.sleep and expected the sleep to not return before expected.

On repeated runs it had a jitter on the order of 10us. (The printout is in nanoseconds. and the expected duration is 100 ms

Console output of observed delta: https://gist.github.com/tfoote/0ec473b38bc517d12779

We added an epsilon to the unit tests for now (#182), but we should review our code to make it as consistent as with the assumptions of developers who are used to calling the standard sleep methods.

Segfault when using Parameter Client with spelling like DemoRobot

When trying to create a demo application for #193 I got another segfault when using a Parameter Client with a spelling like DemoRobot for the parameter name.

Have a look at my demo application https://github.com/firesurfer/ros2_components_demo
It need the qt5 dev package in order to compile.

The application consists of three parts.
demo_parameter_server
demo_server
demo_client

The segfault happens in the demo_client in the file /src/ros2_components/Robot.h in the function ListAllKnownRobots

Configure and Enable clang_format QA tool

We have a tools for checking our code with clang_format but it is not configured to our liking yet.

Acceptance Criteria:

  • Decide on a configuration with the team
  • Reenable the linter
  • Create tasks for fixing failing packages

nodelets vs thread pool

If I understand this executor correctly, it's is a somewhat standard thread pool. there are n threads and m executable things. is it intended that "nodelets" will run under a similar scheme? I.e. That nodelet X will not be tied specifically to thread Y for the duration of the nodelet lifecycle?

Create a generic node container

This is a spin-off from: ros2/ros2#55

We need a generic program which can be run and then remotely instructed to load and execute a node.

This program should probably:

  • Allow configuration of the internal executor.
  • Provide ROS Services for loading and running a node.

This is not really useful until we have the ability to make, find, and dynamically load nodes, see:

This is also blocked by decisions that need to be made in: #48

Context class

why was the Context pattern chosen over a traditional Singleton pattern?

Pub/sub across different nodes in same executor does not work

Branch multiple_nodes in system_tests, package test_rclcpp, illustrates this bug:
https://github.com/ros2/system_tests/tree/multiple_nodes

Case 1 fails:
node1 and node2 are both added to one executor.
node1 publishes "foo", node2 subscribes to "foo"
node2 publishes "bar", node2 subscribes to "bar"
Both publishers publish 5 times.
0/5 messages are received for both subscribers.

Case 2 passes:
one node publishes "foo", "bar", subscribes to "foo" and "bar"
Both publishers publish 5 times.
5/5 messages are received for both subscribers.

Case 3 passes:
node1 and node2 both added to one executor.
node1 publishes "foo", subscribes to "foo"
node2 publishes "bar", subscribes to "bar"
Both publishers publish 5 times.
5/5 messages are received for both subscribers.

Rate::sleep fails to compile on OSX

It is missing coverage and it looks like it has a duration_cast missing.

Found working toward: ros2/ros2#160

http://ci.ros2.org/job/ci_osx/599/console

18:20:33 /Users/osrf/jenkins/workspace/ci_osx/ws/install/rclcpp/include/rclcpp/rate.hpp:74:20: error: no viable overloaded '+='
18:20:33     last_interval_ += period_;
18:20:33     ~~~~~~~~~~~~~~ ^  ~~~~~~~
18:20:33 /Users/osrf/jenkins/workspace/ci_osx/ws/src/ros/geometry_experimental/tf2_ros/src/tf2_echo.cpp:142:12: note: in instantiation of member function 'rclcpp::rate::GenericRate<std::__1::chrono::system_clock>::sleep' requested here
18:20:33       rate.sleep();
18:20:33            ^
18:20:33 /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/chrono:782:79: note: candidate function not viable: no known conversion from 'duration<[...], ratio<[...], 1000000000>>' to 'const duration<[...], ratio<[...], 1000000>>' for 1st argument
18:20:33     __attribute__ ((__visibility__("hidden"), __always_inline__)) time_point& operator+=(const duration& __d) {__d_ += __d; return *this;}

Services using 100% of CPU

Dave Sandage reported this on the NG SIG:

I've just started playing with the ROS2 alpha2 release, and was experimenting with some samples. I wrote a node to act as a service server, modeling it after the add_two_ints_server example. It all works, but after Ive made my first call to the service, the server node pegs the CPU at 100%. add_two_ints_server does this also.

At the end of my node's main() function, I have the following loop:

while (rclcpp::utilities::ok())
{
    executor.spin_node_once(node, std::chrono::milliseconds(1000));
}

After the first call to the service, this method returns immediately every time, leaving the node in a tight loop. Upon further debugging in rclcpp, it appears that in executor::execute_next_ready_executable(), get_next_service always returns a non-null value. Is there something in my service handler that needs to be done to remove the service from showing always ready to execute? I've modeled mine exactly on the add_two_ints_server (and it does the same thing).

services are broken in multiple ways

  • add_two_ints_server__rmw_opensplice_cpp / add_two_ints_client__rmw_opensplice_cpp: the server receives additional uninitialized requests
  • test_replier_cpp__rmw_opensplice_cpp / test_requester_cpp__rmw_opensplice_cpp has the same problem - the test does not cover that (even with ros2/system_tests#34) since the client succeeds
  • add_two_ints_server__rmw_connext_cpp / add_two_ints_client__rmw_connext_cpp do not exchange any messages
  • add_two_ints_client__rmw_connext_cpp can't be stopped with Ctrl-C
  • same for Connext dynamic

Move rmw_implementation to the rmw repo

Currently this repository contains the rmw_implementation package which provides an interface to list and select an implementation for the rmw API. It also sets the default implementation. We agreed that it should be in the rmw repository as a peer to the rmw package instead.

Acceptance Criteria:

  • rmw_implementation package moved
  • git history preserved
  • ros2 is still building after the move

parameter API does not allow to distinguish error cases

E.g.

std::vector<rclcpp::parameter::ParameterVariant>
SyncParametersClient::get_parameters(const std::vector<std::string> & parameter_names)
{
auto f = async_parameters_client_->get_parameters(parameter_names);
if (rclcpp::executors::spin_node_until_future_complete(*executor_, node_, f) ==
rclcpp::executor::FutureReturnCode::SUCCESS)
{
return f.get();
}
// Return an empty vector if unsuccessful
return std::vector<rclcpp::parameter::ParameterVariant>();
}
return an empty vector if something goes wrong which is also a valid response.

parameter client question

so...
node caches parameters locally.
but sends them out to the parameter_event channel... so if all nodes are up, all nodes can get the events.
but it seems the parameter server does not listen to this channel, it relies on a service to set params in its cache. the server requires a separate api for access (parameter_client).
are the parts just not hooked up yet? or am i missing something?

Subscriptions are not triggered sometimes

In the parameter events examples, the callback function is not always triggered. However further testing shows that the data was received, but the executor didn't trigger the callback. This may indicate that there's an issue in the way SingleThreadedExceutor is used.

avoid redundant memory allocations in wait_for_work

This function, wait_for_work which is in the rclcpp::Executor class:

repeatedly malloc's for temporary storage used in the ros_middleware_interface::wait function.

This could be avoided either by only allocating memory when resizing of the structures is required or by always using a structure of the maximum possible size (still would need to be updated when nodes are added or removed but less frequently) and ensuring that the ros_middleware_interface::wait function properly handles the extra, unused storage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.