Skip to content

Commit c883230

Browse files
committed
Mode manager publishs inferred transitions
Mode manager is now publishing transitions that are inferred by the mode inference, i.e. state and mode transitions of systems, mode transitions of nodes. State transitions of nodes don't have to be published as lifecycle nodes do this on their own. #42 Signed-off-by: Arne Nordmann <arne.nordmann@de.bosch.com>
1 parent 412fe61 commit c883230

2 files changed

Lines changed: 99 additions & 42 deletions

File tree

system_modes/include/system_modes/mode_manager.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ class ModeManager : public rclcpp::Node
9090
const std::string &,
9191
const std::string &);
9292

93+
virtual void publish_transitions();
94+
9395
private:
9496
std::shared_ptr<ModeInference> mode_inference_;
9597

@@ -117,16 +119,23 @@ class ModeManager : public rclcpp::Node
117119
std::map<std::string, rclcpp::AsyncParametersClient::SharedPtr>
118120
param_change_clients_;
119121

120-
// Lifecycle transition request
122+
// Lifecycle transition publisher
123+
std::map<std::string, rclcpp::Publisher<lifecycle_msgs::msg::TransitionEvent>::SharedPtr>
124+
transition_pub_;
121125
std::map<std::string, rclcpp::Publisher<lifecycle_msgs::msg::TransitionEvent>::SharedPtr>
122126
state_request_pub_;
123127

124-
// Mode transition request publisher
128+
// Mode transition publisher
129+
std::map<std::string, rclcpp::Publisher<system_modes::msg::ModeEvent>::SharedPtr>
130+
mode_transition_pub_;
125131
std::map<std::string, rclcpp::Publisher<system_modes::msg::ModeEvent>::SharedPtr>
126132
mode_request_pub_;
127133

128134
// Remember states and modes of the systems
129135
std::map<std::string, StateAndMode> current_modes_;
136+
137+
// Timer to check for and publish recent transitions
138+
rclcpp::TimerBase::SharedPtr transition_timer_;
130139
};
131140

132141
} // namespace system_modes

system_modes/src/system_modes/mode_manager.cpp

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ ModeManager::ModeManager()
6262
state_change_srv_(), get_state_srv_(), states_srv_(),
6363
mode_change_srv_(), get_mode_srv_(), modes_srv_(),
6464
state_change_clients_(), mode_change_clients_(),
65-
state_request_pub_(), mode_request_pub_()
65+
transition_pub_(), state_request_pub_(),
66+
mode_transition_pub_(), mode_request_pub_()
6667
{
6768
declare_parameter("modelfile", rclcpp::ParameterValue(std::string("")));
6869
std::string model_path = get_parameter("modelfile").as_string();
@@ -90,6 +91,12 @@ ModeManager::ModeManager()
9091
RCLCPP_INFO(get_logger(), " - %s/get_mode", node.c_str());
9192
RCLCPP_INFO(get_logger(), " - %s/get_available_modes", node.c_str());
9293
}
94+
95+
transition_timer_ = this->create_wall_timer(
96+
1s,
97+
[this]() {
98+
this->publish_transitions();
99+
});
93100
}
94101

