Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to run the demo #19

Closed
amodpatil1 opened this issue Jun 4, 2024 · 88 comments
Closed

Not able to run the demo #19

amodpatil1 opened this issue Jun 4, 2024 · 88 comments

Comments

@amodpatil1
Copy link

colcon build --packages-select yasmin
ros2 run yasmin_demo yasmin_demo.py
Package 'yasmin_demo' not found
not able to run the command. please help me out.

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 4, 2024

Hey @amodpatil1, have you source (source install/setup.bash) after using colcon?

@amodpatil1
Copy link
Author

Yes, I did source the workspace before the running the command and I tried it multiple times and I also tried doing from start as well, but it did not work.

@amodpatil1
Copy link
Author

I think there is some problem with the action_client_demo.py

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

Have you colcon all the yasmin packages (yasmin, yasmin_msgs, yasmin_demo, yasmin_ros, yasmin_viewe) or only yasmin?

@amodpatil1
Copy link
Author

I did it for yasmin only. Shouldn't the entire package get built when I do Colcon build?

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

No, since they are different packages.

@amodpatil1
Copy link
Author

okay I will try that.

@amodpatil1
Copy link
Author

Starting >>> yasmin_demo
--- stderr: yasmin_demo
In file included from /home/amodpatil/ros2/src/yasmin/yasmin_demo/src/action_client_demo.cpp:24:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp: In instantiation of ‘std::string yasmin_ros::ActionState::execute(std::shared_ptryasmin::blackboard::Blackboard) [with ActionT = action_tutorials_interfaces::action::Fibonacci; std::string = std::__cxx11::basic_string]’:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:103:3: required from here
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:113:46: error: no match for ‘operator=’ (operand types are ‘rclcpp_action::Client<action_tutorials_interfaces::action::Fibonacci>::GoalResponseCallback’ {aka ‘std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>’} and ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’})
113 | send_goal_options.goal_response_callback =
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
114 | std::bind(&ActionState::goal_response_callback, this, _1);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/future:48,
from /opt/ros/foxy/include/rclcpp/executors.hpp:18,
from /opt/ros/foxy/include/rclcpp/rclcpp.hpp:146,
from /home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:23,
from /home/amodpatil/ros2/src/yasmin/yasmin_demo/src/action_client_demo.cpp:24:
/usr/include/c++/9/bits/std_function.h:462:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
462 | operator=(const function& __x)
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:462:33: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’} to ‘const std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&’
462 | operator=(const function& __x)
| ~~~~~~~~~~~~~~~~^~~
/usr/include/c++/9/bits/std_function.h:480:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
480 | operator=(function&& __x) noexcept
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:480:28: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’} to ‘std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&&’
480 | operator=(function&& __x) noexcept
| ~~~~~~~~~~~^~~
/usr/include/c++/9/bits/std_function.h:494:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::nullptr_t) [with _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}; std::nullptr_t = std::nullptr_t]’
494 | operator=(nullptr_t) noexcept
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:494:17: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’} to ‘std::nullptr_t’
494 | operator=(nullptr_t) noexcept
| ^~~~~~~~~
/usr/include/c++/9/bits/std_function.h:523:2: note: candidate: ‘template std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_Functor>::type>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
523 | operator=(_Functor&& __f)
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:523:2: note: template argument deduction/substitution failed:
/usr/include/c++/9/bits/std_function.h: In substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::_Callable<std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>, std::__invoke_result<std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>&, std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > > > >; _Tp = std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&; _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’:
/usr/include/c++/9/bits/std_function.h:523:2: required by substitution of ‘template std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::_Requires<std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::_Callable<typename std::decay<_Tp>::type, std::__invoke_result<typename std::decay<_Tp>::type&, std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > > > >, std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&> std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::operator=<_Functor>(_Functor&&) [with _Functor = std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>]’
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:113:46: required from ‘std::string yasmin_ros::ActionState::execute(std::shared_ptryasmin::blackboard::Blackboard) [with ActionT = action_tutorials_interfaces::action::Fibonacci; std::string = std::__cxx11::basic_string]’
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:103:3: required from here
/usr/include/c++/9/bits/std_function.h:385:8: error: no type named ‘type’ in ‘struct std::enable_if<false, std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&>’
385 | using _Requires = typename enable_if<_Cond::value, _Tp>::type;
| ^~~~~~~~~
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp: In instantiation of ‘std::string yasmin_ros::ActionState::execute(std::shared_ptryasmin::blackboard::Blackboard) [with ActionT = action_tutorials_interfaces::action::Fibonacci; std::string = std::__cxx11::basic_string]’:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:103:3: required from here
/usr/include/c++/9/bits/std_function.h:532:2: note: candidate: ‘template std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::reference_wrapper<_Functor>) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
532 | operator=(reference_wrapper<_Functor> __f) noexcept
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:532:2: note: template argument deduction/substitution failed:
In file included from /home/amodpatil/ros2/src/yasmin/yasmin_demo/src/action_client_demo.cpp:24:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:113:46: note: ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’ is not derived from ‘std::reference_wrapper<_Tp>’
113 | send_goal_options.goal_response_callback =
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
114 | std::bind(&ActionState::goal_response_callback, this, _1);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/action_client_demo.dir/build.make:63: CMakeFiles/action_client_demo.dir/src/action_client_demo.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/action_client_demo.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:141: all] Error 2

