Greetings,
I’m trying to compile the file “action_client.cpp” with example 5.2 in Unit 5.2.2.
The code was same as the exmaple, but I still got the error below:
image
961×430 71.4 KB
I found the same error in this page:
[ROS2 Foxy] rclcpp_action "no match for ‘operator=’ " - ROS Answers: Open Source Q&A Forum
But the code in the file “action_client.cpp” has already used “SharedPtr”.
Is the system error or something else?
Hi
@kjoelovelife
and
@mosgaed
,
I just tried to compile and execute that code. It is working fine for me.
But I tried on the
ROS2 Basics in 5 Days (C++)
course. The course states that it will be deprecated on Jan 13, 2023.
I did not try this out on the
Humble
version yet.
Are you guys on the
ROS2 Basics in 5 Days (C++)
course or
ROS2 Basics in 5 Days Humble (C++)
course?
Regards,
Girish
Hi
@kjoelovelife
,
@mosgaed
,
@Voltedge
,
Just working on that package - you don’t get that single error. There is a bunch of errors and warnings.
user:~/ros2_ws$ colcon build --packages-select my_action_client
Starting >>> my_action_client
[Processing: my_action_client]
--- stderr: my_action_client
/home/user/ros2_ws/src/my_action_client/src/action_client.cpp: In member function 'void MyActionClient::send_goal()':
/home/user/ros2_ws/src/my_action_client/src/action_client.cpp:61:66: error: no match for 'operator=' (operand types are 'rclcpp_action::Client<t3_action_msg::action::Move>::GoalResponseCallback' {aka 'std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>'} and 'std::_Bind_helper<false, void (MyActionClient::*)(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >), MyActionClient*, const std::_Placeholder<1>&>::type')
61 | std::bind(&MyActionClient::goal_response_callback, this, _1);
| ^
In file included from /usr/include/c++/11/functional:59,
from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
from /usr/include/c++/11/algorithm:74,
from /home/simulations/ros2_sims_ws/install/t3_action_msg/include/t3_action_msg/t3_action_msg/action/detail/move__struct.hpp:8,
from /home/simulations/ros2_sims_ws/install/t3_action_msg/include/t3_action_msg/t3_action_msg/action/move.hpp:7,
from /home/user/ros2_ws/src/my_action_client/src/action_client.cpp:6:
/usr/include/c++/11/bits/std_function.h:530:9: note: candidate: 'template<class _Functor> std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<_Functor>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >}]'
530 | operator=(_Functor&& __f)
| ^~~~~~~~
/usr/include/c++/11/bits/std_function.h:530:9: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/11/bits/move.h:57,
from /usr/include/c++/11/bits/stl_pair.h:59,
from /usr/include/c++/11/bits/stl_algobase.h:64,
from /usr/include/c++/11/memory:63,
from /home/user/ros2_ws/src/my_action_client/src/action_client.cpp:2:
/usr/include/c++/11/type_traits: In substitution of 'template<bool _Cond, class _Tp> using __enable_if_t = typename std::enable_if::type [with bool _Cond = false; _Tp = std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>&]':
/usr/include/c++/11/bits/std_function.h:353:8: required by substitution of 'template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = std::__enable_if_t<_Cond::value, _Tp> [with _Cond = std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>::_Callable<std::_Bind<void (MyActionClient::*(MyActionClient*, std::_Placeholder<1>))(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >)>, std::_Bind<void (MyActionClient::*(MyActionClient*, std::_Placeholder<1>))(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >)>, std::__invoke_result<std::_Bind<void (MyActionClient::*(MyActionClient*, std::_Placeholder<1>))(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move>> >)>&, std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > > >; _Tp = std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>&; _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >}]'
/usr/include/c++/11/bits/std_function.h:530:2: required by substitution of 'template<class _Functor> std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>::_Requires<std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>::_Callable<_Functor, typename std::enable_if<(! std::is_same<typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)> >::value), std::decay<_Tp> >::type::type, std::__invoke_result<typename std::enable_if<(! std::is_same<typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)> >::value), std::decay<_Tp> >::type::type&, std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > > >, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>&> std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>::operator=<_Functor>(_Functor&&) [with _Functor = std::_Bind<void (MyActionClient::*(MyActionClient*, std::_Placeholder<1>))(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >)>]'
/home/user/ros2_ws/src/my_action_client/src/action_client.cpp:61:66: required from here
/usr/include/c++/11/type_traits:2211:11: error: no type named 'type' in 'struct std::enable_if<false, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>&>'
2211 | using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
| ^~~~~~~~~~~~~
In file included from /usr/include/c++/11/functional:59,
from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
from /usr/include/c++/11/algorithm:74,
from /home/simulations/ros2_sims_ws/install/t3_action_msg/include/t3_action_msg/t3_action_msg/action/detail/move__struct.hpp:8,
from /home/simulations/ros2_sims_ws/install/t3_action_msg/include/t3_action_msg/t3_action_msg/action/move.hpp:7,
from /home/user/ros2_ws/src/my_action_client/src/action_client.cpp:6:
/usr/include/c++/11/bits/std_function.h:540:9: note: candidate: 'template<class _Functor> std::function<_Res(_ArgTypes ...)>&std::function<_Res(_ArgTypes ...)>::operator=(std::reference_wrapper<_Functor>) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >}]'
540 | operator=(reference_wrapper<_Functor> __f) noexcept
| ^~~~~~~~
/usr/include/c++/11/bits/std_function.h:540:9: note: template argument deduction/substitution failed:
/home/user/ros2_ws/src/my_action_client/src/action_client.cpp:61:66: note: 'std::_Bind<void (MyActionClient::*(MyActionClient*, std::_Placeholder<1>))(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >)>' is not derived from 'std::reference_wrapper<_Tp>'
61 | std::bind(&MyActionClient::goal_response_callback, this, _1);
| ^
In file included from /usr/include/c++/11/functional:59,
from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
from /usr/include/c++/11/algorithm:74,
from /home/simulations/ros2_sims_ws/install/t3_action_msg/include/t3_action_msg/t3_action_msg/action/detail/move__struct.hpp:8,
from /home/simulations/ros2_sims_ws/install/t3_action_msg/include/t3_action_msg/t3_action_msg/action/move.hpp:7,
from /home/user/ros2_ws/src/my_action_client/src/action_client.cpp:6:
/usr/include/c++/11/bits/std_function.h:469:7: note: candidate: 'std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >}]'
469 | operator=(const function& __x)
| ^~~~~~~~
/usr/include/c++/11/bits/std_function.h:469:33: note: no known conversion for argument 1 from 'std::_Bind_helper<false, void (MyActionClient::*)(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >), MyActionClient*, const std::_Placeholder<1>&>::type' to 'const std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>&'
469 | operator=(const function& __x)
| ~~~~~~~~~~~~~~~~^~~
/usr/include/c++/11/bits/std_function.h:487:7: note: candidate: 'std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >}]'
487 | operator=(function&& __x) noexcept
| ^~~~~~~~
/usr/include/c++/11/bits/std_function.h:487:28: note: no known conversion for argument 1 from 'std::_Bind_helper<false, void (MyActionClient::*)(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >), MyActionClient*, const std::_Placeholder<1>&>::type' to 'std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >)>&&'
487 | operator=(function&& __x) noexcept
| ~~~~~~~~~~~^~~
/usr/include/c++/11/bits/std_function.h:501:7: note: candidate: 'std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::nullptr_t) [with _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> >}; std::nullptr_t = std::nullptr_t]'
501 | operator=(nullptr_t) noexcept
| ^~~~~~~~
/usr/include/c++/11/bits/std_function.h:501:17: note: no known conversion for argument 1 from 'std::_Bind_helper<false, void (MyActionClient::*)(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<t3_action_msg::action::Move> > >), MyActionClient*, const std::_Placeholder<1>&>::type' to 'std::nullptr_t'
501 | operator=(nullptr_t) noexcept
| ^~~~~~~~~
gmake[2]: *** [CMakeFiles/action_client_node.dir/build.make:76: CMakeFiles/action_client_node.dir/src/action_client.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:137: CMakeFiles/action_client_node.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
Failed <<< my_action_client [30.0s, exited with code 2]
Summary: 0 packages finished [31.2s]
1 package failed: my_action_client
1 package had stderr output: my_action_client
I am working on this now to find a fix. If I can fix it, I will keep you guys updated.
Regards,
Girish
Hi @kjoelovelife , @mosgaed , @Voltedge ,
Good News: I have solved this problem! (Let me know if you need my full code.)
Bad News (probably, not sure): It may not be the best solution, but this still works - I have tested this with a couple of examples.
I did quite some research to figure this out. Here are some links for you guys to educate yourself:
goal_response_callback
NewSignature
GoalResponseCallback with NewSignature
Note: The above links are from Galactic version. Documentation pages for Humble does not exist yet! [Replacing “galactic” to “humble” in the above links takes to “page not found”.]
Now, the Solution:
Replace the following function / code:
void goal_response_callback(std::shared_future<GoalHandleMove::SharedPtr> future) {
auto goal_handle = future.get();
if (!goal_handle) {
RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
} else {
RCLCPP_INFO(this->get_logger(),
"Goal accepted by server, waiting for result");
With this function / code:
void goal_response_callback(GoalHandleMove::SharedPtr goal_handle) {
if (goal_handle == nullptr) {
RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
} else {
RCLCPP_INFO(this->get_logger(),
"Goal accepted by server, waiting for result");
goal_response_callback(): Takes a single argument that is a goal handle shared pointer. If the goal is accepted, then the pointer points to a valid goal handle. If the goal is rejected, then pointer has the value nullptr
. Source: Refer Link 1 above.
@albertoezquerro : Please validate my research and the solution I have provided here. This solution works - but I am not sure if this is “The Best Solution” for this problem. Thanks!
Regards,
Girish
Here is the proof of output:
ros2_actions_client_fix 1848×1053 254 KB
Hi @girishkumar.kannan , @kjoelovelife , @Voltedge
I researched in the official ROS2 Humble documentation for the action service client. In the example code they also use the NewSignature as mentioned from @girishkumar.kannan .
Link for the Humble Documentation: Writing an action server and client (C++) — ROS 2 Documentation: Humble documentation
but in ths example they are using a const shared pointer.
Hi @mosgaed ,
Wow! I did check the same page. I can’t believe that I overlooked this function definition! My bad!
Anyways, glad you have found it!
@albertoezquerro : Please make the changes in the course notes when you find time. Thanks!
Regards,
Girish
Hello everyone!
First of all, many thanks to @girishkumar.kannan for reacting so fast and so well to the issue. Great work!
I’ve been investigating and testing myself and the correct solution is the one presented by @mosgaed in his last post. I’ve already pushed the changes to the notebook to show the updated code for the action client.
girishkumar.kannan:
Note: The above links are from Galactic version. Documentation pages for Humble does not exist yet! [Replacing “galactic” to “humble” in the above links takes to “page not found”.]
That is because https://docs.ros2.org/ is deprecated.
Links to the API documentation of packages can now be found through the ROS Index .
E.g. for rclcpp_action see this package info page . At the top right you can find the link to the API documentation .
Regards,
Johan
Hi @JRTG ,
Thanks a lot for sharing this info! I never knew about ROS Index, perhaps because I have not moved to Humble yet.
Finally, I can see a clean and well explained documentation that also looks pretty!
The main link to the API on README.md still takes me to docs.ros2.org .
Clicking on “API Docs” on the top right takes me to the better looking documentation page.
ros_index_page 856×965 80 KB
– Girish
Indeed…
It’s because the readme’s haven’t been updated in github.
If you feel like it, you can provide a pull request to change it…
Or create an issue.
Johan
Wow! Great works! Thanks @girishkumar.kannan took the solution first, @mosgaed offered the official document, and @albertoezquerro update the code.
Thanks again and a lot! Wish everyone here has a nice day!
Hi @kjoelovelife ,
The actual solution is the one posted by @mosgaed , the picture to the documentation code.
I request that you change the solution to the above post, so that people who (might) see this post in the future will not be tempted to copy-paste my solution.
Regards,
Girish