Skip to content

Commit 59bb10f

Browse files
committed
fix(hazard_status_converter): backport autowarefoundation#10224 to v0.39.0
Signed-off-by: Takagi, Isamu <isamu.takagi@tier4.jp>
1 parent 2fc4c87 commit 59bb10f

File tree

5 files changed

+163
-11
lines changed

5 files changed

+163
-11
lines changed

system/hazard_status_converter/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ autoware_package()
66

77
ament_auto_add_library(${PROJECT_NAME} SHARED
88
src/converter.cpp
9+
src/mode_interface.cpp
910
)
1011

1112
rclcpp_components_register_node(${PROJECT_NAME}

system/hazard_status_converter/src/converter.cpp

+27-9
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414

1515
#include "converter.hpp"
1616

17+
#include <string>
1718
#include <utility>
1819
#include <vector>
1920

2021
namespace hazard_status_converter
2122
{
2223

23-
Converter::Converter(const rclcpp::NodeOptions & options) : Node("converter", options)
24+
Converter::Converter(const rclcpp::NodeOptions & options)
25+
: Node("converter", options), mode_interface_(*this)
2426
{
2527
using std::placeholders::_1;
2628
pub_hazard_ = create_publisher<HazardStatusStamped>("~/hazard_status", rclcpp::QoS(1));
@@ -31,9 +33,9 @@ Converter::Converter(const rclcpp::NodeOptions & options) : Node("converter", op
3133

3234
void Converter::on_create(DiagGraph::ConstSharedPtr graph)
3335
{
34-
const auto find_auto_mode_root = [](const DiagGraph & graph) {
36+
const auto find_auto_mode_root = [](const DiagGraph & graph, const std::string & root_name) {
3537
for (const auto & unit : graph.units()) {
36-
if (unit->path() == "/autoware/modes/autonomous") return unit;
38+
if (unit->path() == root_name) return unit;
3739
}
3840
return static_cast<DiagUnit *>(nullptr);
3941
};
@@ -53,8 +55,17 @@ void Converter::on_create(DiagGraph::ConstSharedPtr graph)
5355
return result;
5456
};
5557

56-
auto_mode_root_ = find_auto_mode_root(*graph);
57-
auto_mode_tree_ = make_auto_mode_tree(auto_mode_root_);
58+
std::vector<std::pair<RootModeStatus::Mode, std::string>> root_modes = {
59+
{RootModeStatus::Mode::AUTO, "/autoware/modes/autonomous"},
60+
{RootModeStatus::Mode::REMOTE, "/autoware/modes/remote"},
61+
{RootModeStatus::Mode::LOCAL, "/autoware/modes/local"},
62+
};
63+
for (const auto & [mode, root_name] : root_modes) {
64+
ModeSubgraph subgraph;
65+
subgraph.root = find_auto_mode_root(*graph, root_name);
66+
subgraph.nodes = make_auto_mode_tree(subgraph.root);
67+
mode_subgraphs_[mode] = subgraph;
68+
}
5869
}
5970

6071
void Converter::on_update(DiagGraph::ConstSharedPtr graph)
@@ -98,17 +109,24 @@ void Converter::on_update(DiagGraph::ConstSharedPtr graph)
98109
return static_cast<std::vector<DiagnosticStatus> *>(nullptr);
99110
};
100111

101-
if (!auto_mode_root_) {
102-
RCLCPP_ERROR_STREAM_THROTTLE(get_logger(), *get_clock(), 10000, "No auto mode unit.");
112+
// Get subgraph related to the current operation mode.
113+
const auto root = mode_interface_.get_root();
114+
if (root.mode == RootModeStatus::Mode::UNKNOWN) {
115+
RCLCPP_ERROR_STREAM_THROTTLE(get_logger(), *get_clock(), 10000, "Unknown root mode.");
116+
return;
117+
}
118+
const auto & subgraph = mode_subgraphs_.at(root.mode);
119+
if (!subgraph.root) {
120+
RCLCPP_ERROR_STREAM_THROTTLE(get_logger(), *get_clock(), 10000, "No current mode root.");
103121
return;
104122
}
105123

106124
// Calculate hazard level from unit level and root level.
107125
HazardStatusStamped hazard;
108126
for (const auto & unit : graph->units()) {
109127
if (unit->path().empty()) continue;
110-
const bool is_auto_tree = auto_mode_tree_.count(unit);
111-
const auto root_level = is_auto_tree ? auto_mode_root_->level() : DiagnosticStatus::OK;
128+
const bool is_ignored = root.ignore || !subgraph.nodes.count(unit);
129+
const auto root_level = is_ignored ? DiagnosticStatus::OK : subgraph.root->level();
112130
const auto unit_level = unit->level();
113131
if (auto diags = get_hazards_vector(hazard.status, get_hazard_level(unit_level, root_level))) {
114132
diags->push_back(unit->create_diagnostic_status());

system/hazard_status_converter/src/converter.hpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
#ifndef CONVERTER_HPP_
1616
#define CONVERTER_HPP_
1717

18+
#include "mode_interface.hpp"
19+
1820
#include <diagnostic_graph_utils/subscription.hpp>
1921
#include <rclcpp/rclcpp.hpp>
2022

2123
#include <autoware_system_msgs/msg/hazard_status_stamped.hpp>
2224

25+
#include <unordered_map>
2326
#include <unordered_set>
2427

2528
namespace hazard_status_converter
@@ -39,8 +42,14 @@ class Converter : public rclcpp::Node
3942
diagnostic_graph_utils::DiagGraphSubscription sub_graph_;
4043
rclcpp::Publisher<HazardStatusStamped>::SharedPtr pub_hazard_;
4144

42-
DiagUnit * auto_mode_root_;
43-
std::unordered_set<DiagUnit *> auto_mode_tree_;
45+
struct ModeSubgraph
46+
{
47+
DiagUnit * root;
48+
std::unordered_set<DiagUnit *> nodes;
49+
};
50+
51+
ModeInterface mode_interface_;
52+
std::unordered_map<RootModeStatus::Mode, ModeSubgraph> mode_subgraphs_;
4453
};
4554

4655
} // namespace hazard_status_converter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2025 The Autoware Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "mode_interface.hpp"
16+
17+
namespace hazard_status_converter
18+
{
19+
20+
ModeInterface::ModeInterface(rclcpp::Node & node) : node_(node)
21+
{
22+
sub_operation_mode_state_ = node.create_subscription<OperationModeState>(
23+
"/api/operation_mode/state", rclcpp::QoS(1).transient_local(),
24+
[this](const OperationModeState & msg) { operation_mode_state_ = msg; });
25+
sub_autoware_state_ = node.create_subscription<AutowareState>(
26+
"/autoware/state", rclcpp::QoS(1),
27+
[this](const AutowareState & msg) { autoware_state_ = msg; });
28+
}
29+
30+
RootModeStatus ModeInterface::get_root() const
31+
{
32+
const auto is_not_autoware_running = [this]() {
33+
if (autoware_state_->state == AutowareState::INITIALIZING) return true;
34+
if (autoware_state_->state == AutowareState::FINALIZING) return true;
35+
return false;
36+
};
37+
38+
const auto is_not_autonomous_ready = [this]() {
39+
if (autoware_state_->state == AutowareState::WAITING_FOR_ROUTE) return true;
40+
if (autoware_state_->state == AutowareState::PLANNING) return true;
41+
return false;
42+
};
43+
44+
// Returns unknown before receiving state messages.
45+
if (!operation_mode_state_ || !autoware_state_) {
46+
return {RootModeStatus::Mode::UNKNOWN, false};
47+
}
48+
49+
// During stop mode refer to autonomous mode diagnostics.
50+
if (operation_mode_state_->mode == OperationModeState::STOP) {
51+
return {RootModeStatus::Mode::AUTO, is_not_autoware_running() || is_not_autonomous_ready()};
52+
}
53+
if (operation_mode_state_->mode == OperationModeState::AUTONOMOUS) {
54+
return {RootModeStatus::Mode::AUTO, is_not_autoware_running() || is_not_autonomous_ready()};
55+
}
56+
if (operation_mode_state_->mode == OperationModeState::REMOTE) {
57+
return {RootModeStatus::Mode::REMOTE, is_not_autoware_running()};
58+
}
59+
if (operation_mode_state_->mode == OperationModeState::LOCAL) {
60+
return {RootModeStatus::Mode::LOCAL, is_not_autoware_running()};
61+
}
62+
return {RootModeStatus::Mode::UNKNOWN, false};
63+
}
64+
65+
} // namespace hazard_status_converter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2025 The Autoware Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef MODE_INTERFACE_HPP_
16+
#define MODE_INTERFACE_HPP_
17+
18+
#include <rclcpp/rclcpp.hpp>
19+
20+
#include <autoware_adapi_v1_msgs/msg/operation_mode_state.hpp>
21+
#include <autoware_system_msgs/msg/autoware_state.hpp>
22+
23+
#include <optional>
24+
25+
namespace hazard_status_converter
26+
{
27+
28+
struct RootModeStatus
29+
{
30+
enum class Mode {
31+
UNKNOWN,
32+
AUTO,
33+
REMOTE,
34+
LOCAL,
35+
};
36+
Mode mode;
37+
bool ignore;
38+
};
39+
40+
class ModeInterface
41+
{
42+
public:
43+
explicit ModeInterface(rclcpp::Node & node);
44+
RootModeStatus get_root() const;
45+
46+
private:
47+
using OperationModeState = autoware_adapi_v1_msgs::msg::OperationModeState;
48+
using AutowareState = autoware_system_msgs::msg::AutowareState;
49+
rclcpp::Node & node_;
50+
rclcpp::Subscription<OperationModeState>::SharedPtr sub_operation_mode_state_;
51+
rclcpp::Subscription<AutowareState>::SharedPtr sub_autoware_state_;
52+
53+
std::optional<OperationModeState> operation_mode_state_;
54+
std::optional<AutowareState> autoware_state_;
55+
};
56+
57+
} // namespace hazard_status_converter
58+
59+
#endif // MODE_INTERFACE_HPP_

0 commit comments

Comments
 (0)