Failed <<< yasmin_demo [7.38s, exited with code 2]

Summary: 0 packages finished [7.67s]
1 package failed: yasmin_demo
1 package had stderr output: yasmin_demo

I built all other packages but the demo is only facing an issue

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

That is a problem with the ROS 2 distro. Foxy EOL was on June 20th, 2023. Thus, yasmin was updated to Humble.

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

I have just added support for Foxy. It should work now.

@amodpatil1
Copy link
Author

okay I will try

@amodpatil1
Copy link
Author

--- stderr: yasmin_demo
In file included from /home/amodpatil/ros2/src/yasmin/yasmin_demo/src/action_client_demo.cpp:24:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp: In instantiation of ‘std::string yasmin_ros::ActionState::execute(std::shared_ptryasmin::blackboard::Blackboard) [with ActionT = action_tutorials_interfaces::action::Fibonacci; std::string = std::__cxx11::basic_string]’:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:103:3: required from here
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:113:46: error: no match for ‘operator=’ (operand types are ‘rclcpp_action::Client<action_tutorials_interfaces::action::Fibonacci>::GoalResponseCallback’ {aka ‘std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>’} and ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’})
113 | send_goal_options.goal_response_callback =
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
114 | std::bind(&ActionState::goal_response_callback, this, _1);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/future:48,
from /opt/ros/foxy/include/rclcpp/executors.hpp:18,
from /opt/ros/foxy/include/rclcpp/rclcpp.hpp:146,
from /home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:23,
from /home/amodpatil/ros2/src/yasmin/yasmin_demo/src/action_client_demo.cpp:24:
/usr/include/c++/9/bits/std_function.h:462:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
462 | operator=(const function& __x)
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:462:33: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’} to ‘const std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&’
462 | operator=(const function& __x)
| ~~~~~~~~~~~~~~~~^~~
/usr/include/c++/9/bits/std_function.h:480:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
480 | operator=(function&& __x) noexcept
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:480:28: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’} to ‘std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&&’
480 | operator=(function&& __x) noexcept
| ~~~~~~~~~~~^~~
/usr/include/c++/9/bits/std_function.h:494:7: note: candidate: ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::nullptr_t) [with _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}; std::nullptr_t = std::nullptr_t]’
494 | operator=(nullptr_t) noexcept
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:494:17: note: no known conversion for argument 1 from ‘std::_Bind_helper<false, void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::)(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&), yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, const std::_Placeholder<1>&>::type’ {aka ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’} to ‘std::nullptr_t’
494 | operator=(nullptr_t) noexcept
| ^~~~~~~~~
/usr/include/c++/9/bits/std_function.h:523:2: note: candidate: ‘template std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_Functor>::type>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
523 | operator=(_Functor&& __f)
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:523:2: note: template argument deduction/substitution failed:
/usr/include/c++/9/bits/std_function.h: In substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::_Callable<std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>, std::__invoke_result<std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>&, std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > > > >; _Tp = std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&; _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’:
/usr/include/c++/9/bits/std_function.h:523:2: required by substitution of ‘template std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::_Requires<std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::_Callable<typename std::decay<_Tp>::type, std::__invoke_result<typename std::decay<_Tp>::type&, std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > > > >, std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&> std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>::operator=<_Functor>(_Functor&&) [with _Functor = std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>]’
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:113:46: required from ‘std::string yasmin_ros::ActionState::execute(std::shared_ptryasmin::blackboard::Blackboard) [with ActionT = action_tutorials_interfaces::action::Fibonacci; std::string = std::__cxx11::basic_string]’
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:103:3: required from here
/usr/include/c++/9/bits/std_function.h:385:8: error: no type named ‘type’ in ‘struct std::enable_if<false, std::function<void(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >)>&>’
385 | using _Requires = typename enable_if<_Cond::value, _Tp>::type;
| ^~~~~~~~~
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp: In instantiation of ‘std::string yasmin_ros::ActionState::execute(std::shared_ptryasmin::blackboard::Blackboard) [with ActionT = action_tutorials_interfaces::action::Fibonacci; std::string = std::__cxx11::basic_string]’:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:103:3: required from here
/usr/include/c++/9/bits/std_function.h:532:2: note: candidate: ‘template std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::reference_wrapper<_Functor>) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> > >}]’
532 | operator=(reference_wrapper<_Functor> __f) noexcept
| ^~~~~~~~
/usr/include/c++/9/bits/std_function.h:532:2: note: template argument deduction/substitution failed:
In file included from /home/amodpatil/ros2/src/yasmin/yasmin_demo/src/action_client_demo.cpp:24:
/home/amodpatil/ros2/install/yasmin_ros/include/yasmin_ros/action_state.hpp:113:46: note: ‘std::_Bind<void (yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>::(yasmin_ros::ActionState<action_tutorials_interfaces::action::Fibonacci>, std::_Placeholder<1>))(const std::shared_ptr<rclcpp_action::ClientGoalHandle<action_tutorials_interfaces::action::Fibonacci> >&)>’ is not derived from ‘std::reference_wrapper<_Tp>’
113 | send_goal_options.goal_response_callback =
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
114 | std::bind(&ActionState::goal_response_callback, this, _1);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/action_client_demo.dir/build.make:63: CMakeFiles/action_client_demo.dir/src/action_client_demo.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/action_client_demo.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:141: all] Error 2