95102
std::shared_ptr<ModeInference>
@@ -101,122 +108,126 @@ ModeManager::inference()
101108
void
102109
ModeManager::add_system(const std::string & system)
103110
{
104-
string service_name;
111+
string topic_name;
105112

106113
// Lifecycle services
107-
service_name = system + "/change_state";
114+
topic_name = system + "/change_state";
108115
std::function<void(const std::shared_ptr<rmw_request_id_t>,
109116
const std::shared_ptr<ChangeState::Request>,
110117
std::shared_ptr<ChangeState::Response>)> state_change_callback =
111118
std::bind(&ModeManager::on_change_state, this, system, _2, _3);
112119
this->state_change_srv_[system] = this->create_service<ChangeState>(
113-
service_name,
120+
topic_name,
114121
state_change_callback);
115122

116-
service_name = system + "/get_state";
123+
topic_name = system + "/get_state";
117124
std::function<void(const std::shared_ptr<rmw_request_id_t>,
118125
const std::shared_ptr<GetState::Request>,
119126
std::shared_ptr<GetState::Response>)> state_get_callback =
120127
std::bind(&ModeManager::on_get_state, this, system, _3);
121128
this->get_state_srv_[system] = this->create_service<GetState>(
122-
service_name,
129+
topic_name,
123130
state_get_callback);
124131

125-
service_name = system + "/get_available_states";
132+
topic_name = system + "/get_available_states";
126133
std::function<void(const std::shared_ptr<rmw_request_id_t>,
127134
const std::shared_ptr<GetAvailableStates::Request>,
128135
std::shared_ptr<GetAvailableStates::Response>)> state_avail_callback =
129136
std::bind(&ModeManager::on_get_available_states, this, system, _3);
130137
this->states_srv_[system] = this->create_service<GetAvailableStates>(
131-
service_name,
138+
topic_name,
132139
state_avail_callback);
133140

134141
// Mode services
135-
service_name = system + "/change_mode";
142+
topic_name = system + "/change_mode";
136143
std::function<void(const std::shared_ptr<rmw_request_id_t>,
137144
const std::shared_ptr<ChangeMode::Request>,
138145
std::shared_ptr<ChangeMode::Response>)> mode_change_callback =
139146
std::bind(&ModeManager::on_change_mode, this, system, _2, _3);
140147
this->mode_change_srv_[system] = this->create_service<ChangeMode>(
141-
service_name,
148+
topic_name,
142149
mode_change_callback);
143150

144-
service_name = system + "/get_mode";
151+
topic_name = system + "/get_mode";
145152
std::function<void(const std::shared_ptr<rmw_request_id_t>,
146153
const std::shared_ptr<GetMode::Request>,
147154
std::shared_ptr<GetMode::Response>)> mode_get_callback =
148155
std::bind(&ModeManager::on_get_mode, this, system, _3);
149156
this->get_mode_srv_[system] =
150157
this->create_service<system_modes::srv::GetMode>(
151-
service_name,
158+
topic_name,
152159
mode_get_callback);
153160

154-
service_name = system + "/get_available_modes";
161+
topic_name = system + "/get_available_modes";
155162
std::function<void(const std::shared_ptr<rmw_request_id_t>,
156163
const std::shared_ptr<GetAvailableModes::Request>,
157164
std::shared_ptr<GetAvailableModes::Response>)> mode_avail_callback =
158165
std::bind(&ModeManager::on_get_available_modes, this, system, _3);
159166
this->modes_srv_[system] = this->create_service<GetAvailableModes>(
160-
service_name,
167+
topic_name,
161168
mode_avail_callback);
162169

163170
// Lifecycle change clients
164-
service_name = system + "/change_state";
165-
this->state_change_clients_[system] = this->create_client<ChangeState>(service_name);
171+
topic_name = system + "/change_state";
172+
this->state_change_clients_[system] = this->create_client<ChangeState>(topic_name);
166173

167174
// Mode change clients
168-
service_name = system + "/change_mode";
169-
this->mode_change_clients_[system] = this->create_client<ChangeMode>(service_name);
170-
171-
// State request publisher
172-
service_name = system + "/transition_request_info";
173-
this->state_request_pub_[system] = this->create_publisher<TransitionEvent>(service_name, 1);
174-
175-
// Mode request publisher
176-
service_name = system + "/mode_request_info";
177-
this->mode_request_pub_[system] = this->create_publisher<ModeEvent>(service_name, 1);
175+
topic_name = system + "/change_mode";
176+
this->mode_change_clients_[system] = this->create_client<ChangeMode>(topic_name);
177+
178+
// Lifecycle transition publisher
179+
topic_name = system + "/transition_event";
180+
this->transition_pub_[system] = this->create_publisher<TransitionEvent>(topic_name, 1);
181+
topic_name = system + "/transition_request_info";
182+
this->state_request_pub_[system] = this->create_publisher<TransitionEvent>(topic_name, 1);
183+
184+
// Mode transition publisher
185+
topic_name = system + "/mode_event";
186+
this->mode_transition_pub_[system] = this->create_publisher<ModeEvent>(topic_name, 1);
187+
topic_name = system + "/mode_request_info";
188+
this->mode_request_pub_[system] = this->create_publisher<ModeEvent>(topic_name, 1);
178189
}
179190

