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.
guidance_state_machine.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2022 LEIDOS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
18
19namespace guidance
20{
21 GuidanceStateMachine::GuidanceStateMachine(rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger)
22 : logger_(logger) {}
23
25 {
26 // Set to OFF state of SHUTDOWN signal received
27 if(signal == Signal::SHUTDOWN) {
29 return;
30 }
32 {
33 case State::STARTUP:
34 if(signal == Signal::INITIALIZED) {
35 current_guidance_state_ = State::DRIVERS_READY;
36 }
37 break;
38 case State::DRIVERS_READY:
39 if(signal == Signal::ACTIVATED)
40 {
42 }
43 break;
44 case State::ACTIVE:
45 if(signal == Signal::ENGAGE)
46 {
48 } else if(signal == Signal::DISENGAGED)
49 {
50 current_guidance_state_ = State::DRIVERS_READY;
51 }
52 break;
53 case State::ENGAGED:
54 if(signal == Signal::DISENGAGED)
55 {
56 current_guidance_state_ = State::DRIVERS_READY;
57 } else if(signal == Signal::OVERRIDE)
58 {
60 } else if(signal == Signal::PARK)
61 {
62 current_guidance_state_ = State::ENTER_PARK;
63 }
64 break;
65 case State::INACTIVE:
66 if(signal == Signal::ACTIVATED)
67 {
69 }else if(signal == Signal::INITIALIZED){
70 current_guidance_state_ = State::DRIVERS_READY;
71 }
72 break;
73 case State::ENTER_PARK:
74 if(signal == Signal::OVERRIDE)
75 {
77 }
78 else if(signal == Signal::DISENGAGED)
79 {
80 current_guidance_state_ = State::DRIVERS_READY;
81 }
82 break;
83 default:
84 break;
85 }
86 }
87
88 void GuidanceStateMachine::onVehicleStatus(autoware_msgs::msg::VehicleStatus::UniquePtr msg)
89 {
90 current_velocity_ = msg->speed * 0.277777; // Convert kilometers per hour to meters per second. Rounded down so that it comes under epsilon for parking check
91 if (current_guidance_state_ == State::ENTER_PARK)
92 {
93 // '3' indicates vehicle gearshift is currently set to PARK
94 if(msg->current_gear.gear== autoware_msgs::msg::Gear::PARK)
95 {
96 onGuidanceSignal(Signal::OVERRIDE); // Required for ENTER_PARK -> INACTIVE
97
98 onGuidanceSignal(Signal::INITIALIZED); // Required for INACTIVE -> DRIVERS_READY
99 }
100 }
101 }
102
104 {
105 onGuidanceSignal(Signal::INITIALIZED);
106 }
107
109 {
111 }
112
114 {
115 if(msg)
116 {
117 onGuidanceSignal(Signal::ACTIVATED);
118 } else
119 {
121 }
122
123 }
124
125 void GuidanceStateMachine::onRoboticStatus(carma_driver_msgs::msg::RobotEnabled::UniquePtr msg)
126 {
127 // robotic status changes from false to true
128 if(!robotic_active_status_ && msg->robot_active)
129 {
131 onGuidanceSignal(Signal::ENGAGE);
132 }
133 // robotic status changes from true to false
134 else if(robotic_active_status_ && !msg->robot_active)
135 {
137 onGuidanceSignal(Signal::OVERRIDE);
138 }
139 }
140
141 void GuidanceStateMachine::onRouteEvent(carma_planning_msgs::msg::RouteEvent::UniquePtr msg)
142 {
143 if(msg->event == carma_planning_msgs::msg::RouteEvent::ROUTE_DEPARTED ||
144 msg->event == carma_planning_msgs::msg::RouteEvent::ROUTE_ABORTED) {
146 }
147 else if(msg->event == carma_planning_msgs::msg::RouteEvent::ROUTE_COMPLETED){
148 if (fabs(current_velocity_) < 0.001) { // Check we have successfully stopped
149 onGuidanceSignal(Signal::PARK); // ENGAGED -> ENTER_PARK this state restricts transitioning out of ENTER_PARK until vehicle is shifted to PARK
150 } else { // Vehicle was not able to stop transition to inactive
151 RCLCPP_WARN_STREAM(logger_->get_logger(), "Vehicle failed to park on route completion because current velocity was " << current_velocity_);
152 onGuidanceSignal(Signal::OVERRIDE);
153 }
154 }
155 }
156
158 {
159 return static_cast<uint8_t>(current_guidance_state_);
160 }
161
163 {
164 // call SetEnableRobotic service once when we enter ACTIVE state
166 {
168 {
170 return true;
171 }
172 } else {
173 // Reset when we leave ACTIVE state
175 }
176 return false;
177 }
178
179}
void onGuidanceShutdown()
Updates Guidance State Machine with SHUTDOWN signal.
void onRoboticStatus(carma_driver_msgs::msg::RobotEnabled::UniquePtr msg)
Handle robotic_status message from ROS network.
uint8_t getCurrentState()
Get current state machine status.
void onVehicleStatus(autoware_msgs::msg::VehicleStatus::UniquePtr msg)
Handle vehicle status message from ROS network.
void onRouteEvent(carma_planning_msgs::msg::RouteEvent::UniquePtr msg)
Handle route event message.
void onGuidanceInitialized()
Updates Guidance State Machine with INITIALIZED signal.
bool shouldCallSetEnableRobotic()
Indicate if SetEnableRobotic needs to be called in ACTIVE state.
void onGuidanceSignal(Signal signal)
Actual state machine logic driven by signal enum.
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger_
GuidanceStateMachine(rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr logger)
constructor for GuidanceStateMachine
void onSetGuidanceActive(bool msg)
Handle set_guidance_active service call from ROS network.