Carma-platform v4.2.0
CARMA Platform is built on robot operating system (ROS) and utilizes open source software (OSS) that enables Cooperative Driving Automation (CDA) features to allow Automated Driving Systems to interact and cooperate with infrastructure and other vehicles through communication.
drivers_controller_node.cpp
Go to the documentation of this file.
1
2/*
3 * Copyright (C) 2021 LEIDOS.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 * use this file except in compliance with the License. You may obtain a copy of
7 * the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17
19
21{
22DriversControllerNode::DriversControllerNode(const rclcpp::NodeOptions & options)
24{
25 // Don't automatically trigger state transitions from base class on configure
26 // In this class the managed nodes list first needs to be modified then the transition will be
27 // triggered manually
29
30 config_.startup_duration_ = declare_parameter<int>("startup_duration", config_.startup_duration_);
32 declare_parameter<double>("ros1_ssc_driver_timeout ", config_.driver_timeout_);
33
34 // carma-config parameters
36 declare_parameter<std::string>("ros1_ssc_driver_name", config_.ros1_ssc_driver_name_);
37 config_.excluded_namespace_nodes_ = declare_parameter<std::vector<std::string>>(
38 "excluded_namespace_nodes", config_.excluded_namespace_nodes_);
39}
40
41carma_ros2_utils::CallbackReturn DriversControllerNode::handle_on_configure(
42 const rclcpp_lifecycle::State & prev_state)
43{
44 auto base_return = BaseSubsystemController::handle_on_configure(prev_state);
45
46 if (base_return != carma_ros2_utils::CallbackReturn::SUCCESS) {
47 RCLCPP_ERROR(get_logger(), "Drivers Controller could not configure");
48 return base_return;
49 }
50
52
53 // Load required plugins and default enabled plugins
54 get_parameter<std::string>("ros1_ssc_driver_name", config_.ros1_ssc_driver_name_);
55 get_parameter<int>("startup_duration", config_.startup_duration_);
56 get_parameter<double>("ros1_ssc_driver_timeout ", config_.driver_timeout_);
57 get_parameter<std::vector<std::string>>(
58 "excluded_namespace_nodes", config_.excluded_namespace_nodes_);
59
60 RCLCPP_INFO_STREAM(get_logger(), "Config: " << config_);
61
62 // Handle fact that parameter vectors cannot be empty
63 if (
66 }
67
68 auto base_managed_nodes = lifecycle_mgr_.get_managed_nodes();
69 // Update managed nodes
70 // Collect namespace nodes not managed by other subsystem controllers - manually specified in
71 // carma-config
72 auto updated_managed_nodes =
74
75 lifecycle_mgr_.set_managed_nodes(updated_managed_nodes);
76
78 std::make_shared<SSCDriverManager>(config_.ros1_ssc_driver_name_, config_.driver_timeout_);
79
80 // record starup time
81 start_up_timestamp_ = this->now().nanoseconds() / 1e6;
82
83 driver_status_sub_ = create_subscription<carma_driver_msgs::msg::DriverStatus>(
84 "driver_discovery", 20,
85 std::bind(&DriversControllerNode::driver_discovery_cb, this, std::placeholders::_1));
86
87 ssc_status_check_timer_ = create_timer(
88 get_clock(), std::chrono::milliseconds(1000),
90
91 // Configure our drivers
92 bool success = lifecycle_mgr_
93 .configure(
94 std::chrono::milliseconds(base_config_.service_timeout_ms),
95 std::chrono::milliseconds(base_config_.call_timeout_ms))
96 .empty();
97
98 if (success) {
99 RCLCPP_INFO_STREAM(get_logger(), "Subsystem able to configure");
100 return CallbackReturn::SUCCESS;
101 } else {
102 RCLCPP_INFO_STREAM(get_logger(), "Subsystem unable to configure");
103 return CallbackReturn::FAILURE;
104 }
105}
106
107carma_ros2_utils::CallbackReturn DriversControllerNode::handle_on_activate(
108 const rclcpp_lifecycle::State & prev_state)
109{
110 // Reset to automatically trigger state transitions from base class
112
113 // return only either SUCCESS or FAILURE
115 prev_state); // This will activate all base_managed_nodes
116
117 if (base_return == CallbackReturn::SUCCESS) {
118 RCLCPP_INFO(get_logger(), "Driver Controller activated!");
119 } else if (base_return == CallbackReturn::FAILURE) {
120 RCLCPP_ERROR(
121 get_logger(),
122 "Driver Controller encountered FAILURE when trying to activate the subsystems... please "
123 "check which driver failed to activate...");
124 }
125
126 return base_return;
127}
128
130{
131 if (get_current_state().id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) {
132 return; // Exit early if node is not active
133 }
134
135 long time_now = this->now().nanoseconds() / 1e6;
136 long start_duration = rclcpp::Duration(config_.startup_duration_, 0).nanoseconds() / 1e6;
137
138 auto sys_alert_msg_from_ssc =
139 ssc_driver_manager_->get_latest_system_alert(time_now, start_up_timestamp_, start_duration);
140
141 // Only publish if it is first time publishing
142 // or if its type or description changed
143 if (
144 !prev_alert || prev_alert->type != sys_alert_msg_from_ssc.type ||
145 prev_alert->description != sys_alert_msg_from_ssc.description) {
146 prev_alert = sys_alert_msg_from_ssc;
147 publish_system_alert(sys_alert_msg_from_ssc);
148 } else {
149 RCLCPP_DEBUG_STREAM(get_logger(), "No change to alert status");
150 }
151}
152
154 const carma_driver_msgs::msg::DriverStatus::SharedPtr msg)
155{
156 // Driver discovery only published by ros1 drivers
157 ssc_driver_manager_->update_driver_status(msg, this->now().nanoseconds() / 1e6);
158}
159
160} // namespace subsystem_controllers
161
162#include "rclcpp_components/register_node_macro.hpp"
163
164// Register the component with class_loader
165RCLCPP_COMPONENTS_REGISTER_NODE(subsystem_controllers::DriversControllerNode)
A base class for all subsystem_controllers which provides default lifecycle behavior for subsystems.
BaseSubSystemControllerConfig base_config_
The configuration struct.
virtual carma_ros2_utils::CallbackReturn handle_on_configure(const rclcpp_lifecycle::State &prev_state)
virtual carma_ros2_utils::CallbackReturn handle_on_activate(const rclcpp_lifecycle::State &prev_state)
std::vector< std::string > get_non_intersecting_set(const std::vector< std::string > &set_a, const std::vector< std::string > &set_b) const
Returns all elements of the provided set_a which are NOT contained in the provided set_b.
bool trigger_managed_nodes_configure_from_base_class_
Collection of flags which, if true, will cause the base class to make lifecycle service calls to mana...
ros2_lifecycle_manager::Ros2LifecycleManager lifecycle_mgr_
Lifecycle Manager which will track the managed nodes and call their lifecycle services on request.
void critical_drivers_check_callback()
Timer callback function to check status of required ros1 drivers.
DriversControllerConfig config_
Config for user provided parameters.
std::shared_ptr< SSCDriverManager > ssc_driver_manager_
carma_ros2_utils::SubPtr< carma_driver_msgs::msg::DriverStatus > driver_status_sub_
ROS handles.
boost::optional< carma_msgs::msg::SystemAlert > prev_alert
void driver_discovery_cb(const carma_driver_msgs::msg::DriverStatus::SharedPtr msg)
carma_ros2_utils::CallbackReturn handle_on_activate(const rclcpp_lifecycle::State &prev_state)
carma_ros2_utils::CallbackReturn handle_on_configure(const rclcpp_lifecycle::State &prev_state)
Stuct containing the algorithm configuration values for the GuidanceController.
double driver_timeout_
The timeout threshold for essential drivers in ms.
int startup_duration_
The time allocated for system startup in seconds.
std::vector< std::string > excluded_namespace_nodes_
List of nodes in the namespace which will not be managed by this subsystem controller.