Repository: reelrbtx/SMACC Branch: noetic-devel Commit: e5abc09c51b1 Files: 1000 Total size: 2.1 MB Directory structure: gitextract_y9gdi5pk/ ├── .codespell-ignore-words.txt ├── .github/ │ └── workflows/ │ ├── CI.yaml │ ├── bloom_release.yml │ ├── code_quality.yml │ └── doxygen.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .vscode/ │ └── launch.json ├── LICENSE.txt ├── README.md ├── documentation/ │ ├── Dance_Bot FlowchartX.odp │ ├── Dance_Bot FlowchartX.v2.odp │ └── ReelSmacc.v2.odp ├── smacc/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── include/ │ │ └── smacc/ │ │ ├── callback_counter_semaphore.h │ │ ├── client_base_components/ │ │ │ ├── cp_ros_control_interface.h │ │ │ └── cp_topic_subscriber.h │ │ ├── client_bases/ │ │ │ ├── smacc_action_client.h │ │ │ ├── smacc_action_client_base.h │ │ │ ├── smacc_publisher_client.h │ │ │ ├── smacc_service_client.h │ │ │ ├── smacc_service_server_client.h │ │ │ └── smacc_subscriber_client.h │ │ ├── client_behavior_bases/ │ │ │ ├── cb_service_server_callback_base.h │ │ │ └── cb_subscription_callback_base.h │ │ ├── common.h │ │ ├── component.h │ │ ├── impl/ │ │ │ ├── smacc_asynchronous_client_behavior_impl.h │ │ │ ├── smacc_client_behavior_impl.h │ │ │ ├── smacc_client_impl.h │ │ │ ├── smacc_component_impl.h │ │ │ ├── smacc_event_generator_impl.h │ │ │ ├── smacc_orthogonal_impl.h │ │ │ ├── smacc_state_impl.h │ │ │ ├── smacc_state_machine_impl.h │ │ │ └── smacc_state_reactor_impl.h │ │ ├── introspection/ │ │ │ ├── introspection.h │ │ │ ├── smacc_state_info.h │ │ │ ├── smacc_state_machine_info.h │ │ │ ├── state_traits.h │ │ │ └── string_type_walker.h │ │ ├── smacc.h │ │ ├── smacc_asynchronous_client_behavior.h │ │ ├── smacc_client.h │ │ ├── smacc_client_behavior.h │ │ ├── smacc_client_behavior_base.h │ │ ├── smacc_default_events.h │ │ ├── smacc_event_generator.h │ │ ├── smacc_fifo_scheduler.h │ │ ├── smacc_fifo_worker.h │ │ ├── smacc_orthogonal.h │ │ ├── smacc_signal.h │ │ ├── smacc_signal_detector.h │ │ ├── smacc_state.h │ │ ├── smacc_state_base.h │ │ ├── smacc_state_machine.h │ │ ├── smacc_state_machine_base.h │ │ ├── smacc_state_reactor.h │ │ ├── smacc_transition.h │ │ ├── smacc_types.h │ │ └── smacc_updatable.h │ ├── package.xml │ ├── rosdoc.yaml │ ├── smacc_client_behavior_base.h │ ├── src/ │ │ └── smacc/ │ │ ├── callback_counter_semaphore.cpp │ │ ├── client.cpp │ │ ├── client_bases/ │ │ │ └── smacc_action_client.cpp │ │ ├── common.cpp │ │ ├── components/ │ │ │ └── cp_ros_control_interface.cpp │ │ ├── introspection/ │ │ │ ├── reflection.cpp │ │ │ └── string_type_walker.cpp │ │ ├── orthogonal.cpp │ │ ├── signal_detector.cpp │ │ ├── smacc_client_async_behavior.cpp │ │ ├── smacc_client_behavior.cpp │ │ ├── smacc_client_behavior_base.cpp │ │ ├── smacc_component.cpp │ │ ├── smacc_event_generator.cpp │ │ ├── smacc_state.cpp │ │ ├── smacc_state_info.cpp │ │ ├── smacc_state_machine.cpp │ │ ├── smacc_state_machine_info.cpp │ │ ├── smacc_updatable.cpp │ │ └── state_reactor.cpp │ └── test/ │ └── type_info_unit_test.cpp ├── smacc_ci/ │ ├── .gitignore │ ├── Doxyfile │ ├── docker/ │ │ ├── ros_kinetic_ubuntu_16.04/ │ │ │ ├── Dockerfile │ │ │ ├── build.sh │ │ │ ├── examples/ │ │ │ │ └── run_sm_atomic.sh │ │ │ └── run_bash.sh │ │ ├── ros_melodic_ubuntu_18.04/ │ │ │ ├── Dockerfile │ │ │ ├── build.sh │ │ │ ├── examples/ │ │ │ │ └── run_sm_atomic.sh │ │ │ └── run_bash.sh │ │ └── ros_noetic_ubuntu_20.04/ │ │ ├── Dockerfile │ │ ├── build.sh │ │ ├── examples/ │ │ │ └── run_sm_atomic.sh │ │ └── run_bash.sh │ ├── gh-pages.sh │ ├── packagecloud_docker/ │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── build_ubuntu_16_04_kinetic.sh │ │ ├── build_ubuntu_18_04_melodic.sh │ │ ├── build_ubuntu_20_04_noetic.sh │ │ ├── generate_debs.py │ │ ├── generate_smacc_debs.bash │ │ ├── local_build_18_04_melodic.sh │ │ └── local_build_20_04_noetic.sh │ ├── rosdep_kinetic.yaml │ ├── rosdep_melodic.yaml │ └── rosdep_noetic.yaml ├── smacc_client_library/ │ ├── battery_monitor_client/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── include/ │ │ │ └── battery_monitor_client/ │ │ │ └── cl_battery_monitor.h │ │ ├── package.xml │ │ ├── server/ │ │ │ └── battery_monitor_node.py │ │ └── src/ │ │ └── battery_monitor_client/ │ │ └── cl_battery_monitor.cpp │ ├── keyboard_client/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── include/ │ │ │ └── keyboard_client/ │ │ │ ├── cl_keyboard.h │ │ │ └── client_behaviors/ │ │ │ └── cb_default_keyboard_behavior.h │ │ ├── package.xml │ │ ├── server/ │ │ │ └── keyboard_server_node/ │ │ │ └── keyboard_server_node.py │ │ └── src/ │ │ └── keyboard_client/ │ │ └── cl_keyboard.cpp │ ├── move_base_z_client/ │ │ ├── README.md │ │ ├── custom_planners/ │ │ │ ├── backward_global_planner/ │ │ │ │ ├── CHANGELOG.rst │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── bgp_plugin.xml │ │ │ │ ├── include/ │ │ │ │ │ └── backward_global_planner/ │ │ │ │ │ └── backward_global_planner.h │ │ │ │ ├── package.xml │ │ │ │ ├── rosdoc.yaml │ │ │ │ └── src/ │ │ │ │ └── backward_global_planner.cpp │ │ │ ├── backward_local_planner/ │ │ │ │ ├── CHANGELOG.rst │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── blp_plugin.xml │ │ │ │ ├── cfg/ │ │ │ │ │ └── BackwardLocalPlanner.cfg │ │ │ │ ├── include/ │ │ │ │ │ └── backward_local_planner/ │ │ │ │ │ └── backward_local_planner.h │ │ │ │ ├── package.xml │ │ │ │ ├── rosdoc.yaml │ │ │ │ └── src/ │ │ │ │ └── backward_local_planner.cpp │ │ │ ├── forward_global_planner/ │ │ │ │ ├── CHANGELOG.rst │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── fgp_plugin.xml │ │ │ │ ├── include/ │ │ │ │ │ └── forward_global_planner/ │ │ │ │ │ ├── forward_global_planner.h │ │ │ │ │ └── move_base_z_client_tools.h │ │ │ │ ├── package.xml │ │ │ │ ├── rosdoc.yaml │ │ │ │ └── src/ │ │ │ │ ├── forward_global_planner.cpp │ │ │ │ └── path_tools.cpp │ │ │ ├── forward_local_planner/ │ │ │ │ ├── CHANGELOG.rst │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── cfg/ │ │ │ │ │ └── ForwardLocalPlanner.cfg │ │ │ │ ├── flp_plugin.xml │ │ │ │ ├── include/ │ │ │ │ │ └── forward_local_planner/ │ │ │ │ │ └── forward_local_planner.h │ │ │ │ ├── package.xml │ │ │ │ ├── rosdoc.yaml │ │ │ │ └── src/ │ │ │ │ └── forward_local_planner.cpp │ │ │ ├── pure_spinning_local_planner/ │ │ │ │ ├── CHANGELOG.rst │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── cfg/ │ │ │ │ │ └── PureSpinningLocalPlanner.cfg │ │ │ │ ├── config/ │ │ │ │ │ └── pure_spinning_local_planner.yaml │ │ │ │ ├── include/ │ │ │ │ │ └── pure_spinning_local_planner/ │ │ │ │ │ └── pure_spinning_local_planner.h │ │ │ │ ├── package.xml │ │ │ │ ├── pslp_plugin.xml │ │ │ │ ├── rosdoc.yaml │ │ │ │ └── src/ │ │ │ │ └── pure_spinning_local_planner/ │ │ │ │ └── pure_spinning_local_planner.cpp │ │ │ └── undo_path_global_planner/ │ │ │ ├── CHANGELOG.rst │ │ │ ├── CMakeLists.txt │ │ │ ├── include/ │ │ │ │ └── undo_path_global_planner/ │ │ │ │ └── undo_path_global_planner.h │ │ │ ├── package.xml │ │ │ ├── rosdoc.yaml │ │ │ ├── src/ │ │ │ │ └── undo_path_global_planner.cpp │ │ │ └── upgp_plugin.xml │ │ └── move_base_z_client_plugin/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── action/ │ │ │ └── OdomTracker.action │ │ ├── cfg/ │ │ │ └── OdomTracker.cfg │ │ ├── include/ │ │ │ └── move_base_z_client_plugin/ │ │ │ ├── client_behaviors/ │ │ │ │ ├── cb_absolute_rotate.h │ │ │ │ ├── cb_move_base_client_behavior_base.h │ │ │ │ ├── cb_navigate_backwards.h │ │ │ │ ├── cb_navigate_forward.h │ │ │ │ ├── cb_navigate_global_position.h │ │ │ │ ├── cb_navigate_next_waypoint.h │ │ │ │ ├── cb_rotate.h │ │ │ │ ├── cb_undo_path_backwards.h │ │ │ │ └── cb_undo_path_backwards2.h │ │ │ ├── client_behaviors.h │ │ │ ├── components/ │ │ │ │ ├── costmap_switch/ │ │ │ │ │ └── cp_costmap_switch.h │ │ │ │ ├── odom_tracker/ │ │ │ │ │ └── odom_tracker.h │ │ │ │ ├── planner_switcher/ │ │ │ │ │ └── planner_switcher.h │ │ │ │ ├── pose/ │ │ │ │ │ └── cp_pose.h │ │ │ │ └── waypoints_navigator/ │ │ │ │ ├── waypoints_event_dispatcher.h │ │ │ │ └── waypoints_navigator.h │ │ │ └── move_base_z_client_plugin.h │ │ ├── package.xml │ │ ├── rosdoc.yaml │ │ └── src/ │ │ ├── client_behaviors/ │ │ │ ├── cb_absolute_rotate.cpp │ │ │ ├── cb_move_base_client_behavior_base.cpp │ │ │ ├── cb_navigate_backward.cpp │ │ │ ├── cb_navigate_forward.cpp │ │ │ ├── cb_navigate_global_position.cpp │ │ │ ├── cb_navigate_next_waypoint.cpp │ │ │ ├── cb_rotate.cpp │ │ │ ├── cb_undo_path_backwards.cpp │ │ │ └── cb_undo_path_backwards2.cpp │ │ ├── components/ │ │ │ ├── costmap_switch/ │ │ │ │ └── cp_costmap_switch.cpp │ │ │ ├── odom_tracker/ │ │ │ │ ├── odom_tracker.cpp │ │ │ │ └── odom_tracker_node.cpp │ │ │ ├── planner_switcher/ │ │ │ │ └── planner_switcher.cpp │ │ │ ├── pose/ │ │ │ │ └── cp_pose.cpp │ │ │ └── waypoints_navigator/ │ │ │ ├── waypoints_event_dispatcher.cpp │ │ │ └── waypoints_navigator.cpp │ │ └── move_base_z_client_plugin.cpp │ ├── move_eye/ │ │ └── move_eye_client/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── package.xml │ │ └── src/ │ │ └── cl_move_eye.cpp │ ├── move_group_interface_client/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── include/ │ │ │ └── move_group_interface_client/ │ │ │ ├── cl_movegroup.h │ │ │ ├── client_behaviors/ │ │ │ │ ├── cb_attach_object.h │ │ │ │ ├── cb_circular_pivot_motion.h │ │ │ │ ├── cb_detach_object.h │ │ │ │ ├── cb_end_effector_rotate.h │ │ │ │ ├── cb_execute_last_trajectory.h │ │ │ │ ├── cb_move_cartesian_relative.h │ │ │ │ ├── cb_move_cartesian_relative2.h │ │ │ │ ├── cb_move_end_effector.h │ │ │ │ ├── cb_move_end_effector_relative.h │ │ │ │ ├── cb_move_end_effector_trajectory.h │ │ │ │ ├── cb_move_joints.h │ │ │ │ ├── cb_move_joints_relative.h │ │ │ │ ├── cb_move_known_state.h │ │ │ │ ├── cb_move_last_trajectory_initial_state.h │ │ │ │ ├── cb_move_named_target.h │ │ │ │ ├── cb_pouring_motion.h │ │ │ │ └── cb_undo_last_trajectory.h │ │ │ ├── client_behaviors.h │ │ │ └── components/ │ │ │ ├── cp_grasping_objects.h │ │ │ ├── cp_tf_listener.h │ │ │ └── cp_trajectory_history.h │ │ ├── package.xml │ │ └── src/ │ │ └── move_group_interface_client/ │ │ ├── cl_movegroup.cpp │ │ ├── client_behaviors/ │ │ │ ├── cb_attach_object.cpp │ │ │ ├── cb_circular_pivot_motion.cpp │ │ │ ├── cb_detach_object.cpp │ │ │ ├── cb_end_effector_rotate.cpp │ │ │ ├── cb_execute_last_trajectory.cpp │ │ │ ├── cb_move_cartesian_relative.cpp │ │ │ ├── cb_move_end_effector.cpp │ │ │ ├── cb_move_end_effector_relative.cpp │ │ │ ├── cb_move_end_effector_trajectory.cpp │ │ │ ├── cb_move_joints.cpp │ │ │ ├── cb_move_known_state.cpp │ │ │ ├── cb_move_last_trajectory_initial_state.cpp │ │ │ ├── cb_move_named_target.cpp │ │ │ ├── cb_pouring_motion.cpp │ │ │ └── cb_undo_last_trajectory.cpp │ │ └── components/ │ │ ├── cp_grasping_objects.cpp │ │ └── cp_trajectory_history.cpp │ ├── multirole_sensor_client/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── include/ │ │ │ └── multirole_sensor_client/ │ │ │ ├── cl_multirole_sensor.h │ │ │ └── client_behaviors/ │ │ │ └── cb_default_multirole_sensor_behavior.h │ │ ├── package.xml │ │ └── rosdoc.yaml │ ├── ros_publisher_client/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── include/ │ │ │ └── ros_publisher_client/ │ │ │ ├── cl_ros_publisher.h │ │ │ └── client_behaviors/ │ │ │ ├── cb_default_publish_loop.h │ │ │ ├── cb_muted_behavior.h │ │ │ └── cb_publish_once.h │ │ └── package.xml │ └── ros_timer_client/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── README.md │ ├── include/ │ │ └── ros_timer_client/ │ │ ├── cl_ros_timer.h │ │ └── client_behaviors/ │ │ ├── cb_ros_timer.h │ │ ├── cb_timer_countdown_loop.h │ │ └── cb_timer_countdown_once.h │ ├── package.xml │ └── src/ │ └── ros_timer_client/ │ ├── cb_timer.cpp │ ├── cb_timer_countdown_loop.cpp │ ├── cb_timer_countdown_once.cpp │ └── timer_client.cpp ├── smacc_diagnostics/ │ ├── readme.md │ ├── scripts/ │ │ └── regex_template.py │ ├── smacc_runtime_test/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── config/ │ │ │ └── state_machine_config_test_file.yaml │ │ ├── launch/ │ │ │ └── meta_test.launch │ │ ├── package.xml │ │ └── src/ │ │ └── smacc_runtime_test_node.cpp │ └── smacc_rviz_plugin/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── media/ │ │ └── .empty │ ├── package.xml │ ├── plugin_description.xml │ └── src/ │ ├── imu_visual.cpp │ ├── imu_visual.h │ ├── smacc_rviz_display.cpp │ └── smacc_rviz_display.h ├── smacc_event_generator_library/ │ ├── eg_conditional_generator/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── include/ │ │ │ └── eg_conditional_generator/ │ │ │ └── eg_conditional_generator.h │ │ ├── package.xml │ │ └── src/ │ │ └── eg_conditional_generator/ │ │ └── eg_conditional_generator.cpp │ └── eg_random_generator/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── include/ │ │ └── eg_random_generator/ │ │ └── eg_random_generator.h │ ├── package.xml │ └── src/ │ └── eg_random_generator/ │ └── eg_random_generator.cpp ├── smacc_msgs/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── msg/ │ │ ├── SmaccContainerInitialStatusCmd.msg │ │ ├── SmaccContainerStatus.msg │ │ ├── SmaccContainerStructure.msg │ │ ├── SmaccEvent.msg │ │ ├── SmaccEventGenerator.msg │ │ ├── SmaccOrthogonal.msg │ │ ├── SmaccSMCommand.msg │ │ ├── SmaccState.msg │ │ ├── SmaccStateMachine.msg │ │ ├── SmaccStateReactor.msg │ │ ├── SmaccStatus.msg │ │ ├── SmaccTransition.msg │ │ └── SmaccTransitionLogEntry.msg │ ├── package.xml │ └── srv/ │ └── SmaccGetTransitionHistory.srv ├── smacc_sm_reference_library/ │ ├── sm_atomic/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── sm_atomic_config.yaml │ │ │ └── sm_atomic_test.yaml │ │ ├── include/ │ │ │ └── sm_atomic/ │ │ │ ├── orthogonals/ │ │ │ │ └── or_timer.h │ │ │ ├── sm_atomic.h │ │ │ └── states/ │ │ │ ├── st_state_1.h │ │ │ └── st_state_2.h │ │ ├── launch/ │ │ │ └── sm_atomic.launch │ │ ├── package.xml │ │ ├── src/ │ │ │ └── sm_atomic_node.cpp │ │ └── test/ │ │ └── sm_atomic.test │ ├── sm_atomic_cb/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_atomic_cb_config.yaml │ │ ├── include/ │ │ │ └── sm_atomic_cb/ │ │ │ ├── orthogonals/ │ │ │ │ └── or_timer.h │ │ │ ├── sm_atomic_cb.h │ │ │ └── states/ │ │ │ ├── st_state_1.h │ │ │ └── st_state_2.h │ │ ├── launch/ │ │ │ └── sm_atomic_cb.launch │ │ ├── package.xml │ │ └── src/ │ │ └── sm_atomic_cb_node.cpp │ ├── sm_atomic_mode_states/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── sm_atomic_config.yaml │ │ │ └── sm_atomic_test.yaml │ │ ├── include/ │ │ │ └── sm_atomic_mode_states/ │ │ │ ├── client_behaviors/ │ │ │ │ └── cb_updatable_test.h │ │ │ ├── orthogonals/ │ │ │ │ └── or_timer.h │ │ │ ├── sm_atomic_mode_states.h │ │ │ └── states/ │ │ │ ├── ms_state_1.h │ │ │ ├── ms_state_2.h │ │ │ ├── st_state_1.h │ │ │ └── st_state_2.h │ │ ├── launch/ │ │ │ └── sm_atomic_mode_states.launch │ │ ├── package.xml │ │ ├── src/ │ │ │ └── sm_atomic_node.cpp │ │ └── test/ │ │ └── sm_atomic.test │ ├── sm_atomic_services/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── sm_atomic_services_config.yaml │ │ │ └── sm_atomic_services_test.yaml │ │ ├── include/ │ │ │ └── sm_atomic_services/ │ │ │ ├── clients/ │ │ │ │ ├── cl_service_client.h │ │ │ │ ├── cl_service_server.h │ │ │ │ └── client_behaviors/ │ │ │ │ └── cb_service_server.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_services.h │ │ │ │ └── or_timer.h │ │ │ ├── sm_atomic_services.h │ │ │ └── states/ │ │ │ ├── st_state_1.h │ │ │ └── st_state_2.h │ │ ├── launch/ │ │ │ └── sm_atomic_services.launch │ │ ├── package.xml │ │ ├── src/ │ │ │ └── sm_atomic_services_node.cpp │ │ └── test/ │ │ └── sm_atomic_services.test │ ├── sm_calendar_week/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_calendar_week_config.yaml │ │ ├── include/ │ │ │ └── sm_calendar_week/ │ │ │ ├── clients/ │ │ │ │ └── cl_subscriber/ │ │ │ │ ├── cl_subscriber.h │ │ │ │ └── client_behaviors/ │ │ │ │ ├── cb_default_subscriber_behavior.h │ │ │ │ └── cb_watchdog_subscriber_behavior.h │ │ │ ├── mode_states/ │ │ │ │ ├── ms_weekend.h │ │ │ │ └── ms_workweek.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_keyboard.h │ │ │ │ └── or_timer.h │ │ │ ├── sm_calendar_week.h │ │ │ └── states/ │ │ │ ├── st_friday.h │ │ │ ├── st_monday.h │ │ │ ├── st_saturday.h │ │ │ ├── st_sunday.h │ │ │ ├── st_thursday.h │ │ │ ├── st_tuesday.h │ │ │ └── st_wednesday.h │ │ ├── launch/ │ │ │ └── sm_calendar_week.launch │ │ ├── package.xml │ │ ├── package_REMOTE_32590.xml │ │ └── src/ │ │ └── sm_calendar_week_node.cpp │ ├── sm_dance_bot/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── move_base_client/ │ │ │ │ ├── backward_local_planner.yaml │ │ │ │ ├── base_local_planner_params.yaml │ │ │ │ ├── costmap_common_params.yaml │ │ │ │ ├── forward_local_planner.yaml │ │ │ │ ├── global_costmap_params.yaml │ │ │ │ ├── local_costmap_params.yaml │ │ │ │ └── waypoints_plan.yaml │ │ │ ├── navigation.rviz │ │ │ ├── rosconsole.config │ │ │ └── sm_dance_bot_config.yaml │ │ ├── docs/ │ │ │ └── Global Transition Rules.txt │ │ ├── include/ │ │ │ └── sm_dance_bot/ │ │ │ ├── clients/ │ │ │ │ ├── cl_led/ │ │ │ │ │ ├── cl_led.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ ├── cb_led_off.h │ │ │ │ │ └── cb_led_on.h │ │ │ │ ├── cl_lidar/ │ │ │ │ │ ├── cl_lidar.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_lidar_sensor.h │ │ │ │ ├── cl_service3/ │ │ │ │ │ ├── cl_service3.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_service3.h │ │ │ │ ├── cl_string_publisher/ │ │ │ │ │ ├── cl_string_publisher.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_string_publisher.h │ │ │ │ └── cl_temperature_sensor/ │ │ │ │ ├── cl_temperature_sensor.h │ │ │ │ └── client_behaviors/ │ │ │ │ └── cb_custom_condition_temperature_sensor.h │ │ │ ├── modestates/ │ │ │ │ ├── ms_dance_bot_recovery_mode.h │ │ │ │ └── ms_dance_bot_run_mode.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_led.h │ │ │ │ ├── or_navigation.h │ │ │ │ ├── or_obstacle_perception.h │ │ │ │ ├── or_service3.h │ │ │ │ ├── or_string_publisher.h │ │ │ │ ├── or_temperature_sensor.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_dance_bot.h │ │ │ ├── states/ │ │ │ │ ├── f_pattern_states/ │ │ │ │ │ ├── sti_fpattern_forward_1.h │ │ │ │ │ ├── sti_fpattern_forward_2.h │ │ │ │ │ ├── sti_fpattern_loop_start.h │ │ │ │ │ ├── sti_fpattern_return_1.h │ │ │ │ │ ├── sti_fpattern_rotate_1.h │ │ │ │ │ └── sti_fpattern_rotate_2.h │ │ │ │ ├── radial_motion_states/ │ │ │ │ │ ├── sti_radial_end_point.h │ │ │ │ │ ├── sti_radial_loop_start.h │ │ │ │ │ ├── sti_radial_return.h │ │ │ │ │ └── sti_radial_rotate.h │ │ │ │ ├── s_pattern_states/ │ │ │ │ │ ├── sti_spattern_forward_1.h │ │ │ │ │ ├── sti_spattern_forward_2.h │ │ │ │ │ ├── sti_spattern_forward_3.h │ │ │ │ │ ├── sti_spattern_forward_4.h │ │ │ │ │ ├── sti_spattern_loop_start.h │ │ │ │ │ ├── sti_spattern_rotate_1.h │ │ │ │ │ ├── sti_spattern_rotate_2.h │ │ │ │ │ ├── sti_spattern_rotate_3.h │ │ │ │ │ └── sti_spattern_rotate_4.h │ │ │ │ ├── st_acquire_sensors.h │ │ │ │ ├── st_event_count_down.h │ │ │ │ ├── st_navigate_forward_1.h │ │ │ │ ├── st_navigate_forward_2.h │ │ │ │ ├── st_navigate_reverse_1.h │ │ │ │ ├── st_navigate_reverse_2.h │ │ │ │ ├── st_navigate_reverse_3.h │ │ │ │ ├── st_navigate_to_waypoint_1.h │ │ │ │ ├── st_navigate_to_waypoints_x.h │ │ │ │ ├── st_rotate_degrees_1.h │ │ │ │ ├── st_rotate_degrees_2.h │ │ │ │ ├── st_rotate_degrees_3.h │ │ │ │ ├── st_rotate_degrees_4.h │ │ │ │ ├── st_rotate_degrees_5.h │ │ │ │ └── st_rotate_degrees_6.h │ │ │ └── superstates/ │ │ │ ├── ss_f_pattern_1.h │ │ │ ├── ss_radial_pattern_1.h │ │ │ ├── ss_radial_pattern_2.h │ │ │ ├── ss_radial_pattern_3.h │ │ │ └── ss_s_pattern_1.h │ │ ├── launch/ │ │ │ ├── readme.md │ │ │ ├── ridgeback_simulation.launch │ │ │ └── sm_dance_bot.launch │ │ ├── package.xml │ │ ├── servers/ │ │ │ ├── action_server_node_3/ │ │ │ │ └── src/ │ │ │ │ └── action_server_node_3.cpp │ │ │ ├── led_action_server/ │ │ │ │ ├── action/ │ │ │ │ │ └── LEDControl.action │ │ │ │ └── src/ │ │ │ │ └── led_action_server_node.cpp │ │ │ ├── lidar_node/ │ │ │ │ └── src/ │ │ │ │ └── lidar_node.cpp │ │ │ ├── service_node_3/ │ │ │ │ ├── __init__.py │ │ │ │ └── src/ │ │ │ │ └── service_node_3.py │ │ │ └── temperature_sensor_node/ │ │ │ └── src/ │ │ │ └── temperature_sensor_node.cpp │ │ ├── src/ │ │ │ ├── clients/ │ │ │ │ └── cl_led/ │ │ │ │ └── cl_led.cpp │ │ │ └── sm_dance_bot.cpp │ │ └── urdf/ │ │ └── empty.xacro │ ├── sm_dance_bot_2/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── move_base_client/ │ │ │ │ ├── backward_local_planner.yaml │ │ │ │ ├── base_local_planner_params.yaml │ │ │ │ ├── costmap_common_params.yaml │ │ │ │ ├── forward_local_planner.yaml │ │ │ │ ├── global_costmap_params.yaml │ │ │ │ ├── local_costmap_params.yaml │ │ │ │ └── waypoints_plan.yaml │ │ │ ├── navigation.rviz │ │ │ ├── rosconsole.config │ │ │ └── sm_dance_bot_2_config.yaml │ │ ├── docs/ │ │ │ ├── Global Transition Rules.txt │ │ │ └── StateChart - sm_dance_bot.odp │ │ ├── include/ │ │ │ └── sm_dance_bot_2/ │ │ │ ├── clients/ │ │ │ │ ├── cl_led/ │ │ │ │ │ ├── cl_led.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ ├── cb_led_off.h │ │ │ │ │ └── cb_led_on.h │ │ │ │ ├── cl_lidar/ │ │ │ │ │ ├── cl_lidar.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_lidar_sensor.h │ │ │ │ ├── cl_service3/ │ │ │ │ │ ├── cl_service3.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_service3.h │ │ │ │ ├── cl_string_publisher/ │ │ │ │ │ ├── cl_string_publisher.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_string_publisher.h │ │ │ │ └── cl_temperature_sensor/ │ │ │ │ ├── cl_temperature_sensor.h │ │ │ │ └── client_behaviors/ │ │ │ │ └── cb_custom_condition_temperature_sensor.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_led.h │ │ │ │ ├── or_navigation.h │ │ │ │ ├── or_obstacle_perception.h │ │ │ │ ├── or_service3.h │ │ │ │ ├── or_string_publisher.h │ │ │ │ ├── or_temperature_sensor.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_dance_bot_2.h │ │ │ └── states/ │ │ │ ├── ms_dance_bot_recovery_mode/ │ │ │ │ └── ms_dance_bot_recovery_mode.h │ │ │ └── ms_dance_bot_run_mode/ │ │ │ ├── f_pattern_states/ │ │ │ │ ├── ss_f_pattern_1.h │ │ │ │ ├── sti_fpattern_forward_1.h │ │ │ │ ├── sti_fpattern_forward_2.h │ │ │ │ ├── sti_fpattern_loop_start.h │ │ │ │ ├── sti_fpattern_return_1.h │ │ │ │ ├── sti_fpattern_rotate_1.h │ │ │ │ └── sti_fpattern_rotate_2.h │ │ │ ├── ms_dance_bot_run_mode.h │ │ │ ├── radial_motion_states/ │ │ │ │ ├── ss_radial_pattern_1.h │ │ │ │ ├── ss_radial_pattern_2.h │ │ │ │ ├── ss_radial_pattern_3.h │ │ │ │ ├── sti_radial_end_point.h │ │ │ │ ├── sti_radial_loop_start.h │ │ │ │ ├── sti_radial_return.h │ │ │ │ └── sti_radial_rotate.h │ │ │ ├── s_pattern_states/ │ │ │ │ ├── ss_s_pattern_1.h │ │ │ │ ├── sti_spattern_forward_1.h │ │ │ │ ├── sti_spattern_forward_2.h │ │ │ │ ├── sti_spattern_forward_3.h │ │ │ │ ├── sti_spattern_forward_4.h │ │ │ │ ├── sti_spattern_loop_start.h │ │ │ │ ├── sti_spattern_rotate_1.h │ │ │ │ ├── sti_spattern_rotate_2.h │ │ │ │ ├── sti_spattern_rotate_3.h │ │ │ │ └── sti_spattern_rotate_4.h │ │ │ ├── st_acquire_sensors.h │ │ │ ├── st_event_count_down.h │ │ │ ├── st_navigate_forward_1.h │ │ │ ├── st_navigate_forward_2.h │ │ │ ├── st_navigate_reverse_1.h │ │ │ ├── st_navigate_reverse_2.h │ │ │ ├── st_navigate_reverse_3.h │ │ │ ├── st_navigate_to_waypoint_1.h │ │ │ ├── st_navigate_to_waypoints_x.h │ │ │ ├── st_rotate_degrees_1.h │ │ │ ├── st_rotate_degrees_2.h │ │ │ ├── st_rotate_degrees_3.h │ │ │ ├── st_rotate_degrees_4.h │ │ │ ├── st_rotate_degrees_5.h │ │ │ └── st_rotate_degrees_6.h │ │ ├── launch/ │ │ │ ├── readme.md │ │ │ ├── ridgeback_simulation.launch │ │ │ └── sm_dance_bot_2.launch │ │ ├── package.xml │ │ ├── servers/ │ │ │ ├── action_server_node_3/ │ │ │ │ └── src/ │ │ │ │ └── action_server_node_3.cpp │ │ │ ├── led_action_server/ │ │ │ │ ├── action/ │ │ │ │ │ └── LEDControl.action │ │ │ │ └── src/ │ │ │ │ └── led_action_server_node.cpp │ │ │ ├── lidar_node/ │ │ │ │ └── src/ │ │ │ │ └── lidar_node.cpp │ │ │ ├── service_node_3/ │ │ │ │ ├── __init__.py │ │ │ │ └── src/ │ │ │ │ └── service_node_3.py │ │ │ └── temperature_sensor_node/ │ │ │ └── src/ │ │ │ └── temperature_sensor_node.cpp │ │ ├── src/ │ │ │ ├── clients/ │ │ │ │ └── cl_led/ │ │ │ │ └── cl_led.cpp │ │ │ └── sm_dance_bot_2.cpp │ │ └── urdf/ │ │ └── empty.xacro │ ├── sm_dance_bot_strikes_back/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── move_base_client/ │ │ │ │ ├── backward_local_planner.yaml │ │ │ │ ├── base_local_planner_params.yaml │ │ │ │ ├── costmap_common_params.yaml │ │ │ │ ├── forward_local_planner.yaml │ │ │ │ ├── global_costmap_params.yaml │ │ │ │ ├── local_costmap_params.yaml │ │ │ │ └── waypoints_plan.yaml │ │ │ ├── rosconsole.config │ │ │ └── sm_dancebot_strikes_back_config.yaml │ │ ├── include/ │ │ │ └── sm_dance_bot_strikes_back/ │ │ │ ├── clients/ │ │ │ │ ├── cl_led/ │ │ │ │ │ ├── cl_led.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ ├── cb_led_off.h │ │ │ │ │ └── cb_led_on.h │ │ │ │ ├── cl_lidar/ │ │ │ │ │ ├── cl_lidar.h │ │ │ │ │ ├── client_behaviors/ │ │ │ │ │ │ └── cb_lidar_sensor.h │ │ │ │ │ └── components/ │ │ │ │ │ └── cp_lidar_data.h │ │ │ │ ├── cl_service3/ │ │ │ │ │ ├── cl_service3.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_service3.h │ │ │ │ ├── cl_string_publisher/ │ │ │ │ │ ├── cl_string_publisher.h │ │ │ │ │ └── client_behaviors/ │ │ │ │ │ └── cb_string_publisher.h │ │ │ │ └── cl_temperature_sensor/ │ │ │ │ ├── cl_temperature_sensor.h │ │ │ │ └── client_behaviors/ │ │ │ │ └── cb_custom_condition_temperature_sensor.h │ │ │ ├── modestates/ │ │ │ │ ├── ms_dance_bot_recovery_mode.h │ │ │ │ └── ms_dance_bot_run_mode.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_led.h │ │ │ │ ├── or_navigation.h │ │ │ │ ├── or_obstacle_perception.h │ │ │ │ ├── or_service3.h │ │ │ │ ├── or_string_publisher.h │ │ │ │ ├── or_temperature_sensor.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_dance_bot_strikes_back.h │ │ │ ├── states/ │ │ │ │ ├── f_pattern_states/ │ │ │ │ │ ├── sti_fpattern_forward_1.h │ │ │ │ │ ├── sti_fpattern_forward_2.h │ │ │ │ │ ├── sti_fpattern_loop_start.h │ │ │ │ │ ├── sti_fpattern_return_1.h │ │ │ │ │ ├── sti_fpattern_rotate_1.h │ │ │ │ │ └── sti_fpattern_rotate_2.h │ │ │ │ ├── radial_motion_states/ │ │ │ │ │ ├── sti_radial_end_point.h │ │ │ │ │ ├── sti_radial_loop_start.h │ │ │ │ │ ├── sti_radial_return.h │ │ │ │ │ └── sti_radial_rotate.h │ │ │ │ ├── s_pattern_states/ │ │ │ │ │ ├── sti_spattern_forward_1.h │ │ │ │ │ ├── sti_spattern_forward_2.h │ │ │ │ │ ├── sti_spattern_forward_3.h │ │ │ │ │ ├── sti_spattern_forward_4.h │ │ │ │ │ ├── sti_spattern_loop_start.h │ │ │ │ │ ├── sti_spattern_rotate_1.h │ │ │ │ │ ├── sti_spattern_rotate_2.h │ │ │ │ │ ├── sti_spattern_rotate_3.h │ │ │ │ │ └── sti_spattern_rotate_4.h │ │ │ │ ├── st_acquire_sensors.h │ │ │ │ ├── st_event_count_down.h │ │ │ │ ├── st_fpattern_prealignment.h │ │ │ │ ├── st_navigate_to_waypoints_x.h │ │ │ │ └── st_spattern_prealignment.h │ │ │ └── superstates/ │ │ │ ├── ss_f_pattern_1.h │ │ │ ├── ss_radial_pattern_1.h │ │ │ ├── ss_radial_pattern_2.h │ │ │ ├── ss_radial_pattern_3.h │ │ │ └── ss_s_pattern_1.h │ │ ├── launch/ │ │ │ ├── readme.md │ │ │ ├── ridgeback_simulation.launch │ │ │ └── sm_dance_bot_strikes_back.launch │ │ ├── package.xml │ │ ├── servers/ │ │ │ ├── action_server_node_3/ │ │ │ │ └── src/ │ │ │ │ └── action_server_node_3.cpp │ │ │ ├── led_action_server/ │ │ │ │ ├── action/ │ │ │ │ │ └── LEDControl.action │ │ │ │ └── src/ │ │ │ │ └── led_action_server_node.cpp │ │ │ ├── lidar_node/ │ │ │ │ └── src/ │ │ │ │ └── lidar_node.cpp │ │ │ ├── service_node_3/ │ │ │ │ ├── __init__.py │ │ │ │ └── src/ │ │ │ │ └── service_node_3.py │ │ │ └── temperature_sensor_node/ │ │ │ └── src/ │ │ │ └── temperature_sensor_node.cpp │ │ ├── src/ │ │ │ ├── clients/ │ │ │ │ └── cl_led/ │ │ │ │ └── cl_led.cpp │ │ │ └── sm_dance_bot_strikes_back.cpp │ │ └── urdf/ │ │ └── empty.xacro │ ├── sm_ferrari/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_three_some_config.yaml │ │ ├── include/ │ │ │ └── sm_ferrari/ │ │ │ ├── clients/ │ │ │ │ └── cl_subscriber/ │ │ │ │ ├── cl_subscriber.h │ │ │ │ └── client_behaviors/ │ │ │ │ └── cb_my_subscriber_behavior.h │ │ │ ├── mode_states/ │ │ │ │ ├── ms_recover.h │ │ │ │ └── ms_run.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_keyboard.h │ │ │ │ ├── or_subscriber.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_ferrari.h │ │ │ ├── states/ │ │ │ │ ├── inner_states/ │ │ │ │ │ ├── sti_state_1.h │ │ │ │ │ ├── sti_state_2.h │ │ │ │ │ └── sti_state_3.h │ │ │ │ ├── st_state_1.h │ │ │ │ ├── st_state_2.h │ │ │ │ ├── st_state_3.h │ │ │ │ └── st_state_4.h │ │ │ └── superstates/ │ │ │ ├── ss_superstate_1.h │ │ │ └── ss_superstate_2.h │ │ ├── launch/ │ │ │ └── sm_ferrari.launch │ │ ├── package.xml │ │ ├── servers/ │ │ │ └── temperature_sensor_node/ │ │ │ └── src/ │ │ │ └── temperature_sensor_node.cpp │ │ └── src/ │ │ └── sm_ferrari_node.cpp │ ├── sm_packml/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_packml_config.yaml │ │ ├── include/ │ │ │ └── sm_packml/ │ │ │ ├── clients/ │ │ │ │ └── cl_subscriber/ │ │ │ │ ├── cl_subscriber.h │ │ │ │ └── client_behaviors/ │ │ │ │ ├── cb_default_subscriber_behavior.h │ │ │ │ └── cb_watchdog_subscriber_behavior.h │ │ │ ├── mode_states/ │ │ │ │ ├── ms_run.h │ │ │ │ └── ms_stop.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_keyboard.h │ │ │ │ ├── or_subscriber.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_packml.h │ │ │ └── states/ │ │ │ ├── st_aborted.h │ │ │ ├── st_aborting.h │ │ │ ├── st_clearing.h │ │ │ ├── st_complete.h │ │ │ ├── st_completing.h │ │ │ ├── st_execute.h │ │ │ ├── st_held.h │ │ │ ├── st_holding.h │ │ │ ├── st_idle.h │ │ │ ├── st_resetting.h │ │ │ ├── st_starting.h │ │ │ ├── st_stopped.h │ │ │ ├── st_stopping.h │ │ │ ├── st_suspended.h │ │ │ ├── st_suspending.h │ │ │ ├── st_unholding.h │ │ │ └── st_unsuspending.h │ │ ├── launch/ │ │ │ └── sm_packML.launch │ │ ├── package.xml │ │ └── src/ │ │ └── sm_packml_node.cpp │ ├── sm_respira_1/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_respira_1_config.yaml │ │ ├── include/ │ │ │ └── sm_respira_1/ │ │ │ ├── clients/ │ │ │ │ └── cl_subscriber/ │ │ │ │ ├── cl_subscriber.h │ │ │ │ └── client_behaviors/ │ │ │ │ ├── cb_default_subscriber_behavior.h │ │ │ │ └── cb_watchdog_subscriber_behavior.h │ │ │ ├── mode_states/ │ │ │ │ ├── ms_calibration.h │ │ │ │ ├── ms_leaky_lung.h │ │ │ │ ├── ms_patient_obstruction.h │ │ │ │ ├── ms_run.h │ │ │ │ └── ms_shutdown.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_keyboard.h │ │ │ │ ├── or_subscriber.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_respira_1.h │ │ │ ├── states/ │ │ │ │ ├── ac_cycle_inner_states/ │ │ │ │ │ ├── sti_ac_cycle_dwell.h │ │ │ │ │ ├── sti_ac_cycle_expire.h │ │ │ │ │ ├── sti_ac_cycle_inspire.h │ │ │ │ │ ├── sti_ac_cycle_loop.h │ │ │ │ │ └── sti_ac_cycle_plateau.h │ │ │ │ ├── cmv_cycle_inner_states/ │ │ │ │ │ ├── sti_cmv_cycle_dwell.h │ │ │ │ │ ├── sti_cmv_cycle_expire.h │ │ │ │ │ ├── sti_cmv_cycle_inspire.h │ │ │ │ │ ├── sti_cmv_cycle_loop.h │ │ │ │ │ └── sti_cmv_cycle_plateau.h │ │ │ │ ├── ms_calibration_inner_states/ │ │ │ │ │ └── st_calibration_step_1.h │ │ │ │ ├── ms_leaky_lung_inner_states/ │ │ │ │ │ ├── st_leaky_lung_step_1.h │ │ │ │ │ ├── st_leaky_lung_step_2.h │ │ │ │ │ └── st_leaky_lung_step_3.h │ │ │ │ ├── ms_patient_obstruction_inner_states/ │ │ │ │ │ ├── st_patient_obstruction_step_1.h │ │ │ │ │ └── st_patient_obstruction_step_2.h │ │ │ │ ├── ms_shutdown_inner_states/ │ │ │ │ │ └── st_system_shutdown.h │ │ │ │ ├── pc_cycle_inner_states/ │ │ │ │ │ ├── sti_pc_cycle_dwell.h │ │ │ │ │ ├── sti_pc_cycle_expire.h │ │ │ │ │ ├── sti_pc_cycle_inspire.h │ │ │ │ │ ├── sti_pc_cycle_loop.h │ │ │ │ │ └── sti_pc_cycle_plateau.h │ │ │ │ ├── ps_cycle_inner_states/ │ │ │ │ │ ├── sti_ps_cycle_dwell.h │ │ │ │ │ ├── sti_ps_cycle_expire.h │ │ │ │ │ ├── sti_ps_cycle_inspire.h │ │ │ │ │ ├── sti_ps_cycle_loop.h │ │ │ │ │ └── sti_ps_cycle_plateau.h │ │ │ │ └── st_observe.h │ │ │ └── superstates/ │ │ │ ├── ss_ac_cycle.h │ │ │ ├── ss_cmv_cycle.h │ │ │ ├── ss_pc_cycle.h │ │ │ └── ss_ps_cycle.h │ │ ├── launch/ │ │ │ └── sm_respira_1.launch │ │ ├── package.xml │ │ └── src/ │ │ └── sm_respira_1_node.cpp │ ├── sm_ridgeback_barrel_search_1/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── move_base_client/ │ │ │ │ ├── backward_local_planner.yaml │ │ │ │ ├── base_local_planner_params.yaml │ │ │ │ ├── costmap_common_params.yaml │ │ │ │ ├── forward_local_planner.yaml │ │ │ │ ├── global_costmap_params.yaml │ │ │ │ ├── local_costmap_params.yaml │ │ │ │ └── waypoints_plan.yaml │ │ │ ├── navigation.rviz │ │ │ ├── radial_motion_sm_config.yaml │ │ │ ├── rosconsole.config │ │ │ └── sm_ridgeback_barrel_search_1_config.yaml │ │ ├── include/ │ │ │ └── sm_ridgeback_barrel_search_1/ │ │ │ ├── clients/ │ │ │ │ └── opencv_perception_client/ │ │ │ │ └── cl_opencv_perception_client.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_navigation.h │ │ │ │ └── or_perception.h │ │ │ ├── sm_ridgeback_barrel_search_1.h │ │ │ └── states/ │ │ │ ├── st_detect_items.h │ │ │ └── st_navigate_to_waypoint_x.h │ │ ├── launch/ │ │ │ ├── ridgeback_simulation.launch │ │ │ └── sm_ridgeback_barrel_search_1.launch │ │ ├── msg/ │ │ │ └── DetectedBlobs.msg │ │ ├── package.xml │ │ ├── servers/ │ │ │ └── opencv_perception_node/ │ │ │ ├── CMakeLists.txt2 │ │ │ └── opencv_perception_node.cpp │ │ ├── simulation/ │ │ │ └── worlds/ │ │ │ └── opencv_world.sdf │ │ ├── src/ │ │ │ └── sm_ridgeback_barrel_search_1.cpp │ │ └── urdf/ │ │ ├── ridgeback.camera.gazebo │ │ └── ridgeback.urdf.xacro │ ├── sm_ridgeback_barrel_search_2/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ ├── move_base_client/ │ │ │ │ ├── backward_local_planner.yaml │ │ │ │ ├── base_local_planner_params.yaml │ │ │ │ ├── costmap_common_params.yaml │ │ │ │ ├── forward_local_planner.yaml │ │ │ │ ├── global_costmap_params.yaml │ │ │ │ ├── local_costmap_params.yaml │ │ │ │ └── waypoints_plan.yaml │ │ │ ├── navigation.rviz │ │ │ ├── rosconsole.config │ │ │ └── sm_ridgeback_barrel_search_2_config.yaml │ │ ├── include/ │ │ │ └── sm_ridgeback_barrel_search_2/ │ │ │ ├── clients/ │ │ │ │ └── opencv_perception_client/ │ │ │ │ └── cl_opencv_perception_client.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_navigation.h │ │ │ │ └── or_perception.h │ │ │ ├── sm_ridgeback_barrel_search_2.h │ │ │ └── states/ │ │ │ ├── st_detect_items.h │ │ │ └── st_navigate_to_waypoint_x.h │ │ ├── launch/ │ │ │ ├── ridgeback_simulation.launch │ │ │ └── sm_ridgeback_barrel_search_2.launch │ │ ├── msg/ │ │ │ └── DetectedBlobs.msg │ │ ├── package.xml │ │ ├── servers/ │ │ │ └── opencv_perception_node/ │ │ │ ├── CMakeLists.txt2 │ │ │ └── opencv_perception_node.cpp │ │ ├── simulation/ │ │ │ └── worlds/ │ │ │ └── opencv_world.sdf │ │ ├── src/ │ │ │ └── sm_ridgeback_barrel_search_2.cpp │ │ └── urdf/ │ │ ├── ridgeback.camera.gazebo │ │ └── ridgeback.urdf.xacro │ ├── sm_ridgeback_floor_coverage_dynamic_1/ │ │ └── config/ │ │ └── move_base_client/ │ │ └── base_local_planner_params.yaml │ ├── sm_ridgeback_floor_coverage_static_1/ │ │ └── config/ │ │ └── move_base_client/ │ │ └── base_local_planner_params.yaml │ ├── sm_starcraft_ai/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_starcraft_ai_config.yaml │ │ ├── include/ │ │ │ └── sm_starcraft_ai/ │ │ │ ├── clients/ │ │ │ │ └── cl_subscriber/ │ │ │ │ ├── cl_subscriber.h │ │ │ │ └── client_behaviors/ │ │ │ │ ├── cb_default_subscriber_behavior.h │ │ │ │ └── cb_watchdog_subscriber_behavior.h │ │ │ ├── mode_states/ │ │ │ │ └── ms_run.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_keyboard.h │ │ │ │ ├── or_subscriber.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_starcraft_ai.h │ │ │ ├── states/ │ │ │ │ ├── attack_inner_states/ │ │ │ │ │ ├── sti_attack_1.h │ │ │ │ │ ├── sti_attack_2.h │ │ │ │ │ └── sti_attack_3.h │ │ │ │ ├── build_inner_states/ │ │ │ │ │ ├── sti_build_1.h │ │ │ │ │ ├── sti_build_2.h │ │ │ │ │ └── sti_build_3.h │ │ │ │ ├── move_inner_states/ │ │ │ │ │ ├── sti_move_1.h │ │ │ │ │ ├── sti_move_2.h │ │ │ │ │ └── sti_move_3.h │ │ │ │ └── st_observe.h │ │ │ └── superstates/ │ │ │ ├── ss_attack.h │ │ │ ├── ss_build.h │ │ │ └── ss_move.h │ │ ├── launch/ │ │ │ └── sm_starcraft_ai.launch │ │ ├── package.xml │ │ └── src/ │ │ └── sm_starcraft_ai_node.cpp │ ├── sm_subscriber/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── config/ │ │ │ ├── rosconsole.config │ │ │ └── sm_subscriber_config.yaml │ │ ├── include/ │ │ │ └── sm_subscriber/ │ │ │ ├── clients/ │ │ │ │ └── cl_numbers_subscription/ │ │ │ │ ├── cl_numbers_subscription.h │ │ │ │ └── client_behaviors/ │ │ │ │ ├── cb_post_custom_event.h │ │ │ │ └── cb_print_message_number.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_subscriber.h │ │ │ │ └── or_timer.h │ │ │ ├── sm_subscriber.h │ │ │ └── states/ │ │ │ ├── st_state_1.h │ │ │ └── st_state_2.h │ │ ├── launch/ │ │ │ └── sm_subscriber.launch │ │ ├── package.xml │ │ ├── servers/ │ │ │ └── numbers_publisher/ │ │ │ └── numbers_publisher.cpp │ │ └── src/ │ │ └── sm_subscriber_node.cpp │ ├── sm_three_some/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_three_some_config.yaml │ │ ├── include/ │ │ │ └── sm_three_some/ │ │ │ ├── clients/ │ │ │ │ └── cl_subscriber/ │ │ │ │ ├── cl_subscriber.h │ │ │ │ └── client_behaviors/ │ │ │ │ ├── cb_default_subscriber_behavior.h │ │ │ │ └── cb_watchdog_subscriber_behavior.h │ │ │ ├── mode_states/ │ │ │ │ ├── ms_recover.h │ │ │ │ └── ms_run.h │ │ │ ├── orthogonals/ │ │ │ │ ├── or_keyboard.h │ │ │ │ ├── or_subscriber.h │ │ │ │ ├── or_timer.h │ │ │ │ └── or_updatable_publisher.h │ │ │ ├── sm_three_some.h │ │ │ ├── states/ │ │ │ │ ├── inner_states/ │ │ │ │ │ ├── sti_state_1.h │ │ │ │ │ ├── sti_state_2.h │ │ │ │ │ └── sti_state_3.h │ │ │ │ ├── st_state_1.h │ │ │ │ ├── st_state_2.h │ │ │ │ ├── st_state_3.h │ │ │ │ └── st_state_4.h │ │ │ └── superstates/ │ │ │ ├── ss_superstate_1.h │ │ │ └── ss_superstate_2.h │ │ ├── launch/ │ │ │ └── sm_three_some.launch │ │ ├── package.xml │ │ └── src/ │ │ └── sm_three_some_node.cpp │ ├── sm_update_loop/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── config/ │ │ │ └── sm_update_loop_config.yaml │ │ ├── include/ │ │ │ └── sm_update_loop/ │ │ │ ├── orthogonals/ │ │ │ │ └── or_timer.h │ │ │ ├── sm_update_loop.h │ │ │ └── states/ │ │ │ ├── st_state_1.h │ │ │ └── st_state_2.h │ │ ├── launch/ │ │ │ └── sm_update_loop.launch │ │ ├── package.xml │ │ └── src/ │ │ └── sm_update_loop_node.cpp │ └── sm_viewer_sim/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── README.md │ ├── config/ │ │ └── sm_viewer_sim_config.yaml │ ├── include/ │ │ └── sm_viewer_sim/ │ │ ├── modestates/ │ │ │ ├── ms_recovery_mode.h │ │ │ └── ms_run_mode.h │ │ ├── orthogonals/ │ │ │ └── or_navigation.h │ │ ├── sm_viewer_sim.h │ │ └── states/ │ │ ├── st_st1.h │ │ ├── st_st2.h │ │ └── st_st3.h │ ├── launch/ │ │ └── sm_viewer_sim.launch │ ├── package.xml │ └── src/ │ └── sm_viewer_sim.cpp ├── smacc_state_reactor_library/ │ ├── sr_all_events_go/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── include/ │ │ │ └── sr_all_events_go/ │ │ │ └── sr_all_events_go.h │ │ ├── package.xml │ │ └── src/ │ │ └── sr_all_events_go/ │ │ └── sr_all_events_go.cpp │ ├── sr_conditional/ │ │ ├── CHANGELOG.rst │ │ ├── CMakeLists.txt │ │ ├── include/ │ │ │ └── sr_conditional/ │ │ │ └── sr_conditional.h │ │ ├── package.xml │ │ └── src/ │ │ └── sr_conditional/ │ │ └── sr_conditional.cpp │ └── sr_event_countdown/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── include/ │ │ └── sr_event_countdown/ │ │ └── sr_event_countdown.h │ ├── package.xml │ └── src/ │ └── sr_event_countdown/ │ └── sr_event_countdown.cpp └── test/ ├── sm_coretest_transition_speed_1/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── README.md │ ├── config/ │ │ └── rosconsole.config │ ├── include/ │ │ └── sm_coretest_transition_speed_1/ │ │ ├── orthogonals/ │ │ │ └── or_timer.h │ │ ├── sm_coretest_transition_speed_1.h │ │ └── states/ │ │ ├── st_state_1.h │ │ └── st_state_2.h │ ├── launch/ │ │ └── sm_coretest_transition_speed_1.launch │ ├── package.xml │ └── src/ │ └── sm_coretest_transition_speed_1_node.cpp ├── sm_coretest_x_y_1/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── README.md │ ├── config/ │ │ └── rosconsole.config │ ├── include/ │ │ └── sm_coretest_x_y_1/ │ │ ├── orthogonals/ │ │ │ └── or_timer.h │ │ ├── sm_coretest_x_y_1.h │ │ └── states/ │ │ ├── st_state_1.h │ │ └── st_state_2.h │ ├── launch/ │ │ └── sm_coretest_x_y_1.launch │ ├── package.xml │ └── src/ │ └── sm_coretest_x_y_1_node.cpp ├── sm_coretest_x_y_2/ │ ├── CHANGELOG.rst │ ├── CMakeLists.txt │ ├── README.md │ ├── config/ │ │ └── rosconsole.config │ ├── include/ │ │ └── sm_coretest_x_y_2/ │ │ ├── orthogonals/ │ │ │ └── or_timer.h │ │ ├── sm_coretest_x_y_2.h │ │ └── states/ │ │ ├── st_state_1.h │ │ └── st_state_2.h │ ├── launch/ │ │ └── sm_coretest_x_y_2.launch │ ├── package.xml │ └── src/ │ └── sm_coretest_x_y_2_node.cpp └── sm_coretest_x_y_3/ ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.md ├── config/ │ └── rosconsole.config ├── include/ │ └── sm_coretest_x_y_3/ │ ├── orthogonals/ │ │ └── or_timer.h │ ├── sm_coretest_x_y_3.h │ └── states/ │ ├── st_state_1.h │ └── st_state_2.h ├── launch/ │ └── sm_coretest_x_y_3.launch ├── package.xml └── src/ └── sm_coretest_x_y_3_node.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codespell-ignore-words.txt ================================================ ba ================================================ FILE: .github/workflows/CI.yaml ================================================ name: Noetic Continuous Integration on: push: pull_request: jobs: CI: runs-on: ubuntu-latest container: osrf/ros:noetic-desktop steps: - uses: actions/checkout@v1 with: path: src/SMACC - shell: bash run: | source /opt/ros/noetic/setup.bash apt update rosdep update rosdep install --from-paths . --ignore-src -r -y cd ../../ catkin_make -DCMAKE_BUILD_TYPE=Debug ================================================ FILE: .github/workflows/bloom_release.yml ================================================ name: bloom-release on: push: paths: - package.xml - '*/package.xml' - '.github/workflows/bloom_release.yml' branches: noetic-devel jobs: bloom-release: runs-on: ubuntu-latest env: ROS_DISTRO: noetic PRERELEASE: true BASEDIR: ${{ github.workspace }}/.work steps: - name: checkout uses: actions/checkout@v2 # BASIC CODE QUALITY - run: | sudo apt-get update sudo apt-get install -y clang-format-12 - uses: actions/setup-python@v3 with: python-version: 3.9 - name: code quality check uses: pre-commit/action@v3.0.0 # BLOOM PRERELEASE CHECK # - name: industrial_ci prerelease check # uses: ros-industrial/industrial_ci@master # BLOOM RELEASE - name: bloom release uses: pabloinigoblasco/bloom-release-action@master with: ros_distro: ${{ env.ROS_DISTRO }} github_token_bloom: ${{ secrets.GITTOKEN_BLOOM }} github_user: pabloinigoblasco git_user: pabloinigoblasco git_email: pablo@ibrobotics.com release_repository_push_url: https://github.com/robosoft-ai/SMACC-release tag_and_release: true #open_pr: true ================================================ FILE: .github/workflows/code_quality.yml ================================================ name: Code Format & Quality on: pull_request: push: jobs: pre-commit: runs-on: ubuntu-latest steps: - run: | sudo apt-get update sudo apt-get install -y clang-format-12 - uses: actions/checkout@v3 - uses: actions/setup-python@v3 with: python-version: 3.9 - uses: pre-commit/action@v3.0.0 ================================================ FILE: .github/workflows/doxygen.yml ================================================ name: Doxygen on: push: branches: [noetic-devel] jobs: doxygen: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v1 - uses: mattnotmitt/doxygen-action@v1 with: doxyfile-path: 'smacc_ci/Doxyfile' - uses: peaceiris/actions-gh-pages@v3 with: deploy_key: ${{ secrets.ACTION_DEPLOY_KEY }} external_repository: robosoft-ai/smacc_doxygen publish_branch: gh-pages publish_dir: docs/ destination_dir: noetic commit_message: ${{ github.event.head_commit.message }} ================================================ FILE: .gitignore ================================================ build install log bin ================================================ FILE: .pre-commit-config.yaml ================================================ # To use: # # pre-commit run -a # # Or: # # pre-commit install # (runs every time you commit in git) # # To update this file: # # pre-commit autoupdate # # See https://github.com/pre-commit/pre-commit repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.1.0 hooks: - id: check-added-large-files - id: check-ast - id: check-case-conflict - id: check-docstring-first - id: check-merge-conflict - id: check-symlinks - id: check-xml #- id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: mixed-line-ending - id: trailing-whitespace - id: fix-byte-order-marker # Python hooks - repo: https://github.com/asottile/pyupgrade rev: v2.31.0 hooks: - id: pyupgrade args: [--py36-plus] - repo: https://github.com/psf/black rev: 22.3.0 hooks: - id: black args: ["--line-length=99"] # PEP 257 - repo: https://github.com/FalconSocial/pre-commit-mirrors-pep257 rev: v0.3.3 hooks: - id: pep257 args: ["--ignore=D100,D101,D102,D103,D104,D105,D106,D107,D203,D212,D404"] - repo: https://github.com/pycqa/flake8 rev: 4.0.1 hooks: - id: flake8 args: ["--ignore=E501,W503,E203"] # CPP hooks - repo: local hooks: - id: clang-format name: clang-format description: Format files with ClangFormat. entry: clang-format language: system files: \.(c|cc|cxx|cpp|frag|glsl|h|hpp|hxx|ih|ispc|ipp|java|js|m|proto|vert)$ args: ['-fallback-style=none', '-i'] # exclude: smacc2_sm_reference_library/ # Docs - RestructuredText hooks - repo: https://github.com/PyCQA/doc8 rev: 0.10.1 hooks: - id: doc8 args: ['--max-line-length=100', '--ignore=D001'] exclude: CHANGELOG\.rst$ - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.9.0 hooks: - id: rst-backticks exclude: CHANGELOG\.rst$ - id: rst-directive-colons - id: rst-inline-touching-normal # Spellcheck in comments and docs # skipping of *.svg files is not working... - repo: https://github.com/codespell-project/codespell rev: v2.1.0 hooks: - id: codespell name: codespell description: Checks for common misspellings in text files. entry: codespell language: python types: [text] args: ['--ignore-words=.codespell-ignore-words.txt', '--write-changes'] exclude: \.(svg|pyc)$ ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) sm_fetch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/devel/lib/sm_fetch_six_table_pick_n_sort_1/sm_fetch_six_table_pick_n_sort_1_node", "args": ["__name:=sm_fetch_six_table_pick_n_sort_1_node"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "console": "externalTerminal", "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, { "name": "(gdb) sm_atomic_mode_states", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/../../devel/lib/sm_atomic_mode_states/sm_atomic_mode_states_node", "args": ["__name:=sm_fetch_six_table_pick_n_sort_1_node"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "console": "externalTerminal", "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, { "name": "(gdb) smacc_rta", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/../build/smacc_rta/smacc_rta", "args": ["__name:=smacc_rta"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "console": "externalTerminal", "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] }, { "name": "Smacc Viewer", "type": "python", "request": "launch", "program": "${workspaceFolder}/src/SMACC_Viewer/smacc_viewer/scripts/smacc_viewer_node.py", "console": "integratedTerminal" } ] } ================================================ FILE: LICENSE.txt ================================================ BSD 3-Clause License Copyright (c) Reelrobotix, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ ## Continuous Integration: | ROS Distro | Code Format & Quality | Documentation | Binary Packages | | :-----------: | :-----------: | :-----------: | :-----------: | | Melodic | [![Code Format & Quality](https://github.com/robosoft-ai/SMACC/actions/workflows/code_quality.yml/badge.svg?branch=melodic-devel)](https://github.com/robosoft-ai/SMACC/actions/workflows/code_quality.yml) | [![Doxygen](https://github.com/robosoft-ai/SMACC/actions/workflows/doxygen.yml/badge.svg?branch=melodic-devel)](https://github.com/robosoft-ai/SMACC/actions/workflows/doxygen.yml)
doxygen|[![Build Status](https://build.ros.org/job/Mdev__smacc__ubuntu_bionic_amd64/badge/icon?subject=ros-buildfarm)](https://build.ros.org/job/Mdev__smacc__ubuntu_bionic_amd64/)
[![bloom-release](https://build.ros2.org/job/Hdev__SMACC2__ubuntu_jammy_amd64/badge/icon?style=plastic&subject=bloom-release&status=E.O.L&color=lightgray)](http://wiki.ros.org/Distributions)
[SMACC](https://index.ros.org/p/smacc/github-robosoft-ai-smacc/#melodic)| | Noetic | [![Code Format & Quality](https://github.com/robosoft-ai/SMACC/actions/workflows/code_quality.yml/badge.svg?branch=noetic-devel)](https://github.com/robosoft-ai/SMACC/actions/workflows/code_quality.yml) | [![Doxygen](https://github.com/robosoft-ai/SMACC/actions/workflows/doxygen.yml/badge.svg?branch=noetic-devel)](https://github.com/robosoft-ai/SMACC/actions/workflows/doxygen.yml)
doxygen| [![Build Status](https://build.ros.org/job/Ndev__smacc__ubuntu_focal_amd64/badge/icon?subject=ros-buildfarm)](https://build.ros.org/job/Ndev__smacc__ubuntu_focal_amd64/)
[![bloom-release](https://github.com/robosoft-ai/SMACC/actions/workflows/bloom_release.yml/badge.svg?branch=noetic-devel)](https://github.com/robosoft-ai/smacc/actions/workflows/bloom_release.yml)
[SMACC](https://index.ros.org/p/smacc/github-robosoft-ai-smacc/#noetic)| ## Docker Containers [![Docker Automated build](https://img.shields.io/docker/automated/pabloinigoblasco/smacc.svg?maxAge=2592000)](https://hub.docker.com/r/pabloinigoblasco/smacc/) [![Docker Pulls](https://img.shields.io/docker/pulls/pabloinigoblasco/smacc.svg?maxAge=2592000)](https://hub.docker.com/r/pabloinigoblasco/smacc/) [![Docker Stars](https://img.shields.io/docker/stars/pabloinigoblasco/smacc.svg)](https://registry.hub.docker.com/pabloinigoblasco/smacc/) # SMACC SMACC is an event-driven, asynchronous, behavioral state machine library for real-time ROS (Robotic Operating System) applications written in C++, designed to allow programmers to build robot control applications for multicomponent robots, in an intuitive and systematic manner. SMACC was inspired by Harel's statecharts and the [SMACH ROS package](http://wiki.ros.org/smach). SMACC is built on top of the [Boost StateChart library](https://www.boost.org/doc/libs/1_53_0/libs/statechart/doc/index.html). ## Features * ***Powered by ROS:*** SMACC has been developed specifically to work with ROS. It supports ROS topics, services and actions, right out of the box. * ***Written in C++:*** Until now, ROS has lacked a library to develop task-level behavioral state machines in C++. Although libraries have been developed in scripting languages such as python, these are unsuitable for real-world industrial environments where real-time requirements are demanded. * ***Orthogonals:*** Originally conceived by David Harel in 1987, orthogonality is absolutely crucial to developing state machines for complex robotic systems. This is because complex robots are always a collection of hardware devices which require communication protocols, start-up determinism, etc. With orthogonals, it is an intuitive and relatively straight forward exercise (at least conceptually;) to code a state machine for a robot comprising a mobile base, a robotic arm, a gripper, two lidar sensors, a gps transceiver and an imu, for instance. * ***Static State Machine Checking:*** One of the features that SMACC inherits from Boost Statechart is that you get compile time validation checking. This benefits developers in that the amount of runtime testing necessary to ship quality software that is both stable and safe is dramatically reduced. Our philosophy is "Wherever possible, let the compiler do it". * ***State Machine Reference Library:*** With a constantly growing library of out-of-the-box reference state machines, (found in the folder [sm_reference_library](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library)) guaranteed to compile and run, you can jumpstart your development efforts by choosing a reference machine that is closest to your needs, and then customize and extend to meet the specific requirements of your robotic application. All the while knowing that the library supports advanced functionalities that are practically universal among actual working robots. * ***SMACC Client Library:*** SMACC also features a constantly growing library of [clients](https://github.com/robosoft-ai/SMACC/tree/master/smacc_client_library) that support ROS Action Servers, Service Servers and other nodes right out-of-the box. The clients within the SMACC Client library have been built utilizing a component based architecture that allows for developer to build powerful clients of their own. Current clients of note include MoveBaseZ, a full featured Action Client built to integrate with the ROS Navigation stack, the ros_timer_client, the multi_role_sensor_client, and a keyboard_client used extensively for state machine drafting & debugging. * ***Extensive Documentation:*** Although many ROS users are familiar with doxygen, our development team has spent a lot of time researching the more advanced features of doxygen such as uml style class diagrams and call graphs, and we've used them to document the SMACC library. Have a look to [our doxygen sites](https://robosoft-ai.github.io/smacc_doxygen/master/html/namespaces.html) and we think you'll be blown away at what Doxygen looks like when [it's done right](https://robosoft-ai.github.io/smacc_doxygen/master/html/classsmacc_1_1ISmaccStateMachine.html) and it becomes a powerful tool to research a codebase. * ***SMACC1 Runtime Analyzer:*** The SMACC library for ROS1 works out of the box with the SMACC1 RTA. This allows developers to visualize and runtime debug the state machines they are working on. The SMACC1 RTA is closed source, but is free for individual and academic use. It can be found [here](https://robosoft.ai/product-category/smacc1-runtime-analyzer/), along with installation instructions which can be found [here](https://robosoft.ai/smacc1_rta-installation/). ## SMACC applications From it's inception, SMACC was written to support the programming of multi-component, complex robots. If your project involves small, solar-powered insect robots, that simply navigate towards a light source, then SMACC might not be the right choice for you. But if you are trying to program a robot with a mobile base, a robotic arm, a gripper, two lidar sensors, a gps transceiver and an imu, then you've come to the right place. ## Getting Started The easiest way to get started is by selecting one of the state machines in our [reference library](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library), and then hacking it to meet your needs. Each state machine in the reference library comes with it's own README.md file, which contains the appropriate operating instructions, so that all you have to do is simply copy & paste some commands into your terminal. * If you are looking for a minimal example, we recommend [sm_atomic](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library/sm_atomic). * If you are looking for a slightly more complicated, but still very simple example, try [sm_calendar_week](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library/sm_calendar_week). * If you are looking for a minimal example but with a looping superstate, try [sm_three_some](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library/sm_three_some). * If you want to get started with the ROS Navigation stack right away, try [sm_dance_bot](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library/sm_dance_bot). * If you want to get started with ROS Navigation and exploring the orthogonal read-write cycle, then try [sm_dance_bot_strikes_back](https://github.com/robosoft-ai/SMACC/tree/master/smacc_sm_reference_library/sm_dance_bot_strikes_back). Operating instructions can be found in each reference state machines readme file. Happy Coding. ## Support If you are interested in getting involved or need a little support, feel free to contact us by emailing brett@robosoft.ai ================================================ FILE: smacc/CHANGELOG.rst ================================================ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package smacc ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Forthcoming ----------- * Progressing on transition log * dynamic behavior * progress on viewer, modestates and history mode * smacc megastate example * missing changes on previous commit * more improvements on status message on the viewer and the smacc core * some stable version of the viewer, code cleaning, fixes on dancebot * progress in the viewer, creating a new concept of transition tag * progress in the viewer * SMACC improvements on the viewer and loop branching funcionality * progressing in the smacc viewer * fixing logic units event source information * progressing in viewer and metainformation * progressing in the viewer and adding more metaknoledge about triggering events of logic units * progress in the viewer and examples * fixing eveng aggregator compilation issue * more fixings and progressing to the smacc_viewer * recurrent pattern for sensors and substate behaviors * template recurrent pattern, string type walker, showing string for smacc viewer * adding transition file * moving behavior creation of sm_dance_bot to static staticConfigure * action client moving to event convention Ev * logic units, better output of the state machine knowledge at the startup * StateTransition info structure * creating static staticConfigure functionality * removing obsolete state funcionality * broken build orthogonal fix * changes on architecture, orthogonal role, client role and component role changes, fixing all examples * adding service client * smacc_msgs dependencies * smacc_msgs dependencies * gh-pages travis * ff pattern and spattern first implementation * fixing build * testing status message, creation of rviz display plugin, refactoring of sm_dance_bot.launch to make it lightweight, readme.md for launching * adding SmaccStatus message funcionality * PackML inspired funcionalities for SM: stop, estop, reset * several improvements: adding topicPublisherClient, fixing install build, further testing of sm_dance_bot on install workspace * adding publisher client * working on fixing travis build * working on fixing travis * superstates improving the viewer for the dance_bot * many core fixes and refactorings, substate behavior destroying, dance_bot keyboard separated in two files, topic sensor separated in two files too for the client and the substate behavior * progressing on keyboard * introducing the client concept and moving smacc topic subscriber to the smacc 'core' package * ClMultiroleSensor and TopicSubscriber * detaching substatebehaviors from component and renaming class refactoring * making smacc_viewer run and also refactoring smacc_state_info headers * Merge branch 'master' of https://github.com/robosoft-ai/SMACC * minor changes * Minor commenting edits * more improvements on sensor topics keyboard events, and architecture improvements * refactoring smacc substate behaviors and states * changes on code * better rosout and some progress on sm_dance_bot and fixing travis build * runtime testing of examples * hard renaming - namming convention - initial integration of smach_viewer * Folder Renaming * SMACC building * Merge branch 'master' of https://github.com/robosoft-ai/SMACC * fixing smacc for melodic * c++11 for indigo in some projects * Merge branch 'master' into indigo-devel * removing boost demangle dependency to make build indigo * makin build SMACC for indigo * Merge branch 'master' into indigo-devel * merge on melodic * updating backward and forward local planners * Merge remote-tracking branch 'origin/master' into melodic-devel * Merge branch 'master' into indigo-devel * updating cmakelists * Merge branch 'master' of https://github.com/pabloinigoblasco/SMACC * Merge pull request `#1 `_ from robosoft-ai/master merging * smacc improvements * minor * navigation improvements and syntax improvements in example * final waypoints tests * progress on waypoints * renaming getglobalData setGlobalData * authory in code files and more in documentation * important refactoring and fixes, and the creation of the radial_motion example * syntax improvement to remove the context from smacc code * adapting to the smacc requiresComponent method refactoring * refactoring smacc to support other kind of plugins beyond actionclients, such as the odom tracker, also ading a custom radial_motion_example independent to the reel * refactoring SMACC to contain navigation plugins * adding planners to SMACC * package version * package.xml format * adding feedback message information to feedback events * syntax improvement for better action result reaction * some refactoring on smacc code * more on documentation * fixing ros parameters * Tool orthogonal line and wiki documentation * cleaning and refactoring smacc library * adding tool orthogonal line * Adapting to smacc feedback message improvemnts. Now, the transitions reacts on these action feedback messages, instead of action results * minor changes on radial motion sample * feedback message support * refactoring, renamings, documenting smacc * some more on style * more comments and style * some more comments * large refactoring of the smacc example code and comments * minor * initial version of radial motion example * going forward to radial example * minor to show some example * going forward to smacc * minor fixes * initials on smacc * Moved SMACC to it's own repo.. * Contributors: Pablo Inigo Blasco, Pablo Iñigo Blasco, brett2@robosoft-ai.com, brettpac, travis ================================================ FILE: smacc/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.8) project(smacc) ## Compile as C++11, supported in ROS Kinetic and newer # add_compile_options(-std=c++11) ## Find catkin macros and libraries ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) ## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS actionlib roscpp pluginlib smacc_msgs controller_manager_msgs ) ################################################ ## Declare ROS messages, services and actions ## ################################################ ################################################ ## Declare ROS dynamic reconfigure parameters ## ################################################ ################################### ## catkin specific configuration ## ################################### catkin_package( INCLUDE_DIRS include LIBRARIES smacc CATKIN_DEPENDS actionlib roscpp smacc_msgs controller_manager_msgs smacc_msgs message_runtime # DEPENDS system_lib ) ########### ## Build ## ########### SET(CMAKE_CXX_STANDARD 14) add_compile_options(-std=c++11) #workaround for ubuntu 16.04, to extinguish ## Specify additional locations of header files ## Your package locations should be listed before other locations include_directories( include ${catkin_INCLUDE_DIRS} ) file(GLOB_RECURSE ${PROJECT_NAME}_IncludeFilesPaths "*.h") add_custom_target(${PROJECT_NAME}_IncludeFilesTarget SOURCES ${${PROJECT_NAME}_IncludeFilesPaths}) # sources file(GLOB_RECURSE SRC_FILES "src/smacc/*.cpp" "src/smacc/introspection/*.cpp" "src/smacc/state_reactors/*.cpp") # opcionalmente GLOB add_library(${PROJECT_NAME} ${SRC_FILES}) ## Add cmake target dependencies of the executable ## same as for the library above add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Specify libraries to link a library or executable target against target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ) ############# ## Install ## ############# ## Mark executables and/or libraries for installation install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) ## Mark cpp header files for installation install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE ) ############# ## Testing ## ############# ================================================ FILE: smacc/include/smacc/callback_counter_semaphore.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include #include #include #include #include namespace smacc { class CallbackCounterSemaphore { public: CallbackCounterSemaphore(std::string name, int count = 0); bool acquire(); void release(); void finalize(); void addConnection(boost::signals2::connection conn); private: int count_; std::mutex mutex_; std::condition_variable cv_; std::vector connections_; bool finalized = false; std::string name_; }; } ================================================ FILE: smacc/include/smacc/client_base_components/cp_ros_control_interface.h ================================================ #pragma once #include #include namespace smacc { namespace components { struct ControllerTypeInfo { std::string type; std::string baseClass; }; enum Strictness { BEST_EFFORT = 1, STRICT = 2 }; class CpRosControlInterface : public smacc::ISmaccComponent { public: CpRosControlInterface(); virtual ~CpRosControlInterface(); virtual void onInitialize() override; // template // void onOrthogonalAllocation() {} std::vector listControllerTypes(); std::vector listControllers(); bool loadController(std::string name); bool unloadController(std::string name); bool reloadControllerLibraries(bool forceKill); bool switchControllers(std::vector start_controllers, std::vector stop_controllers, Strictness strictness); boost::optional serviceName_; private: ros::NodeHandle nh_; ros::ServiceClient srvListControllers; ros::ServiceClient srvListControllersTypes; ros::ServiceClient srvLoadController; ros::ServiceClient srvReloadControllerLibraries; ros::ServiceClient srvSwitchControllers; ros::ServiceClient srvUnloadController; }; } } ================================================ FILE: smacc/include/smacc/client_base_components/cp_topic_subscriber.h ================================================ #pragma once #include #include #include #include namespace smacc { namespace components { using namespace smacc::default_events; template class CpTopicSubscriber : public smacc::ISmaccComponent { public: boost::optional topicName; boost::optional queueSize; typedef MessageType TMessageType; CpTopicSubscriber() { initialized_ = false; } CpTopicSubscriber(std::string topicname) { topicName = topicname; } virtual ~CpTopicSubscriber() { sub_.shutdown(); } smacc::SmaccSignal onFirstMessageReceived_; smacc::SmaccSignal onMessageReceived_; std::function postMessageEvent; std::function postInitialMessageEvent; template boost::signals2::connection onMessageReceived(void (T::*callback)(const MessageType &), T *object) { return this->getStateMachine()->createSignalConnection(onMessageReceived_, callback, object); } template boost::signals2::connection onFirstMessageReceived(void (T::*callback)(const MessageType &), T *object) { return this->getStateMachine()->createSignalConnection(onFirstMessageReceived_, callback, object); } template void onOrthogonalAllocation() { this->postMessageEvent = [=](auto msg) { auto event = new EvTopicMessage(); event->msgData = msg; this->postEvent(event); }; this->postInitialMessageEvent = [=](auto msg) { auto event = new EvTopicInitialMessage(); event->msgData = msg; this->postEvent(event); }; } virtual void initialize() { if (!initialized_) { firstMessage_ = true; if (!queueSize) queueSize = 1; if (!topicName) { ROS_ERROR("topic client with no topic name set. Skipping subscribing"); } else { ROS_INFO_STREAM("[" << this->getName() << "] Subscribing to topic: " << topicName); sub_ = nh_.subscribe(*topicName, *queueSize, &CpTopicSubscriber::messageCallback, this); this->initialized_ = true; } } } protected: ros::NodeHandle nh_; private: ros::Subscriber sub_; bool firstMessage_; bool initialized_; void messageCallback(const MessageType &msg) { if (firstMessage_) { postInitialMessageEvent(msg); onFirstMessageReceived_(msg); firstMessage_ = false; } postMessageEvent(msg); onMessageReceived_(msg); } }; } } ================================================ FILE: smacc/include/smacc/client_bases/smacc_action_client.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include namespace smacc { namespace client_bases { using namespace actionlib; // This class interface shows the basic set of methods that // a SMACC "resource" or "plugin" Action Client has class ISmaccActionClient : public ISmaccClient { public: ISmaccActionClient(); // The destructor. This is called when the object is not // referenced anymore by its owner virtual ~ISmaccActionClient(); // Gets the ros path of the action... inline std::string getNamespace() const { return name_; } virtual void cancelGoal() = 0; virtual SimpleClientGoalState getState() = 0; protected: // The ros path where the action server is located std::string name_; }; } // namespace smacc } // namespace smacc ================================================ FILE: smacc/include/smacc/client_bases/smacc_action_client_base.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include namespace smacc { namespace client_bases { using namespace smacc::default_events; template class SmaccActionClientBase : public ISmaccActionClient { public: // Inside this macro you can find the typedefs for Goal and other types ACTION_DEFINITION(ActionType); typedef actionlib::SimpleActionClient ActionClient; typedef actionlib::SimpleActionClient GoalHandle; typedef typename ActionClient::SimpleDoneCallback SimpleDoneCallback; typedef typename ActionClient::SimpleActiveCallback SimpleActiveCallback; typedef typename ActionClient::SimpleFeedbackCallback SimpleFeedbackCallback; SmaccActionClientBase(std::string actionServerName) : ISmaccActionClient(), name_(actionServerName) { } SmaccActionClientBase() : ISmaccActionClient(), name_("") { } static std::string getEventLabel() { auto type = TypeInfo::getTypeInfoFromType(); return type->getNonTemplatedTypeName(); } virtual ~SmaccActionClientBase() { } /// rosnamespace path std::string name_; virtual void initialize() override { client_ = std::make_shared(name_); } smacc::SmaccSignal onSucceeded_; smacc::SmaccSignal onAborted_; smacc::SmaccSignal onPreempted_; smacc::SmaccSignal onRejected_; // event creation/posting factory functions std::function postSuccessEvent; std::function postAbortedEvent; std::function postPreemptedEvent; std::function postRejectedEvent; std::function postFeedbackEvent; SimpleDoneCallback done_cb; SimpleActiveCallback active_cb; SimpleFeedbackCallback feedback_cb; template void postResultEvent(ResultConstPtr result) { auto *ev = new EvType(); //ev->client = this; ev->resultMessage = *result; ROS_INFO("Posting EVENT %s", demangleSymbol(typeid(ev).name()).c_str()); this->postEvent(ev); } template void onOrthogonalAllocation() { // we create here all the event factory functions capturing the TOrthogonal postSuccessEvent = [=](auto msg) { this->postResultEvent>(msg); }; postAbortedEvent = [=](auto msg) { this->postResultEvent>(msg); }; postPreemptedEvent = [=](auto msg) { this->postResultEvent>(msg); }; postRejectedEvent = [=](auto msg) { this->postResultEvent>(msg); }; postFeedbackEvent = [=](auto msg) { auto actionFeedbackEvent = new EvActionFeedback(); actionFeedbackEvent->client = this; actionFeedbackEvent->feedbackMessage = *msg; this->postEvent(actionFeedbackEvent); ROS_DEBUG("[%s] FEEDBACK EVENT", demangleType(typeid(*this)).c_str()); }; done_cb = boost::bind(&SmaccActionClientBase::onResult, this, _1, _2); //active_cb; feedback_cb = boost::bind(&SmaccActionClientBase::onFeedback, this, _1); } template boost::signals2::connection onSucceeded(void (T::*callback)(ResultConstPtr &), T *object) { return this->getStateMachine()->createSignalConnection(onSucceeded_, callback, object); } template boost::signals2::connection onSucceeded(std::function callback) { return this->getStateMachine()->createSignalConnection(onSucceeded_, callback); } template boost::signals2::connection onAborted(void (T::*callback)(ResultConstPtr &), T *object) { return this->getStateMachine()->createSignalConnection(onAborted_, callback, object); } template boost::signals2::connection onAborted(std::function callback) { return this->getStateMachine()->createSignalConnection(onAborted_, callback); } template boost::signals2::connection onPreempted(void (T::*callback)(ResultConstPtr &), T *object) { return this->getStateMachine()->createSignalConnection(onPreempted_, callback, object); } template boost::signals2::connection onPreempted(std::function callback) { return this->getStateMachine()->createSignalConnection(onPreempted_, callback); } template boost::signals2::connection onRejected(void (T::*callback)(ResultConstPtr &), T *object) { return this->getStateMachine()->createSignalConnection(onRejected_, callback, object); } template boost::signals2::connection onRejected(std::function callback) { return this->getStateMachine()->createSignalConnection(onRejected_, callback); } virtual void cancelGoal() override { if (client_->isServerConnected()) { ROS_INFO("Cancelling goal of %s", this->getName().c_str()); client_->cancelGoal(); } else { ROS_ERROR("%s [at %s]: not connected with actionserver, skipping cancel goal ...", getName().c_str(), getNamespace().c_str()); } } virtual SimpleClientGoalState getState() override { return client_->getState(); } void sendGoal(Goal &goal) { ROS_INFO_STREAM("[ActionClient<"<< demangledTypeName() <<">] Sending goal to actionserver located in " << this->name_ << "\""); if (client_->isServerConnected()) { ROS_INFO_STREAM(getName() << ": Goal Value: " << std::endl << goal); client_->sendGoal(goal, done_cb, active_cb, feedback_cb); } else { ROS_ERROR("%s [at %s]: not connected with actionserver, skipping goal request ...", getName().c_str(), getNamespace().c_str()); //client_->waitForServer(); } } protected: std::shared_ptr client_; void onFeedback(const FeedbackConstPtr &feedback_msg) { postFeedbackEvent(feedback_msg); } void onResult(const SimpleClientGoalState &state, const ResultConstPtr &result_msg) { // auto *actionResultEvent = new EvActionResult(); // actionResultEvent->client = this; // actionResultEvent->resultMessage = *result_msg; const auto &resultType = this->getState(); ROS_INFO("[%s] request result: %s", this->getName().c_str(), resultType.toString().c_str()); if (resultType == actionlib::SimpleClientGoalState::SUCCEEDED) { ROS_INFO("[%s] request result: Success", this->getName().c_str()); onSucceeded_(result_msg); postSuccessEvent(result_msg); } else if (resultType == actionlib::SimpleClientGoalState::ABORTED) { ROS_INFO("[%s] request result: Aborted", this->getName().c_str()); onAborted_(result_msg); postAbortedEvent(result_msg); } else if (resultType == actionlib::SimpleClientGoalState::REJECTED) { ROS_INFO("[%s] request result: Rejected", this->getName().c_str()); onRejected_(result_msg); postRejectedEvent(result_msg); } else if (resultType == actionlib::SimpleClientGoalState::PREEMPTED) { ROS_INFO("[%s] request result: Preempted", this->getName().c_str()); onPreempted_(result_msg); postPreemptedEvent(result_msg); } else { ROS_INFO("[%s] request result: NOT HANDLED TYPE: %s", this->getName().c_str(), resultType.toString().c_str()); } } }; #define SMACC_ACTION_CLIENT_DEFINITION(ActionType) ACTION_DEFINITION(ActionType); typedef smacc::client_bases::SmaccActionClientBase Base; } // namespace client_bases } // namespace smacc ================================================ FILE: smacc/include/smacc/client_bases/smacc_publisher_client.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { namespace client_bases { class SmaccPublisherClient : public smacc::ISmaccClient { public: boost::optional topicName; boost::optional queueSize; SmaccPublisherClient() { initialized_ = false; } virtual ~SmaccPublisherClient() { pub_.shutdown(); } template void configure(std::string topicName) { this->topicName = topicName; if (!initialized_) { if (!this->topicName) { ROS_ERROR("topic publisher with no topic name set. Skipping advertising."); return; } if (!queueSize) queueSize = 1; ROS_INFO_STREAM("[" << this->getName() << "] Client Publisher to topic: " << topicName); pub_ = nh_.advertise(*(this->topicName), *queueSize); this->initialized_ = true; } } template void publish(const MessageType &msg) { pub_.publish(msg); } protected: ros::NodeHandle nh_; ros::Publisher pub_; private: bool initialized_; }; } // namespace client_bases } // namespace smacc ================================================ FILE: smacc/include/smacc/client_bases/smacc_service_client.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { namespace client_bases { template class SmaccServiceClient : public smacc::ISmaccClient { public: boost::optional serviceName_; SmaccServiceClient() { initialized_ = false; } SmaccServiceClient(std::string service_name) { serviceName_ = service_name; initialized_ = false; } virtual void initialize() override { if (!initialized_) { if (!serviceName_) { ROS_ERROR("service client with no service name set. Skipping."); } else { ROS_INFO_STREAM("[" << this->getName() << "] Client Service: " << *serviceName_); this->initialized_ = true; client_ = nh_.serviceClient(*serviceName_); } } } bool call(ServiceType &srvreq) { return client_.call(srvreq); } protected: ros::NodeHandle nh_; ros::ServiceClient client_; bool initialized_; }; } // namespace client_bases } // namespace smacc ================================================ FILE: smacc/include/smacc/client_bases/smacc_service_server_client.h ================================================ #pragma once #include #include #include #include namespace smacc { namespace client_bases { template class SmaccServiceServerClient : public smacc::ISmaccClient { using TServiceRequest = typename TService::Request; using TServiceResponse = typename TService::Response; public: boost::optional serviceName_; SmaccServiceServerClient() { initialized_ = false; } SmaccServiceServerClient(std::string service_name) { serviceName_ = service_name; initialized_ = false; } virtual ~SmaccServiceServerClient() { server_.shutdown(); } smacc::SmaccSignal)> onServiceRequestReceived_; template boost::signals2::connection onServiceRequestReceived( void (T::*callback)(TServiceRequest&, std::shared_ptr), T* object) { return this->getStateMachine()->createSignalConnection( onServiceRequestReceived_, callback, object); } virtual void initialize() override { if (!initialized_) { if (!serviceName_) { ROS_ERROR("service server with no service name set. Skipping."); } else { ROS_INFO_STREAM("[" << this->getName() << "] Client Service: " << serviceName_); server_ = nh_.advertiseService( *serviceName_, &SmaccServiceServerClient::serviceCallback, this); this->initialized_ = true; } } } protected: ros::NodeHandle nh_; private: bool serviceCallback(TServiceRequest& req, TServiceResponse& res) { std::shared_ptr response{new TServiceResponse}; onServiceRequestReceived_(req, response); res = *response; return true; } ros::ServiceServer server_; bool initialized_; }; } // namespace client_bases } // namespace smacc ================================================ FILE: smacc/include/smacc/client_bases/smacc_subscriber_client.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include namespace smacc { namespace client_bases { using namespace smacc::default_events; template class SmaccSubscriberClient : public smacc::ISmaccClient { public: boost::optional topicName; boost::optional queueSize; typedef MessageType TMessageType; SmaccSubscriberClient() { initialized_ = false; } SmaccSubscriberClient(std::string topicname) { topicName = topicname; } virtual ~SmaccSubscriberClient() { sub_.shutdown(); } smacc::SmaccSignal onFirstMessageReceived_; smacc::SmaccSignal onMessageReceived_; std::function postMessageEvent; std::function postInitialMessageEvent; template boost::signals2::connection onMessageReceived(void (T::*callback)(const MessageType &), T *object) { return this->getStateMachine()->createSignalConnection(onMessageReceived_, callback, object); } template boost::signals2::connection onFirstMessageReceived(void (T::*callback)(const MessageType &), T *object) { return this->getStateMachine()->createSignalConnection(onFirstMessageReceived_, callback, object); } template void onOrthogonalAllocation() { this->postMessageEvent = [=](auto msg) { auto event = new EvTopicMessage(); event->msgData = msg; this->postEvent(event); }; this->postInitialMessageEvent = [=](auto msg) { auto event = new EvTopicInitialMessage(); event->msgData = msg; this->postEvent(event); }; } virtual void initialize() { if (!initialized_) { firstMessage_ = true; if (!queueSize) queueSize = 1; if (!topicName) { ROS_ERROR("topic client with no topic name set. Skipping subscribing"); } else { ROS_INFO_STREAM("[" << this->getName() << "] Subscribing to topic: " << topicName); sub_ = nh_.subscribe(*topicName, *queueSize, &SmaccSubscriberClient::messageCallback, this); this->initialized_ = true; } } } protected: ros::NodeHandle nh_; private: ros::Subscriber sub_; bool firstMessage_; bool initialized_; void messageCallback(const MessageType &msg) { if (firstMessage_) { postInitialMessageEvent(msg); onFirstMessageReceived_(msg); firstMessage_ = false; } onMessageReceived_(msg); postMessageEvent(msg); } }; } // namespace client_bases } // namespace smacc ================================================ FILE: smacc/include/smacc/client_behavior_bases/cb_service_server_callback_base.h ================================================ #pragma once #include namespace smacc { template class CbServiceServerCallbackBase : public smacc::SmaccClientBehavior { public: virtual void onEntry() override { this->requiresClient(attachedClient_); attachedClient_->onServiceRequestReceived( &CbServiceServerCallbackBase::onServiceRequestReceived, this); } virtual void onServiceRequestReceived(typename TService::Request& req, std::shared_ptr res) = 0; protected: smacc::client_bases::SmaccServiceServerClient* attachedClient_ = nullptr; }; } // namespace smacc ================================================ FILE: smacc/include/smacc/client_behavior_bases/cb_subscription_callback_base.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018-2021 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include namespace smacc { template class CbSubscriptionCallbackBase : public smacc::SmaccClientBehavior { public: virtual void onEntry() override { this->requiresClient(attachedClient_); attachedClient_->onMessageReceived(&CbSubscriptionCallbackBase::onMessageReceived, this); } virtual void onMessageReceived(const TMsg& msg) = 0; protected: smacc::client_bases::SmaccSubscriberClient* attachedClient_ = nullptr; }; } // namespace smacc ================================================ FILE: smacc/include/smacc/common.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include typedef boost::statechart::processor_container, boost::function0, std::allocator>::processor_context my_context; namespace smacc { namespace utils { // demangles the type name to be used as a node handle path std::string cleanShortTypeName(const std::type_info &tinfo); } // namespace utils enum class SMRunMode { DEBUG, RELEASE }; } // namespace smacc #include #include ================================================ FILE: smacc/include/smacc/component.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { class ISmaccComponent { public: ISmaccComponent(); virtual ~ISmaccComponent(); // Returns a custom identifier defined by the specific plugin implementation virtual std::string getName() const; protected: virtual void initialize(ISmaccClient *owner); // Assigns the owner of this resource to the given state machine parameter object void setStateMachine(ISmaccStateMachine *stateMachine); template void postEvent(const EventType &ev); template void postEvent(); template void onOrthogonalAllocation() {} template void requiresComponent(TComponent *& requiredComponentStorage); template void requiresClient(TClient *& requiredClientStorage); virtual void onInitialize(); template SmaccComponentType *createSiblingComponent(TArgs... targs); template SmaccComponentType *createSiblingNamedComponent(std::string name, TArgs... targs); // A reference to the state machine object that owns this resource ISmaccStateMachine *stateMachine_; ISmaccClient *owner_; friend class ISmaccOrthogonal; friend class ISmaccClient; }; } // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_asynchronous_client_behavior_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { template void SmaccAsyncClientBehavior::onOrthogonalAllocation() { postFinishEventFn_ = [=] { this->onFinished_(); this->postEvent>(); }; postSuccessEventFn_ = [=] { this->onSuccess_(); this->postEvent>(); }; postFailureEventFn_ = [=] { this->onFailure_(); this->postEvent>(); }; } template boost::signals2::connection SmaccAsyncClientBehavior::onSuccess(TCallback callback, T *object) { return this->getStateMachine()->createSignalConnection(onSuccess_, callback, object); } template boost::signals2::connection SmaccAsyncClientBehavior::onFinished(TCallback callback, T *object) { return this->getStateMachine()->createSignalConnection(onFinished_, callback, object); } template boost::signals2::connection SmaccAsyncClientBehavior::onFailure(TCallback callback, T *object) { return this->getStateMachine()->createSignalConnection(onFailure_, callback, object); } } ================================================ FILE: smacc/include/smacc/impl/smacc_client_behavior_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { template void ISmaccClientBehavior::postEvent(const EventType &ev) { if (stateMachine_ == nullptr) { ROS_ERROR("The client behavior cannot post events before being assigned to an orthogonal. Ignoring post event call."); } else { stateMachine_->postEvent(ev, EventLifeTime::CURRENT_STATE); } } template void ISmaccClientBehavior::postEvent() { if (stateMachine_ == nullptr) { ROS_ERROR("The client behavior cannot post events before being assigned to an orthogonal. Ignoring post event call."); } else { stateMachine_->template postEvent(EventLifeTime::CURRENT_STATE); } } //inline ISmaccStateMachine *ISmaccClientBehavior::getStateMachine() { return this->stateMachine_; } //inline ISmaccState *ISmaccClientBehavior::getCurrentState() { return this->currentState; } template void ISmaccClientBehavior::requiresClient(SmaccClientType *&storage) { currentOrthogonal->requiresClient(storage); } template void ISmaccClientBehavior::requiresComponent(SmaccComponentType *&storage) { if (stateMachine_ == nullptr) { ROS_ERROR("Cannot use the requiresComponent funcionality before assigning the client behavior to an orthogonal. Try using the OnEntry method to capture required components."); } else { stateMachine_->requiresComponent(storage); } } template void ISmaccClientBehavior::onOrthogonalAllocation() {} } // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_client_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { template void ISmaccClient::postEvent(const EventType &ev) { stateMachine_->postEvent(ev); } template void ISmaccClient::postEvent() { stateMachine_->postEvent(); } template TComponent *ISmaccClient::getComponent() { return this->getComponent(std::string()); } template TComponent *ISmaccClient::getComponent(std::string name) { for (auto &component : components_) { if (component.first.name != name) continue; auto *tcomponent = dynamic_cast(component.second.get()); if (tcomponent != nullptr) { return tcomponent; } } return nullptr; } //inline ISmaccStateMachine *ISmaccClient::getStateMachine() { return this->stateMachine_; } template SmaccComponentType *ISmaccClient::createNamedComponent(std::string name, TArgs... targs) { ComponentKey componentkey(&typeid(SmaccComponentType), name); std::shared_ptr ret; auto it = this->components_.find(componentkey); if (it == this->components_.end()) { auto tname = demangledTypeName(); ROS_DEBUG("%s smacc component is required. Creating a new instance.", tname.c_str()); ret = std::shared_ptr(new SmaccComponentType(targs...)); ret->setStateMachine(this->getStateMachine()); ret->owner_ = this; ret->initialize(this); this->components_[componentkey] = ret; //std::dynamic_pointer_cast(ret); ROS_DEBUG("%s resource is required. Done.", tname.c_str()); } else { ROS_DEBUG("%s resource is required. Found resource in cache.", demangledTypeName().c_str()); ret = dynamic_pointer_cast(it->second); } ret->template onOrthogonalAllocation(); return ret.get(); } template SmaccComponentType *ISmaccClient::createComponent(TArgs... targs) { return this->createNamedComponent(std::string(), targs...); } template void ISmaccClient::connectSignal(TSmaccSignal &signal, void (T::*callback)(), T *object) { return this->getStateMachine()->createSignalConnection(signal, callback, object); } template void ISmaccClient::requiresClient(SmaccClientType *&storage) { this->orthogonal_->requiresClient(storage); } } // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_component_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { template void ISmaccComponent::postEvent(const EventType &ev) { stateMachine_->postEvent(ev); } template void ISmaccComponent::requiresComponent(TComponent *&requiredComponentStorage) { requiredComponentStorage = this->owner_->getComponent(); } template void ISmaccComponent::requiresClient(TClient *&requiredClientStorage) { this->owner_->requiresClient(requiredClientStorage); } template SmaccComponentType *ISmaccComponent::createSiblingComponent(TArgs... targs) { return this->owner_->createComponent(targs...); } template SmaccComponentType *ISmaccComponent::createSiblingNamedComponent(std::string name, TArgs... targs) { return this->owner_->createNamedComponent(name, targs...); } } // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_event_generator_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { template void SmaccEventGenerator::postEvent(const EventType &ev) { ownerState_->postEvent(ev); } template void SmaccEventGenerator::postEvent() { ownerState_->postEvent(); } template void SmaccEventGenerator::onStateAllocation() { } } // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_orthogonal_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include namespace smacc { template bool ISmaccOrthogonal::requiresClient(SmaccClientType *&storage) { for (auto &client : clients_) { storage = dynamic_cast(client.get()); if (storage != nullptr) return true; } auto requiredClientName = demangledTypeName(); ROS_WARN_STREAM("Required client ["<< requiredClientName<< "] not found in current orthogonal. Searching in other orthogonals."); for (auto &orthoentry : this->getStateMachine()->getOrthogonals()) { for (auto &client : orthoentry.second->getClients()) { storage = dynamic_cast(client.get()); if (storage != nullptr) { ROS_WARN_STREAM("Required client ["<< requiredClientName<<"] found in other orthogonal."); return true; } } } ROS_ERROR_STREAM("Required client ["<< requiredClientName<< "] not found even in other orthogonals. Returning null pointer. If the requested client is used may result in a segmentation fault."); return false; } template void ISmaccOrthogonal::requiresComponent(SmaccComponentType *&storage) { if (stateMachine_ == nullptr) { ROS_ERROR("Cannot use the requiresComponent funcionality from an orthogonal before onInitialize"); } else { stateMachine_->requiresComponent(storage); } } template void ISmaccOrthogonal::assignClientToOrthogonal(TClient* client) { client->setStateMachine(getStateMachine()); client->setOrthogonal(this); client->template onOrthogonalAllocation(); } template TClientBehavior *ISmaccOrthogonal::getClientBehavior() { for (auto &cb : this->clientBehaviors_.back()) { auto *ret = dynamic_cast(cb.get()); if (ret != nullptr) { return ret; } } return nullptr; } inline const std::vector> &ISmaccOrthogonal::getClients() { return clients_; } inline const std::vector>> &ISmaccOrthogonal::getClientBehaviors() const { return this->clientBehaviors_; } template void ISmaccOrthogonal::setGlobalSMData(std::string name, T value) { this->getStateMachine()->setGlobalSMData(name, value); } template bool ISmaccOrthogonal::getGlobalSMData(std::string name, T &ret) { return this->getStateMachine()->getGlobalSMData(name, ret); } //inline ISmaccStateMachine *ISmaccOrthogonal::getStateMachine() { return this->stateMachine_; } template class ClientHandler : public TClient { public: template ClientHandler(TArgs... args) : TClient(args...) { } ClientHandler() : TClient() { } template SmaccComponentType *createComponent(TArgs... targs) { return ISmaccClient::createComponent(targs...); } template SmaccComponentType *createNamedComponent(std::string name, TArgs... targs) { return ISmaccClient::createNamedComponent(name, targs...); } virtual smacc::introspection::TypeInfo::Ptr getType() override { return smacc::introspection::TypeInfo::getTypeInfoFromType(); } }; template class Orthogonal : public ISmaccOrthogonal { public: template std::shared_ptr> createClient(TArgs... args) { //static_assert(std::is_base_of::value, "The object Tag must be the orthogonal type where the client was created"); // if (typeid(*this) != typeid(TOrthogonal)) // { // ROS_ERROR_STREAM("Error creating client. The object Tag must be the type of the orthogonal where the client was created:" << demangleType(typeid(*this)) << ". The object creation was skipped and a nullptr was returned"); // return nullptr; // } ROS_INFO("[%s] creates a client of type '%s' and object tag '%s'", demangleType(typeid(*this)).c_str(), demangledTypeName().c_str(), demangledTypeName().c_str() ); auto client = std::make_shared>(args...); this->template assignClientToOrthogonal(client.get()); // it is stored the client (not the client handler) clients_.push_back(client); return client; } }; }; // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_state_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include #include #include //#include #include #include #include namespace smacc { using namespace smacc::introspection; //------------------------------------------------------------------------------------------------------- // Delegates to ROS param access with the current NodeHandle template bool ISmaccState::getParam(std::string param_name, T ¶m_storage) { return nh.getParam(param_name, param_storage); } //------------------------------------------------------------------------------------------------------- // Delegates to ROS param access with the current NodeHandle template void ISmaccState::setParam(std::string param_name, T param_val) { return nh.setParam(param_name, param_val); } //------------------------------------------------------------------------------------------------------- //Delegates to ROS param access with the current NodeHandle template bool ISmaccState::param(std::string param_name, T ¶m_val, const T &default_val) const { return nh.param(param_name, param_val, default_val); } //------------------------------------------------------------------------------------------------------- #define THIS_STATE_NAME ((demangleSymbol(typeid(*this).name()).c_str())) template std::shared_ptr ISmaccState::configure(Args &&... args) { std::string orthogonalkey = demangledTypeName(); ROS_INFO("[%s] Configuring orthogonal: %s", THIS_STATE_NAME, orthogonalkey.c_str()); TOrthogonal *orthogonal = this->getOrthogonal(); if (orthogonal != nullptr) { auto clientBehavior = std::shared_ptr(new TBehavior(args...)); clientBehavior->currentState = this; orthogonal->addClientBehavior(clientBehavior); clientBehavior->template onOrthogonalAllocation(); return clientBehavior; } else { ROS_ERROR("[%s] Skipping client behavior creation in orthogonal [%s]. It does not exist.", THIS_STATE_NAME, orthogonalkey.c_str()); return nullptr; } } //------------------------------------------------------------------------------------------------------- template void ISmaccState::requiresComponent(SmaccComponentType *&storage) { this->getStateMachine().requiresComponent(storage); } //------------------------------------------------------------------------------------------------------- template void ISmaccState::requiresClient(SmaccClientType *&storage) { const char *sname = (demangleSymbol(typeid(*this).name()).c_str()); storage = nullptr; auto &orthogonals = this->getStateMachine().getOrthogonals(); for (auto &ortho : orthogonals) { ortho.second->requiresClient(storage); if (storage != nullptr) return; } ROS_ERROR("[%s] Client of type '%s' not found in any orthogonal of the current state machine. This may produce a segmentation fault if the returned reference is used.", sname, demangleSymbol().c_str()); } //------------------------------------------------------------------------------------------------------- template bool ISmaccState::getGlobalSMData(std::string name, T &ret) { return this->getStateMachine().getGlobalSMData(name, ret); } //------------------------------------------------------------------------------------------------------- // Store globally in this state machine. (By value parameter ) template void ISmaccState::setGlobalSMData(std::string name, T value) { this->getStateMachine().setGlobalSMData(name, value); } //------------------------------------------------------------------------------------------------------- template std::shared_ptr ISmaccState::createStateReactor(TEvArgs... args) { auto sr = std::make_shared(args...); //sb->initialize(this, mock); //sb->setOutputEvent(typelist()); stateReactors_.push_back(sr); return sr; } template std::shared_ptr ISmaccState::createEventGenerator(TEvArgs... args) { auto eg = std::make_shared(args...); eventGenerators_.push_back(eg); return eg; } template struct AddTEventType { smacc::StateReactor *sr_; AddTEventType(smacc::StateReactor *sr) : sr_(sr) { } template void operator()(T) { sr_->addInputEvent(); } }; template std::shared_ptr ISmaccState::createStateReactor(TEvArgs... args) { auto sr = std::make_shared(args...); TEventList *mock; sr->initialize(this); sr->template setOutputEvent(); using boost::mpl::_1; using wrappedList = typename boost::mpl::transform::type; AddTEventType op(sr.get()); boost::mpl::for_each(op); stateReactors_.push_back(sr); return sr; } template TOrthogonal *ISmaccState::getOrthogonal() { //static_assert(boost::type_traits::is_base_of::value); return this->getStateMachine().getOrthogonal(); } template TEventGenerator* ISmaccState::getEventGenerator() { TEventGenerator* ret = nullptr; for(auto& evg: this->eventGenerators_) { ret = dynamic_cast(evg.get()); if(ret!=nullptr) break; } return ret; } template TStateReactor* ISmaccState::getStateReactor() { TStateReactor* ret = nullptr; for(auto& sr: this->stateReactors_) { ret = dynamic_cast(sr.get()); if(ret!=nullptr) break; } return ret; } // template // std::shared_ptr ISmaccState::createStateReactor(TEvArgs... args) // { // auto sb = std::make_shared(std::forward(args...)); // sb->initialize(this, typelist()); // sb->setOutputEvent(typelist()); // stateReactors_.push_back(sb); // return sb; // } //------------------------------------------------------------------------------------------------------- template void ISmaccState::postEvent(const EventType &ev) { getStateMachine().postEvent(ev); } template void ISmaccState::postEvent() { getStateMachine().postEvent(); } //------------------------------------------------------------------------------------------------------- template void ISmaccState::notifyTransition() { auto transitionType = TypeInfo::getTypeInfoFromType(); this->notifyTransitionFromTransitionTypeInfo(transitionType); } //------------------------------------------------------------------------------------------------------------------- } // namespace smacc // implementation depends on state definition #include #include ================================================ FILE: smacc/include/smacc/impl/smacc_state_machine_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace smacc { using namespace smacc::introspection; template TOrthogonal *ISmaccStateMachine::getOrthogonal() { std::lock_guard lock(m_mutex_); std::string orthogonalkey = demangledTypeName(); TOrthogonal *ret; auto it = orthogonals_.find(orthogonalkey); if (it != orthogonals_.end()) { ROS_DEBUG("Orthogonal %s resource is being required from some state, client or component. Found resource in cache.", orthogonalkey.c_str()); ret = dynamic_cast(it->second.get()); return ret; } else { std::stringstream ss; ss << "Orthogonal not found " << orthogonalkey.c_str() << std::endl; ss << "The existing orthogonals are the following: " << std::endl; for (auto &orthogonal : orthogonals_) { ss << " - " << orthogonal.first << std::endl; } ROS_WARN_STREAM(ss.str()); return nullptr; } } //------------------------------------------------------------------------------------------------------- template void ISmaccStateMachine::createOrthogonal() { this->lockStateMachine("create orthogonal"); std::string orthogonalkey = demangledTypeName(); if (orthogonals_.count(orthogonalkey) == 0) { auto ret = std::make_shared(); orthogonals_[orthogonalkey] = dynamic_pointer_cast(ret); ret->setStateMachine(this); ROS_INFO("%s Orthogonal is created", orthogonalkey.c_str()); } else { ROS_WARN_STREAM("There were already one existing orthogonal of type " << orthogonalkey.c_str() << ". Skipping creation orthogonal request. "); std::stringstream ss; ss << "The existing orthogonals are the following: " << std::endl; for (auto &orthogonal : orthogonals_) { ss << " - " << orthogonal.first << std::endl; } ROS_WARN_STREAM(ss.str()); } this->unlockStateMachine("create orthogonal"); } //------------------------------------------------------------------------------------------------------- template void ISmaccStateMachine::requiresComponent(SmaccComponentType *&storage) { ROS_DEBUG("component %s is required", demangleSymbol(typeid(SmaccComponentType).name()).c_str()); std::lock_guard lock(m_mutex_); for (auto ortho : this->orthogonals_) { for (auto &client : ortho.second->clients_) { storage = client->getComponent(); if (storage != nullptr) { return; } } } ROS_WARN("component %s is required but it was not found in any orthogonal", demangleSymbol(typeid(SmaccComponentType).name()).c_str()); // std::string componentkey = demangledTypeName(); // SmaccComponentType *ret; // auto it = components_.find(componentkey); // if (it == components_.end()) // { // ROS_DEBUG("%s smacc component is required. Creating a new instance.", componentkey.c_str()); // ret = new SmaccComponentType(); // ret->setStateMachine(this); // components_[componentkey] = static_cast(ret); // ROS_DEBUG("%s resource is required. Done.", componentkey.c_str()); // } // else // { // ROS_DEBUG("%s resource is required. Found resource in cache.", componentkey.c_str()); // ret = dynamic_cast(it->second); // } // storage = ret; } //------------------------------------------------------------------------------------------------------- template void ISmaccStateMachine::postEvent(EventType *ev, EventLifeTime evlifetime) { std::lock_guard guard(eventQueueMutex_); if (evlifetime == EventLifeTime::CURRENT_STATE && (stateMachineCurrentAction == StateMachineInternalAction::STATE_EXITING || stateMachineCurrentAction == StateMachineInternalAction::TRANSITIONING)) { ROS_WARN_STREAM("CURRENT STATE SCOPED EVENT SKIPPED, state is exiting/transitioning " << demangleSymbol()); return; // in this case we may lose/skip events, if this is not right for some cases we should create a queue // to lock the events during the transitions. This issues appeared when a client asyncbehavior was posting an event // meanwhile we were doing the transition, but the main thread was waiting for its correct finalization (with thread.join) } // when a postting event is requested by any component, client, or client behavior // we reach this place. Now, we propagate the events to all the state state reactors to generate // some more events ROS_DEBUG_STREAM("[PostEvent entry point] " << demangleSymbol()); for (auto currentState : currentState_) { propagateEventToStateReactors(currentState, ev); } this->signalDetector_->postEvent(ev); } template void ISmaccStateMachine::postEvent(EventLifeTime evlifetime) { auto *ev = new EventType(); this->postEvent(ev, evlifetime); } template bool ISmaccStateMachine::getGlobalSMData(std::string name, T &ret) { std::lock_guard lock(m_mutex_); // ROS_WARN("get SM Data lock acquire"); bool success = false; if (!globalData_.count(name)) { // ROS_WARN("get SM Data - data do not exist"); success = false; } else { // ROS_WARN("get SM DAta -data exist. accessing"); try { auto &v = globalData_[name]; // ROS_WARN("get SM DAta -data exist. any cast"); ret = boost::any_cast(v.second); success = true; // ROS_WARN("get SM DAta -data exist. success"); } catch (boost::bad_any_cast &ex) { ROS_ERROR("bad any cast: %s", ex.what()); success = false; } } // ROS_WARN("get SM Data lock release"); return success; } template void ISmaccStateMachine::setGlobalSMData(std::string name, T value) { { std::lock_guard lock(m_mutex_); // ROS_WARN("set SM Data lock acquire"); globalData_[name] = {[this, name]() { std::stringstream ss; auto val = any_cast(globalData_[name].second); ss << val; return ss.str(); }, value}; } this->updateStatusMessage(); } template void ISmaccStateMachine::mapBehavior() { std::string stateFieldName = demangleSymbol(typeid(StateField).name()); std::string behaviorType = demangleSymbol(typeid(BehaviorType).name()); ROS_INFO("Mapping state field '%s' to stateReactor '%s'", stateFieldName.c_str(), behaviorType.c_str()); SmaccClientBehavior *globalreference; if (!this->getGlobalSMData(stateFieldName, globalreference)) { // Using the requires component approach, we force a unique existence // of this component BehaviorType *behavior; this->requiresComponent(behavior); globalreference = dynamic_cast(behavior); this->setGlobalSMData(stateFieldName, globalreference); } } namespace utils { template struct Bind { template boost::signals2::connection bindaux(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object, std::shared_ptr callbackCounter); }; template <> struct Bind<1> { template boost::signals2::connection bindaux(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object, std::shared_ptr callbackCounter) { return signal.connect( [=]() { if(callbackCounter == nullptr) { (object->*callback)(); } else if (callbackCounter->acquire()) { (object->*callback)(); callbackCounter->release(); }}); } }; template <> struct Bind<2> { template boost::signals2::connection bindaux(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object, std::shared_ptr callbackCounter) { return signal.connect([=](auto a1) { if(callbackCounter == nullptr) { (object->*callback)(a1); } else if (callbackCounter->acquire()) { (object->*callback)(a1); callbackCounter->release(); } }); } }; template <> struct Bind<3> { template boost::signals2::connection bindaux(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object, std::shared_ptr callbackCounter) { return signal.connect([=](auto a1, auto a2) { if(callbackCounter == nullptr) { (object->*callback)(a1,a2); } else if (callbackCounter->acquire()) { (object->*callback)(a1,a2); callbackCounter->release(); } }); } }; template <> struct Bind<4> { template boost::signals2::connection bindaux(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object, std::shared_ptr callbackCounter) { return signal.connect([=](auto a1, auto a2, auto a3) { if(callbackCounter == nullptr) { (object->*callback)(a1,a2,a3); } else if (callbackCounter->acquire()) { (object->*callback)(a1,a2,a3); callbackCounter->release(); } }); } }; } // namespace utils using namespace smacc::utils; template boost::signals2::connection ISmaccStateMachine::createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object) { std::lock_guard lock(m_mutex_); static_assert(std::is_base_of::value || std::is_base_of::value || std::is_base_of::value || std::is_base_of::value || std::is_base_of::value, "Only are accepted smacc types as subscribers for smacc signals"); typedef decltype(callback) ft; Bind::value> binder; boost::signals2::connection connection; // long life-time objects if (std::is_base_of::value || std::is_base_of::value || std::is_base_of::value || std::is_base_of::value) { connection = binder.bindaux(signal, callback, object, nullptr); } else if (std::is_base_of::value || std::is_base_of::value || std::is_base_of::value) { ROS_INFO("[StateMachine] life-time constrained smacc signal subscription created. Subscriber is %s", demangledTypeName().c_str()); std::shared_ptr callbackCounterSemaphore; if(stateCallbackConnections.count(object)) { callbackCounterSemaphore = stateCallbackConnections[object]; } else { callbackCounterSemaphore = std::make_shared(demangledTypeName().c_str()); stateCallbackConnections[object] = callbackCounterSemaphore; } connection = binder.bindaux(signal, callback, object, callbackCounterSemaphore); callbackCounterSemaphore->addConnection(connection); } else // state life-time objects { ROS_WARN("[StateMachine] connecting signal to an unknown object with life-time unknown behavior. It might provoke " "an exception if the object is destroyed during the execution."); connection = binder.bindaux(signal, callback, object, nullptr); } return connection; } template bool ISmaccStateMachine::getParam(std::string param_name, T ¶m_storage) { return nh_.getParam(param_name, param_storage); } // Delegates to ROS param access with the current NodeHandle template void ISmaccStateMachine::setParam(std::string param_name, T param_val) { return nh_.setParam(param_name, param_val); } // Delegates to ROS param access with the current NodeHandle template bool ISmaccStateMachine::param(std::string param_name, T ¶m_val, const T &default_val) const { return nh_.param(param_name, param_val, default_val); } template void ISmaccStateMachine::notifyOnStateEntryStart(StateType *state) { std::lock_guard lock(m_mutex_); ROS_DEBUG("[State Machne] Initializating a new state '%s' and updating current state. Getting state meta-information. number of orthogonals: %ld", demangleSymbol(typeid(StateType).name()).c_str(), this->orthogonals_.size()); stateSeqCounter_++; currentState_.push_back(state); currentStateInfo_ = stateMachineInfo_->getState(); } template void ISmaccStateMachine::notifyOnStateEntryEnd(StateType *state) { ROS_INFO("[%s] State OnEntry code finished", demangleSymbol(typeid(StateType).name()).c_str()); auto currentState = this->currentState_.back(); for (auto pair : this->orthogonals_) { //ROS_INFO("ortho onentry: %s", pair.second->getName().c_str()); auto &orthogonal = pair.second; try { orthogonal->onEntry(); } catch (const std::exception &e) { ROS_ERROR("[Orthogonal %s] Exception on Entry - continuing with next orthogonal. Exception info: %s", pair.second->getName().c_str(), e.what()); } } for (auto &sr : currentState->getStateReactors()) { auto srname = smacc::demangleSymbol(typeid(*sr).name()).c_str(); ROS_INFO("state reactor onEntry: %s", srname); try { sr->onEntry(); } catch (const std::exception &e) { ROS_ERROR("[State Reactor %s] Exception on Entry - continuing with next state reactor. Exception info: %s", srname, e.what()); } } for (auto &eg : currentState->getEventGenerators()) { auto egname = smacc::demangleSymbol(typeid(*eg).name()).c_str(); ROS_INFO("state reactor onEntry: %s", egname); try { eg->onEntry(); } catch (const std::exception &e) { ROS_ERROR("[Event generator %s] Exception on Entry - continuing with next state reactor. Exception info: %s", egname, e.what()); } } { std::lock_guard lock(m_mutex_); this->updateStatusMessage(); stateMachineCurrentAction = StateMachineInternalAction::STATE_STEADY; } } template void ISmaccStateMachine::notifyOnRuntimeConfigurationFinished(StateType *state) { for (auto pair : this->orthogonals_) { //ROS_INFO("ortho onruntime configure: %s", pair.second->getName().c_str()); auto &orthogonal = pair.second; orthogonal->runtimeConfigure(); } { std::lock_guard lock(m_mutex_); this->updateStatusMessage(); this->signalDetector_->notifyStateConfigured(this->currentState_.back()); stateMachineCurrentAction = StateMachineInternalAction::STATE_ENTERING; } } template void ISmaccStateMachine::notifyOnRuntimeConfigured(StateType *state) { stateMachineCurrentAction = StateMachineInternalAction::STATE_CONFIGURING; } template void ISmaccStateMachine::notifyOnStateExitting(StateType *state) { stateMachineCurrentAction = StateMachineInternalAction::STATE_EXITING; auto fullname = demangleSymbol(typeid(StateType).name()); ROS_WARN_STREAM("exiting state: " << fullname); //this->setParam("destroyed", true); ROS_INFO_STREAM("Notification State Exit: leaving state" << state); for (auto pair : this->orthogonals_) { auto &orthogonal = pair.second; try { orthogonal->onExit(); } catch (const std::exception &e) { ROS_ERROR("[Orthogonal %s] Exception onExit - continuing with next orthogonal. Exception info: %s", pair.second->getName().c_str(), e.what()); } } for (auto &sr : state->getStateReactors()) { auto srname = smacc::demangleSymbol(typeid(*sr).name()).c_str(); ROS_INFO("state reactor OnExit: %s", srname); try { sr->onExit(); } catch (const std::exception &e) { ROS_ERROR("[State Reactor %s] Exception on OnExit - continuing with next state reactor. Exception info: %s", srname, e.what()); } } for (auto &eg : state->getEventGenerators()) { auto egname = smacc::demangleSymbol(typeid(*eg).name()).c_str(); ROS_INFO("state reactor OnExit: %s", egname); try { eg->onExit(); } catch (const std::exception &e) { ROS_ERROR("[State Reactor %s] Exception on OnExit - continuing with next state reactor. Exception info: %s", egname, e.what()); } } } template void ISmaccStateMachine::notifyOnStateExited(StateType *state) { this->lockStateMachine("state exit"); signalDetector_->notifyStateExited(state); auto fullname = demangleSymbol(typeid(StateType).name()); ROS_WARN_STREAM("exiting state: " << fullname); ROS_INFO_STREAM("Notification State Disposing: leaving state" << state); for (auto pair : this->orthogonals_) { auto &orthogonal = pair.second; try { orthogonal->onDispose(); } catch (const std::exception &e) { ROS_ERROR("[Orthogonal %s] Exception onDispose - continuing with next orthogonal. Exception info: %s", pair.second->getName().c_str(), e.what()); } } for (auto &sr : state->getStateReactors()) { auto srname = smacc::demangleSymbol(typeid(*sr).name()).c_str(); ROS_INFO("state reactor disposing: %s", srname); try { this->disconnectSmaccSignalObject(sr.get()); } catch (const std::exception &e) { ROS_ERROR("[State Reactor %s] Exception on OnDispose - continuing with next state reactor. Exception info: %s", srname, e.what()); } } for (auto &eg : state->getEventGenerators()) { auto egname = smacc::demangleSymbol(typeid(*eg).name()).c_str(); ROS_INFO("state reactor disposing: %s", egname); try { this->disconnectSmaccSignalObject(eg.get()); } catch (const std::exception &e) { ROS_ERROR("[State Reactor %s] Exception on OnDispose - continuing with next state reactor. Exception info: %s", egname, e.what()); } } this->stateCallbackConnections.clear(); currentState_.pop_back(); // then call exit state ROS_WARN_STREAM("state exit: " << fullname); stateMachineCurrentAction = StateMachineInternalAction::TRANSITIONING; this->unlockStateMachine("state exit"); } //------------------------------------------------------------------------------------------------------- template void ISmaccStateMachine::propagateEventToStateReactors(ISmaccState *st, EventType *ev) { ROS_DEBUG("PROPAGATING EVENT [%s] TO LUs [%s]: ", demangleSymbol().c_str(), st->getClassName().c_str()); for (auto &sb : st->getStateReactors()) { sb->notifyEvent(ev); } auto *pst = st->getParentState(); if (pst != nullptr) { propagateEventToStateReactors(pst, ev); } } template void ISmaccStateMachine::buildStateMachineInfo() { this->stateMachineInfo_ = std::make_shared(); this->stateMachineInfo_->buildStateMachineInfo(); this->stateMachineInfo_->assembleSMStructureMessage(this); this->checkStateMachineConsistence(); } uint64_t ISmaccStateMachine::getCurrentStateCounter() const { return this->stateSeqCounter_; } ISmaccState *ISmaccStateMachine::getCurrentState() const { return this->currentState_.back(); } const smacc::introspection::SmaccStateMachineInfo &ISmaccStateMachine::getStateMachineInfo() { return *this->stateMachineInfo_; } } // namespace smacc ================================================ FILE: smacc/include/smacc/impl/smacc_state_reactor_impl.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include namespace smacc { template void StateReactor::postEvent(const EventType &ev) { ownerState->postEvent(ev); } template void StateReactor::postEvent() { ownerState->postEvent(); } template void StateReactor::setOutputEvent() { this->postEventFn = [this]() { ROS_INFO_STREAM("[State Reactor Base] postingfn posting event: " << demangleSymbol()); auto *ev = new TEv(); this->ownerState->getStateMachine().postEvent(ev); }; } template void StateReactor::addInputEvent() { this->eventTypes.push_back(&typeid(TEv)); } template void StateReactor::createEventCallback(void (TClass::*callback)(T *), TClass *object) { const auto *eventtype = &typeid(T); this->eventCallbacks_[eventtype] = [=](void *msg) { T *evptr = (T *)msg; (object->*callback)(evptr); }; } template void StateReactor::createEventCallback(std::function callback) { const auto *eventtype = &typeid(T); this->eventCallbacks_[eventtype] = [=](void *msg) { T *evptr = (T *)msg; callback(evptr); }; } namespace introspection { template void StateReactorHandler::addInputEvent() { StateReactorCallbackFunctor functor; functor.fn = [=](std::shared_ptr sr) { ROS_INFO("[%s] State Reactor adding input event: %s", demangleType(srInfo_->stateReactorType).c_str(), demangledTypeName().c_str()); sr->addInputEvent(); }; this->callbacks_.push_back(functor); auto evtype = TypeInfo::getFromStdTypeInfo(typeid(TEv)); auto evinfo = std::make_shared(evtype); EventLabel(evinfo->label); srInfo_->sourceEventTypes.push_back(evinfo); } template void StateReactorHandler::setOutputEvent() { StateReactorCallbackFunctor functor; functor.fn = [=](std::shared_ptr sr) { ROS_INFO("[%s] State Reactor setting output event: %s", demangleType(srInfo_->stateReactorType).c_str(), demangledTypeName().c_str()); sr->setOutputEvent(); }; this->callbacks_.push_back(functor); } } // namespace introspection } // namespace smacc ================================================ FILE: smacc/include/smacc/introspection/introspection.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace sc = boost::statechart; namespace smacc { namespace introspection { using namespace boost; using namespace smacc::default_transition_tags; void transitionInfoToMsg(const SmaccTransitionInfo &transition, smacc_msgs::SmaccTransition &transitionMsg); typedef std::allocator SmaccAllocator; template auto optionalNodeHandle(boost::intrusive_ptr &obj) -> ros::NodeHandle { return obj->getROSNode(); } template auto optionalNodeHandle(T *) -> ros::NodeHandle { return ros::NodeHandle(""); } inline std::string demangleSymbol(const std::string &name) { return demangleSymbol(name.c_str()); } inline std::string demangleSymbol(const char *name) { #if (__GNUC__ && __cplusplus && __GNUC__ >= 3) int status; char *res = abi::__cxa_demangle(name, 0, 0, &status); if (res) { const std::string demangled_name(res); std::free(res); return demangled_name; } // Demangling failed, fallback to mangled name return std::string(name); #else return std::string(name); #endif } template inline std::string demangleSymbol() { return demangleSymbol(typeid(T).name()); } template inline std::string demangledTypeName() { return demangleSymbol(typeid(T).name()); } inline std::string demangleType(const std::type_info* tinfo) { return demangleSymbol(tinfo->name()); } inline std::string demangleType(const std::type_info &tinfo) { return demangleSymbol(tinfo.name()); } template struct typelist { }; //------------------------------------------------------------------------- template class HasEventLabel { private: typedef char YesType[1]; typedef char NoType[2]; template static YesType &test(decltype(&C::getEventLabel)); template static NoType &test(...); public: enum { value = sizeof(test(0)) == sizeof(YesType) }; }; template typename std::enable_if::value, void>::type EventLabel(std::string &label) { label = T::getEventLabel(); } template typename std::enable_if::value, void>::type EventLabel(std::string &label) { label = ""; } //----------------------------------------------------------------------- template class HasAutomaticTransitionTag { private: typedef char YesType[1]; typedef char NoType[2]; template static YesType &test(decltype(&C::getDefaultTransitionTag)); template static NoType &test(...); public: enum { value = sizeof(test(0)) == sizeof(YesType) }; }; template typename std::enable_if::value, void>::type automaticTransitionTag(std::string &transition_name) { transition_name = T::getDefaultTransitionTag(); } template typename std::enable_if::value, void>::type automaticTransitionTag(std::string &transition_name) { transition_name = ""; } //------------------------------------------------- template class HasAutomaticTransitionType { private: typedef char YesType[1]; typedef char NoType[2]; template static YesType &test(decltype(&C::getDefaultTransitionType)); template static NoType &test(...); public: enum { value = sizeof(test(0)) == sizeof(YesType) }; }; template typename std::enable_if::value, void>::type automaticTransitionType(std::string &transition_type) { transition_type = T::getDefaultTransitionType(); } template typename std::enable_if::value, void>::type automaticTransitionType(std::string &transition_type) { transition_type = demangledTypeName(); } // there are many ways to implement this, for instance adding static methods to the types typedef boost::mpl::list DEFAULT_TRANSITION_TYPES; //-------------------------------- template struct type_ { using type = T; }; //--------------------------------------------- template struct add_type_wrapper { using type = type_; }; template struct CheckType { CheckType(std::string *transitionTypeName) { this->transitionTypeName = transitionTypeName; } std::string *transitionTypeName; template void operator()(T) { //ROS_INFO_STREAM("comparing.."<< demangleSymbol() <<" vs " << demangleSymbol() ); if (std::is_base_of::value || std::is_same::value) { *(this->transitionTypeName) = demangledTypeName(); //ROS_INFO("YESS!"); } } }; template static std::string getTransitionType() { std::string output; CheckType op(&output); using boost::mpl::_1; using wrappedList = typename boost::mpl::transform::type; boost::mpl::for_each(op); return output; }; // // BASE CASE // template // static void walkStateReactorsSources(SmaccStateReactorInfo &sbinfo, typelist) // { // auto sourceType = TypeInfo::getFromStdTypeInfo(typeid(T)); // auto evinfo = std::make_shared(sourceType); // EventLabel(evinfo->label); // sbinfo.sourceEventTypes.push_back(evinfo); // ROS_INFO_STREAM("event: " << sourceType->getFullName()); // ROS_INFO_STREAM("event parameters: " << sourceType->templateParameters.size()); // } // // RECURSIVE CASE // template // static void walkStateReactorsSources(SmaccStateReactorInfo &sbinfo, typelist) // { // auto sourceType = TypeInfo::getFromStdTypeInfo(typeid(TEvHead)); // auto evinfo = std::make_shared(sourceType); // EventLabel(evinfo->label); // sbinfo.sourceEventTypes.push_back(evinfo); // ROS_INFO_STREAM("event: " << sourceType->getFullName()); // ROS_INFO_STREAM("event parameters: " << sourceType->templateParameters.size()); // walkStateReactorsSources(sbinfo, typelist()); // } } // namespace introspection } // namespace smacc #include ================================================ FILE: smacc/include/smacc/introspection/smacc_state_info.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include #include #include namespace smacc { namespace introspection { struct ClientBehaviorInfoEntry { std::function factoryFunction; const std::type_info *behaviorType; const std::type_info *orthogonalType; }; //--------------------------------------------- struct SmaccEventInfo { SmaccEventInfo(std::shared_ptr eventType); std::string getEventTypeName(); std::string getEventSourceName(); // AKA orthogonal std::string getOrthogonalName(); std::string label; std::shared_ptr eventType; private: }; struct SmaccTransitionInfo { SmaccTransitionInfo() { } bool historyNode; int index; std::shared_ptr sourceState; std::shared_ptr destinyState; std::string transitionTag; std::string transitionType; std::shared_ptr eventInfo; smacc::introspection::TypeInfo::Ptr transitionTypeInfo; }; //--------------------------------------------- struct StateReactorCallbackFunctor { std::function)> fn; }; class StateReactorHandler { private: std::vector callbacks_; public: void configureStateReactor(std::shared_ptr sr); template void addInputEvent(); template void setOutputEvent(); std::shared_ptr srInfo_; }; struct SmaccStateReactorInfo { std::shared_ptr ownerState; std::function factoryFunction; const std::type_info *stateReactorType; std::shared_ptr objectTagType; std::vector> sourceEventTypes; std::shared_ptr srh; }; //--------------------------------------------------------- struct EventGeneratorCallbackFunctor { std::function)> fn; }; class EventGeneratorHandler { private: std::vector callbacks_; public: void configureEventGenerator(std::shared_ptr eg); template void setOutputEvent(); std::shared_ptr egInfo_; }; struct SmaccEventGeneratorInfo { std::shared_ptr ownerState; std::function factoryFunction; const std::type_info *eventGeneratorType; std::shared_ptr objectTagType; std::vector> sourceEventTypes; std::shared_ptr egh; }; //--------------------------------------------- enum class SmaccStateType { SUPERSTATE = 2, STATE = 1, SUPERSTATE_ROUTINE = 1 }; class SmaccStateInfo : public std::enable_shared_from_this { public: typedef std::shared_ptr Ptr; static std::map> staticBehaviorInfo; static std::map>> stateReactorsInfo; static std::map>> eventGeneratorsInfo; int stateIndex_; std::string fullStateName; std::string demangledStateName; std::shared_ptr stateMachine_; std::shared_ptr parentState_; std::vector transitions_; std::vector> children_; int depth_; const std::type_info *tid_; SmaccStateInfo(const std::type_info *tid, std::shared_ptr parentState, std::shared_ptr stateMachineInfo); SmaccStateType getStateLevel(); inline int depth() const { return depth_; } void getAncestors(std::list &ancestorsList) const; std::string getFullPath(); template std::shared_ptr createChildState(); template void declareTransition(std::shared_ptr &dstState, std::string transitionTag, std::string transitionType, bool history, TypeInfo::Ptr transitionTypeInfo); // template typename EvType> // void declareTransition(std::shared_ptr &dstState, std::string transitionTag, std::string transitionType, bool history); const std::string &toShortName() const; std::string getDemangledFullName() const; }; } // namespace introspection } // namespace smacc ================================================ FILE: smacc/include/smacc/introspection/smacc_state_machine_info.h ================================================ /***************************************************************************************************************** * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018 * Authors: Pablo Inigo Blasco, Brett Aldrich * ******************************************************************************************************************/ #pragma once #include #include // smacc_msgs #include #include #include #include #include namespace smacc { namespace introspection { class SmaccStateMachineInfo : public std::enable_shared_from_this { public: std::map> states; std::vector stateMsgs; template void buildStateMachineInfo(); template std::shared_ptr createState(std::shared_ptr parentState); template bool containsState() { auto typeNameStr = typeid(StateType).name(); return states.count(typeNameStr) > 0; } template std::shared_ptr getState() { if (this->containsState()) { return states[typeid(StateType).name()]; } return nullptr; } template void addState(std::shared_ptr &state); void assembleSMStructureMessage(ISmaccStateMachine *sm); }; //--------------------------------------------- struct AddSubState { std::shared_ptr &parentState_; AddSubState(std::shared_ptr &parentState) : parentState_(parentState) { } template void operator()(T); }; //--------------------------------------------- struct AddTransition { std::shared_ptr ¤tState_; AddTransition(std::shared_ptr ¤tState) : currentState_(currentState) { } template