Skip to content

Commit 52f26c1

Browse files
committed
(dev) cleanup for c-statemachine
(dev) cleanup for c-statemachine
1 parent c79bc6d commit 52f26c1

File tree

5 files changed

+257
-106
lines changed

5 files changed

+257
-106
lines changed

rclcpp_lifecycle/include/rcl_lifecycle/lifecycle_state.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,10 @@ typedef struct LIFECYCLE_EXPORT _rcl_state_t
5454
*/
5555
typedef struct LIFECYCLE_EXPORT _rcl_state_transition_t
5656
{
57-
rcl_state_t transition_index;
58-
//rcl_state_t transition_state;
59-
// function callback
57+
rcl_state_t transition_state;
6058
void* callback;
61-
rcl_state_t goal;
59+
rcl_state_t* start;
60+
rcl_state_t* goal;
6261
} rcl_state_transition_t;
6362

6463
/**
@@ -71,7 +70,6 @@ typedef struct LIFECYCLE_EXPORT _rcl_state_transition_t
7170
*/
7271
typedef struct LIFECYCLE_EXPORT _rcl_state_machine_t
7372
{
74-
// current state of the lifecycle
7573
rcl_state_t* current_state;
7674
rcl_transition_map_t transition_map;
7775
} rcl_state_machine_t;
@@ -82,10 +80,17 @@ typedef struct LIFECYCLE_EXPORT _rcl_state_machine_t
8280
* @brief traverses the transition map of the given
8381
* state machine to find if there is a transition from the
8482
* current state to the specified goal state
83+
* @return the transition state which is valid
84+
* NULL if not available
8585
*/
86-
bool
86+
const rcl_state_transition_t*
8787
LIFECYCLE_EXPORT rcl_is_valid_transition(rcl_state_machine_t* state_machine, const rcl_state_t* goal_state);
8888

89+
const rcl_state_transition_t*
90+
LIFECYCLE_EXPORT rcl_get_registered_transition_by_index(rcl_state_machine_t* state_machine, unsigned int transition_state_index);
91+
const rcl_state_transition_t*
92+
LIFECYCLE_EXPORT rcl_get_registered_transition_by_label(rcl_state_machine_t* state_machine, const char* transition_state_label);
93+
8994
rcl_state_t
9095
LIFECYCLE_EXPORT rcl_create_state(unsigned int state, char* label);
9196

rclcpp_lifecycle/include/rcl_lifecycle/transition_map.h

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,50 +24,79 @@ extern "C"
2424
#endif
2525

2626
typedef struct _rcl_state_t rcl_state_t;
27-
2827
typedef struct _rcl_state_transition_t rcl_state_transition_t;
2928

3029
/**
31-
* @brief The actual data array
32-
* within the map. One array belongs
33-
* to one label within the map.
30+
* @brief All transitions which are
31+
* valid associations for a primary state.
32+
* One array belongs to one primary state
33+
* within the map.
3434
*/
35-
typedef struct LIFECYCLE_EXPORT _data_array
35+
typedef struct LIFECYCLE_EXPORT _transition_array
3636
{
3737
rcl_state_transition_t* transitions;
3838
unsigned int size;
3939
} rcl_transition_array_t;
4040

41-
/**
42-
* @brief helper index for keeping
43-
* track of the map content
44-
*/
45-
typedef struct LIFECYCLE_EXPORT _index
46-
{
47-
unsigned int index;
48-
const char* label;
49-
} rcl_transition_map_index_t;
50-
5141
/**
5242
* @brief stores an array of transitions
5343
* index by a start state
5444
*/
5545
typedef struct LIFECYCLE_EXPORT _map
5646
{
5747
//rcl_state_t* state_index;
58-
rcl_transition_map_index_t* state_index;
48+
// associative array between primary state and their respective transitions
49+
// 1 ps -> 1 transition_array
50+
rcl_state_t* primary_states;
5951
rcl_transition_array_t* transition_arrays;
6052
unsigned int size;
6153
} rcl_transition_map_t;
6254

