Skip to content

Commit

Permalink
Specify data capture times for SD card and wireless telem in JSONCAN (#…
Browse files Browse the repository at this point in the history
…1273)

### Changelist 
<!-- Give a list of the changes covered in this PR. This will help both
you and the reviewer keep this PR within scope. -->

Add the ability to specify the data capture rate for both SD card
logging and wireless telemetry. The schema is as follows:
```json
"<msg name>": {
    <other signals omitted>
    "data_capture": {
        "log_cycle_time": 1000,
        "telem_cycle_time": 1000
     }
}
```

`log_cycle_time` is the cycle time at which the message will be logged
to the SD card. If `null`, this message will not be logged. This signal
can be omitted and the normal message cycle time will be used instead.

`telem_cycle_time` is the cycle time at which the message will be
transmitted via wireless telemetry. If `null`, this message will not be
sent. This signal can be omitted and the normal message cycle time will
be used instead.

### Testing Done
<!-- Outline the testing that was done to demonstrate the changes are
solid. This could be unit tests, integration tests, testing on the car,
etc. Include relevant code snippets, screenshots, etc as needed. -->

TODO
  • Loading branch information
gtaharaedmonds authored May 23, 2024
1 parent 15d1bd5 commit a62a19e
Show file tree
Hide file tree
Showing 10 changed files with 314 additions and 103 deletions.
24 changes: 24 additions & 0 deletions can_bus/quadruna/INVL/INVL_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
"max": 3276.7,
"unit": "degC"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"Temperatures2": {
Expand Down Expand Up @@ -89,6 +93,10 @@
"max": 3276.7,
"unit": "degC"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"Temperatures3": {
Expand Down Expand Up @@ -135,6 +143,10 @@
"max": 3276.7,
"unit": "Nm"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"AnalogInputVoltages": {
Expand Down Expand Up @@ -201,6 +213,10 @@
"max": 327.67,
"unit": "V"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"DigitalInputStatus": {
Expand Down Expand Up @@ -239,6 +255,10 @@
"start_bit": 56,
"bits": 1
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"MotorPositionInfo": {
Expand Down Expand Up @@ -469,6 +489,10 @@
"max": 327.67,
"unit": "V"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"InternalStates": {
Expand Down
20 changes: 20 additions & 0 deletions can_bus/quadruna/INVR/INVR_tx.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
"max": 3276.7,
"unit": "degC"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"Temperatures2": {
Expand Down Expand Up @@ -89,6 +93,10 @@
"max": 3276.7,
"unit": "degC"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"Temperatures3": {
Expand Down Expand Up @@ -135,6 +143,10 @@
"max": 3276.7,
"unit": "Nm"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"AnalogInputVoltages": {
Expand Down Expand Up @@ -201,6 +213,10 @@
"max": 327.67,
"unit": "V"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"DigitalInputStatus": {
Expand Down Expand Up @@ -469,6 +485,10 @@
"max": 327.67,
"unit": "V"
}
},
"data_capture": {
"log_cycle_time": 1000,
"telem_cycle_time": 1000
}
},
"InternalStates": {
Expand Down
28 changes: 16 additions & 12 deletions firmware/quadruna/VC/src/tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "app_canTx.h"
#include "app_canRx.h"
#include "app_canAlerts.h"
#include "app_canDataCapture.h"
#include "app_commitInfo.h"
#include "app_powerManager.h"
#include "app_efuse.h"
Expand All @@ -30,6 +31,7 @@
#include "io_telemMessage.h"
#include "io_pcm.h"
#include "io_tsms.h"
#include "io_time.h"

#include "hw_bootup.h"
#include "hw_utils.h"
Expand All @@ -53,26 +55,28 @@ extern UART_HandleTypeDef huart3;
extern SD_HandleTypeDef hsd1;
// extern IWDG_HandleTypeDef hiwdg1;

static bool io_logging_functional(void); // TODO make this a general io logging happy function
static bool loggingEnabled(void); // TODO make this a general io logging happy function

static uint32_t can_logging_overflow_count = 0;
static uint32_t read_count = 0; // TODO debugging variables
static uint32_t write_count = 0; // TODO debugging variables
static bool can_logging_enable = true;

static void tasks_canRx_callback(CanMsg *rx_msg)
static void canRxCallback(CanMsg *rx_msg)
{
io_can_pushRxMsgToQueue(rx_msg); // push to queue
if (io_logging_functional())

if (loggingEnabled() && app_dataCapture_needsLog((uint16_t)rx_msg->std_id, io_time_getCurrentMs()))
{
io_canLogging_loggingQueuePush(rx_msg); // push to logging queue
read_count++;
}

// TODO all telemetry here
}

SdCard sd = { .hsd = &hsd1, .timeout = 1000 };
static const CanHandle can = { .can = &hfdcan1, .can_msg_received_callback = tasks_canRx_callback };
static const CanHandle can = { .can = &hfdcan1, .can_msg_received_callback = canRxCallback };

void canRxQueueOverflowCallBack(uint32_t overflow_count)
{
Expand Down Expand Up @@ -153,7 +157,7 @@ static const Gpio nprogram_3v3 = { .port = NPROGRAM_3V3_GPIO_Port, .pin
static const Gpio sb_ilck_shdn_sns = { .port = SB_ILCK_SHDN_SNS_GPIO_Port, .pin = SB_ILCK_SHDN_SNS_Pin };
static const Gpio tsms_shdn_sns = { .port = TSMS_SHDN_SNS_GPIO_Port, .pin = TSMS_SHDN_SNS_Pin };

static bool io_logging_functional(void)
static bool loggingEnabled(void)
{
return !hw_gpio_readPin(&sd_present) && can_logging_enable;
}
Expand Down Expand Up @@ -388,7 +392,7 @@ void tasks_init(void)
Error_Handler();
}

if (io_logging_functional())
if (loggingEnabled())
{
if (io_fileSystem_init() == FILE_OK)
{
Expand All @@ -411,6 +415,7 @@ void tasks_init(void)

app_canTx_init();
app_canRx_init();
app_canDataCapture_init();

app_heartbeatMonitor_init(
heartbeatMonitorChecklist, heartbeatGetters, heartbeatUpdaters, &app_canTx_VC_Heartbeat_set,
Expand Down Expand Up @@ -549,15 +554,14 @@ _Noreturn void tasks_runCanRx(void)

_Noreturn void tasks_runLogging(void)
{
osDelayUntil(osWaitForever);
if (!loggingEnabled())
{
osThreadSuspend(osThreadGetId());
}

static uint32_t message_batch_count = 0;
for (;;)
{
if (!io_logging_functional())
{
osThreadSuspend(osThreadGetId());
}

io_canLogging_recordMsgFromQueue();
message_batch_count++;
write_count++;
Expand Down
96 changes: 18 additions & 78 deletions scripts/code_generation/jsoncan/generate_can_from_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,26 @@
TODO: Generate callback functions for received messages? Could be cool
TODO: Why do we need start values???
"""

import argparse
import os
from src.json_parsing.json_can_parsing import JsonCanParser
from src.utils import write_text
from src.codegen.dbc_generation.dbc_generation import DbcGenerator
from src.codegen.c_generation.app_can_utils_module import AppCanUtilsModule
from src.codegen.c_generation.app_can_tx_module import AppCanTxModule
from src.codegen.c_generation.app_can_rx_module import AppCanRxModule
from src.codegen.c_generation.app_can_alerts_module import AppCanAlertsModule
from src.codegen.c_generation.io_can_rx_module import IoCanRxModule
from src.codegen.c_generation.io_can_tx_module import IoCanTxModule
from src.codegen.c_generation.app_can_alerts_module import AppCanAlertsModule
from src.codegen.c_generation.app_can_data_capture_module import AppCanDataCaptureModule


if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--board", help="Choose a board name")
parser.add_argument("--can_data_dir", help="Path to JSON CAN data")
parser.add_argument(
"--app_can_tx_source_output",
help="Path to the output CAN TX source file for the App layer",
)
parser.add_argument(
"--app_can_tx_header_output",
help="Path to the output CAN TX header file for the App layer",
)
parser.add_argument(
"--io_can_tx_source_output",
help="Path to the output CAN TX source file for the IO layer",
)
parser.add_argument(
"--io_can_tx_header_output",
help="Path to the output CAN TX header file for the IO layer",
)
parser.add_argument(
"--app_can_rx_source_output",
help="Path to the output CAN RX source file for the App layer",
)
parser.add_argument(
"--app_can_rx_header_output",
help="Path to the output CAN RX header file for the App layer",
)
parser.add_argument(
"--io_can_rx_source_output",
help="Path to the output CAN RX source file for the IO layer",
)
parser.add_argument(
"--io_can_rx_header_output",
help="Path to the output CAN RX header file for the IO layer",
)
parser.add_argument(
"--app_can_utils_source_output",
help="Path to the output source file for packing/unpacking CAN messages",
)
parser.add_argument(
"--app_can_utils_header_output",
help="Path to the output header file for packing/unpacking CAN messages",
)
parser.add_argument(
"--app_can_alerts_source_output",
help="Path to the output source file for aperiodic alerts",
)
parser.add_argument(
"--app_can_alerts_header_output",
help="Path to the output header file for aperiodic alerts",
)
parser.add_argument("--output_dir", help="Path to the output source files")
parser.add_argument("--dbc_output", help="Path to the DBC file")
parser.add_argument(
"--only_dbc", action="store_true", help="Only generate DBC file"
Expand All @@ -81,32 +37,16 @@
if args.only_dbc:
exit()

# Generate app_canUtils.h/c
app_can_utils_mod = AppCanUtilsModule(can_db, args.board)
write_text(app_can_utils_mod.header(), args.app_can_utils_header_output)
write_text(app_can_utils_mod.source(), args.app_can_utils_source_output)

# Generate app_canTx.h/c
app_can_tx_mod = AppCanTxModule(can_db, args.board)
write_text(app_can_tx_mod.header(), args.app_can_tx_header_output)
write_text(app_can_tx_mod.source(), args.app_can_tx_source_output)

# Generate app_canRx.h/c
app_can_rx_mod = AppCanRxModule(can_db, args.board)
write_text(app_can_rx_mod.header(), args.app_can_rx_header_output)
write_text(app_can_rx_mod.source(), args.app_can_rx_source_output)

# Generate io_canTx.h/c
io_can_tx_mod = IoCanTxModule(can_db, args.board)
write_text(io_can_tx_mod.header(), args.io_can_tx_header_output)
write_text(io_can_tx_mod.source(), args.io_can_tx_source_output)

# Generate io_canRx.h/c
io_can_rx_mod = IoCanRxModule(can_db, args.board)
write_text(io_can_rx_mod.header(), args.io_can_rx_header_output)
write_text(io_can_rx_mod.source(), args.io_can_rx_source_output)

# Generate app_canAlerts.h/c
app_can_alerts_mod = AppCanAlertsModule(can_db, args.board)
write_text(app_can_alerts_mod.header(), args.app_can_alerts_header_output)
write_text(app_can_alerts_mod.source(), args.app_can_alerts_source_output)
modules = {
AppCanUtilsModule(can_db, args.board): os.path.join("app", "app_canUtils"),
AppCanTxModule(can_db, args.board): os.path.join("app", "app_canTx"),
AppCanRxModule(can_db, args.board): os.path.join("app", "app_canRx"),
AppCanAlertsModule(can_db, args.board): os.path.join("app", "app_canAlerts"),
AppCanDataCaptureModule(can_db): os.path.join("app", "app_canDataCapture"),
IoCanTxModule(can_db, args.board): os.path.join("io", "io_canTx"),
IoCanRxModule(can_db, args.board): os.path.join("io", "io_canRx"),
}
for module, module_path in modules.items():
module_full_path = os.path.join(args.output_dir, module_path)
write_text(module.header(), module_full_path + ".h")
write_text(module.source(), module_full_path + ".c")
21 changes: 9 additions & 12 deletions scripts/code_generation/jsoncan/jsoncan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ function(jsoncan_sources JSONCAN_PY_BOARD OUTPUT_DIR USE_IO CAR)
set(APP_CAN_UTILS_HEADER_OUTPUT "${OUTPUT_DIR}/app/app_canUtils.h")
set(APP_CAN_ALERTS_SRC_OUTPUT "${OUTPUT_DIR}/app/app_canAlerts.c")
set(APP_CAN_ALERTS_HEADER_OUTPUT "${OUTPUT_DIR}/app/app_canAlerts.h")
set(APP_CAN_DATA_CAPTURE_SRC_OUTPUT "${OUTPUT_DIR}/app/app_canDataCapture.c")
set(APP_CAN_DATA_CAPTURE_HEADER_OUTPUT "${OUTPUT_DIR}/app/app_canDataCapture.h")

set(CAN_DIR ${REPO_ROOT_DIR}/can_bus)
set(DBC_OUTPUT ${CAN_DIR}/dbcs/${CAR}.dbc)
Expand All @@ -41,22 +43,13 @@ function(jsoncan_sources JSONCAN_PY_BOARD OUTPUT_DIR USE_IO CAR)
${APP_CAN_UTILS_HEADER_OUTPUT}
${APP_CAN_ALERTS_SRC_OUTPUT}
${APP_CAN_ALERTS_HEADER_OUTPUT}
${APP_CAN_DATA_CAPTURE_SRC_OUTPUT}
${APP_CAN_DATA_CAPTURE_HEADER_OUTPUT}
COMMAND ${PYTHON_COMMAND}
${SCRIPTS_DIR}/code_generation/jsoncan/generate_can_from_json.py
--board ${JSONCAN_PY_BOARD}
--can_data_dir ${CAN_JSON_DIR}
--app_can_tx_header_output ${APP_CAN_TX_HEADER_OUTPUT}
--app_can_tx_source_output ${APP_CAN_TX_SRC_OUTPUT}
--io_can_tx_header_output ${IO_CAN_TX_HEADER_OUTPUT}
--io_can_tx_source_output ${IO_CAN_TX_SRC_OUTPUT}
--app_can_rx_header_output ${APP_CAN_RX_HEADER_OUTPUT}
--app_can_rx_source_output ${APP_CAN_RX_SRC_OUTPUT}
--io_can_rx_header_output ${IO_CAN_RX_HEADER_OUTPUT}
--io_can_rx_source_output ${IO_CAN_RX_SRC_OUTPUT}
--app_can_utils_header_output ${APP_CAN_UTILS_HEADER_OUTPUT}
--app_can_utils_source_output ${APP_CAN_UTILS_SRC_OUTPUT}
--app_can_alerts_header_output ${APP_CAN_ALERTS_HEADER_OUTPUT}
--app_can_alerts_source_output ${APP_CAN_ALERTS_SRC_OUTPUT}
--output_dir ${OUTPUT_DIR}
--dbc_output ${DBC_OUTPUT}
DEPENDS ${CAN_JSON_SRCS} ${CAN_JSON_PY_SRCS}
WORKING_DIRECTORY ${REPO_ROOT_DIR}
Expand All @@ -76,6 +69,8 @@ function(jsoncan_sources JSONCAN_PY_BOARD OUTPUT_DIR USE_IO CAR)
${APP_CAN_UTILS_HEADER_OUTPUT}
${APP_CAN_ALERTS_SRC_OUTPUT}
${APP_CAN_ALERTS_HEADER_OUTPUT}
${APP_CAN_DATA_CAPTURE_SRC_OUTPUT}
${APP_CAN_DATA_CAPTURE_HEADER_OUTPUT}
PARENT_SCOPE
)
set(CAN_INCLUDE_DIRS
Expand All @@ -96,6 +91,8 @@ function(jsoncan_sources JSONCAN_PY_BOARD OUTPUT_DIR USE_IO CAR)
${APP_CAN_UTILS_HEADER_OUTPUT}
${APP_CAN_ALERTS_SRC_OUTPUT}
${APP_CAN_ALERTS_HEADER_OUTPUT}
${APP_CAN_DATA_CAPTURE_SRC_OUTPUT}
${APP_CAN_DATA_CAPTURE_HEADER_OUTPUT}
PARENT_SCOPE
)
set(CAN_INCLUDE_DIRS
Expand Down
Loading

0 comments on commit a62a19e

Please sign in to comment.