Failed <<< yasmin_demo [6.82s, exited with code 2]

Summary: 0 packages finished [7.10s]
1 package failed: yasmin_demo
1 package had stderr output: yasmin_demo

still the same error

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

Pull and try again. I have done another update.

@amodpatil1
Copy link
Author

It is working now. But now there is this ros2 run demo_nodes_py add_two_ints_servers
No executable found. I am sorry for too many questions

@amodpatil1
Copy link
Author

The service demo is not running

@amodpatil1
Copy link
Author

Both the commands are not executable

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

You have to install the ROS 2 demo packages (ros-humble-demo-nodes-py, ros-humble-demo-nodes-cpp, ros-humble-action-tutorials-py, ros-humble-action-tutorials-cpp).

@amodpatil1
Copy link
Author

I am able to find the demos for foxy, can you please help me out?

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 5, 2024

Have you tried to install them with sudo apt install ros-foxy-demo-nodes-py, ros-foxy-demo-nodes-cpp, ros-foxy-action-tutorials-py, ros-foxy-action-tutorials-cpp?

@amodpatil1
Copy link
Author

Yes it started working but I am not able to understand how can I build a custom FSM on yasmin. Could we please have a call on this where you can explain me the implementation of yasmin on my project?
I am a Masters student at Coburg University of applied science in germany and I am currently working on an autonomous vehicle, where the vehicle needs to park itself autonomously in the parking spot and I am working on the behaviour planning component which decides the state of the vehicle.

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 6, 2024

@amodpatil1, you have several examples in the README that includes basic states, ROS 2-based states and a demo with Nav2. If you want further explanations, you can send me an email.

@amodpatil1
Copy link
Author

Do I need to have a separate package for my state machine?

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 6, 2024

Yes, you should create a new package with your code.

@amodpatil1
Copy link
Author

amodpatil1 commented Jun 6, 2024

do I need to add the dependencies from yasmin into my package.xml as well?

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 6, 2024

No, but you can add them to the package.xml.

@amodpatil1
Copy link
Author

