Skip to content

Commit 7b6ee8a

Browse files
authored
should pull valid transition before trying to change the state. (#2774)
Signed-off-by: Tomoya Fujita <Tomoya.Fujita@sony.com>
1 parent aae375b commit 7b6ee8a

2 files changed

Lines changed: 146 additions & 4 deletions

File tree

rclcpp_lifecycle/src/lifecycle_node_interface_impl.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,17 +539,24 @@ const State &
539539
LifecycleNode::LifecycleNodeInterfaceImpl::trigger_transition(uint8_t transition_id)
540540
{
541541
node_interfaces::LifecycleNodeInterface::CallbackReturn error;
542-
change_state(transition_id, error);
543-
(void) error;
544-
return get_current_state();
542+
return trigger_transition(transition_id, error);
545543
}
546544

547545
const State &
548546
LifecycleNode::LifecycleNodeInterfaceImpl::trigger_transition(
549547
uint8_t transition_id,
550548
node_interfaces::LifecycleNodeInterface::CallbackReturn & cb_return_code)
551549
{
552-
change_state(transition_id, cb_return_code);
550+
const rcl_lifecycle_transition_t * transition;
551+
{
552+
std::lock_guard<std::recursive_mutex> lock(state_machine_mutex_);
553+
554+
transition =
555+
rcl_lifecycle_get_transition_by_id(state_machine_.current_state, transition_id);
556+
}
557+
if (transition) {
558+
change_state(static_cast<uint8_t>(transition->id), cb_return_code);
559+
}
553560
return get_current_state();
554561
}
555562

rclcpp_lifecycle/test/test_lifecycle_node.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,146 @@ TEST_F(TestDefaultStateMachine, trigger_transition) {
282282
ASSERT_EQ(
283283
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
284284
rclcpp_lifecycle::Transition(Transition::TRANSITION_CLEANUP)).id());
285+
// supposed to fail because primary state is NOT active
286+
ASSERT_EQ(
287+
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
288+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVE_SHUTDOWN)).id());
289+
// supposed to fail because primary state is NOT inactive
290+
ASSERT_EQ(
291+
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
292+
rclcpp_lifecycle::Transition(Transition::TRANSITION_INACTIVE_SHUTDOWN)).id());
285293
ASSERT_EQ(
286294
State::PRIMARY_STATE_FINALIZED, test_node->trigger_transition(
287295
rclcpp_lifecycle::Transition(Transition::TRANSITION_UNCONFIGURED_SHUTDOWN)).id());
288296
}
289297

