Skip to content

Commit e94a388

Browse files
authored
Implement the G Force Recording System (#392)
* Added Accelerometer.h. (#87) * Reformatted Accelerometer.h. (#87) * Updated the accelerometer. (#87) * Added the other 5 DOFs in the data container. (#87) * Added the other 4 DOFs in the headers. (#87) * Added `Accelerometer`. (#87) * Added `toString()`. (#87) * Code reformatted. (#87) * Bug fixed. (#87) * Bug fixed. (#87) * Changed the output type to `Acceleration` (#87) * Enabled the accelerometer. (#87)
1 parent 000c003 commit e94a388

File tree

10 files changed

+127
-19
lines changed

10 files changed

+127
-19
lines changed
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include "Accelerometer.h"
2+
3+
String Acceleration::toString() {
4+
return String(yaw) + "," + pitch + "," + roll + "," + forwardAcceleration + "," + lateralAcceleration + "," + verticalAcceleration;
5+
}
6+
Accelerometer::Accelerometer(OnAccelerometerUpdate onUpdate) : _onUpdate(onUpdate) {}
7+
void Accelerometer::initialize(const ArrayList<String> &parentTags) {
8+
Device<Acceleration>::initialize(parentTags);
9+
Serial1.begin(115200);
10+
while (!Serial1) delay(10);
11+
if (!_rvc.begin(&Serial1)) delay(10);
12+
}
13+
Acceleration Accelerometer::read() {
14+
BNO08x_RVC_Data heading;
15+
Acceleration r = Acceleration();
16+
if (!_rvc.read(&heading)) return r;
17+
r.yaw = heading.yaw;
18+
r.pitch = heading.pitch;
19+
r.roll = heading.roll;
20+
r.forwardAcceleration = heading.x_accel;
21+
r.lateralAcceleration = heading.y_accel;
22+
r.verticalAcceleration = heading.z_accel;
23+
_onUpdate(r);
24+
return r;
25+
}

arduino/leads_vec_wsc/Accelerometer.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "Adafruit_BNO08x_RVC.h"
2+
#include "LEADS.h"
3+
4+
5+
struct Acceleration {
6+
float yaw = 0, pitch = 0, roll = 0;
7+
float forwardAcceleration = 0, lateralAcceleration = 0, verticalAcceleration = 0;
8+
String toString();
9+
};
10+
11+
12+
typedef void (*OnAccelerometerUpdate)(Acceleration acceleration);
13+
14+
15+
class Accelerometer : public Device<Acceleration> {
16+
protected:
17+
Adafruit_BNO08x_RVC _rvc = Adafruit_BNO08x_RVC();
18+
const OnAccelerometerUpdate _onUpdate;
19+
public:
20+
Accelerometer(OnAccelerometerUpdate onUpdate);
21+
void initialize(const ArrayList<String> &parentTags) override;
22+
Acceleration read() override;
23+
};

arduino/leads_vec_wsc/leads_vec_wsc.ino

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "LEADS.h" // LEADS>=1.1.0
1+
#include "Accelerometer.h"
22

33
const int PIN_LFWSS[] = {2};
44
const int PIN_RFWSS[] = {3};
@@ -12,6 +12,7 @@ WheelSpeedSensor RFWSS{ArrayList<int>(PIN_RFWSS, 1), [](float ws) {returnFloat(P
1212
WheelSpeedSensor LRWSS{ArrayList<int>(PIN_LRWSS, 1), [](float ws) {returnFloat(P, LEFT_REAR_WHEEL_SPEED_SENSOR, ws);}};
1313
WheelSpeedSensor RRWSS{ArrayList<int>(PIN_RRWSS, 1), [](float ws) {returnFloat(P, RIGHT_REAR_WHEEL_SPEED_SENSOR, ws);}};
1414
WheelSpeedSensor CRWSS{ArrayList<int>(PIN_CRWSS, 1), [](float ws) {returnFloat(P, CENTER_REAR_WHEEL_SPEED_SENSOR, ws);}};
15+
Accelerometer ACCL{[](Acceleration acceleration) {returnString(P, ACCELEROMETER, acceleration.toString());}};
1516

1617
void setup() {
1718
P.initializeAsRoot();
@@ -20,6 +21,7 @@ void setup() {
2021
LRWSS.initializeAsRoot();
2122
RRWSS.initializeAsRoot();
2223
CRWSS.initializeAsRoot();
24+
ACCL.initializeAsRoot();
2325
}
2426

2527
void loop() {
@@ -29,4 +31,5 @@ void loop() {
2931
LRWSS.read();
3032
RRWSS.read();
3133
CRWSS.read();
34+
ACCL.read();
3235
}

leads/data.py

+16-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ def __init__(self,
1717
speed: float = 0,
1818
front_wheel_speed: float = 0,
1919
rear_wheel_speed: float = 0,
20+
yaw: float = 0,
21+
pitch: float = 0,
22+
roll: float = 0,
2023
forward_acceleration: float = 0,
2124
lateral_acceleration: float = 0,
25+
vertical_acceleration: float = 0,
2226
front_proximity: float = -1,
2327
left_proximity: float = -1,
2428
right_proximity: float = -1,
@@ -37,8 +41,12 @@ def __init__(self,
3741
self.speed: float = speed
3842
self.front_wheel_speed: float = front_wheel_speed
3943
self.rear_wheel_speed: float = rear_wheel_speed
44+
self.yaw: float = yaw
45+
self.pitch: float = pitch
46+
self.roll: float = roll
4047
self.forward_acceleration: float = forward_acceleration
4148
self.lateral_acceleration: float = lateral_acceleration
49+
self.vertical_acceleration: float = vertical_acceleration
4250
self.front_proximity: float = front_proximity
4351
self.left_proximity: float = left_proximity
4452
self.right_proximity: float = right_proximity
@@ -96,8 +104,12 @@ def __init__(self,
96104
speed: float = 0,
97105
front_wheel_speed: float = 0,
98106
rear_wheel_speed: float = 0,
107+
yaw: float = 0,
108+
pitch: float = 0,
109+
roll: float = 0,
99110
forward_acceleration: float = 0,
100111
lateral_acceleration: float = 0,
112+
vertical_acceleration: float = 0,
101113
front_proximity: float = -1,
102114
left_proximity: float = -1,
103115
right_proximity: float = -1,
@@ -119,10 +131,10 @@ def __init__(self,
119131
rear_view_base64: str = "",
120132
rear_view_latency: int = 0,
121133
**kwargs) -> None:
122-
super().__init__(voltage, speed, front_wheel_speed, rear_wheel_speed, forward_acceleration,
123-
lateral_acceleration, front_proximity, left_proximity, right_proximity, rear_proximity,
124-
mileage, gps_valid, gps_ground_speed, latitude, longitude, steering_position, throttle, brake,
125-
**kwargs)
134+
super().__init__(voltage, speed, front_wheel_speed, rear_wheel_speed, yaw, pitch, roll, forward_acceleration,
135+
lateral_acceleration, vertical_acceleration, front_proximity, left_proximity, right_proximity,
136+
rear_proximity, mileage, gps_valid, gps_ground_speed, latitude, longitude, steering_position,
137+
throttle, brake, **kwargs)
126138
self.front_view_base64: str = front_view_base64
127139
self.front_view_latency: int = front_view_latency
128140
self.left_view_base64: str = left_view_base64

leads/data_persistence/core.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from numpy import nan as _nan
88

99
from leads.types import Compressor as _Compressor, VisualHeader as _VisualHeader, \
10-
VisualHeaderFull as _VisualHeaderFull, DefaultHeaderFull as _DefaultHeaderFull
10+
VisualHeaderFull as _VisualHeaderFull, DefaultHeaderFull as _DefaultHeaderFull, DefaultHeader as _DefaultHeader
1111
from ._computational import mean as _mean, array as _array, norm as _norm, read_csv as _read_csv, \
1212
DataFrame as _DataFrame, TextFileReader as _TextFileReader
1313

@@ -253,10 +253,10 @@ def close(self) -> None:
253253
self._csv.close()
254254

255255

256-
DEFAULT_HEADER: tuple[str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str] = (
257-
"t", "voltage", "speed", "front_wheel_speed", "rear_wheel_speed", "forward_acceleration", "lateral_acceleration",
258-
"front_proximity", "left_proximity", "right_proximity", "rear_proximity", "mileage", "gps_valid",
259-
"gps_ground_speed", "latitude", "longitude"
256+
DEFAULT_HEADER: _DefaultHeader = (
257+
"t", "voltage", "speed", "front_wheel_speed", "rear_wheel_speed", "yaw", "pitch", "roll", "forward_acceleration",
258+
"lateral_acceleration", "vertical_acceleration", "front_proximity", "left_proximity", "right_proximity",
259+
"rear_proximity", "mileage", "gps_valid", "gps_ground_speed", "latitude", "longitude"
260260
)
261261
DEFAULT_HEADER_FULL: _DefaultHeaderFull = DEFAULT_HEADER + (
262262
"steering_position", "throttle", "brake"

leads/types.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
type OnRegisterChain[T] = _Callable[[OnRegister[T]], OnRegister[T]]
77
type SupportedConfigValue = bool | int | float | str | None
88
type SupportedConfig = SupportedConfigValue | tuple[SupportedConfig, ...]
9+
type DefaultHeader = tuple[
10+
str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str]
911
type DefaultHeaderFull = tuple[
10-
str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str]
12+
str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str]
1113
type VisualHeader = tuple[
1214
str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str,
13-
str]
15+
str, str, str, str, str]
1416
type VisualHeaderFull = tuple[
1517
str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str, str,
16-
str, str, str, str]
18+
str, str, str, str, str, str, str, str]

leads_arduino/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
if not _find_spec("serial"):
44
raise ImportError("Please install `pyserial` to run this module\n>>>pip install pyserial")
55

6+
from leads_arduino.accelerometer import *
67
from leads_arduino.arduino_proto import *
78
from leads_arduino.arduino_nano import *
89
from leads_arduino.arduino_micro import *

leads_arduino/accelerometer.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from dataclasses import dataclass as _dataclass
2+
from typing import override as _override
3+
4+
from leads import Device as _Device, Serializable as _Serializable
5+
6+
7+
@_dataclass
8+
class Acceleration(_Serializable):
9+
yaw: float
10+
pitch: float
11+
roll: float
12+
forward_acceleration: float
13+
lateral_acceleration: float
14+
vertical_acceleration: float
15+
16+
17+
class Accelerometer(_Device):
18+
def __init__(self) -> None:
19+
super().__init__()
20+
self._yaw: float = 0
21+
self._pitch: float = 0
22+
self._roll: float = 0
23+
self._fa: float = 0
24+
self._la: float = 0
25+
self._va: float = 0
26+
27+
@_override
28+
def update(self, data: str) -> None:
29+
self._yaw, self._pitch, self._roll, self._fa, self._la, self._va = tuple(map(float, data.split(',')))
30+
31+
@_override
32+
def read(self) -> Acceleration:
33+
return Acceleration(self._yaw, self._pitch, self._roll, self._fa, self._la, self._va)

leads_can/prototype.py

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ def __init__(self) -> None:
1212
self._bus: _Bus | None = None
1313
self._notifier: _Notifier | None = None
1414

15-
@_override
1615
def on_message_received(self, msg: _Message) -> None:
1716
for device in self.devices():
1817
device.update(msg)

leads_vec/devices.py

+15-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
Controller, CENTER_REAR_WHEEL_SPEED_SENSOR, require_config, mark_device, ODOMETER, GPS_RECEIVER, \
55
ConcurrentOdometer, LEFT_INDICATOR, RIGHT_INDICATOR, VOLTAGE_SENSOR, DataContainer, has_device, \
66
FRONT_VIEW_CAMERA, LEFT_VIEW_CAMERA, RIGHT_VIEW_CAMERA, REAR_VIEW_CAMERA, VisualDataContainer, BRAKE_INDICATOR, \
7-
SFT, read_device_marker, has_controller, POWER_CONTROLLER, WHEEL_SPEED_CONTROLLER
8-
from leads_arduino import ArduinoMicro, WheelSpeedSensor, VoltageSensor
7+
SFT, read_device_marker, has_controller, POWER_CONTROLLER, WHEEL_SPEED_CONTROLLER, ACCELEROMETER
8+
from leads_arduino import ArduinoMicro, WheelSpeedSensor, VoltageSensor, Accelerometer
99
from leads_gpio import NMEAGPSReceiver, LEDGroup, LED, LEDGroupCommand, LEDCommand, Entire, Transition
1010
from leads_vec.config import Config
1111
from leads_video import Base64Camera, get_camera
@@ -57,7 +57,9 @@ def read(self) -> DataContainer:
5757
"longitude": gps[3],
5858
**self.device(POWER_CONTROLLER).read()
5959
}
60-
wsc = {"speed": gps[0]} if GPS_ONLY else self.device(WHEEL_SPEED_CONTROLLER).read()
60+
wsc = self.device(WHEEL_SPEED_CONTROLLER).read()
61+
if GPS_ONLY:
62+
wsc["speed"] = gps[1]
6163
visual = {}
6264
if has_device(FRONT_VIEW_CAMERA):
6365
cam = get_camera(FRONT_VIEW_CAMERA, Base64Camera)
@@ -113,9 +115,9 @@ def initialize(self, *parent_tags: str) -> None:
113115
def read(self) -> dict[str, float]:
114116
lfws = self.device(LEFT_FRONT_WHEEL_SPEED_SENSOR).read()
115117
rfws = self.device(RIGHT_FRONT_WHEEL_SPEED_SENSOR).read()
116-
front_wheel_speed = (lfws + rfws) * .5
117118
return {"speed": min(lfws, rfws, rws := self.device(CENTER_REAR_WHEEL_SPEED_SENSOR).read()),
118-
"front_wheel_speed": front_wheel_speed, "rear_wheel_speed": rws}
119+
"front_wheel_speed": (lfws + rfws) * .5, "rear_wheel_speed": rws,
120+
**self.device(ACCELEROMETER).read().to_dict()}
119121

120122

121123
@device(ODOMETER, MAIN_CONTROLLER)
@@ -141,6 +143,14 @@ def initialize(self, *parent_tags: str) -> None:
141143
super().initialize(*parent_tags)
142144

143145

146+
@device(ACCELEROMETER, WHEEL_SPEED_CONTROLLER)
147+
class Accele(Accelerometer):
148+
@override
149+
def initialize(self, *parent_tags: str) -> None:
150+
mark_device(self, "WSC", "ESC")
151+
super().initialize(*parent_tags)
152+
153+
144154
@device(GPS_RECEIVER, MAIN_CONTROLLER, (GPS_RECEIVER_PORT,))
145155
class GPS(NMEAGPSReceiver):
146156
@override

0 commit comments

Comments
 (0)