55+
LIFECYCLE_EXPORT
56+
void
57+
rcl_register_primary_state(rcl_transition_map_t* m, rcl_state_t primary_state);
58+
59+
/**
60+
* @brief appends a transition in a map
61+
* the classification is based on the start state
62+
* within the given transition
63+
*/
64+
LIFECYCLE_EXPORT
65+
void
66+
rcl_register_transition_by_state(rcl_transition_map_t* m, rcl_state_t start, rcl_state_t goal, rcl_state_transition_t transition);
67+
6368
/**
6469
* @brief appends a transition in a map
6570
* the classification is based on the start state
6671
* within the given transition
6772
*/
6873
LIFECYCLE_EXPORT
6974
void
70-
rcl_append_transition(rcl_transition_map_t* m, rcl_state_t state, rcl_state_transition_t transition);
75+
rcl_register_transition_by_label(rcl_transition_map_t* m, const char* start_label, const char* goal_label, rcl_state_transition_t transition);
76+
77+
/**
78+
* @brief appends a transition in a map
79+
* the classification is based on the start state
80+
* within the given transition
81+
*/
82+
LIFECYCLE_EXPORT
83+
void
84+
rcl_register_transition_by_index(rcl_transition_map_t* m, unsigned int start_index, unsigned int goal_index, rcl_state_transition_t transition);
85+
86+
/**
87+
* @brief gets the registered primary state based on a label
88+
* @return primary state pointer, NULL if not found
89+
*/
90+
LIFECYCLE_EXPORT
91+
rcl_state_t*
92+
rcl_get_primary_state_by_label(rcl_transition_map_t* m, const char* label);
93+
/**
94+
* @brief gets the registered primary state based on a index
95+
* @return primary state pointer, NULL if not found
96+
*/
97+
LIFECYCLE_EXPORT
98+
rcl_state_t*
99+
rcl_get_primary_state_by_index(rcl_transition_map_t* m, unsigned int index);
71100

72101
/**
73102
* @brief gets all transitions based on a label
@@ -89,7 +118,7 @@ rcl_get_transitions_by_index(rcl_transition_map_t* m, unsigned int index);
89118
*/
90119
LIFECYCLE_EXPORT
91120
void
92-
rcl_print_transition_array(const rcl_transition_array_t* da);
121+
rcl_print_transition_array(const rcl_transition_array_t* transition_array);
93122
LIFECYCLE_EXPORT
94123
void
95124
rcl_print_transition_map(const rcl_transition_map_t* m);

rclcpp_lifecycle/src/default_state_machine.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ rcl_create_state(unsigned int index, char* label)
3535
}
3636

3737
rcl_state_transition_t
38-
rcl_create_state_transition(rcl_state_t index, rcl_state_t goal)
38+
rcl_create_state_transition(unsigned int index, const char* label)
3939
{
40-
rcl_state_transition_t ret_transition = {.transition_index = index, NULL, .goal = goal};
40+
rcl_state_transition_t ret_transition = {{.index = index, .label = label}, NULL, NULL, NULL};
4141
return ret_transition;
4242
}
4343