What would be the effieicent way to implement yasmin? Would it be via creating a package or a YAML file?

@amodpatil1
Copy link
Author

Can I use this as a reference for my custom machine?

Copyright (C) 2023 Miguel Ángel González Santamarta

This program is free software: you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation, either version 3 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program. If not, see https://www.gnu.org/licenses/.

from typing import Dict, List, Union
from threading import Lock
from yasmin.state import State
from yasmin.blackboard import Blackboard

class StateMachine(State):
def init(self, outcomes: List[str]) -> None:

    super().__init__(outcomes)

    self._states = {}
    self._start_state = None
    self.__current_state = None
    self.__current_state_lock = Lock()

def add_state(
    self,
    name: str,
    state: State,
    transitions: Dict[str, str] = None
) -> None:

    if not transitions:
        transitions = {}

    self._states[name] = {
        "state": state,
        "transitions": transitions
    }

    if not self._start_state:
        self._start_state = name

def set_start_state(self, name: str) -> None:
    self._start_state = name

def get_start_state(self) -> str:
    return self._start_state

def cancel_state(self) -> None:
    super().cancel_state()
    with self.__current_state_lock:
        if self.__current_state:
            self._states[self.__current_state]["state"].cancel_state()

def execute(self, blackboard: Blackboard) -> str:

    with self.__current_state_lock:
        self.__current_state = self._start_state

    while True:

        with self.__current_state_lock:
            state = self._states[self.__current_state]

        outcome = state["state"](blackboard)

        # check outcome belongs to state
        if outcome not in state["state"].get_outcomes():
            raise Exception(
                f"Outcome ({outcome}) is not register in state {self.__current_state}")

        # translate outcome using transitions
        if outcome in state["transitions"]:
            outcome = state["transitions"][outcome]

        # outcome is an outcome of the sm
        if outcome in self.get_outcomes():
            with self.__current_state_lock:
                self.__current_state = None
            return outcome

        # outcome is a state
        elif outcome in self._states:
            with self.__current_state_lock:
                self.__current_state = outcome

        # outcome is not in the sm
        else:
            raise Exception(f"Outcome ({outcome}) without transition")

def get_states(self) -> Dict[str, Union[State, Dict[str, str]]]:
    return self._states

def get_current_state(self) -> str:
    with self.__current_state_lock:
        if self.__current_state:
            return self.__current_state

    return ""

def __str__(self) -> str:
    return f"StateMachine: {self._states}"

@mgonzs13
Copy link
Collaborator

mgonzs13 commented Jun 7, 2024

What would be the effieicent way to implement yasmin? Would it be via creating a package or a YAML file?

I prefer using new packages. What do you mean by a YAML file?

Can I use this as a reference for my custom machine?

What do you mean by reference?

@amodpatil1
Copy link
Author

I mean can I write my state machine using the one you wrote as a base for mine custom state machine

@amodpatil1
Copy link
Author

states:

  • id: idle
    on_enter:

    • log: Entered idle state
    • custom_action: adapt_vi_start
    • custom_action: adapt_loc_start
    • custom_action: adapt_obj_start
    • custom_action: adapt_envmod_start
    • custom_action: ylidar_start
    • custom_action: adapt_livtrac_start
      transitions:
    • trigger: start
      target: driving
  • id: driving
    on_enter:

    • log: Entered driving state
    • custom_action: adapt_vi_drive
    • custom_action: adapt_loc_drive
    • custom_action: adapt_obj_drive
    • custom_action: adapt_envmod_drive
    • custom_action: ylidar_drive
    • custom_action: adapt_livtrac_drive
      transitions:
    • trigger: stop
      target: idle

This is the example for the yaml file
I have not implemented this

@amodpatil1
Copy link
Author

Can you send me the screenshot of it?

@mgonzs13
Copy link
Collaborator

Here you have a video. I am pushing msgs in different topics and different tabs. Is this what you want?

Screencast.2024-06-17.18.18.58.mp4

@amodpatil1
Copy link
Author

Yes this is what I want. Did you do any changes in the yasmin_node?

@mgonzs13
Copy link
Collaborator

No, I haven't changed anything. I have just executed it as you gave me.

@amodpatil1
Copy link
Author

amodpatil1 commented Jun 17, 2024

Now I just want to listen to multiple topics simultaneously when the state machine is running, after this my state machine will complete

