// Copyright 2016 Open Source Robotics Foundation, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include "lifecycle_msgs/msg/state.h" #include "lifecycle_msgs/msg/transition.h" #include "rcl/error_handling.h" #include "rcl/rcl.h" #include "rcl_lifecycle/transition_map.h" #include "default_state_machine.h" // NOLINT #include "states.h" // NOLINT #if __cplusplus extern "C" { #endif rcl_lifecycle_transition_key_t * empty_transition_key = NULL; rcl_lifecycle_transition_t * empty_transition = NULL; unsigned int empty_transition_size = 0; // Primary States const rcl_lifecycle_state_t rcl_state_unknown = {"unknown", lifecycle_msgs__msg__State__PRIMARY_STATE_UNKNOWN, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_unconfigured = {"unconfigured", lifecycle_msgs__msg__State__PRIMARY_STATE_UNCONFIGURED, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_inactive = {"inactive", lifecycle_msgs__msg__State__PRIMARY_STATE_INACTIVE, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_active = {"active", lifecycle_msgs__msg__State__PRIMARY_STATE_ACTIVE, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_finalized = {"finalized", lifecycle_msgs__msg__State__PRIMARY_STATE_FINALIZED, NULL, NULL, 0}; // Transition States const rcl_lifecycle_state_t rcl_state_configuring = {"configuring", lifecycle_msgs__msg__State__TRANSITION_STATE_CONFIGURING, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_cleaningup = {"cleaningup", lifecycle_msgs__msg__State__TRANSITION_STATE_CLEANINGUP, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_shuttingdown = {"shuttingdown", lifecycle_msgs__msg__State__TRANSITION_STATE_SHUTTINGDOWN, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_activating = {"activating", lifecycle_msgs__msg__State__TRANSITION_STATE_ACTIVATING, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_deactivating = {"deactivating", lifecycle_msgs__msg__State__TRANSITION_STATE_DEACTIVATING, NULL, NULL, 0}; const rcl_lifecycle_state_t rcl_state_errorprocessing = {"errorprocessing", lifecycle_msgs__msg__State__TRANSITION_STATE_ERRORPROCESSING, NULL, NULL, 0}; // Transitions const rcl_lifecycle_transition_t rcl_transition_configure = {"configure", lifecycle_msgs__msg__Transition__TRANSITION_CONFIGURE, &rcl_state_unconfigured, &rcl_state_configuring}; const rcl_lifecycle_transition_t rcl_transition_configure_success = {"configure_success", lifecycle_msgs__msg__Transition__TRANSITION_ON_CONFIGURE_SUCCESS, &rcl_state_configuring, &rcl_state_inactive}; const rcl_lifecycle_transition_t rcl_transition_configure_failure = {"configure_failure", lifecycle_msgs__msg__Transition__TRANSITION_ON_CONFIGURE_FAILURE, &rcl_state_configuring, &rcl_state_unconfigured}; const rcl_lifecycle_transition_t rcl_transition_configure_error = {"configure_error", lifecycle_msgs__msg__Transition__TRANSITION_ON_CLEANUP_ERROR, &rcl_state_configuring, &rcl_state_errorprocessing}; const rcl_lifecycle_transition_t rcl_transition_cleanup = {"cleanup", lifecycle_msgs__msg__Transition__TRANSITION_CLEANUP, &rcl_state_inactive, &rcl_state_cleaningup}; const rcl_lifecycle_transition_t rcl_transition_cleanup_success = {"cleanup_success", lifecycle_msgs__msg__Transition__TRANSITION_ON_CLEANUP_SUCCESS, &rcl_state_cleaningup, &rcl_state_unconfigured}; const rcl_lifecycle_transition_t rcl_transition_cleanup_failure = {"cleanup_failure", lifecycle_msgs__msg__Transition__TRANSITION_ON_CLEANUP_FAILURE, &rcl_state_cleaningup, &rcl_state_inactive}; const rcl_lifecycle_transition_t rcl_transition_cleanup_error = {"cleanup_error", lifecycle_msgs__msg__Transition__TRANSITION_ON_CLEANUP_ERROR, &rcl_state_cleaningup, &rcl_state_errorprocessing}; const rcl_lifecycle_transition_t rcl_transition_activate = {"activate", lifecycle_msgs__msg__Transition__TRANSITION_ACTIVATE, &rcl_state_inactive, &rcl_state_activating}; const rcl_lifecycle_transition_t rcl_transition_activate_success = {"activate_success", lifecycle_msgs__msg__Transition__TRANSITION_ON_ACTIVATE_SUCCESS, &rcl_state_activating, &rcl_state_active}; const rcl_lifecycle_transition_t rcl_transition_activate_failure = {"activate_failure", lifecycle_msgs__msg__Transition__TRANSITION_ON_ACTIVATE_FAILURE, &rcl_state_activating, &rcl_state_inactive}; const rcl_lifecycle_transition_t rcl_transition_activate_error = {"activate_error", lifecycle_msgs__msg__Transition__TRANSITION_ON_ACTIVATE_ERROR, &rcl_state_activating, &rcl_state_errorprocessing}; const rcl_lifecycle_transition_t rcl_transition_deactivate = {"deactivate", lifecycle_msgs__msg__Transition__TRANSITION_DEACTIVATE, &rcl_state_active, &rcl_state_deactivating}; const rcl_lifecycle_transition_t rcl_transition_deactivate_success = {"deactivate_success", lifecycle_msgs__msg__Transition__TRANSITION_ON_DEACTIVATE_SUCCESS, &rcl_state_deactivating, &rcl_state_inactive}; const rcl_lifecycle_transition_t rcl_transition_deactivate_failure = {"deactivate_failure", lifecycle_msgs__msg__Transition__TRANSITION_ON_DEACTIVATE_FAILURE, &rcl_state_deactivating, &rcl_state_active}; const rcl_lifecycle_transition_t rcl_transition_deactivate_error = {"deactivate_error", lifecycle_msgs__msg__Transition__TRANSITION_ON_DEACTIVATE_ERROR, &rcl_state_deactivating, &rcl_state_errorprocessing}; const rcl_lifecycle_transition_t rcl_transition_unconfigured_shutdown = {"unconfigured_shutdown", lifecycle_msgs__msg__Transition__TRANSITION_UNCONFIGURED_SHUTDOWN, &rcl_state_unconfigured, &rcl_state_shuttingdown}; const rcl_lifecycle_transition_t rcl_transition_inactive_shutdown = {"inactive_shutdown", lifecycle_msgs__msg__Transition__TRANSITION_INACTIVE_SHUTDOWN, &rcl_state_inactive, &rcl_state_shuttingdown}; const rcl_lifecycle_transition_t rcl_transition_active_shutdown = {"active_shutdown", lifecycle_msgs__msg__Transition__TRANSITION_ACTIVE_SHUTDOWN, &rcl_state_active, &rcl_state_shuttingdown}; const rcl_lifecycle_transition_t rcl_transition_shutdown_success = {"shutdown_success", lifecycle_msgs__msg__Transition__TRANSITION_ON_SHUTDOWN_SUCCESS, &rcl_state_shuttingdown, &rcl_state_finalized}; const rcl_lifecycle_transition_t rcl_transition_shutdown_failure = {"shutdown_failure", lifecycle_msgs__msg__Transition__TRANSITION_ON_SHUTDOWN_FAILURE, &rcl_state_shuttingdown, &rcl_state_finalized}; const rcl_lifecycle_transition_t rcl_transition_shutdown_error = {"shutdown_error", lifecycle_msgs__msg__Transition__TRANSITION_ON_SHUTDOWN_ERROR, &rcl_state_shuttingdown, &rcl_state_errorprocessing}; const rcl_lifecycle_transition_t rcl_transition_error_success = {"errorprocessing_success", lifecycle_msgs__msg__Transition__TRANSITION_ON_ERROR_SUCCESS, &rcl_state_errorprocessing, &rcl_state_unconfigured}; const rcl_lifecycle_transition_t rcl_transition_error_failure = {"errorprocessing_failure", lifecycle_msgs__msg__Transition__TRANSITION_ON_ERROR_FAILURE, &rcl_state_errorprocessing, &rcl_state_finalized}; const rcl_lifecycle_transition_t rcl_transition_error_error = {"errorprocessing_error", lifecycle_msgs__msg__Transition__TRANSITION_ON_ERROR_ERROR, &rcl_state_errorprocessing, &rcl_state_finalized}; // default implementation as despicted on // design.ros2.org rcl_ret_t rcl_lifecycle_init_default_state_machine( rcl_lifecycle_state_machine_t * state_machine, const rcutils_allocator_t * allocator) { rcutils_ret_t ret; /* * we once register all primary states */ ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_unknown, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_unconfigured, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_inactive, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_active, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_finalized, allocator); if (ret != RCL_RET_OK) { goto fail; } /* * we once register all transition states */ ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_configuring, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_cleaningup, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_shuttingdown, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_activating, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_deactivating, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_state( &state_machine->transition_map, rcl_state_errorprocessing, allocator); if (ret != RCL_RET_OK) { goto fail; } /* * we register all transitions from each primary state * it registers the transition and the key on which to trigger */ // transition configure ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_configure, lifecycle_msgs__msg__Transition__TRANSITION_CONFIGURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_configure_success, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_SUCCESS, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_configure_failure, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_FAILURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_configure_error, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_ERROR, allocator); if (ret != RCL_RET_OK) { goto fail; } // transition cleanup ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_cleanup, lifecycle_msgs__msg__Transition__TRANSITION_CLEANUP, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_cleanup_success, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_SUCCESS, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_cleanup_failure, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_FAILURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_cleanup_error, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_ERROR, allocator); if (ret != RCL_RET_OK) { goto fail; } // transition activate ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_activate, lifecycle_msgs__msg__Transition__TRANSITION_ACTIVATE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_activate_success, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_SUCCESS, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_activate_failure, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_FAILURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_activate_error, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_ERROR, allocator); if (ret != RCL_RET_OK) { goto fail; } // transition deactivate ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_deactivate, lifecycle_msgs__msg__Transition__TRANSITION_DEACTIVATE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_deactivate_success, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_SUCCESS, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_deactivate_failure, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_FAILURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_deactivate_error, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_ERROR, allocator); if (ret != RCL_RET_OK) { goto fail; } // transition shutdown ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_unconfigured_shutdown, lifecycle_msgs__msg__Transition__TRANSITION_SHUTDOWN, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_inactive_shutdown, lifecycle_msgs__msg__Transition__TRANSITION_SHUTDOWN, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_active_shutdown, lifecycle_msgs__msg__Transition__TRANSITION_SHUTDOWN, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_shutdown_success, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_SUCCESS, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_shutdown_failure, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_FAILURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_shutdown_error, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_ERROR, allocator); if (ret != RCL_RET_OK) { goto fail; } // error state ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_error_success, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_SUCCESS, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_error_failure, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_FAILURE, allocator); if (ret != RCL_RET_OK) { goto fail; } ret = rcl_lifecycle_register_transition( &state_machine->transition_map, rcl_transition_error_error, lifecycle_msgs__msg__Transition__TRANSITION_CALLBACK_ERROR, allocator); if (ret != RCL_RET_OK) { goto fail; } state_machine->current_state = &rcl_state_unconfigured; return RCL_RET_OK; fail: if (rcl_lifecycle_transition_map_fini(&state_machine->transition_map, allocator) != RCL_RET_OK) { RCL_SET_ERROR_MSG("could not free lifecycle transition map. Leaking memory!\n", rcl_get_default_allocator()); } return RCL_RET_ERROR; } #if __cplusplus } #endif // extern "C"