Skip to content

Commit 7750b9e

Browse files
committed
Update CAN frame pasrsing and visualization
1 parent e0cbb85 commit 7750b9e

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

VisionPilot/Production_Releases/0.5/include/drivers/can_interface.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ struct CanVehicleState {
1616
double speed_kmph = std::numeric_limits<double>::quiet_NaN(); // Speed, CAN ID 0xA1
1717
double steering_angle_deg = std::numeric_limits<double>::quiet_NaN(); // Steering, CAN ID 0xA4
1818
bool is_valid = false;
19+
bool is_steering_angle = false;
20+
21+
void clear()
22+
{
23+
speed_kmph = std::numeric_limits<double>::quiet_NaN();
24+
is_steering_angle = false;
25+
steering_angle_deg = std::numeric_limits<double>::quiet_NaN();
26+
}
1927
};
2028

2129
/**

VisionPilot/Production_Releases/0.5/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,8 @@ void displayThread(
594594
std::optional<float> gtSteeringAngle;
595595
cv::Mat rotatedGtSteeringWheelImg;
596596
if (can_interface) {
597-
if (can_interface->getState().is_valid) {
597+
// float gtSteeringSpeed = can_interface->getState().speed_kmph;
598+
if (can_interface->getState().is_valid && can_interface->getState().is_steering_angle) {
598599
gtSteeringAngle = can_interface->getState().steering_angle_deg;
599600
if (gtSteeringAngle.has_value()) {
600601
rotatedGtSteeringWheelImg = rotateSteeringWheel(gtSteeringWheelImg, gtSteeringAngle.value());

VisionPilot/Production_Releases/0.5/src/drivers/can_interface.cpp

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ CanInterface::~CanInterface() {
5656

5757
// Main update loop
5858
bool CanInterface::update() {
59+
// clear because data get from state!
60+
current_state_.clear();
5961

6062
if (is_file_mode_) {
6163
return readFileLine();
@@ -89,6 +91,7 @@ void CanInterface::parseFrame(
8991
double val = decodeSteering(data);
9092
current_state_.steering_angle_deg = val;
9193
current_state_.is_valid = true;
94+
current_state_.is_steering_angle = true;
9295
}
9396
}
9497

@@ -109,31 +112,34 @@ double CanInterface::decodeSpeed(const std::vector<uint8_t>& data) {
109112
return static_cast<double>(raw) * 0.01;
110113
}
111114

112-
// SSA (Steering angle) : Start Bit 46 | Length 15 | Signed | Factor 0.1
113-
// Format: Motorola (Big Endian: https://en.wikipedia.org/wiki/Endianness)
114-
// Bit 46 is in byte 5 (bit 6).
115-
// This is complex. We verify strictly against provided logic if possible.
116-
// Lacking exact bit-matrix, we assume standard Big Endian alignment crossing byte 5 and 6.
115+
// Steering angle
116+
// SSA (Measured steering angle) : 46|15@0- (0.1,0) [0|0] "-"
117+
// SSAZ (Steering zero point) : 29|15@0- (0.1,0) [0|0] "-"
117118
double CanInterface::decodeSteering(const std::vector<uint8_t>& data) {
118-
119-
if (data.size() < 8) return 0.0;
120119

121-
// Masking logic based on 15-bit signed integer
122-
// Assuming MSB is in byte 5, LSB in byte 6
123-
uint16_t raw_high = data[5];
124-
uint16_t raw_low = data[6];
125-
126-
// Combine
127-
uint16_t raw = (raw_high << 8) | raw_low;
128-
129-
// If it's 15 bits, we might need to shift or mask.
130-
// Assuming the 15 bits are right-aligned in the extraction:
131-
// (This is a best-guess implementation until A4 is actually observed in logs)
132-
133-
// Convert to signed 16-bit to handle negative values (Two's complement)
134-
int16_t signed_val = static_cast<int16_t>(raw);
135-
136-
return static_cast<double>(signed_val) * 0.1;
120+
// Sanity: need at least 8 bytes
121+
if (data.size() < 8) return std::numeric_limits<double>::quiet_NaN();
122+
123+
// SSAZ
124+
uint16_t b6 = (data[5] & 0xC0) >> 7; // Bit 7 from byte 6 BigEndian
125+
uint16_t b5 = data[4]; // Byte 5
126+
bool ssazSign = (data[3] & 0x10) != 0; // bit 4 → sign
127+
int16_t b4 = data[3] & 0x0F; // bits 3..0 → magnitude
128+
129+
uint16_t ssaz = (b4 << 10) | (b5 << 2) | b6;
130+
int16_t ssazSigned = ssazSign ? -ssaz : ssaz;
131+
132+
// SSA
133+
uint16_t ssa_b7 = data[6];
134+
bool ssaSign = (data[5] & 0x40) != 0; // bit 6 = sign
135+
uint16_t ssa_b6 = data[5] & 0x3F; // bits 5..0 = magnitude
136+
137+
int16_t ssa = (ssa_b6 << 7) | ssa_b7;
138+
int16_t ssaSigned = ssaSign ? -ssa : ssa;
139+
140+
double steering_angle = ssaSigned - ssazSigned;
141+
142+
return steering_angle;
137143
}
138144

139145
// ============================== REAL-TIME INFERENCE (SocketCAN) ============================== //

0 commit comments

Comments
 (0)