Skip to content

Commit

Permalink
[FC] A safer way of printing enum to string maps.
Browse files Browse the repository at this point in the history
Closes #310.
  • Loading branch information
stojadin2701 committed Sep 9, 2023
1 parent ec20a07 commit 98c1711
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 69 deletions.
12 changes: 6 additions & 6 deletions flight_computer/src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,8 @@ static void print_value_pointer(const char *cmdName, const cli_value_t *var, con
}
break;
case MODE_LOOKUP:
if (value < lookup_tables[var->config.lookup.table_index].value_count) {
cli_print(lookup_tables[var->config.lookup.table_index].values[value]);
if (static_cast<size_t>(value) < lookup_tables[var->config.lookup.table_index].size()) {
cli_print(lookup_tables[var->config.lookup.table_index][value]);
} else {
value_is_corrupted = true;
}
Expand Down Expand Up @@ -430,15 +430,15 @@ void cli_print_var_range(const cli_value_t *var) {
}
} break;
case (MODE_LOOKUP): {
const lookup_table_entry_t *tableEntry = &lookup_tables[var->config.lookup.table_index];
const EnumToStrMap &tableEntry = lookup_tables[var->config.lookup.table_index];
cli_print("Allowed values: ");
bool first_entry = true;
for (uint32_t i = 0; i < tableEntry->value_count; i++) {
if (tableEntry->values[i]) {
for (uint32_t i = 0; i < tableEntry.size(); i++) {
if (tableEntry[i]) {
if (!first_entry) {
cli_print(", ");
}
cli_printf("%s", tableEntry->values[i]);
cli_printf("%s", tableEntry[i]);
first_entry = false;
}
}
Expand Down
29 changes: 16 additions & 13 deletions flight_computer/src/cli/cli_commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@ static void cli_cmd_set(const char *cmd_name, char *args) {
} else {
tableIndex = val->config.lookup.table_index;
}
const lookup_table_entry_t *tableEntry = &lookup_tables[tableIndex];
const EnumToStrMap &tableEntry = lookup_tables[tableIndex];
bool matched = false;
for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry->value_count && !matched; tableValueIndex++) {
matched = tableEntry->values[tableValueIndex] && strcasecmp(tableEntry->values[tableValueIndex], eqptr) == 0;
for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry.size() && !matched; tableValueIndex++) {
matched = tableEntry[tableValueIndex] && strcasecmp(tableEntry[tableValueIndex], eqptr) == 0;

if (matched) {
cli_set_var(val, tableValueIndex);
Expand Down Expand Up @@ -410,7 +410,7 @@ static void cli_cmd_status(const char *cmd_name, char *args) {
if (new_enum > TOUCHDOWN || new_enum < CALIBRATING) {
new_enum = INVALID;
}
cli_printf("State: %s\n", fsm_map[new_enum]);
cli_printf("State: %s\n", GetStr(new_enum, fsm_map));
cli_printf("Voltage: %.2fV\n", (double)battery_voltage());
cli_printf("h: %.2fm, v: %.2fm/s, a: %.2fm/s^2", (double)task::global_state_estimation->GetEstimationOutput().height,
(double)task::global_state_estimation->GetEstimationOutput().velocity,
Expand Down Expand Up @@ -847,33 +847,36 @@ static void print_control_config() {
}

static void print_action_config() {
const lookup_table_entry_t *p_event_table = &lookup_tables[TABLE_EVENTS];
const lookup_table_entry_t *p_action_table = &lookup_tables[TABLE_ACTIONS];
const EnumToStrMap &p_event_table = lookup_tables[TABLE_EVENTS];
const EnumToStrMap &p_action_table = lookup_tables[TABLE_ACTIONS];

cli_printf("\n * ACTION CONFIGURATION *\n");
config_action_t action;
for (int i = 0; i < NUM_EVENTS; i++) {
int nr_actions = cc_get_num_actions((cats_event_e)(i));
const auto ev = static_cast<cats_event_e>(i);
int nr_actions = cc_get_num_actions(ev);
if (nr_actions > 0) {
cli_printf("\n%s\n", p_event_table->values[i]);
cli_printf("\n%s\n", GetStr(ev, p_event_table));
cli_printf(" Number of Actions: %d\n", nr_actions);
for (int j = 0; j < nr_actions; j++) {
cc_get_action((cats_event_e)(i), j, &action);
cli_printf(" %s - %d\n", p_action_table->values[action.action_idx], action.arg);
cc_get_action(ev, j, &action);
cli_printf(" %s - %d\n", p_action_table[action.action_idx], action.arg);
}
}
}
}

static void print_timer_config() {
const lookup_table_entry_t *p_event_table = &lookup_tables[TABLE_EVENTS];
const EnumToStrMap &p_event_table = lookup_tables[TABLE_EVENTS];

cli_printf("\n\n * TIMER CONFIGURATION *\n");
for (int i = 0; i < NUM_TIMERS; i++) {
if (global_cats_config.timers[i].duration > 0) {
cli_printf("\nTIMER %d\n", i + 1);
cli_printf(" Start: %s\n", p_event_table->values[global_cats_config.timers[i].start_event]);
cli_printf(" Trigger: %s\n", p_event_table->values[global_cats_config.timers[i].trigger_event]);
cli_printf(" Start: %s\n",
GetStr(static_cast<cats_event_e>(global_cats_config.timers[i].start_event), p_event_table));
cli_printf(" Trigger: %s\n",
GetStr(static_cast<cats_event_e>(global_cats_config.timers[i].trigger_event), p_event_table));
cli_printf(" Duration: %lu ms\n", global_cats_config.timers[i].duration);
}
}
Expand Down
9 changes: 0 additions & 9 deletions flight_computer/src/cli/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,6 @@

#include <cstddef>

#define LOOKUP_TABLE_ENTRY(name) \
{ name, ARRAYLEN(name) }

const lookup_table_entry_t lookup_tables[] = {
LOOKUP_TABLE_ENTRY(event_map), LOOKUP_TABLE_ENTRY(action_map),
LOOKUP_TABLE_ENTRY(on_off_map), {(const char *const *)recorder_speed_map, NUM_REC_SPEEDS},
LOOKUP_TABLE_ENTRY(battery_map),
};

#undef LOOKUP_TABLE_ENTRY

const cli_value_t value_table[] = {
Expand Down
12 changes: 6 additions & 6 deletions flight_computer/src/cli/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,15 @@

#pragma once

#include <array>

#include "config/cats_config.hpp"
#include "util/enum_str_maps.hpp"

#define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))

enum lookup_table_index_e { TABLE_EVENTS = 0, TABLE_ACTIONS, TABLE_POWER, TABLE_SPEEDS, TABLE_BATTERY };

struct lookup_table_entry_t {
const char *const *values;
const uint8_t value_count;
};

#define VALUE_TYPE_OFFSET 0
#define VALUE_SECTION_OFFSET 3
#define VALUE_MODE_OFFSET 5
Expand Down Expand Up @@ -102,7 +100,9 @@ struct cli_value_t {
callback_f cb;
} __attribute__((packed));

extern const lookup_table_entry_t lookup_tables[];
inline constexpr std::array<EnumToStrMap, 5> lookup_tables{event_map, action_map, on_off_map, recorder_speed_map,
battery_map};

extern const uint16_t value_table_entry_count;

extern const cli_value_t value_table[];
Expand Down
6 changes: 3 additions & 3 deletions flight_computer/src/flash/reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,16 +262,16 @@ void parse_recording(uint16_t flight_num, rec_entry_type_e filter_mask) {
size_t elem_sz = sizeof(rec_elem.u.flight_state);
lfs_file_read(&lfs, &curr_file, (uint8_t *)&rec_elem.u.imu, elem_sz);
if ((rec_type_without_id & filter_mask) > 0) {
log_raw("%lu|FLIGHT_STATE|%s", rec_elem.ts, fsm_map[rec_elem.u.flight_state]);
log_raw("%lu|FLIGHT_STATE|%s", rec_elem.ts, GetStr(rec_elem.u.flight_state, fsm_map));
}
} break;
case EVENT_INFO: {
size_t elem_sz = sizeof(rec_elem.u.event_info);
lfs_file_read(&lfs, &curr_file, (uint8_t *)&rec_elem.u.imu, elem_sz);
if ((rec_type_without_id & filter_mask) > 0) {
peripheral_act_t action = rec_elem.u.event_info.action;
log_raw("%lu|EVENT_INFO|%s|%s|%d", rec_elem.ts, event_map[rec_elem.u.event_info.event],
action_map[rec_elem.u.event_info.action.action], action.action_arg);
log_raw("%lu|EVENT_INFO|%s|%s|%d", rec_elem.ts, GetStr(rec_elem.u.event_info.event, event_map),
GetStr(rec_elem.u.event_info.action.action, action_map), action.action_arg);
}
} break;
case ERROR_INFO: {
Expand Down
4 changes: 2 additions & 2 deletions flight_computer/src/init/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ static void init_timers() {
/* Init timers */
for (uint32_t i = 0; i < NUM_TIMERS; i++) {
if (global_cats_config.timers[i].duration > 0) {
ev_timers[i].timer_init_event = (cats_event_e)global_cats_config.timers[i].start_event;
ev_timers[i].execute_event = (cats_event_e)global_cats_config.timers[i].trigger_event;
ev_timers[i].timer_init_event = static_cast<cats_event_e>(global_cats_config.timers[i].start_event);
ev_timers[i].execute_event = static_cast<cats_event_e>(global_cats_config.timers[i].trigger_event);
ev_timers[i].timer_duration_ticks = global_cats_config.timers[i].duration;
}
}
Expand Down
4 changes: 2 additions & 2 deletions flight_computer/src/tasks/task_flight_fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ namespace task {
m_task_state_estimation.GetEstimationOutput(), &settings);

if (flight_state.state_changed) {
log_info("State Changed FlightFSM to %s", fsm_map[flight_state.flight_state]);
log_sim("State Changed FlightFSM to %s", fsm_map[flight_state.flight_state]);
log_info("State Changed FlightFSM to %s", GetStr(flight_state.flight_state, fsm_map));
log_sim("State Changed FlightFSM to %s", GetStr(flight_state.flight_state, fsm_map));
record(tick_count, FLIGHT_STATE, &flight_state.flight_state);
}

Expand Down
7 changes: 4 additions & 3 deletions flight_computer/src/tasks/task_peripherals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,17 @@ namespace task {
/* get the actuator function */
peripheral_act_fp curr_fp = action_table[action_list[i].action];
if (curr_fp != nullptr) {
log_error("EXECUTING EVENT: %s, ACTION: %s, ACTION_ARG: %d", event_map[curr_event],
action_map[action_list[i].action], action_list[i].action_arg);
log_error("EXECUTING EVENT: %s, ACTION: %s, ACTION_ARG: %d", GetStr(curr_event, event_map),
GetStr(action_list[i].action, action_map), action_list[i].action_arg);
/* call the actuator function */
curr_fp(action_list[i].action_arg);
event_info_t event_info = {.event = curr_event, .action = action_list[i]};
record(curr_ts, EVENT_INFO, &event_info);
}
}
if (num_actions == 0) {
log_error("EXECUTING EVENT: %s, ACTION: %s", event_map[curr_event], action_map[action_list[0].action]);
log_error("EXECUTING EVENT: %s, ACTION: %s", GetStr(curr_event, event_map),
GetStr(action_list[0].action, action_map));
timestamp_t curr_ts = osKernelGetTickCount();
event_info_t event_info = {.event = curr_event, .action = {ACT_NO_OP}};
record(curr_ts, EVENT_INFO, &event_info);
Expand Down
21 changes: 2 additions & 19 deletions flight_computer/src/util/enum_str_maps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,11 @@
#include "config/globals.hpp"
#include "util/log.h"

#include <array>
#include <cstdio>

const char* const fsm_map[8] = {"INVALID", "CALIBRATING", "READY", "THRUSTING",
"COASTING", "DROGUE", "MAIN", "TOUCHDOWN"};

const char* const event_map[9] = {
"CALIBRATE", "READY", "LIFTOFF", "MAX_V", "APOGEE", "MAIN_DEPLOYMENT", "TOUCHDOWN", "CUSTOM_1", "CUSTOM_2",
};

const char* const action_map[8] = {
"NONE", "DELAY", "HC_ONE", "HC_TWO", "LL_ONE", "SERVO_ONE", "SERVO_TWO", "RECORDER",
};

const char* const battery_map[3] = {"LI-ION", "LI-PO", "ALKALINE"};

// Filled later depending on tick frequency
char* recorder_speed_map[NUM_REC_SPEEDS] = {};

const char* const on_off_map[2] = {
"OFF",
"ON",
};
std::array<char*, NUM_REC_SPEEDS> recorder_speed_map = {};

void init_recorder_speed_map() {
for (uint32_t i = 0; i < NUM_REC_SPEEDS; ++i) {
Expand Down
48 changes: 42 additions & 6 deletions flight_computer/src/util/enum_str_maps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,50 @@

#pragma once

#include <array>
#include <span>
#include <type_traits>

#include "config/cats_config.hpp"

extern const char *const fsm_map[8];
extern const char *const event_map[9];
extern const char *const action_map[8];
extern const char *const on_off_map[2];
extern const char *const battery_map[3];
using EnumToStrMap = std::span<const char *const>;

/**
* @brief Prints the string mapping of a given enum value.
*
* @tparam T - enum type
* @param enum_val - enum value
* @param map - enum to string map
* @return string value of the given enumt, prints "Unknown" if the passed enum value is out of bounds.
*/
template <typename T>
constexpr const char *GetStr(T enum_val, EnumToStrMap map) {
static_assert(std::is_enum<T>::value, "Must be an enum!");
const auto map_idx = std::underlying_type_t<T>(enum_val);
if (map_idx < 0 || map_idx >= map.size()) {
return "Unknown";
}
return map[map_idx];
}

inline constexpr std::array<const char *, 8> fsm_map{"INVALID", "CALIBRATING", "READY", "THRUSTING",
"COASTING", "DROGUE", "MAIN", "TOUCHDOWN"};

inline constexpr std::array<const char *, NUM_EVENTS> event_map{
"CALIBRATE", "READY", "LIFTOFF", "MAX_V", "APOGEE", "MAIN_DEPLOYMENT", "TOUCHDOWN", "CUSTOM_1", "CUSTOM_2",
};

inline constexpr std::array<const char *, 8> action_map{
"NONE", "DELAY", "HC_ONE", "HC_TWO", "LL_ONE", "SERVO_ONE", "SERVO_TWO", "RECORDER",
};

inline constexpr std::array<const char *, 2> on_off_map{
"OFF",
"ON",
};

inline constexpr std::array<const char *, 3> battery_map{"LI-ION", "LI-PO", "ALKALINE"};

extern char *recorder_speed_map[NUM_REC_SPEEDS];
extern std::array<char *, NUM_REC_SPEEDS> recorder_speed_map;

void init_recorder_speed_map();

0 comments on commit 98c1711

Please sign in to comment.