@@ -47,39 +47,39 @@ rcl_state_machine_t
4747
rcl_get_default_state_machine()
4848
{
4949
rcl_state_machine_t state_machine;
50-
state_machine.transition_map.state_index = NULL;
50+
state_machine.transition_map.primary_states = NULL;
5151
state_machine.transition_map.transition_arrays = NULL;
5252
state_machine.transition_map.size = 0;
5353

5454
// set default state as unconfigured
55-
state_machine.current_state = &rcl_state_unconfigured;
55+
//state_machine.current_state = &rcl_state_unconfigured;
5656

57-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_unconfigured_inactive
58-
= {rcl_state_configuring, NULL, rcl_state_inactive};
59-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_unconfigured_finalized
60-
= {rcl_state_shuttingdown, NULL, rcl_state_finalized};
57+
rcl_state_transition_t rcl_transition_configuring
58+
= rcl_create_state_transition(rcl_state_configuring.index, rcl_state_configuring.label);
59+
rcl_state_transition_t rcl_transition_shuttingdown
60+
= rcl_create_state_transition(rcl_state_shuttingdown.index, rcl_state_shuttingdown.label);
61+
rcl_state_transition_t rcl_transition_cleaningup
62+
= rcl_create_state_transition(rcl_state_cleaningup.index, rcl_state_cleaningup.label);
63+
rcl_state_transition_t rcl_transition_activating
64+
= rcl_create_state_transition(rcl_state_activating.index, rcl_state_activating.label);
65+
rcl_state_transition_t rcl_transition_deactivating
66+
= rcl_create_state_transition(rcl_state_deactivating.index, rcl_state_deactivating.label);;
6167

62-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_inactive_unconfigured
63-
= {rcl_state_cleaningup, NULL, rcl_state_unconfigured};
64-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_inactive_finalized
65-
= {rcl_state_shuttingdown, NULL, rcl_state_finalized};
66-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_inactive_active
67-
= {rcl_state_activating, NULL, rcl_state_active};
68-
69-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_active_inactive
70-
= {rcl_state_deactivating, NULL, rcl_state_inactive};
71-
rcl_state_transition_t LIFECYCLE_EXPORT rcl_transition_active_finalized
72-
= {rcl_state_shuttingdown, NULL, rcl_state_finalized};
68+
rcl_register_primary_state(&state_machine.transition_map, rcl_state_unconfigured);
69+
rcl_register_primary_state(&state_machine.transition_map, rcl_state_inactive);
70+
rcl_register_primary_state(&state_machine.transition_map, rcl_state_active);
71+
rcl_register_primary_state(&state_machine.transition_map, rcl_state_finalized);
7372

7473
// add transitions to map
75-
rcl_append_transition(&state_machine.transition_map, rcl_state_unconfigured, rcl_transition_unconfigured_inactive);
76-
rcl_append_transition(&state_machine.transition_map, rcl_state_unconfigured, rcl_transition_unconfigured_finalized);
77-
rcl_append_transition(&state_machine.transition_map, rcl_state_inactive, rcl_transition_inactive_unconfigured);
78-
rcl_append_transition(&state_machine.transition_map, rcl_state_inactive, rcl_transition_inactive_finalized);
79-
rcl_append_transition(&state_machine.transition_map, rcl_state_inactive, rcl_transition_inactive_active);
80-
rcl_append_transition(&state_machine.transition_map, rcl_state_active, rcl_transition_active_inactive);
81-
rcl_append_transition(&state_machine.transition_map, rcl_state_active, rcl_transition_active_finalized);
74+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_unconfigured, rcl_state_inactive, rcl_transition_configuring);
75+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_inactive, rcl_state_unconfigured, rcl_transition_cleaningup);
76+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_unconfigured, rcl_state_finalized, rcl_transition_shuttingdown);
77+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_inactive, rcl_state_finalized, rcl_transition_shuttingdown);
78+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_inactive, rcl_state_active, rcl_transition_activating);
79+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_active, rcl_state_inactive, rcl_transition_deactivating);
80+
rcl_register_transition_by_state(&state_machine.transition_map, rcl_state_active, rcl_state_finalized, rcl_transition_shuttingdown);
8281

82+
state_machine.current_state = &state_machine.transition_map.primary_states[0]; // set to first entry
8383
return state_machine;
8484
}
8585