180191
void
181192
ModeManager::add_node(const std::string & node)
182193
{
183-
string service_name;
194+
string topic_name;
184195

185196
// Mode services
186-
service_name = node + "/change_mode";
197+
topic_name = node + "/change_mode";
187198
std::function<void(const std::shared_ptr<rmw_request_id_t>,
188199
const std::shared_ptr<ChangeMode::Request>,
189200
std::shared_ptr<ChangeMode::Response>)> mode_change_callback =
190201
std::bind(&ModeManager::on_change_mode, this, node, _2, _3);
191202
this->mode_change_srv_[node] = this->create_service<ChangeMode>(
192-
service_name,
203+
topic_name,
193204
mode_change_callback);
194205

195-
service_name = node + "/get_mode";
206+
topic_name = node + "/get_mode";
196207
std::function<void(const std::shared_ptr<rmw_request_id_t>,
197208
const std::shared_ptr<GetMode::Request>,
198209
std::shared_ptr<GetMode::Response>)> mode_get_callback =
199210
std::bind(&ModeManager::on_get_mode, this, node, _3);
200211
this->get_mode_srv_[node] =
201212
this->create_service<system_modes::srv::GetMode>(
202-
service_name,
213+
topic_name,
203214
mode_get_callback);
204215

205-
service_name = node + "/get_available_modes";
216+
topic_name = node + "/get_available_modes";
206217
std::function<void(const std::shared_ptr<rmw_request_id_t>,
207218
const std::shared_ptr<GetAvailableModes::Request>,
208219
std::shared_ptr<GetAvailableModes::Response>)> mode_avail_callback =
209220
std::bind(&ModeManager::on_get_available_modes, this, node, _3);
210221
this->modes_srv_[node] = this->create_service<GetAvailableModes>(
211-
service_name,
222+
topic_name,
212223
mode_avail_callback);
213224

214225
// Lifecycle change clients
215-
service_name = node + "/change_state";
216-
this->state_change_clients_[node] = this->create_client<ChangeState>(service_name);
226+
topic_name = node + "/change_state";
227+
this->state_change_clients_[node] = this->create_client<ChangeState>(topic_name);
217228

218229
// Parameter change clients
219-
service_name = node + "/set_parameters_atomically";
230+
topic_name = node + "/set_parameters_atomically";
220231
this->param_change_clients_[node] = std::make_shared<rclcpp::AsyncParametersClient>(
221232
this->get_node_base_interface(),
222233
this->get_node_topics_interface(),
@@ -225,12 +236,14 @@ ModeManager::add_node(const std::string & node)
225236
node);
226237

227238
// State request publisher
228-
service_name = node + "/transition_request_info";
229-
this->state_request_pub_[node] = this->create_publisher<TransitionEvent>(service_name, 1);
239+
topic_name = node + "/transition_request_info";
240+
this->state_request_pub_[node] = this->create_publisher<TransitionEvent>(topic_name, 1);
230241

231242
// Mode request publisher
232-
service_name = node + "/mode_request_info";
233-
this->mode_request_pub_[node] = this->create_publisher<ModeEvent>(service_name, 1);
243+
topic_name = node + "/mode_event";
244+
this->mode_transition_pub_[node] = this->create_publisher<ModeEvent>(topic_name, 1);
245+
topic_name = node + "/mode_request_info";
246+
this->mode_request_pub_[node] = this->create_publisher<ModeEvent>(topic_name, 1);
234247
}
235248

236249
void
@@ -547,4 +560,39 @@ ModeManager::change_part_mode(const string & node, const string & mode)
547560
}
548561
}
549562

563+
void
564+
ModeManager::publish_transitions()
565+
{
566+
auto transitions = mode_inference_->infer_transitions();
567+
auto systems = mode_inference_->get_systems();
568+
569+
for (auto dev = transitions.begin(); dev != transitions.end(); dev++) {
570+
auto part = dev->first;
571+
auto from = dev->second.first;
572+
auto to = dev->second.second;
573+
RCLCPP_DEBUG(
574+
this->get_logger(),
575+
"publish transition of %s from %s to %s.\n",
576+
part.c_str(), from.as_string().c_str(), to.as_string().c_str());
577+
578+
if (std::find(systems.begin(), systems.end(), part) != systems.end() &&
579+
from.state != to.state)
580+
{
581+
auto info = std::make_shared<TransitionEvent>();
582+
info->start_state.id = from.state;
583+
info->start_state.label = state_label_(from.state);
584+
info->goal_state.id = to.state;
585+
info->goal_state.label = state_label_(to.state);
586+
this->transition_pub_[part]->publish(TransitionEvent());
587+
this->transition_pub_[part]->publish(*info);
588+
}
589+
if (from.mode.compare(to.mode) != 0) {
590+
auto info = std::make_shared<ModeEvent>();
591+
info->start_mode.label = from.mode;
592+
info->goal_mode.label = to.mode;
593+
this->mode_transition_pub_[part]->publish(*info);
594+
}
595+
}
596+
}
597+
550598
} // namespace system_modes

0 commit comments

Comments
 (0)