298+
TEST_F(TestDefaultStateMachine, trigger_transition_shutdown_id) {
299+
// test Transition::TRANSITION_ACTIVE_SHUTDOWN
300+
{
301+
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
302+
303+
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
304+
ASSERT_EQ(
305+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
306+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE)).id());
307+
ASSERT_EQ(
308+
State::PRIMARY_STATE_ACTIVE, test_node->trigger_transition(
309+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE)).id());
310+
ASSERT_EQ(
311+
State::PRIMARY_STATE_FINALIZED, test_node->trigger_transition(
312+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVE_SHUTDOWN)).id());
313+
}
314+
315+
// test Transition::TRANSITION_INACTIVE_SHUTDOWN
316+
{
317+
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
318+
319+
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
320+
ASSERT_EQ(
321+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
322+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE)).id());
323+
ASSERT_EQ(
324+
State::PRIMARY_STATE_ACTIVE, test_node->trigger_transition(
325+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE)).id());
326+
ASSERT_EQ(
327+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
328+
rclcpp_lifecycle::Transition(Transition::TRANSITION_DEACTIVATE)).id());
329+
// supposed to fail because primary state is NOT active
330+
ASSERT_EQ(
331+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
332+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVE_SHUTDOWN)).id());
333+
ASSERT_EQ(
334+
State::PRIMARY_STATE_FINALIZED, test_node->trigger_transition(
335+
rclcpp_lifecycle::Transition(Transition::TRANSITION_INACTIVE_SHUTDOWN)).id());
336+
}
337+
338+
// test Transition::TRANSITION_UNCONFIGURED_SHUTDOWN
339+
{
340+
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
341+
342+
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
343+
ASSERT_EQ(
344+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
345+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE)).id());
346+
ASSERT_EQ(
347+
State::PRIMARY_STATE_ACTIVE, test_node->trigger_transition(
348+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE)).id());
349+
ASSERT_EQ(
350+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
351+
rclcpp_lifecycle::Transition(Transition::TRANSITION_DEACTIVATE)).id());
352+
ASSERT_EQ(
353+
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
354+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CLEANUP)).id());
355+
// supposed to fail because primary state is NOT active
356+
ASSERT_EQ(
357+
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
358+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVE_SHUTDOWN)).id());
359+
// supposed to fail because primary state is NOT inactive
360+
ASSERT_EQ(
361+
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
362+
rclcpp_lifecycle::Transition(Transition::TRANSITION_INACTIVE_SHUTDOWN)).id());
363+
ASSERT_EQ(
364+
State::PRIMARY_STATE_FINALIZED, test_node->trigger_transition(
365+
rclcpp_lifecycle::Transition(Transition::TRANSITION_UNCONFIGURED_SHUTDOWN)).id());
366+
}
367+
}
368+
369+
TEST_F(TestDefaultStateMachine, trigger_transition_shutdown_label) {
370+
// test Transition::TRANSITION_ACTIVE_SHUTDOWN
371+
{
372+
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
373+
374+
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
375+
ASSERT_EQ(
376+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
377+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE)).id());
378+
ASSERT_EQ(
379+
State::PRIMARY_STATE_ACTIVE, test_node->trigger_transition(
380+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE)).id());
381+
ASSERT_EQ(
382+
State::PRIMARY_STATE_FINALIZED, test_node->shutdown().id());
383+
}
384+
385+
// test Transition::TRANSITION_INACTIVE_SHUTDOWN
386+
{
387+
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
388+
389+
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
390+
ASSERT_EQ(
391+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
392+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE)).id());
393+
ASSERT_EQ(
394+
State::PRIMARY_STATE_ACTIVE, test_node->trigger_transition(
395+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE)).id());
396+
ASSERT_EQ(
397+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
398+
rclcpp_lifecycle::Transition(Transition::TRANSITION_DEACTIVATE)).id());
399+
ASSERT_EQ(
400+
State::PRIMARY_STATE_FINALIZED, test_node->shutdown().id());
401+
}
402+
403+
// test Transition::TRANSITION_UNCONFIGURED_SHUTDOWN
404+
{
405+
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
406+
407+
EXPECT_EQ(State::PRIMARY_STATE_UNCONFIGURED, test_node->get_current_state().id());
408+
ASSERT_EQ(
409+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
410+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CONFIGURE)).id());
411+
ASSERT_EQ(
412+
State::PRIMARY_STATE_ACTIVE, test_node->trigger_transition(
413+
rclcpp_lifecycle::Transition(Transition::TRANSITION_ACTIVATE)).id());
414+
ASSERT_EQ(
415+
State::PRIMARY_STATE_INACTIVE, test_node->trigger_transition(
416+
rclcpp_lifecycle::Transition(Transition::TRANSITION_DEACTIVATE)).id());
417+
ASSERT_EQ(
418+
State::PRIMARY_STATE_UNCONFIGURED, test_node->trigger_transition(
419+
rclcpp_lifecycle::Transition(Transition::TRANSITION_CLEANUP)).id());
420+
ASSERT_EQ(
421+
State::PRIMARY_STATE_FINALIZED, test_node->shutdown().id());
422+
}
423+
}
424+
290425
TEST_F(TestDefaultStateMachine, trigger_transition_rcl_errors) {
291426
auto test_node = std::make_shared<EmptyLifecycleNode>("testnode");
292427

0 commit comments

Comments
 (0)