|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <stdbool.h> |
| 4 | +#include <stdint.h> |
| 5 | + |
| 6 | +#include "board/can.h" |
| 7 | +#include "board/health.h" |
| 8 | +#include "board/body/motor_control.h" |
| 9 | +#include "board/drivers/can_common_declarations.h" |
| 10 | +#include "opendbc/safety/declarations.h" |
| 11 | + |
| 12 | +#define BODY_CAN_ADDR_MOTOR_SPEED 0x201U |
| 13 | +#define BODY_CAN_MOTOR_SPEED_PERIOD_US 10000U |
| 14 | +#define BODY_BUS_NUMBER 0U |
| 15 | + |
| 16 | +static struct { |
| 17 | + bool pending; |
| 18 | + int32_t left_target_deci_rpm; |
| 19 | + int32_t right_target_deci_rpm; |
| 20 | +} body_can_command; |
| 21 | + |
| 22 | +void body_can_send_motor_speeds(uint8_t bus, float left_speed_rpm, float right_speed_rpm) { |
| 23 | + CANPacket_t pkt; |
| 24 | + pkt.bus = bus; |
| 25 | + pkt.addr = BODY_CAN_ADDR_MOTOR_SPEED; |
| 26 | + pkt.returned = 0; |
| 27 | + pkt.rejected = 0; |
| 28 | + pkt.extended = 0; |
| 29 | + pkt.fd = 0; |
| 30 | + pkt.data_len_code = 8; |
| 31 | + int16_t left_speed_deci = left_speed_rpm * 10; |
| 32 | + int16_t right_speed_deci = right_speed_rpm * 10; |
| 33 | + pkt.data[0] = (uint8_t)((left_speed_deci >> 8) & 0xFFU); |
| 34 | + pkt.data[1] = (uint8_t)(left_speed_deci & 0xFFU); |
| 35 | + pkt.data[2] = (uint8_t)((right_speed_deci >> 8) & 0xFFU); |
| 36 | + pkt.data[3] = (uint8_t)(right_speed_deci & 0xFFU); |
| 37 | + pkt.data[4] = 0U; |
| 38 | + pkt.data[5] = 0U; |
| 39 | + pkt.data[6] = 0U; |
| 40 | + pkt.data[7] = 0U; |
| 41 | + can_set_checksum(&pkt); |
| 42 | + can_send(&pkt, bus, true); |
| 43 | +} |
| 44 | + |
| 45 | +void body_can_process_target(int16_t left_target_deci_rpm, int16_t right_target_deci_rpm) { |
| 46 | + body_can_command.left_target_deci_rpm = (int32_t)left_target_deci_rpm; |
| 47 | + body_can_command.right_target_deci_rpm = (int32_t)right_target_deci_rpm; |
| 48 | + body_can_command.pending = true; |
| 49 | +} |
| 50 | + |
| 51 | +void body_can_init(void) { |
| 52 | + body_can_command.pending = false; |
| 53 | + can_silent = false; |
| 54 | + can_loopback = false; |
| 55 | + (void)set_safety_hooks(SAFETY_BODY, 0U); |
| 56 | + set_gpio_output(GPIOD, 2U, 0); // Enable CAN transceiver |
| 57 | + can_init_all(); |
| 58 | +} |
| 59 | + |
| 60 | +void body_can_periodic(uint32_t now) { |
| 61 | + if (body_can_command.pending) { |
| 62 | + body_can_command.pending = false; |
| 63 | + float left_target_rpm = ((float)body_can_command.left_target_deci_rpm) * 0.1f; |
| 64 | + float right_target_rpm = ((float)body_can_command.right_target_deci_rpm) * 0.1f; |
| 65 | + motor_speed_controller_set_target_rpm(BODY_MOTOR_LEFT, left_target_rpm); |
| 66 | + motor_speed_controller_set_target_rpm(BODY_MOTOR_RIGHT, right_target_rpm); |
| 67 | + } |
| 68 | + |
| 69 | + static uint32_t last_motor_speed_tx_us = 0; |
| 70 | + if ((now - last_motor_speed_tx_us) >= BODY_CAN_MOTOR_SPEED_PERIOD_US) { |
| 71 | + float left_speed_rpm = motor_encoder_get_speed_rpm(BODY_MOTOR_LEFT); |
| 72 | + float right_speed_rpm = motor_encoder_get_speed_rpm(BODY_MOTOR_RIGHT); |
| 73 | + body_can_send_motor_speeds(BODY_BUS_NUMBER, left_speed_rpm, right_speed_rpm); |
| 74 | + last_motor_speed_tx_us = now; |
| 75 | + } |
| 76 | +} |
0 commit comments