@amodpatil1
Copy link
Author

I am not able to listen to a single node as well.

@mgonzs13
Copy link
Collaborator

Now I just want to listen to multiple topics simultaneously when the state machine is running, after this my state machine will complete

Isn't it what I just showed you in the video?

I am not able to listen to a single node as well.

What do you mean by listening to a node?

@amodpatil1
Copy link
Author

Yes, I tried the same approach as you did but there was no change in the states.

@mgonzs13
Copy link
Collaborator

I don't know what could be happening. Put some logs in the subscriber callbacks to check if your node is receiving msgs. It may also be a problem with the ROS 2 distro, I am using Humble.

@amodpatil1
Copy link
Author

amodpatil1 commented Jun 18, 2024

It ran It was my mistake it was executing the wrong executable.

@amodpatil1
Copy link
Author

#!/usr/bin/env python3

Copyright (C) 2023 Miguel Ángel González Santamarta

This program is free software: you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation, either version 3 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program. If not, see https://www.gnu.org/licenses/.

import time
import math
import rclpy
from rclpy.node import Node
from std_msgs.msg import Bool
from geometry_msgs.msg import Pose
from yasmin import State
from yasmin import Blackboard
from yasmin import StateMachine
from yasmin_viewer import YasminViewerPub

class FSMNode(Node):
def init(self, blackboard):
super().init('fsm_node')
self.blackboard = blackboard

    self.create_subscription(Bool, '/vi_start', self.vi_start_callback, 10)
    self.create_subscription(Pose, '/loc_pose', self.loc_pose_callback, 10)
    self.create_subscription(Bool, '/stop', self.stop_callback, 10)
    self.create_subscription(Pose, '/route', self.route_callback, 10)
    self.create_subscription(Bool, '/trajpf', self.trajpf_callback, 10)
    self.create_subscription(Bool, '/trajpr', self.trajpr_callback, 10)
    print("init")

def vi_start_callback(self, msg):
    self.blackboard.adapt_vi_start_trigger = msg.data

def loc_pose_callback(self, msg):
    self.blackboard.adapt_loc = (msg.position.x, msg.position.y)

def stop_callback(self, msg):
    self.blackboard.adapt_envmod = msg.data
    # If an obstacle is detected, inform adapt_trajp to stop
    if msg.data:  # Assuming True means obstacle detected
        stop_msg = Bool()
        stop_msg.data = True
        self.blackboard.adapt_trajp_publisher.publish(stop_msg)

def route_callback(self, msg):
    self.blackboard.adapt_roucomp = (msg.position.x, msg.position.y)

def trajpf_callback(self, msg):
    self.blackboard.trajpf_complete = msg.data

def trajpr_callback(self, msg):
    self.blackboard.trajpr_complete = msg.data

define state Idle

class IdleState(State):
def init(self) -> None:
super().init(["driving_state"])
self.logger = rclpy.logging.get_logger('IdleState')

def execute(self, blackboard: Blackboard) -> str:
    print("Executing state IDLE")
    # Wait for start trigger from adapt_vi
    while not blackboard.adapt_vi_start_trigger:
        self.logger.info('going to sleep')
        time.sleep(0.1)
    return "driving_state"

define state Driving

class DrivingState(State):
def init(self) -> None:
super().init(["drive", "stop_obstacle", "stop_near_park"])

def execute(self, blackboard: Blackboard) -> str:
    print("Executing state DRIVING")
    time.sleep(3)

    # Check for obstacle detection
    if blackboard.adapt_envmod:
        print("Obstacle detected by adapt_envmod")
        return "stop_obstacle"

    # Calculate distance to parking spot
    vehicle_location = blackboard.adapt_loc
    parking_spot_location = blackboard.adapt_roucomp
    distance_to_parking_spot = math.sqrt(
        (parking_spot_location[0] - vehicle_location[0]) ** 2 +
        (parking_spot_location[1] - vehicle_location[1]) ** 2
    )

    if distance_to_parking_spot < blackboard.parking_threshold:
        print("Near parking spot")
        blackboard.adapt_trajp = True
        return "stop_near_park"

    return "drive"

define state StopObstacle

class StopObstacleState(State):
def init(self) -> None:
super().init(["stop"])