rclcpp_lifecycle/src/lifecycle_state.c

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,73 @@ extern "C"
1717
{
1818
#endif
1919

20-
#include "rcl_lifecycle/lifecycle_state.h"
20+
#include <stdlib.h>
21+
#include <string.h>
2122

22-
typedef rcl_state_transition_t rcl_transition;
23-
typedef rcl_state_t rcl_state;
23+
#include "rcl_lifecycle/lifecycle_state.h"
2424

25-
bool
25+
const rcl_state_transition_t*
2626
rcl_is_valid_transition(rcl_state_machine_t* state_machine, const rcl_state_t* goal_state)
2727
{
28-
rcl_transition_array_t* all_transitions = rcl_get_transitions_by_label(&state_machine->transition_map, state_machine->current_state->label);
28+
unsigned int current_index = state_machine->current_state->index;
29+
const rcl_transition_array_t* valid_transitions = rcl_get_transitions_by_index(&state_machine->transition_map, current_index);
30+
for (unsigned int i=0; i<valid_transitions->size; ++i)
31+
{
32+
if (valid_transitions->transitions[i].goal->index == goal_state->index)
33+
{
34+
return &valid_transitions->transitions[i];
35+
}
36+
}
37+
return NULL;
38+
}
2939

30-
for (unsigned int i=0; i<all_transitions->size; ++i)
40+
const rcl_state_transition_t*
41+
rcl_get_registered_transition_by_index(rcl_state_machine_t* state_machine, unsigned int transition_state_index)
42+
{
43+
// extensive search approach
44+
// TODO(karsten1987) can be improved by having a separate array for "registered transition"
45+
const rcl_transition_map_t* map = &state_machine->transition_map;
46+
for (unsigned int i=0; i<map->size; ++i)
3147
{
32-
if (all_transitions->transitions[i].goal.index == goal_state->index)
48+
for (unsigned int j=0; j<map->transition_arrays[i].size; ++j)
3349
{
34-
return true;
50+
if (map->transition_arrays[i].transitions[j].transition_state.index == transition_state_index)
51+
{
52+
return &map->transition_arrays[i].transitions[j];
53+
}
3554
}
3655
}
37-
return false;
56+
return NULL;
57+
}
58+
59+
const rcl_state_transition_t*
60+
rcl_get_registered_transition_by_label(rcl_state_machine_t* state_machine, const char* transition_state_label)
61+
{
62+
// extensive search approach
63+
// TODO(karsten1987) can be improved by having a separate array for "registered transition"
64+
const rcl_transition_map_t* map = &state_machine->transition_map;
65+
for (unsigned int i=0; i<map->size; ++i)
66+
{
67+
for (unsigned int j=0; j<map->transition_arrays[i].size; ++j)
68+
{
69+
if (strcmp(map->transition_arrays[i].transitions[j].transition_state.label, transition_state_label) == 0)
70+
{
71+
return &map->transition_arrays[i].transitions[j];
72+
}
73+
}
74+
}
75+
return NULL;
3876
}
3977

4078
void
4179
rcl_register_callback(rcl_state_machine_t* state_machine, unsigned int state_index, unsigned int transition_index, bool(*fcn)(void))
4280
{
43-
rcl_transition_array_t* all_transitions = rcl_get_transitions_by_index(&state_machine->transition_map, state_index);
44-
45-
for (unsigned int i=0; i<all_transitions->size; ++i)
81+
rcl_transition_array_t* transitions = rcl_get_transitions_by_index(&state_machine->transition_map, state_index);
82+
for (unsigned int i=0; i<transitions->size; ++i)
4683
{
47-
if (all_transitions->transitions[i].transition_index.index == transition_index)
84+
if (transitions->transitions[i].transition_state.index == transition_index)
4885
{
49-
all_transitions->transitions[i].callback = fcn;
86+
transitions->transitions[i].callback = fcn;
5087
}
5188
}
5289
}
@@ -56,18 +93,19 @@ rcl_register_callback(rcl_state_machine_t* state_machine, unsigned int state_ind
5693
bool
5794
rcl_invoke_transition(rcl_state_machine_t* state_machine, rcl_state_t transition_index)
5895
{
59-
rcl_transition_array_t* all_transitions = rcl_get_transitions_by_index(&state_machine->transition_map, state_machine->current_state->index);
96+
unsigned int current_index = state_machine->current_state->index;
97+
rcl_transition_array_t* transitions = rcl_get_transitions_by_index(&state_machine->transition_map, current_index);
6098

61-
if (!all_transitions)
99+
if (transitions == NULL)
62100
{
63101
return false;
64102
}
65103
bool success = false;
66-
for (unsigned int i=0; i<all_transitions->size; ++i)
104+
for (unsigned int i=0; i<transitions->size; ++i)
67105
{
68-
if (all_transitions->transitions[i].transition_index.index == transition_index.index)
106+
if (transitions->transitions[i].transition_state.index == transition_index.index)
69107
{
70-
((bool(*)(void))all_transitions->transitions[i].callback)();
108+
((bool(*)(void))transitions->transitions[i].callback)();
71109
success = true;
72110
// break here ?! would allow only one to one transitions
73111
}

0 commit comments

Comments
 (0)