@@ -27,16 +27,18 @@ CommandModeDeciderBase::CommandModeDeciderBase(const rclcpp::NodeOptions & optio
27
27
: Node(" command_mode_decider" , options)
28
28
{
29
29
is_modes_ready_ = false ;
30
- target_operation_mode_ = declare_parameter<std::string>(" initial_operation_mode" );
31
- target_mrm_ = std::string ();
32
- curr_command_mode_ = std::string ();
30
+ command_mode_status_.init (declare_parameter<std::vector<std::string>>(" command_modes" ));
33
31
command_mode_request_stamp_ = std::nullopt;
34
32
35
- const auto command_modes = declare_parameter<std::vector<std::string>>(" command_modes" );
36
- for (const auto & mode : command_modes) {
37
- // NOTE: The mode field will be used to check topic reception.
38
- command_mode_status_[mode] = CommandModeStatusItem ();
39
- }
33
+ request_.autoware_control = true ;
34
+ request_.operation_mode = declare_parameter<std::string>(" initial_operation_mode" );
35
+ request_.mrm = std::string ();
36
+
37
+ decided_.autoware_control = true ;
38
+ decided_.command_mode = std::string ();
39
+
40
+ current_.autoware_control = true ;
41
+ current_.command_mode = std::string ();
40
42
41
43
using std::placeholders::_1;
42
44
using std::placeholders::_2;
@@ -54,7 +56,12 @@ CommandModeDeciderBase::CommandModeDeciderBase(const rclcpp::NodeOptions & optio
54
56
srv_operation_mode_ = create_service<ChangeOperationMode>(
55
57
" ~/operation_mode/change_operation_mode" ,
56
58
std::bind (&CommandModeDeciderBase::on_change_operation_mode, this , _1, _2));
57
- srv_request_mrm_ = create_service<RequestMrm>(
59
+ srv_autoware_control_ = create_service<ChangeAutowareControl>(
60
+ " ~/operation_mode/change_autoware_control" ,
61
+ std::bind (&CommandModeDeciderBase::on_change_autoware_control, this , _1, _2));
62
+
63
+ pub_mrm_state_ = create_publisher<MrmState>(" ~/mrm/state" , rclcpp::QoS (1 ));
64
+ srv_mrm_request_ = create_service<RequestMrm>(
58
65
" ~/mrm/request" , std::bind (&CommandModeDeciderBase::on_request_mrm, this , _1, _2));
59
66
60
67
const auto period = rclcpp::Rate (declare_parameter<double >(" update_rate" )).period ();
@@ -63,11 +70,13 @@ CommandModeDeciderBase::CommandModeDeciderBase(const rclcpp::NodeOptions & optio
63
70
64
71
void CommandModeDeciderBase::on_status (const CommandModeStatus & msg)
65
72
{
73
+ // Update command mode status.
66
74
for (const auto & item : msg.items ) {
67
- const auto iter = command_mode_status_.find (item.mode );
68
- if (iter == command_mode_status_.end ()) continue ;
69
- iter->second = item;
75
+ command_mode_status_.set (item);
70
76
}
77
+
78
+ // Check if all command mode status items are ready.
79
+ is_modes_ready_ = is_modes_ready_ ? true : command_mode_status_.ready ();
71
80
update_command_mode ();
72
81
}
73
82
@@ -77,8 +86,10 @@ void CommandModeDeciderBase::on_timer()
77
86
return ;
78
87
}
79
88
89
+ /*
80
90
const auto & status = command_mode_status_.at(curr_command_mode_);
81
91
(void)status;
92
+ */
82
93
83
94
/*
84
95
if (mode.status.activation) {
@@ -97,29 +108,88 @@ void CommandModeDeciderBase::on_timer()
97
108
*/
98
109
}
99
110
111
+ void CommandModeDeciderBase::update_command_mode ()
112
+ {
113
+ if (!is_modes_ready_) {
114
+ return ;
115
+ }
116
+
117
+ const auto stamp = now ();
118
+
119
+ // Decide target command mode.
120
+ bool is_command_mode_changed = false ;
121
+ {
122
+ const auto next_mode = decide_command_mode ();
123
+ const auto curr_mode = decided_.command_mode ;
124
+ is_command_mode_changed = curr_mode != next_mode;
125
+
126
+ if (is_command_mode_changed) {
127
+ const auto curr_text = " '" + curr_mode + " '" ;
128
+ const auto next_text = " '" + next_mode + " '" ;
129
+ RCLCPP_INFO_STREAM (get_logger (), " mode changed: " << curr_text << " -> " << next_text);
130
+ }
131
+ decided_.command_mode = next_mode;
132
+ }
133
+
134
+ // Request command mode to switcher nodes.
135
+ if (is_command_mode_changed) {
136
+ CommandModeRequest msg;
137
+ msg.stamp = stamp;
138
+ msg.ctrl = decided_.autoware_control ;
139
+ msg.mode = decided_.command_mode ;
140
+ pub_command_mode_request_->publish (msg);
141
+
142
+ command_mode_request_stamp_ = stamp;
143
+ }
144
+
145
+ // Update operation mode status.
146
+ const auto is_available = [this ](const auto & mode) {
147
+ return command_mode_status_.get (mode).available ;
148
+ };
149
+ OperationModeState state;
150
+ state.stamp = stamp;
151
+ state.mode = text_to_mode (decided_.command_mode );
152
+ state.is_autoware_control_enabled = true ; // TODO(Takagi, Isamu): subscribe
153
+ state.is_in_transition = false ; // TODO(Takagi, Isamu): check status is enabled
154
+ state.is_stop_mode_available = is_available (" stop" );
155
+ state.is_autonomous_mode_available = is_available (" autonomous" );
156
+ state.is_local_mode_available = is_available (" local" );
157
+ state.is_remote_mode_available = is_available (" remote" );
158
+ pub_operation_mode_->publish (state);
159
+ }
160
+
161
+ void CommandModeDeciderBase::on_change_autoware_control (
162
+ ChangeAutowareControl::Request::SharedPtr req, ChangeAutowareControl::Response::SharedPtr res)
163
+ {
164
+ // TODO(Takagi, Isamu): Commonize on_change_operation_mode and on_request_mrm.
165
+ // TODO(Takagi, Isamu): Check is_modes_ready_.
166
+ (void )req;
167
+ (void )res;
168
+ }
169
+
100
170
void CommandModeDeciderBase::on_change_operation_mode (
101
171
ChangeOperationMode::Request::SharedPtr req, ChangeOperationMode::Response::SharedPtr res)
102
172
{
103
173
// TODO(Takagi, Isamu): Commonize on_change_operation_mode and on_request_mrm.
174
+ // TODO(Takagi, Isamu): Check is_modes_ready_.
104
175
105
176
const auto mode = mode_to_text (req->mode );
106
- const auto iter = command_mode_status_.find (mode);
107
- if (iter == command_mode_status_. end ()) {
177
+ const auto item = command_mode_status_.get (mode);
178
+ if (item. mode . empty ()) {
108
179
RCLCPP_WARN_STREAM (get_logger (), " invalid mode name: " << mode);
109
180
res->status .success = false ;
110
181
res->status .message = " invalid mode name: " + mode;
111
182
return ;
112
183
}
113
184
114
- const auto status = iter->second ;
115
- if (!status.available ) {
185
+ if (!item.available ) {
116
186
RCLCPP_WARN_STREAM (get_logger (), " mode is not available: " << mode);
117
187
res->status .success = false ;
118
188
res->status .message = " mode is not available: " + mode;
119
189
return ;
120
190
}
121
191
122
- target_operation_mode_ = mode;
192
+ request_. operation_mode = mode;
123
193
res->status .success = true ;
124
194
125
195
update_command_mode ();
@@ -129,82 +199,28 @@ void CommandModeDeciderBase::on_request_mrm(
129
199
RequestMrm::Request::SharedPtr req, RequestMrm::Response::SharedPtr res)
130
200
{
131
201
// TODO(Takagi, Isamu): Commonize on_change_operation_mode and on_request_mrm.
202
+ // TODO(Takagi, Isamu): Check is_modes_ready_.
132
203
133
204
const auto mode = req->name ;
134
- const auto iter = command_mode_status_.find (mode);
135
- if (iter == command_mode_status_. end ()) {
205
+ const auto item = command_mode_status_.get (mode);
206
+ if (item. mode . empty ()) {
136
207
RCLCPP_WARN_STREAM (get_logger (), " invalid mode name: " << mode);
137
208
res->status .success = false ;
138
209
res->status .message = " invalid mode name: " + mode;
139
210
return ;
140
211
}
141
212
142
- const auto status = iter->second ;
143
- if (!status.available ) {
213
+ if (!item.available ) {
144
214
RCLCPP_WARN_STREAM (get_logger (), " mode is not available: " << mode);
145
215
res->status .success = false ;
146
216
res->status .message = " mode is not available: " + mode;
147
217
return ;
148
218
}
149
219
150
- target_mrm_ = mode;
220
+ request_. mrm = mode;
151
221
res->status .success = true ;
152
222
153
223
update_command_mode ();
154
224
}
155
225
156
- void CommandModeDeciderBase::update_command_mode ()
157
- {
158
- if (!is_modes_ready_) {
159
- for (const auto & [mode, status] : command_mode_status_) {
160
- if (status.mode .empty ()) {
161
- return ;
162
- }
163
- }
164
- is_modes_ready_ = true ;
165
- }
166
-
167
- const auto stamp = now ();
168
-
169
- // Decide target command mode.
170
- bool is_command_mode_changed = false ;
171
- {
172
- const auto next_command_mode = decide_command_mode ();
173
- is_command_mode_changed = curr_command_mode_ != next_command_mode;
174
- if (is_command_mode_changed) {
175
- const auto curr_text = " '" + curr_command_mode_ + " '" ;
176
- const auto next_text = " '" + next_command_mode + " '" ;
177
- RCLCPP_INFO_STREAM (
178
- get_logger (), " command mode changed: " << curr_text << " -> " << next_text);
179
- }
180
- curr_command_mode_ = next_command_mode;
181
- }
182
-
183
- // Request command mode to switcher nodes.
184
- if (is_command_mode_changed) {
185
- CommandModeRequest msg;
186
- msg.stamp = stamp;
187
- msg.mode = curr_command_mode_;
188
- pub_command_mode_request_->publish (msg);
189
-
190
- command_mode_request_stamp_ = stamp;
191
- }
192
-
193
- // Update operation mode status.
194
- const auto is_available = [this ](const auto & mode) {
195
- const auto iter = command_mode_status_.find (mode);
196
- return iter == command_mode_status_.end () ? false : iter->second .available ;
197
- };
198
- OperationModeState state;
199
- state.stamp = stamp;
200
- state.mode = text_to_mode (target_operation_mode_);
201
- state.is_autoware_control_enabled = true ; // TODO(Takagi, Isamu): subscribe
202
- state.is_in_transition = false ; // TODO(Takagi, Isamu): check status is enabled
203
- state.is_stop_mode_available = is_available (" stop" );
204
- state.is_autonomous_mode_available = is_available (" autonomous" );
205
- state.is_local_mode_available = is_available (" local" );
206
- state.is_remote_mode_available = is_available (" remote" );
207
- pub_operation_mode_->publish (state);
208
- }
209
-
210
226
} // namespace autoware::command_mode_decider
0 commit comments