def execute(self, blackboard: Blackboard) -> str:
    print("Executing state STOP_OBSTACLE")
    time.sleep(2)

    # Check if adapt_envmod detects an obstacle (assuming adapt_envmod is True means obstacle detected)
    if blackboard.adapt_envmod:
        print("Obstacle detected by adapt_envmod")
        # Inform adapt_trajp to stop
        stop_msg = Bool()
        stop_msg.data = True
        blackboard.adapt_trajp_publisher.publish(stop_msg)

    return "stop"

define state StopNearPark

class StopNearParkState(State):
def init(self) -> None:
super().init(["park"])

def execute(self, blackboard: Blackboard) -> str:
    print("Executing state STOP_NEAR_PARK")
    time.sleep(2)
    # Trigger parking procedure
    blackboard.adapt_trajp = True
    return "park"

define state Park

class ParkState(State):
def init(self) -> None:
super().init(["parked"])

def execute(self, blackboard: Blackboard) -> str:
    print("Executing state PARK")

    while not blackboard.trajpf_complete:
        time.sleep(0.1)

    while not blackboard.trajpr_complete:
        time.sleep(0.1)

    print("Vehicle parked")
    return "parked"

main

def main():

print("yasmin_demo")

# init ROS 2
rclpy.init()

# create a FSM
sm = StateMachine(outcomes=["finished"])

# create and set blackboard
blackboard = Blackboard()
blackboard.obstacle_detected = False
blackboard.near_parking_spot = False
blackboard.adapt_vi_start_trigger = False  # Initial state of the start trigger
blackboard.adapt_loc = (0, 0)  # Initialize adapt_loc with a tuple representing coordinates
blackboard.adapt_obj = None  # Initialize adapt_obj
blackboard.adapt_livtrac = None  # Initialize adapt_livtrac
blackboard.adapt_roucomp = (10, 10)  # Initialize adapt_roucomp with a dummy parking spot location
blackboard.adapt_trajp = False  # Initialize adapt_trajp
blackboard.adapt_envmod = False  # Initialize adapt_envmod as no obstacle detected
blackboard.parking_threshold = 1.0  # Distance threshold for parking spot detection
blackboard.trajpf_complete = False  # Initialize trajpf_complete
blackboard.trajpr_complete = False  # Initialize trajpr_complete

# init ROS 2 node
fsm_node = FSMNode(blackboard)
blackboard.adapt_trajp_publisher = fsm_node.create_publisher(Bool, '/adapt_trajp', 10)

# add states
sm.add_state(
    "IDLE",
    IdleState(),
    transitions={
        "driving_state": "DRIVING"
    }
)
sm.add_state(
    "DRIVING",
    DrivingState(),
    transitions={
        "drive": "DRIVING",
        "stop_obstacle": "STOP_OBSTACLE",
        "stop_near_park": "STOP_NEAR_PARK"
    }
)
sm.add_state(
    "STOP_OBSTACLE",
    StopObstacleState(),
    transitions={
        "stop": "STOP_OBSTACLE"  # Ensure outcome is "stop" when obstacle detected
    }
)
sm.add_state(
    "STOP_NEAR_PARK",
    StopNearParkState(),
    transitions={
        "park": "PARK"
    }
)
sm.add_state(
    "PARK",
    ParkState(),
    transitions={
        "parked": "PARKED"  # Changed outcome to "parked"
    }
)

# pub FSM info
YasminViewerPub("YASMIN_DEMO", sm)

# execute FSM
import threading
def execute_fsm():
    outcome = sm.execute(blackboard)
    print(outcome)

fsm_thread = threading.Thread(target=execute_fsm)
fsm_thread.start()

# Spin ROS 2 node
rclpy.spin(fsm_node)

# Shutdown
fsm_thread.join()
rclpy.shutdown()

if name == "main":
main()

This is the code and now I am not able to run the viewer node.

@amodpatil1
Copy link
Author

It was running before

@mgonzs13
Copy link
Collaborator

I have just run it and everything works. Which environment are you using (Ubuntu version, ROS 2 distro, etc)?

@amodpatil1
Copy link
Author

ubuntu 20.04 and ros2 foxy

@amodpatil1
Copy link
Author

I am able to see all the state changes
Screenshot from 2024-06-18 20-09-44

