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{
22 DriversControllerNode::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 triggered manually
28
29 config_.startup_duration_ = declare_parameter<int>("startup_duration", config_.startup_duration_);
30 config_.driver_timeout_ = declare_parameter<double>("required_driver_timeout", config_.driver_timeout_);
31
32 // carma-config parameters
33 config_.ros1_required_drivers_ = declare_parameter<std::vector<std::string>>("ros1_required_drivers", config_.ros1_required_drivers_);
34 config_.ros1_camera_drivers_ = declare_parameter<std::vector<std::string>>("ros1_camera_drivers", config_.ros1_camera_drivers_);
35 config_.excluded_namespace_nodes_ = declare_parameter<std::vector<std::string>>("excluded_namespace_nodes", config_.excluded_namespace_nodes_);
36
37 }
38
39 carma_ros2_utils::CallbackReturn DriversControllerNode::handle_on_configure(const rclcpp_lifecycle::State &prev_state)
40 {
41 auto base_return = BaseSubsystemController::handle_on_configure(prev_state);
42
43 if (base_return != carma_ros2_utils::CallbackReturn::SUCCESS) {
44 RCLCPP_ERROR(get_logger(), "Drivers Controller could not configure");
45 return base_return;
46 }
47
49
50 // Load required plugins and default enabled plugins
51 get_parameter<std::vector<std::string>>("ros1_required_drivers", config_.ros1_required_drivers_);
52 get_parameter<std::vector<std::string>>("ros1_camera_drivers", config_.ros1_camera_drivers_);
53 get_parameter<int>("startup_duration", config_.startup_duration_);
54 get_parameter<double>("required_driver_timeout", config_.driver_timeout_);
55 get_parameter<std::vector<std::string>>("excluded_namespace_nodes", config_.excluded_namespace_nodes_);
56
57 RCLCPP_INFO_STREAM(get_logger(), "Config: " << config_);
58
59 // Handle fact that parameter vectors cannot be empty
60 if (config_.ros1_required_drivers_.size() == 1 && config_.ros1_required_drivers_[0].empty()) {
62 }
63 if (config_.ros1_camera_drivers_.size() == 1 && config_.ros1_camera_drivers_[0].empty()) {
65 }
68 }
69
70 auto base_managed_nodes = lifecycle_mgr_.get_managed_nodes();
71 // Update managed nodes
72 // Collect namespace nodes not managed by other subsystem controllers - manually specified in carma-config
73 auto updated_managed_nodes = get_non_intersecting_set(base_managed_nodes, config_.excluded_namespace_nodes_);
74
75 lifecycle_mgr_.set_managed_nodes(updated_managed_nodes);
76
77 driver_manager_ = std::make_shared<DriverManager>(
81 );
82
83 // record starup time
84 start_up_timestamp_ = this->now().nanoseconds() / 1e6;
85
86 driver_status_sub_ = create_subscription<carma_driver_msgs::msg::DriverStatus>("driver_discovery", 20, std::bind(&DriversControllerNode::driver_discovery_cb, this, std::placeholders::_1));
87
88 timer_ = create_timer(get_clock(), std::chrono::milliseconds(1000), std::bind(&DriversControllerNode::timer_callback,this));
89
90 // Configure our drivers
91 bool success = lifecycle_mgr_.configure(std::chrono::milliseconds(base_config_.service_timeout_ms), std::chrono::milliseconds(base_config_.call_timeout_ms)).empty();
92
93 if (success)
94 {
95 RCLCPP_INFO_STREAM(get_logger(), "Subsystem able to configure");
96 return CallbackReturn::SUCCESS;
97 }
98 else
99 {
100 RCLCPP_INFO_STREAM(get_logger(), "Subsystem unable to configure");
101 return CallbackReturn::FAILURE;
102 }
103
104 }
105
106 carma_ros2_utils::CallbackReturn DriversControllerNode::handle_on_activate(const rclcpp_lifecycle::State &prev_state)
107 {
108
109 // Reset to automatically trigger state transitions from base class
111
112 // return only either SUCCESS or FAILURE
113 auto base_return = BaseSubsystemController::handle_on_activate(prev_state); // This will activate all base_managed_nodes
114
115 if (base_return == CallbackReturn::SUCCESS) {
116 RCLCPP_INFO(get_logger(), "Driver Controller activated!");
117 }
118 else if (base_return == CallbackReturn::FAILURE)
119 {
120 RCLCPP_ERROR(get_logger(), "Driver Controller encountered FAILURE when trying to activate the subsystems... please check which driver failed to activate...");
121 }
122
123 return base_return;
124
125 }
126
128 {
129
130 long time_now = this->now().nanoseconds() / 1e6;
131 rclcpp::Duration sd(config_.startup_duration_, 0);
132 long start_duration = sd.nanoseconds()/1e6;
133
134 auto dm = driver_manager_->handle_spin(time_now, start_up_timestamp_, start_duration);
135
136 //Wait for node to be activated
137 if (get_current_state().id() == lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE){
138 if (!prev_alert) {
139 prev_alert = dm;
140 publish_system_alert(dm);
141 }
142 else if ( prev_alert->type == dm.type && prev_alert->description.compare(dm.description) == 0) { // Do not publish duplicate alerts
143 RCLCPP_DEBUG_STREAM(get_logger(), "No change to alert status");
144 }
145 else{
146 prev_alert = dm;
147 publish_system_alert(dm);
148 }
149 }
150
151 }
152
153
154 void DriversControllerNode::driver_discovery_cb(const carma_driver_msgs::msg::DriverStatus::SharedPtr msg)
155 {
156 // Driver discovery only published by ros1 drivers
157 driver_manager_->update_driver_status(msg, this->now().nanoseconds()/1e6);
158 }
159
160
161} // namespace subsystem_controllers
162
163#include "rclcpp_components/register_node_macro.hpp"
164
165// Register the component with class_loader
166RCLCPP_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.
DriversControllerConfig config_
Config for user provided parameters.
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)
void timer_callback()
Timer callback function to check status of required ros1 drivers.
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.
std::vector< std::string > ros1_camera_drivers_
List of ros1 camera drivers (node name) to consider required and who's failure shall result in automa...
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 > ros1_required_drivers_
List of ros1 controller drivers (node name) to consider required and who's failure shall result in au...
std::vector< std::string > excluded_namespace_nodes_
List of nodes in the namespace which will not be managed by this subsystem controller.