Files
ugv_sdk/src/protocol_v1/agilex_msg_parser_v1.c
2021-08-25 16:36:30 +08:00

177 lines
6.3 KiB
C

/*
* agilex_msg_parser.c
*
* Created on: Jul 09, 2021 22:04
* Description:
*
* Copyright (c) 2021 Ruixiang Du (rdu)
*/
#include "ugv_sdk/details/protocol_v1//agilex_msg_parser_v1.h"
#include "protocol_v1/agilex_protocol_v1.h"
#include "stdio.h"
#include "string.h"
bool DecodeCanFrameV1(const struct can_frame *rx_frame, AgxMessage *msg) {
// if checksum not correct
if (!CalcCanFrameChecksumV1(rx_frame->can_id, (uint8_t *)rx_frame->data,
rx_frame->can_dlc)) {
// printf("wrong checksum for id: %x-------------->\n", rx_frame->can_id);
return false;
}
switch (rx_frame->can_id) {
case CAN_MSG_SYSTEM_STATE_ID: {
msg->type = AgxMsgSystemState;
msg->body.system_state_msg.vehicle_state = rx_frame->data[0];
msg->body.system_state_msg.control_mode = rx_frame->data[1];
msg->body.system_state_msg.battery_voltage =
((((uint16_t)rx_frame->data[2]) << 8) | (uint16_t)rx_frame->data[3]) /
10.0f;
msg->body.system_state_msg.error_code =
((((uint16_t)rx_frame->data[4]) << 8) | (uint16_t)rx_frame->data[5]);
break;
}
case CAN_MSG_MOTION_STATE_ID: {
msg->type = AgxMsgMotionState;
msg->body.motion_state_msg.linear_velocity =
((int16_t)((((uint16_t)rx_frame->data[0]) << 8) |
(uint16_t)rx_frame->data[1])) /
1000.0f;
msg->body.motion_state_msg.angular_velocity =
((int16_t)((((uint16_t)rx_frame->data[2]) << 8) |
(uint16_t)rx_frame->data[3])) /
1000.0f;
msg->body.motion_state_msg.lateral_velocity =
((int16_t)((((uint16_t)rx_frame->data[4]) << 8) |
(uint16_t)rx_frame->data[5])) /
1000.0f;
break;
}
case CAN_MSG_LIGHT_STATE_ID: {
msg->type = AgxMsgLightState;
LightStateFrame *frame = (LightStateFrame *)(rx_frame->data);
msg->body.light_command_msg.enable_cmd_ctrl =
(frame->enable_cmd_ctrl != 0) ? true : false;
msg->body.light_command_msg.front_light.mode = frame->front_mode;
msg->body.light_command_msg.front_light.custom_value =
frame->front_custom;
msg->body.light_command_msg.rear_light.mode = frame->rear_mode;
msg->body.light_command_msg.rear_light.custom_value = frame->rear_custom;
break;
}
case CAN_MSG_VALUE_SET_STATE_ID: {
msg->type = AgxMsgValueSetStateV1;
if (rx_frame->data[0] == 0xaa)
msg->body.v1_value_set_state_msg.set_neutral = true;
else
msg->body.v1_value_set_state_msg.set_neutral = false;
break;
}
case CAN_MSG_ACTUATOR1_STATE_ID:
case CAN_MSG_ACTUATOR2_STATE_ID:
case CAN_MSG_ACTUATOR3_STATE_ID:
case CAN_MSG_ACTUATOR4_STATE_ID: {
msg->type = AgxMsgActuatorStateV1;
msg->body.v1_actuator_state_msg.motor_id =
rx_frame->can_id - CAN_MSG_ACTUATOR1_STATE_ID;
msg->body.v1_actuator_state_msg.current =
((((uint16_t)rx_frame->data[0]) << 8) | (uint16_t)rx_frame->data[1]) /
10.0f;
msg->body.v1_actuator_state_msg.rpm = (int16_t)((
(((uint16_t)rx_frame->data[2]) << 8) | (uint16_t)rx_frame->data[3]));
msg->body.v1_actuator_state_msg.driver_temp = rx_frame->data[4];
msg->body.v1_actuator_state_msg.motor_temp = rx_frame->data[5];
break;
}
default:
break;
}
return true;
}
bool EncodeCanFrameV1(const AgxMessage *msg, struct can_frame *tx_frame) {
bool ret = true;
switch (msg->type) {
case AgxMsgMotionCommandV1: {
static uint8_t count = 0;
tx_frame->can_id = CAN_MSG_MOTION_COMMAND_ID;
tx_frame->can_dlc = 8;
MotionCommandFrame frame;
frame.control_mode = CTRL_MODE_CMD_CAN;
frame.error_clear_byte = ERROR_CLR_NONE;
frame.linear_percentage =
(int8_t)(msg->body.v1_motion_command_msg.linear);
frame.angular_percentage =
(int8_t)(msg->body.v1_motion_command_msg.angular);
frame.lateral_percentage =
(int8_t)(msg->body.v1_motion_command_msg.lateral);
frame.reserved0 = 0;
frame.count = count++;
memcpy(tx_frame->data, (uint8_t *)(&frame), tx_frame->can_dlc);
tx_frame->data[7] = CalcCanFrameChecksumV1(
tx_frame->can_id, tx_frame->data, tx_frame->can_dlc);
break;
}
case AgxMsgValueSetCommandV1: {
static uint8_t count = 0;
tx_frame->can_id = CAN_MSG_VALUE_SET_COMMAND_ID;
tx_frame->can_dlc = 8;
ValueSetCommandFrame frame;
frame.set_neutral =
msg->body.v1_value_set_command_msg.set_neutral ? 0xaa : 0x00;
frame.reserved0 = 0x00;
frame.reserved1 = 0x00;
frame.reserved2 = 0x00;
frame.reserved3 = 0x00;
frame.reserved4 = 0x00;
frame.count = count++;
memcpy(tx_frame->data, (uint8_t *)(&frame), tx_frame->can_dlc);
tx_frame->data[7] = CalcCanFrameChecksumV1(
tx_frame->can_id, tx_frame->data, tx_frame->can_dlc);
break;
}
case AgxMsgLightCommand: {
static uint8_t count = 0;
tx_frame->can_id = CAN_MSG_LIGHT_COMMAND_ID;
tx_frame->can_dlc = 8;
LightCommandFrame frame;
if (msg->body.light_command_msg.enable_cmd_ctrl) {
frame.enable_cmd_ctrl = LIGHT_ENABLE_CMD_CTRL;
frame.front_mode = msg->body.light_command_msg.front_light.mode;
frame.front_custom =
msg->body.light_command_msg.front_light.custom_value;
frame.rear_mode = msg->body.light_command_msg.rear_light.mode;
frame.rear_custom = msg->body.light_command_msg.rear_light.custom_value;
} else {
frame.enable_cmd_ctrl = LIGHT_DISABLE_CMD_CTRL;
frame.front_mode = 0;
frame.front_custom = 0;
frame.rear_mode = 0;
frame.rear_custom = 0;
}
frame.reserved0 = 0;
frame.count = count++;
memcpy(tx_frame->data, (uint8_t *)(&frame), tx_frame->can_dlc);
tx_frame->data[7] = CalcCanFrameChecksumV1(
tx_frame->can_id, tx_frame->data, tx_frame->can_dlc);
break;
}
default: {
ret = false;
break;
}
}
return ret;
}
uint8_t CalcCanFrameChecksumV1(uint16_t id, uint8_t *data, uint8_t dlc) {
uint8_t checksum = 0x00;
checksum = (uint8_t)(id & 0x00ff) + (uint8_t)(id >> 8) + dlc;
for (int i = 0; i < (dlc - 1); ++i) checksum += data[i];
return checksum;
}