@amodpatil1
Copy link
Author

Untitled.video.-.Made.with.Clipchamp.mp4

@mgonzs13
Copy link
Collaborator

Update yasmin by using git pull and try it again.

@amodpatil1
Copy link
Author

Okay

@amodpatil1
Copy link
Author

I will try now

@amodpatil1
Copy link
Author

Screenshot from 2024-06-18 22-45-33

@amodpatil1
Copy link
Author

There is no change

@amodpatil1
Copy link
Author

I will try by cloning it again

@amodpatil1
Copy link
Author

Not working even after cloning it again

@mgonzs13
Copy link
Collaborator

Have you used colcon and source after updating?

@amodpatil1
Copy link
Author

Yes

@mgonzs13
Copy link
Collaborator

I have just found an error with the transitions of your state machine. You are trying to move to a state/outcome named "PARKED" that does not exist. Changing it to an existing outcome or state solves your error. Here you have an example:

#!/usr/bin/env python3

import threading
import time
import math
import rclpy
from rclpy.node import Node
from std_msgs.msg import Bool
from geometry_msgs.msg import Pose
from yasmin import State
from yasmin import Blackboard
from yasmin import StateMachine
from yasmin_viewer import YasminViewerPub


class FSMNode(Node):
    def __init__(self, blackboard):
        super().__init__('fsm_node')
        self.blackboard = blackboard

        self.create_subscription(Bool, '/vi_start', self.vi_start_callback, 10)
        self.create_subscription(Pose, '/loc_pose', self.loc_pose_callback, 10)
        self.create_subscription(Bool, '/stop', self.stop_callback, 10)
        self.create_subscription(Pose, '/route', self.route_callback, 10)
        self.create_subscription(Bool, '/trajpf', self.trajpf_callback, 10)
        self.create_subscription(Bool, '/trajpr', self.trajpr_callback, 10)
        print("init")

    def vi_start_callback(self, msg):
        self.blackboard.adapt_vi_start_trigger = msg.data

    def loc_pose_callback(self, msg):
        self.blackboard.adapt_loc = (msg.position.x, msg.position.y)

    def stop_callback(self, msg):
        self.blackboard.adapt_envmod = msg.data
        # If an obstacle is detected, inform adapt_trajp to stop
        if msg.data:  # Assuming True means obstacle detected
            stop_msg = Bool()
            stop_msg.data = True
            self.blackboard.adapt_trajp_publisher.publish(stop_msg)

    def route_callback(self, msg):
        self.blackboard.adapt_roucomp = (msg.position.x, msg.position.y)

    def trajpf_callback(self, msg):
        self.blackboard.trajpf_complete = msg.data

    def trajpr_callback(self, msg):
        self.blackboard.trajpr_complete = msg.data


class IdleState(State):
    def __init__(self) -> None:
        super().__init__(["driving_state"])
        self.logger = rclpy.logging.get_logger('IdleState')

    def execute(self, blackboard: Blackboard) -> str:
        print("Executing state IDLE")
        # Wait for start trigger from adapt_vi
        while not blackboard.adapt_vi_start_trigger:
            self.logger.info('going to sleep')
            time.sleep(0.1)
        return "driving_state"


class DrivingState(State):
    def __init__(self) -> None:
        super().__init__(["drive", "stop_obstacle", "stop_near_park"])

    def execute(self, blackboard: Blackboard) -> str:
        print("Executing state DRIVING")
        time.sleep(3)

        # Check for obstacle detection
        if blackboard.adapt_envmod:
            print("Obstacle detected by adapt_envmod")
            return "stop_obstacle"

        # Calculate distance to parking spot
        vehicle_location = blackboard.adapt_loc
        parking_spot_location = blackboard.adapt_roucomp
        distance_to_parking_spot = math.sqrt(
            (parking_spot_location[0] - vehicle_location[0]) ** 2 +
            (parking_spot_location[1] - vehicle_location[1]) ** 2
        )

        if distance_to_parking_spot < blackboard.parking_threshold:
            print("Near parking spot")
            blackboard.adapt_trajp = True
            return "stop_near_park"

        return "drive"


class StopObstacleState(State):
    def __init__(self) -> None:
        super().__init__(["stop"])

    def execute(self, blackboard: Blackboard) -> str:
        print("Executing state STOP_OBSTACLE")
        time.sleep(2)

        # Check if adapt_envmod detects an obstacle (assuming adapt_envmod is True means obstacle detected)
        if blackboard.adapt_envmod:
            print("Obstacle detected by adapt_envmod")
            # Inform adapt_trajp to stop
            stop_msg = Bool()
            stop_msg.data = True
            blackboard.adapt_trajp_publisher.publish(stop_msg)

        return "stop"


class StopNearParkState(State):
    def __init__(self) -> None:
        super().__init__(["park"])

    def execute(self, blackboard: Blackboard) -> str:
        print("Executing state STOP_NEAR_PARK")
        time.sleep(2)
        # Trigger parking procedure
        blackboard.adapt_trajp = True
        return "park"


class ParkState(State):
    def __init__(self) -> None:
        super().__init__(["parked"])

    def execute(self, blackboard: Blackboard) -> str:
        print("Executing state PARK")

        while not blackboard.trajpf_complete:
            time.sleep(0.1)

        while not blackboard.trajpr_complete:
            time.sleep(0.1)

        print("Vehicle parked")
        return "parked"


def main():
    print("yasmin_demo")

    # init ROS 2
    rclpy.init()

    # create a FSM
    sm = StateMachine(outcomes=["finished"])

    # create and set blackboard
    blackboard = Blackboard()
    blackboard.obstacle_detected = False
    blackboard.near_parking_spot = False
    blackboard.adapt_vi_start_trigger = False  # Initial state of the start trigger
    # Initialize adapt_loc with a tuple representing coordinates
    blackboard.adapt_loc = (0, 0)
    blackboard.adapt_obj = None  # Initialize adapt_obj
    blackboard.adapt_livtrac = None  # Initialize adapt_livtrac
    # Initialize adapt_roucomp with a dummy parking spot location
    blackboard.adapt_roucomp = (10, 10)
    blackboard.adapt_trajp = False  # Initialize adapt_trajp
    blackboard.adapt_envmod = False  # Initialize adapt_envmod as no obstacle detected
    # Distance threshold for parking spot detection
    blackboard.parking_threshold = 1.0
    blackboard.trajpf_complete = False  # Initialize trajpf_complete
    blackboard.trajpr_complete = False  # Initialize trajpr_complete

    # init ROS 2 node
    fsm_node = FSMNode(blackboard)
    blackboard.adapt_trajp_publisher = fsm_node.create_publisher(
        Bool, '/adapt_trajp', 10)

    # add states
    sm.add_state(
        "IDLE",
        IdleState(),
        transitions={
            "driving_state": "DRIVING"
        }
    )
    sm.add_state(
        "DRIVING",
        DrivingState(),
        transitions={
            "drive": "DRIVING",
            "stop_obstacle": "STOP_OBSTACLE",
            "stop_near_park": "STOP_NEAR_PARK"
        }
    )
    sm.add_state(
        "STOP_OBSTACLE",
        StopObstacleState(),
        transitions={
            "stop": "STOP_OBSTACLE"  # Ensure outcome is "stop" when obstacle detected
        }
    )
    sm.add_state(
        "STOP_NEAR_PARK",
        StopNearParkState(),
        transitions={
            "park": "PARK"
        }
    )
    sm.add_state(
        "PARK",
        ParkState(),
        transitions={
            "parked": "finished"  # Changed outcome to "parked"
        }
    )

    # pub FSM info
    YasminViewerPub("YASMIN_DEMO", sm)

    # execute FSM

    def execute_fsm():
        outcome = sm.execute(blackboard)
        print(outcome)

    fsm_thread = threading.Thread(target=execute_fsm)
    fsm_thread.start()

    # Spin ROS 2 node
    rclpy.spin(fsm_node)

    # Shutdown
    fsm_thread.join()
    rclpy.shutdown()


if __name__ == "__main__":
    main()

@amodpatil1
Copy link
Author

Hi, I have one issue that I want to stay one state only and that state should not have a transition. How do I do that?

@mgonzs13
Copy link
Collaborator

Hey @amodpatil1, all states should have transitions and a path to your state machine's final outcome. You can also make a transition from a state to itself, creating a loop and staying in that state till the transition to another state or a final outcome triggers.

@amodpatil1
Copy link
Author

Okay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants