recorderlegend1 commited on
Commit
a0c8e54
·
verified ·
1 Parent(s): 5d68fec

Upload folder using huggingface_hub

Browse files
Files changed (45) hide show
  1. .DS_Store +0 -0
  2. .gitattributes +14 -0
  3. .gitignore +1 -0
  4. Data_Collection_Scripts/README.md +3 -0
  5. Data_Collection_Scripts/arduino_master.ino +130 -0
  6. Data_Collection_Scripts/arduino_slave.ino +118 -0
  7. Data_Collection_Scripts/left.py +56 -0
  8. Data_Collection_Scripts/requirements.txt +1 -0
  9. Data_Collection_Scripts/right.py +57 -0
  10. Data_Collection_Scripts/run_legs.py +24 -0
  11. NewAccelMaster/NewAccelMaster.ino +90 -0
  12. NewAccelerometer/NewAccelerometer.ino +70 -0
  13. README.md +1 -0
  14. SimpleAccelMaster/SimpleAccelMaster.ino +78 -0
  15. SimpleAccelerometer/SimpleAccelerometer.ino +74 -0
  16. data/.DS_Store +0 -0
  17. data/processed/.DS_Store +0 -0
  18. data/processed/striding/features.csv +0 -0
  19. data/processed/striding/labels.csv +0 -0
  20. data/processed/walking/features.csv +0 -0
  21. data/processed/walking/labels.csv +0 -0
  22. data/unprocessed/StraightWalking/COM10.log +0 -0
  23. data/unprocessed/StraightWalking/COM3.log +0 -0
  24. data/unprocessed/StraightWalking/COM4.log +0 -0
  25. data/unprocessed/StraightWalking/COM5.log +0 -0
  26. data/unprocessed/SwerveWalking/COM10.log +0 -0
  27. data/unprocessed/SwerveWalking/COM3.log +0 -0
  28. data/unprocessed/SwerveWalking/COM4.log +0 -0
  29. data/unprocessed/SwerveWalking/COM5.log +0 -0
  30. data/unprocessed/WideStride/COM10.log +0 -0
  31. data/unprocessed/WideStride/COM3.log +0 -0
  32. data/unprocessed/WideStride/COM4.log +0 -0
  33. data/unprocessed/WideStride/COM5.log +0 -0
  34. data/unprocessed/striding/back_striding.txt +0 -0
  35. data/unprocessed/striding/front_striding.txt +0 -0
  36. data/unprocessed/walking/back_walking.txt +0 -0
  37. data/unprocessed/walking/front_walking.txt +0 -0
  38. model/.DS_Store +0 -0
  39. model/lstm/model.py +15 -0
  40. model/preprocess/preprocess.py +65 -0
  41. model/preprocess/run.sh +2 -0
  42. model/train/model.py +48 -0
  43. model/train/test.py +120 -0
  44. model/train/tran.py +208 -0
  45. sensor_calibration_data +38 -0
.DS_Store ADDED
Binary file (6.15 kB). View file
 
.gitattributes CHANGED
@@ -33,3 +33,17 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.DS_Store filter=lfs diff=lfs merge=lfs -text
37
+ *.gitignore filter=lfs diff=lfs merge=lfs -text
38
+ *.md filter=lfs diff=lfs merge=lfs -text
39
+ *.ino filter=lfs diff=lfs merge=lfs -text
40
+ *.py filter=lfs diff=lfs merge=lfs -text
41
+ *.txt filter=lfs diff=lfs merge=lfs -text
42
+ *.csv filter=lfs diff=lfs merge=lfs -text
43
+ *.log filter=lfs diff=lfs merge=lfs -text
44
+ *.pyc filter=lfs diff=lfs merge=lfs -text
45
+ *.sh filter=lfs diff=lfs merge=lfs -text
46
+ /sensor_calibration_data filter=lfs diff=lfs merge=lfs -text
47
+ *.yaml filter=lfs diff=lfs merge=lfs -text
48
+ *.json filter=lfs diff=lfs merge=lfs -text
49
+ *.wandb filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .idea/
Data_Collection_Scripts/README.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ Each leg requires one Arduino to be flashed as master, and one as slave.
2
+
3
+ The master Arduino should be connected to the Jetson.
Data_Collection_Scripts/arduino_master.ino ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <Wire.h>
2
+ extern TwoWire Wire1; // Declare Wire1 for secondary I²C bus
3
+ #include <SPI.h>
4
+ #include <Adafruit_LSM6DSOX.h>
5
+
6
+ #define CS_PIN 10 // Chip select pin for SPI
7
+
8
+ #define BUFFER_SIZE 48 // 12 floats * 4 bytes per float
9
+
10
+ // Sensor instances and addresses
11
+ Adafruit_LSM6DSOX sensor1;
12
+ uint8_t sensor1_addr = 0x6A; // Sensor 1 I2C address
13
+ Adafruit_LSM6DSOX sensor2;
14
+ uint8_t sensor2_addr = 0x6B; // Sensor 2 I2C address
15
+
16
+ // Arrays to hold sensor data
17
+ float masterData[12]; // Master's sensor data
18
+ float slaveData[12]; // Slave's sensor data
19
+
20
+ uint8_t slaveStorage[BUFFER_SIZE]; // Buffer to hold incoming data from slave
21
+
22
+ // Buffer to hold combined data for I2C transmission
23
+ #define TOTAL_DATA_SIZE 96 // 24 floats * 4 bytes per float
24
+ uint8_t i2cData[TOTAL_DATA_SIZE]; // Holds both masterData and slaveData
25
+
26
+ // Variables for I2C chunked transmission
27
+ volatile uint8_t requestedChunk = 0; // Chunk index requested by the master
28
+ #define CHUNK_SIZE 32 // Number of bytes per I2C chunk
29
+ #define TOTAL_CHUNKS ((TOTAL_DATA_SIZE + CHUNK_SIZE - 1) / CHUNK_SIZE) // Total number of chunks
30
+
31
+ void setup()
32
+ {
33
+ Serial.begin(115200); // Initialize Serial for debugging
34
+
35
+ // Initialize SPI communication
36
+ pinMode(CS_PIN, OUTPUT);
37
+ digitalWrite(CS_PIN, HIGH); // Deselect the slave
38
+ SPI.begin();
39
+ SPI.beginTransaction(SPISettings(21000000, MSBFIRST, SPI_MODE0));
40
+
41
+ // Initialize sensors on default I2C bus (Wire)
42
+ Wire.begin(); // Initialize default I2C bus as master
43
+ while (!sensor1.begin_I2C(sensor1_addr, &Wire))
44
+ {
45
+ Serial.println("Failed to initialize sensor1!");
46
+ delay(10);
47
+ }
48
+
49
+ while (!sensor2.begin_I2C(sensor2_addr, &Wire))
50
+ {
51
+ Serial.println("Failed to initialize sensor2!");
52
+ delay(10);
53
+ }
54
+
55
+ sensor1.setAccelDataRate(LSM6DS_RATE_416_HZ);
56
+ sensor2.setAccelDataRate(LSM6DS_RATE_416_HZ);
57
+
58
+ // Initialize I2C as a slave on the secondary I2C bus (Wire1)
59
+ Wire1.begin(0x08); // Join the I2C bus with address #8
60
+ Wire1.onReceive(receiveEvent); // Register the receive event handler
61
+ Wire1.onRequest(requestEvent); // Register the request event handler
62
+ }
63
+
64
+ void loop()
65
+ {
66
+ // Read master's sensor data
67
+ updateMasterSensorData();
68
+
69
+ // Transfer data byte by byte (sending dummy data)
70
+ digitalWrite(CS_PIN, LOW); // Select the slave
71
+ for (size_t i = 0; i < BUFFER_SIZE; i++)
72
+ {
73
+ slaveStorage[i] = SPI.transfer(0x00); // Send dummy byte and receive data
74
+ }
75
+ digitalWrite(CS_PIN, HIGH); // Deselect the slave
76
+
77
+ // Reconstruct floats received from slave
78
+ memcpy(slaveData, slaveStorage, sizeof(slaveData));
79
+
80
+ // Prepare data for I2C transmission
81
+
82
+ Serial.println(slaveData[0]);
83
+ prepareI2CData();
84
+ }
85
+
86
+ // Function to read master's sensor data
87
+ void updateMasterSensorData()
88
+ {
89
+
90
+ // Read sensor1 data
91
+ sensor1.readAcceleration(masterData[0], masterData[1], masterData[2]);
92
+ sensor1.readGyroscope(masterData[3], masterData[4], masterData[5]);
93
+
94
+ // Read sensor2 data
95
+ sensor2.readAcceleration(masterData[6], masterData[7], masterData[8]);
96
+ sensor2.readGyroscope(masterData[9], masterData[10], masterData[11]);
97
+ }
98
+
99
+ // Function to prepare data for I2C transmission
100
+ void prepareI2CData()
101
+ {
102
+ // Combine masterData and slaveData into i2cData buffer
103
+ memcpy(i2cData, masterData, sizeof(masterData)); // Copy masterData
104
+ memcpy(i2cData + sizeof(masterData), slaveData, sizeof(slaveData)); // Copy slaveData
105
+ }
106
+
107
+ // I2C receive event handler
108
+ void receiveEvent(int numBytes)
109
+ {
110
+ if (numBytes >= 1)
111
+ {
112
+ requestedChunk = Wire1.read(); // Read the requested chunk index
113
+ // Read additional bytes if needed (not in this case)
114
+ }
115
+ }
116
+
117
+ // I2C request event handler
118
+ void requestEvent()
119
+ {
120
+ // Send data in chunks of CHUNK_SIZE bytes based on requestedChunk
121
+ uint16_t offset = requestedChunk * CHUNK_SIZE;
122
+ uint8_t bytesToSend = CHUNK_SIZE;
123
+
124
+ if (offset + CHUNK_SIZE > TOTAL_DATA_SIZE)
125
+ {
126
+ bytesToSend = TOTAL_DATA_SIZE - offset;
127
+ }
128
+
129
+ Wire1.write(i2cData + offset, bytesToSend);
130
+ }
Data_Collection_Scripts/arduino_slave.ino ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <SPI.h>
2
+ #include <Adafruit_LSM6DSOX.h>
3
+ #include <stdint.h>
4
+
5
+ #define BUFFER_SIZE 48 // 12 floats * 4 bytes per float
6
+ #define SS_PIN 10
7
+
8
+ // Sensor instances and addresses
9
+ Adafruit_LSM6DSOX sensor1;
10
+ uint8_t sensor1_addr = 0x6A;
11
+ Adafruit_LSM6DSOX sensor2;
12
+ uint8_t sensor2_addr = 0x6B;
13
+
14
+ // Variables to hold sensor data
15
+ float sensorData[12]; // Array to hold sensor data
16
+
17
+ volatile uint8_t pos = 0;
18
+ volatile bool dataReady = false;
19
+ volatile bool transferComplete = false;
20
+
21
+ uint8_t sendStorage[BUFFER_SIZE]; // Buffer to store bytes to send to master
22
+
23
+ // SPI interrupt number for the SAM3X8E chip:
24
+ #define SPI0_INTERRUPT_NUMBER (IRQn_Type)24
25
+
26
+ void setup() {
27
+ Serial.begin(115200);
28
+ slaveBegin(SS_PIN); // Initialize SPI as slave on pin 10
29
+ }
30
+
31
+ void loop() {
32
+ if (transferComplete) {
33
+ transferComplete = false; // Reset flag
34
+
35
+ // Update sensor data
36
+ updateSensorData();
37
+
38
+ // Prepare data to send in next SPI transaction
39
+ memcpy(sendStorage, sensorData, sizeof(sensorData));
40
+
41
+
42
+ // Serial.println(sensorData[11]);
43
+ // Preload TDR with the first byte to send
44
+ REG_SPI0_TDR = sendStorage[0];
45
+ pos = 1; // Reset position for next transfer
46
+ }
47
+ }
48
+
49
+ void slaveBegin(uint8_t _pin) {
50
+ // Setup the SPI Interrupt registers
51
+ NVIC_ClearPendingIRQ(SPI0_INTERRUPT_NUMBER);
52
+ NVIC_EnableIRQ(SPI0_INTERRUPT_NUMBER);
53
+
54
+ // Initialize the SPI device with Arduino default values
55
+ SPI.begin(_pin);
56
+ REG_SPI0_CR = SPI_CR_SWRST; // Reset SPI
57
+
58
+ // Setup interrupt
59
+ REG_SPI0_IDR = SPI_IDR_TDRE | SPI_IDR_MODF | SPI_IDR_OVRES |
60
+ SPI_IDR_NSSR | SPI_IDR_TXEMPTY | SPI_IDR_UNDES;
61
+ REG_SPI0_IER = SPI_IER_RDRF;
62
+
63
+ // Setup the SPI registers
64
+ REG_SPI0_CR = SPI_CR_SPIEN; // Enable SPI
65
+ REG_SPI0_MR = SPI_MR_MODFDIS; // Slave and no modefault
66
+ REG_SPI0_CSR = SPI_MODE0; // DLYBCT=0, DLYBS=0, SCBR=0, 8-bit transfer
67
+
68
+ // Initialize sensors
69
+ while (!sensor1.begin_I2C(sensor1_addr)) {
70
+ Serial.println("Failed to initialize sensor1!");
71
+ delay(10);
72
+ }
73
+
74
+ while (!sensor2.begin_I2C(sensor2_addr)) {
75
+ Serial.println("Failed to initialize sensor2!");
76
+ delay(10);
77
+ }
78
+
79
+ sensor1.setAccelDataRate(LSM6DS_RATE_416_HZ);
80
+ sensor2.setAccelDataRate(LSM6DS_RATE_416_HZ);
81
+
82
+ // Update sensor data for the first transfer
83
+ updateSensorData();
84
+ memcpy(sendStorage, sensorData, sizeof(sensorData));
85
+
86
+ // Preload TDR with the first byte to send
87
+ REG_SPI0_TDR = sendStorage[0];
88
+ pos = 1; // Start position at 1 since first byte is already loaded
89
+ }
90
+
91
+ void updateSensorData() {
92
+ // Read sensor1 data
93
+ sensor1.readAcceleration(sensorData[0], sensorData[1], sensorData[2]);
94
+ sensor1.readGyroscope(sensorData[3], sensorData[4], sensorData[5]);
95
+
96
+ // Read sensor2 data
97
+ sensor2.readAcceleration(sensorData[6], sensorData[7], sensorData[8]);
98
+ sensor2.readGyroscope(sensorData[9], sensorData[10], sensorData[11]);
99
+ }
100
+
101
+ void SPI0_Handler(void) {
102
+ uint32_t status = REG_SPI0_SR;
103
+
104
+ // Check if data has been received
105
+ if (status & SPI_SR_RDRF) {
106
+ // Read byte from SPI data register
107
+ uint8_t received_byte = REG_SPI0_RDR & 0xFF;
108
+
109
+ // Load next byte to transmit
110
+ if (pos < BUFFER_SIZE) {
111
+ REG_SPI0_TDR = sendStorage[pos++];
112
+ } else {
113
+ // All bytes have been sent
114
+ transferComplete = true;
115
+ pos = 0; // Reset position for the next transfer
116
+ }
117
+ }
118
+ }
Data_Collection_Scripts/left.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smbus2 import SMBus
2
+ import time
3
+ import struct
4
+
5
+ I2C_BUS_NUMBER = 1
6
+
7
+ # I2C address of the Arduino
8
+ ARDUINO_I2C_ADDRESS = 0x08
9
+
10
+ # Total number of bytes to read (24 floats * 4 bytes per float)
11
+ TOTAL_BYTES = 96
12
+
13
+ # Maximum bytes per I2C transaction (due to limitations)
14
+ CHUNK_SIZE = 32
15
+
16
+ OUTPUT_FILE = "left_data.txt"
17
+
18
+
19
+ def read_i2c_data(bus, addr, total_bytes, chunk_size):
20
+ data = []
21
+ chunks = (total_bytes + chunk_size - 1) // chunk_size
22
+ for chunk_index in range(chunks):
23
+ # Use read_i2c_block_data which sends a command byte before reading data
24
+ to_read = min(chunk_size, total_bytes - (chunk_index * chunk_size))
25
+ chunk_data = bus.read_i2c_block_data(addr, chunk_index, to_read)
26
+ data.extend(chunk_data)
27
+ return data
28
+
29
+
30
+
31
+ with SMBus(I2C_BUS_NUMBER) as bus, open(OUTPUT_FILE,'w') as f: # Use the correct I2C bus number
32
+ while True:
33
+ try:
34
+ # Read data in chunks
35
+ data = read_i2c_data(bus, ARDUINO_I2C_ADDRESS, TOTAL_BYTES, CHUNK_SIZE)
36
+
37
+ # Convert byte data to floats
38
+ floats = []
39
+ for i in range(0, TOTAL_BYTES, 4):
40
+ # Combine 4 bytes into a float
41
+ float_bytes = bytes(data[i:i+4])
42
+ value = struct.unpack('<f', float_bytes)[0] # '<f' for little-endian float
43
+ floats.append(value)
44
+
45
+ # Split into master and slave data
46
+ masterData = floats[:12]
47
+ slaveData = floats[12:]
48
+
49
+ # Print the data
50
+ f.write(f"{time.time()}\nM: {masterData}\nS:{slaveData}")
51
+ # print(f"{time.time()}\nM: {masterData}\nS:{slaveData}")
52
+
53
+ except Exception as e:
54
+ f.write(f"Error: {e}")
55
+ # print((f"Error: {e}"))
56
+
Data_Collection_Scripts/requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ smbus2==0.5.0
Data_Collection_Scripts/right.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smbus2 import SMBus
2
+ import time
3
+ import struct
4
+
5
+
6
+ I2C_BUS_NUMBER = 7
7
+
8
+ # I2C address of the Arduino
9
+ ARDUINO_I2C_ADDRESS = 0x08
10
+
11
+ # Total number of bytes to read (24 floats * 4 bytes per float)
12
+ TOTAL_BYTES = 96
13
+
14
+ # Maximum bytes per I2C transaction (due to limitations)
15
+ CHUNK_SIZE = 32
16
+
17
+ OUTPUT_FILE = "right_data.txt"
18
+
19
+
20
+ def read_i2c_data(bus, addr, total_bytes, chunk_size):
21
+ data = []
22
+ chunks = (total_bytes + chunk_size - 1) // chunk_size
23
+ for chunk_index in range(chunks):
24
+ # Use read_i2c_block_data which sends a command byte before reading data
25
+ to_read = min(chunk_size, total_bytes - (chunk_index * chunk_size))
26
+ chunk_data = bus.read_i2c_block_data(addr, chunk_index, to_read)
27
+ data.extend(chunk_data)
28
+ return data
29
+
30
+
31
+
32
+ with SMBus(I2C_BUS_NUMBER) as bus, open(OUTPUT_FILE,'w') as f: # Use the correct I2C bus number
33
+ while True:
34
+ try:
35
+ # Read data in chunks
36
+ data = read_i2c_data(bus, ARDUINO_I2C_ADDRESS, TOTAL_BYTES, CHUNK_SIZE)
37
+
38
+ # Convert byte data to floats
39
+ floats = []
40
+ for i in range(0, TOTAL_BYTES, 4):
41
+ # Combine 4 bytes into a float
42
+ float_bytes = bytes(data[i:i+4])
43
+ value = struct.unpack('<f', float_bytes)[0] # '<f' for little-endian float
44
+ floats.append(value)
45
+
46
+ # Split into master and slave data
47
+ masterData = floats[:12]
48
+ slaveData = floats[12:]
49
+
50
+ # Print the data
51
+ f.write(f"{time.time()}\nM: {masterData}\nS:{slaveData}")
52
+ # print(f"{time.time()}\nM: {masterData}\nS:{slaveData}")
53
+
54
+ except Exception as e:
55
+ f.write(f"Error: {e}")
56
+ # print((f"Error: {e}"))
57
+
Data_Collection_Scripts/run_legs.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """"
2
+ This file just runs both leg collections at once.
3
+ The 3 second delay between scripts is because we experienced some I2C errors when trying to
4
+ instantaneously access both I2C busses on the Jetson.
5
+ """
6
+
7
+ import subprocess
8
+ import time
9
+
10
+ DELAY_SECONDS = 3
11
+
12
+ right = 'right.py'
13
+ left = 'left.py'
14
+
15
+ print(f"Running {right}")
16
+ subprocess.run(["python",right])
17
+
18
+ print(f"Waiting {DELAY_SECONDS} seconds...")
19
+ time.sleep(DELAY_SECONDS)
20
+
21
+ print(f"Running {left}")
22
+ subprocess.run(["python",left])
23
+
24
+ print("Run complete.")
NewAccelMaster/NewAccelMaster.ino ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Arduino LSM6DSOX - Simple Accelerometer
3
+
4
+ This example reads the acceleration values from the LSM6DSOX
5
+ sensor and continuously prints them to the Serial Monitor
6
+ or Serial Plotter.
7
+
8
+ The circuit:
9
+ - Arduino Nano RP2040 Connect
10
+
11
+ created 10 May 2021
12
+ by Arturo Guadalupi
13
+
14
+ This example code is in the public domain.
15
+ */
16
+
17
+ #include <Adafruit_LSM6DSOX.h>
18
+ #include <string>
19
+ #include <TimeLib.h>
20
+ Adafruit_LSM6DSOX sensor1;
21
+ uint8_t sensor1_addr = 0x6A;
22
+ Adafruit_LSM6DSOX sensor2;
23
+ uint8_t sensor2_addr = 0x6B;
24
+ String comma = ",";
25
+ String colon = ":";
26
+ float ax1, ay1, az1, ax2, gx1, gy1, gz1, ay2, az2, gx2, gy2, gz2;
27
+ uint32_t count;
28
+
29
+ void setup() {
30
+ pinMode(2, OUTPUT);
31
+ pinMode(3, OUTPUT);
32
+ pinMode(4, OUTPUT);
33
+
34
+ Serial.begin(115200);
35
+ while (!Serial);
36
+
37
+ while (!sensor1.begin_I2C(sensor1_addr)) {
38
+ Serial.println("Failed to initialize 0x6A!");
39
+ delay(10);
40
+ }
41
+
42
+ sensor1.setAccelDataRate(LSM6DS_RATE_6_66K_HZ);
43
+ Serial.print("Accelerometer sample rate = ");
44
+ Serial.print(sensor1.accelerationSampleRate());
45
+ Serial.println(" Hz");
46
+ Serial.println();
47
+ Serial.println("Acceleration in g's");
48
+ Serial.println("X\tY\tZ");
49
+
50
+ while (!sensor2.begin_I2C(sensor2_addr)) {
51
+ Serial.println("Failed to initialize 0x6B!");
52
+ delay(10);
53
+ }
54
+ sensor2.setAccelDataRate(LSM6DS_RATE_6_66K_HZ);
55
+
56
+ count = 0;
57
+
58
+ while(!Serial.available()); // Wait for serial input
59
+
60
+ digitalWrite(2, HIGH);
61
+ digitalWrite(2, LOW);
62
+
63
+ digitalWrite(3, HIGH); // Send signal pulse to others to sync counts
64
+ digitalWrite(3, LOW);
65
+
66
+ digitalWrite(4, HIGH);
67
+ digitalWrite(4, LOW);
68
+
69
+ }
70
+
71
+ void loop() {
72
+
73
+ digitalWrite(2, HIGH);
74
+ digitalWrite(2, LOW);
75
+
76
+ digitalWrite(3, HIGH); // Send signal pulse to others to process
77
+ digitalWrite(3, LOW);
78
+
79
+ digitalWrite(4, HIGH);
80
+ digitalWrite(4, LOW);
81
+
82
+ sensor1.readAcceleration(ax1, ay1, az1);
83
+ sensor1.readGyroscope(gx1, gy1, gz1);
84
+ sensor2.readAcceleration(ax2, ay2, az2); // Read in sensor data
85
+ sensor2.readGyroscope(gx2, gy2, gz2);
86
+
87
+ Serial.print(count++ + colon + ax1 + comma + ay1 + comma + az1 + comma + ax2 + comma + ay2 + comma + az2 + comma);
88
+ Serial.println(gx1 + comma + gy1 + comma + gz1 + comma + gx2 + comma + gy2 + comma + gz2);
89
+
90
+ }
NewAccelerometer/NewAccelerometer.ino ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Arduino LSM6DSOX - Simple Accelerometer
3
+
4
+ This example reads the acceleration values from the LSM6DSOX
5
+ sensor and continuously prints them to the Serial Monitor
6
+ or Serial Plotter.
7
+
8
+ The circuit:
9
+ - Arduino Nano RP2040 Connect
10
+
11
+ created 10 May 2021
12
+ by Arturo Guadalupi
13
+
14
+ This example code is in the public domain.
15
+ */
16
+
17
+ #include <Adafruit_LSM6DSOX.h>
18
+ #include <string>
19
+ #include <TimeLib.h>
20
+ Adafruit_LSM6DSOX sensor1;
21
+ uint8_t sensor1_addr = 0x6A;
22
+ Adafruit_LSM6DSOX sensor2;
23
+ uint8_t sensor2_addr = 0x6B;
24
+ String comma = ",";
25
+ String colon = ":";
26
+ float ax1, ay1, az1, ax2, gx1, gy1, gz1, ay2, az2, gx2, gy2, gz2;
27
+ uint32_t count;
28
+
29
+ void setup() {
30
+ pinMode(2, INPUT);
31
+
32
+ Serial.begin(115200);
33
+ while (!Serial);
34
+
35
+ while (!sensor1.begin_I2C(sensor1_addr)) {
36
+ Serial.println("Failed to initialize 0x6A!");
37
+ delay(10);
38
+ }
39
+
40
+ sensor1.setAccelDataRate(LSM6DS_RATE_6_66K_HZ);
41
+ Serial.print("Accelerometer sample rate = ");
42
+ Serial.print(sensor1.accelerationSampleRate());
43
+ Serial.println(" Hz");
44
+ Serial.println();
45
+ Serial.println("Acceleration in g's");
46
+ Serial.println("X\tY\tZ");
47
+
48
+ while (!sensor2.begin_I2C(sensor2_addr)) {
49
+ Serial.println("Failed to initialize 0x6B!");
50
+ delay(10);
51
+ }
52
+ sensor2.setAccelDataRate(LSM6DS_RATE_6_66K_HZ);
53
+
54
+ while(!digitalRead(2)); // Wait for signal to start
55
+ count = 0;
56
+ }
57
+
58
+ void loop() {
59
+
60
+ while(!digitalRead(2)); // Wait for signal to proceed
61
+
62
+ sensor1.readAcceleration(ax1, ay1, az1);
63
+ sensor1.readGyroscope(gx1, gy1, gz1);
64
+ sensor2.readAcceleration(ax2, ay2, az2); // Read in sensor data
65
+ sensor2.readGyroscope(gx2, gy2, gz2);
66
+
67
+ Serial.print(count++ + colon + ax1 + comma + ay1 + comma + az1 + comma + gx1 + comma + gy1 + comma + gz1);
68
+ Serial.println(ax2 + comma + ay2 + comma + az2 + comma + gx2 + comma + gy2 + comma + gz2);
69
+
70
+ }
README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ #starx
SimpleAccelMaster/SimpleAccelMaster.ino ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Arduino LSM6DSOX - Simple Accelerometer
3
+
4
+ This example reads the acceleration values from the LSM6DSOX
5
+ sensor and continuously prints them to the Serial Monitor
6
+ or Serial Plotter.
7
+
8
+ The circuit:
9
+ - Arduino Nano RP2040 Connect
10
+
11
+ created 10 May 2021
12
+ by Arturo Guadalupi
13
+
14
+ This example code is in the public domain.
15
+ */
16
+
17
+ #include <Adafruit_LSM6DSOX.h>
18
+ #include <string>
19
+ #include <TimeLib.h>
20
+ Adafruit_LSM6DSOX sensor1;
21
+ uint8_t sensor1_addr = 0x6A;
22
+ Adafruit_LSM6DSOX sensor2;
23
+ uint8_t sensor2_addr = 0x6B;
24
+ String comma = ",";
25
+ float ax1, ay1, az1, ax2, gx1, gy1, gz1, ay2, az2, gx2, gy2, gz2;
26
+ uint32_t time_start;
27
+
28
+ void setup() {
29
+ pinMode(2, OUTPUT);
30
+ pinMode(3, OUTPUT);
31
+ pinMode(4, OUTPUT);
32
+
33
+ Serial.begin(115200);
34
+ while (!Serial);
35
+
36
+ while (!sensor1.begin_I2C(sensor1_addr)) {
37
+ Serial.println("Failed to initialize 0x6A!");
38
+ delay(10);
39
+ }
40
+
41
+ sensor1.setAccelDataRate(LSM6DS_RATE_416_HZ);
42
+ Serial.print("Accelerometer sample rate = ");
43
+ Serial.print(sensor1.accelerationSampleRate());
44
+ Serial.println(" Hz");
45
+ Serial.println();
46
+ Serial.println("Acceleration in g's");
47
+ Serial.println("X\tY\tZ");
48
+
49
+ while (!sensor2.begin_I2C(sensor2_addr)) {
50
+ Serial.println("Failed to initialize 0x6B!");
51
+ delay(10);
52
+ }
53
+ sensor2.setAccelDataRate(LSM6DS_RATE_416_HZ);
54
+
55
+ digitalWrite(2, HIGH);
56
+ digitalWrite(3, HIGH);
57
+ digitalWrite(4, HIGH);
58
+
59
+ time_start = millis();
60
+ }
61
+
62
+ void loop() {
63
+ if (sensor1.accelerationAvailable())
64
+ sensor1.readAcceleration(ax1, ay1, az1);
65
+
66
+ if (sensor1.gyroscopeAvailable())
67
+ sensor1.readGyroscope(gx1, gy1, gz1);
68
+
69
+ if (sensor2.accelerationAvailable())
70
+ sensor2.readAcceleration(ax2, ay2, az2);
71
+
72
+ if (sensor2.gyroscopeAvailable())
73
+ sensor2.readGyroscope(gx2, gy2, gz2);
74
+
75
+ Serial.print((millis() - time_start) + comma + ax1 + comma + ay1 + comma + az1 + comma + ax2 + comma + ay2 + comma + az2 + comma);
76
+ Serial.println(gx1 + comma + gy1 + comma + gz1 + comma + gx2 + comma + gy2 + comma + gz2);
77
+
78
+ }
SimpleAccelerometer/SimpleAccelerometer.ino ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Arduino LSM6DSOX - Simple Accelerometer
3
+
4
+ This example reads the acceleration values from the LSM6DSOX
5
+ sensor and continuously prints them to the Serial Monitor
6
+ or Serial Plotter.
7
+
8
+ The circuit:
9
+ - Arduino Nano RP2040 Connect
10
+
11
+ created 10 May 2021
12
+ by Arturo Guadalupi
13
+
14
+ This example code is in the public domain.
15
+ */
16
+
17
+ #include <Adafruit_LSM6DSOX.h>
18
+ #include <string>
19
+ #include <TimeLib.h>
20
+ Adafruit_LSM6DSOX sensor1;
21
+ uint8_t sensor1_addr = 0x6A;
22
+ Adafruit_LSM6DSOX sensor2;
23
+ uint8_t sensor2_addr = 0x6B;
24
+ String comma = ",";
25
+ float ax1, ay1, az1, ax2, gx1, gy1, gz1, ay2, az2, gx2, gy2, gz2;
26
+ uint32_t time_start;
27
+
28
+ void setup() {
29
+ pinMode(2, INPUT);
30
+
31
+ Serial.begin(115200);
32
+ while (!Serial);
33
+
34
+ while (!sensor1.begin_I2C(sensor1_addr)) {
35
+ Serial.println("Failed to initialize 0x6A!");
36
+ delay(10);
37
+ }
38
+
39
+ sensor1.setAccelDataRate(LSM6DS_RATE_416_HZ);
40
+ Serial.print("Accelerometer sample rate = ");
41
+ Serial.print(sensor1.accelerationSampleRate());
42
+ Serial.println(" Hz");
43
+ Serial.println();
44
+ Serial.println("Acceleration in g's");
45
+ Serial.println("X\tY\tZ");
46
+
47
+ while (!sensor2.begin_I2C(sensor2_addr)) {
48
+ Serial.println("Failed to initialize 0x6B!");
49
+ delay(10);
50
+ }
51
+ sensor2.setAccelDataRate(LSM6DS_RATE_416_HZ);
52
+
53
+ while(!digitalRead(2));
54
+
55
+ time_start = millis();
56
+ }
57
+
58
+ void loop() {
59
+
60
+ if (sensor1.accelerationAvailable())
61
+ sensor1.readAcceleration(ax1, ay1, az1);
62
+
63
+ if (sensor1.gyroscopeAvailable())
64
+ sensor1.readGyroscope(gx1, gy1, gz1);
65
+
66
+ if (sensor2.accelerationAvailable())
67
+ sensor2.readAcceleration(ax2, ay2, az2);
68
+
69
+ if (sensor2.gyroscopeAvailable())
70
+ sensor2.readGyroscope(gx2, gy2, gz2);
71
+
72
+ Serial.print((millis() - time_start) + comma + ax1 + comma + ay1 + comma + az1 + comma + gx1 + comma + gy1 + comma + gz1);
73
+ Serial.println(ax2 + comma + ay2 + comma + az2 + comma + gx2 + comma + gy2 + comma + gz2);
74
+ }
data/.DS_Store ADDED
Binary file (6.15 kB). View file
 
data/processed/.DS_Store ADDED
Binary file (6.15 kB). View file
 
data/processed/striding/features.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/processed/striding/labels.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/processed/walking/features.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/processed/walking/labels.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/StraightWalking/COM10.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/StraightWalking/COM3.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/StraightWalking/COM4.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/StraightWalking/COM5.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/SwerveWalking/COM10.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/SwerveWalking/COM3.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/SwerveWalking/COM4.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/SwerveWalking/COM5.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/WideStride/COM10.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/WideStride/COM3.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/WideStride/COM4.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/WideStride/COM5.log ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/striding/back_striding.txt ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/striding/front_striding.txt ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/walking/back_walking.txt ADDED
The diff for this file is too large to render. See raw diff
 
data/unprocessed/walking/front_walking.txt ADDED
The diff for this file is too large to render. See raw diff
 
model/.DS_Store ADDED
Binary file (6.15 kB). View file
 
model/lstm/model.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+
3
+ class LSTMModel(nn.Module):
4
+ def __init__(self, input_size=12, hidden_size=100, output_size=12, num_layers=2):
5
+ super(LSTMModel, self).__init__()
6
+ self.lstm = nn.LSTM(input_size=input_size,
7
+ hidden_size=hidden_size,
8
+ num_layers=num_layers,
9
+ batch_first=True)
10
+ self.fc = nn.Linear(hidden_size, output_size)
11
+
12
+ def forward(self, x):
13
+ out, _ = self.lstm(x)
14
+ out = self.fc(out)
15
+ return out
model/preprocess/preprocess.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ import torch
4
+ import sys
5
+ import os
6
+ from sklearn.preprocessing import StandardScaler,MinMaxScaler
7
+ np.set_printoptions(suppress=True)
8
+
9
+ ss,mm = StandardScaler(), StandardScaler()
10
+ thigh = pd.read_csv(f"../../data/unprocessed/{sys.argv[1]}/front_{sys.argv[1]}.txt",delimiter=',',usecols =[i for i in range(13) if i != 0])
11
+ shin = pd.read_csv(f"../../data/unprocessed/{sys.argv[1]}/back_{sys.argv[1]}.txt",delimiter=',',usecols =[i for i in range(13) if i != 0])
12
+ thigh,shin = thigh.dropna(),shin.dropna()
13
+ delta = len(thigh) - len(shin)
14
+
15
+ thigh = thigh[delta:]
16
+ thigh.reset_index(inplace=True)
17
+ thigh,shin = thigh[:55000],shin[:55000]
18
+
19
+ for col in thigh.columns:
20
+ thigh.rename(columns={col:col+"_th"},inplace=True)
21
+ shin.rename(columns={col:col+"_sh"},inplace=True)
22
+
23
+
24
+ p_columns_th = [col for col in thigh.columns if col.startswith('p')]
25
+ s_columns_th = [col for col in thigh.columns if col.startswith('s')]
26
+ p_columns_sh = [col for col in shin.columns if col.startswith('p')]
27
+ s_columns_sh = [col for col in shin.columns if col.startswith('s')]
28
+
29
+
30
+
31
+ features = thigh[p_columns_th]
32
+ features = pd.concat([features,shin[p_columns_sh]],axis=1)
33
+
34
+ labels = thigh[s_columns_th]
35
+ labels = pd.concat([labels,shin[s_columns_sh]],axis=1)
36
+
37
+ features_scaled = pd.DataFrame(ss.fit_transform(features), columns=features.columns)
38
+ labels_scaled = pd.DataFrame(mm.fit_transform(labels), columns=labels.columns)
39
+
40
+ os.makedirs(f"../../data/processed/{sys.argv[1]}",exist_ok=True)
41
+ features.to_csv(f"../../data/processed/{sys.argv[1]}/features.csv")
42
+ labels.to_csv(f"../../data/processed/{sys.argv[1]}/labels.csv")
43
+
44
+ def preprocess_data(features_df, labels_df, lookback_window, predict_window, output_file):
45
+ lookback_window *= 150
46
+ predict_window *= 150
47
+
48
+ total_samples = len(features_df) - lookback_window - predict_window
49
+
50
+ x_data = torch.zeros((total_samples, lookback_window, features_df.shape[1]))
51
+ y_data = torch.zeros((total_samples, predict_window, labels_df.shape[1]))
52
+
53
+ for idx, i in enumerate(range(lookback_window, len(features_df) - predict_window)):
54
+ if idx % 1000 == 0:
55
+ print(f"Processing sample {idx}/{total_samples}...")
56
+
57
+ x_data[idx] = torch.tensor(features_df.iloc[i - lookback_window:i].values, dtype=torch.float32)
58
+ y_data[idx] = torch.tensor(labels_df.iloc[i:i + predict_window].values, dtype=torch.float32)
59
+
60
+ torch.save({"x": x_data, "y": y_data}, output_file)
61
+ print(f"Preprocessed data saved to {output_file}")
62
+
63
+ preprocess_data(features,labels,3,3,f"../../data/processed/{sys.argv[1]}/data.pt")
64
+
65
+
model/preprocess/run.sh ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ python preprocess.py striding
2
+ python preprocess.py walking
model/train/model.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+
3
+
4
+ class LSTMModel(nn.Module):
5
+ def __init__(self, input_size=12, hidden_size=64, output_size=12, num_layers=2):
6
+ super(LSTMModel, self).__init__()
7
+ self.lstm = nn.LSTM(input_size=input_size,
8
+ hidden_size=hidden_size,
9
+ num_layers=num_layers,
10
+ batch_first=True)
11
+ self.fc = nn.Linear(hidden_size, output_size)
12
+
13
+ def forward(self, x):
14
+ out, _ = self.lstm(x)
15
+ out = self.fc(out)
16
+ return out
17
+
18
+ from transformers import PreTrainedModel, PretrainedConfig
19
+ import torch.nn as nn
20
+
21
+ # Define a custom configuration class
22
+ class LSTMConfig(PretrainedConfig):
23
+ model_type = "lstm_model"
24
+
25
+ def __init__(self, input_size=12, hidden_size=100, output_size=12, num_layers=2, **kwargs):
26
+ super().__init__(**kwargs)
27
+ self.input_size = input_size
28
+ self.hidden_size = hidden_size
29
+ self.output_size = output_size
30
+ self.num_layers = num_layers
31
+
32
+
33
+ # Define the Hugging Face-compatible model
34
+ class HuggingFaceLSTM(PreTrainedModel):
35
+ config_class = LSTMConfig
36
+
37
+ def __init__(self, config):
38
+ super().__init__(config)
39
+ self.lstm_model = LSTMModel(
40
+ input_size=config.input_size,
41
+ hidden_size=config.hidden_size,
42
+ output_size=config.output_size,
43
+ num_layers=config.num_layers,
44
+ )
45
+
46
+ def forward(self, x, **kwargs):
47
+ return self.lstm_model(x)
48
+
model/train/test.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import numpy as np
3
+ import random
4
+ import os
5
+ from torch.utils.data import DataLoader, TensorDataset
6
+ from torch.utils.data.dataloader import default_collate
7
+ import torch.optim.lr_scheduler as lr_scheduler
8
+
9
+ from tqdm import tqdm
10
+ import matplotlib.pyplot as plt
11
+ os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
12
+
13
+ def set_seed(seed):
14
+ np.random.seed(seed)
15
+ random.seed(seed)
16
+ torch.manual_seed(seed)
17
+ torch.cuda.manual_seed_all(seed)
18
+ torch.backends.cudnn.deterministic = True
19
+ torch.backends.cudnn.benchmark = False
20
+
21
+ set_seed(42)
22
+
23
+ from model import HuggingFaceLSTM
24
+ from model import LSTMConfig
25
+
26
+ def setup_model(device):
27
+ config = LSTMConfig(
28
+ input_size=12,
29
+ hidden_size=100,
30
+ output_size=12,
31
+ num_layers=2
32
+ )
33
+
34
+ model = HuggingFaceLSTM(config)
35
+
36
+ model.to(device)
37
+
38
+ return model
39
+
40
+
41
+ def setup_data(data,batch_size):
42
+ train_split = int(0.85 * 54100)
43
+ X = data['x']
44
+ y = data['y']
45
+
46
+ X_train = X[:train_split]
47
+ y_train = y[:train_split]
48
+
49
+ def normalize_dataset(data):
50
+ data_min = data.amin(dim=(0, 1), keepdim=True)
51
+ data_max = data.amax(dim=(0, 1), keepdim=True)
52
+ normalized_data = (data - data_min) / (data_max - data_min + 1e-8)
53
+ return normalized_data
54
+
55
+ X_norm = normalize_dataset(X_train)
56
+ y_norm = normalize_dataset(y_train)
57
+
58
+ train_dataset = TensorDataset(X_norm,y_norm)
59
+ train_loader = DataLoader(
60
+ train_dataset,
61
+ batch_size=batch_size,
62
+ shuffle=True,
63
+ collate_fn=lambda x: tuple(x_.to(device) for x_ in default_collate(x))
64
+ )
65
+
66
+ return train_loader
67
+
68
+ def train(n_epochs, model, opt,scheduler, loss_fn, batched_data):
69
+ model.train()
70
+ for epoch in range(n_epochs):
71
+ epoch_loss = 0.0
72
+ n_batch = len(batched_data)
73
+
74
+ with tqdm(total=n_batch, desc=f"Epoch {epoch+1}/{n_epochs}", unit="batch") as bar:
75
+ for i, (inputs, targets) in enumerate(batched_data):
76
+
77
+ outputs = model(inputs)
78
+ loss = loss_fn(outputs, targets)
79
+ opt.zero_grad()
80
+ loss.backward()
81
+ opt.step()
82
+
83
+ epoch_loss += loss.item()
84
+ if epoch % 1 == 0:
85
+ plt.plot(outputs[0,:,0].detach().squeeze().cpu(),label="Prediction")
86
+ plt.plot(targets[0,:,0].detach().squeeze().cpu(),label="Actual")
87
+ plt.title("s_a_x_th")
88
+ plt.legend()
89
+ plt.savefig(f"im_{epoch}.png")
90
+ plt.clf()
91
+ scheduler.step()
92
+ bar.set_description(f"Epoch {epoch+1}/{n_epochs} | Loss: {epoch_loss / (i+1):.6f}")
93
+ bar.update(1)
94
+
95
+ print(f"Epoch {epoch+1}/{n_epochs} completed. Average Loss: {epoch_loss / n_batch:.6f}")
96
+
97
+
98
+
99
+ if __name__ == "__main__":
100
+
101
+ device = torch.device('cuda:1')
102
+ raw_data = torch.load('../../data/processed/striding/data.pt')
103
+ model = setup_model(device)
104
+ train_data = setup_data(data=raw_data,batch_size=2048)
105
+ try:
106
+ lr = 0.001
107
+ adam = torch.optim.Adam(model.parameters(),lr=lr)
108
+ linear_scheduler = lr_scheduler.LinearLR(adam, start_factor=1.0, end_factor=0.5, total_iters=30)
109
+ train(
110
+ n_epochs=1000,
111
+ model=model,
112
+ opt=adam,
113
+ scheduler=linear_scheduler,
114
+ loss_fn=torch.nn.HuberLoss(),
115
+ batched_data=train_data
116
+ )
117
+ except Exception as e:
118
+ print(e)
119
+ model.save_pretrained("./lstm_model_with_lr")
120
+ model.save_pretrained("./lstm_model_with_lr")
model/train/tran.py ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.nn as nn
2
+ import torch
3
+ import matplotlib.pyplot as plt
4
+ from tqdm import tqdm
5
+ from torch.utils.data import DataLoader,TensorDataset,default_collate
6
+ device = torch.device('cuda:1')
7
+ from torch.optim import lr_scheduler
8
+ class TransformerModel(nn.Module):
9
+ def __init__(self, input_size=12, hidden_size=64, output_size=12, num_layers=2, nhead=4, seq_length=450):
10
+ super(TransformerModel, self).__init__()
11
+ self.input_size = input_size
12
+ self.hidden_size = hidden_size
13
+ self.output_size = output_size
14
+ self.seq_length = seq_length
15
+
16
+ # Input embedding layer to project input to hidden size
17
+ self.embedding = nn.Linear(input_size, hidden_size)
18
+
19
+ # Positional encoding for sequence information
20
+ self.positional_encoding = nn.Parameter(torch.zeros(1, seq_length, hidden_size))
21
+
22
+ # Transformer encoder
23
+ encoder_layer = nn.TransformerEncoderLayer(d_model=hidden_size, nhead=nhead,dropout=0.3)
24
+ self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
25
+
26
+ # Output projection layer
27
+ self.fc = nn.Linear(hidden_size, output_size)
28
+
29
+ def forward(self, x):
30
+ # x: (batch_size, seq_length, input_size)
31
+
32
+ # Apply input embedding
33
+ x = self.embedding(x) # (batch_size, seq_length, hidden_size)
34
+
35
+ # Add positional encoding
36
+ x = x + self.positional_encoding # (batch_size, seq_length, hidden_size)
37
+
38
+ # Pass through transformer
39
+ x = self.transformer(x.permute(1, 0, 2)) # Transformer expects (seq_length, batch_size, hidden_size)
40
+
41
+ # Project back to output size
42
+ x = self.fc(x.permute(1, 0, 2)) # (batch_size, seq_length, output_size)
43
+ return x
44
+
45
+
46
+ from transformers import PreTrainedModel, PretrainedConfig
47
+
48
+ class TransformerConfig(PretrainedConfig):
49
+ model_type = "transformer_model"
50
+
51
+ def __init__(self, input_size=12, hidden_size=64, output_size=12, num_layers=2, nhead=4, seq_length=450, **kwargs):
52
+ super().__init__(**kwargs)
53
+ self.input_size = input_size
54
+ self.hidden_size = hidden_size
55
+ self.output_size = output_size
56
+ self.num_layers = num_layers
57
+ self.nhead = nhead
58
+ self.seq_length = seq_length
59
+
60
+ class HuggingFaceTransformer(PreTrainedModel):
61
+ config_class = TransformerConfig
62
+
63
+ def __init__(self, config):
64
+ super().__init__(config)
65
+ self.transformer_model = TransformerModel(
66
+ input_size=config.input_size,
67
+ hidden_size=config.hidden_size,
68
+ output_size=config.output_size,
69
+ num_layers=config.num_layers,
70
+ nhead=config.nhead,
71
+ seq_length=config.seq_length,
72
+ )
73
+
74
+ def forward(self, x, **kwargs):
75
+ return self.transformer_model(x)
76
+
77
+
78
+ config = TransformerConfig(
79
+ input_size=12,
80
+ hidden_size=64,
81
+ output_size=12,
82
+ num_layers=2,
83
+ nhead=4,
84
+ seq_length=450,
85
+ )
86
+
87
+ model = HuggingFaceTransformer(config)
88
+
89
+ def train(
90
+ n_epochs,
91
+ model,
92
+ opt,
93
+ scheduler,
94
+ loss_fn,
95
+ train_loader,
96
+ save_path="./model_checkpoint.pt"
97
+ ):
98
+ best_val_loss = float("inf")
99
+ training_history = {"train_loss": [], "val_loss": []}
100
+
101
+ for epoch in range(n_epochs):
102
+ model.train() # Set model to training mode
103
+ train_loss = 0.0
104
+ n_train_batch = len(train_loader)
105
+
106
+ # Training Loop
107
+ with tqdm(total=n_train_batch, desc=f"Epoch {epoch+1}/{n_epochs}", unit="batch") as bar:
108
+ for i, (inputs, targets) in enumerate(train_loader):
109
+ inputs, targets = inputs.to(next(model.parameters()).device), targets.to(next(model.parameters()).device)
110
+
111
+ # Forward pass
112
+ outputs = model(inputs)
113
+ loss = loss_fn(outputs, targets)
114
+
115
+ # Backward pass
116
+ opt.zero_grad()
117
+ loss.backward()
118
+ opt.step()
119
+
120
+ train_loss += loss.item()
121
+
122
+ # Update the progress bar
123
+ avg_train_loss = train_loss / (i + 1)
124
+ bar.set_postfix({"Train Loss": avg_train_loss})
125
+ bar.update(1)
126
+
127
+ # Step the scheduler after the epoch
128
+ scheduler.step()
129
+
130
+ # Log training loss
131
+ training_history["train_loss"].append(train_loss / n_train_batch)
132
+
133
+
134
+ # Plot Predictions Every Epoch
135
+ if epoch % 1 == 0:
136
+ plt.figure(figsize=(10, 6))
137
+ plt.plot(outputs[0, :, 0].detach().cpu(), label="Prediction")
138
+ plt.plot(targets[0, :, 0].detach().cpu(), label="Actual")
139
+ plt.title(f"Epoch {epoch+1} Predictions")
140
+ plt.legend()
141
+ plt.savefig(f"predictions_epoch_{epoch+1}.png")
142
+ plt.close()
143
+
144
+ print(f"Epoch {epoch+1}/{n_epochs} Completed. Train Loss: {avg_train_loss:.6f}")
145
+
146
+ # Return the training history for analysis
147
+ return training_history
148
+
149
+
150
+
151
+ def setup_data(data, batch_size):
152
+ train_split = int(0.85 * len(data['x']))
153
+ X = data['x']
154
+ y = data['y']
155
+
156
+ X_train = X[:train_split]
157
+ y_train = y[:train_split]
158
+ X_val = X[train_split:]
159
+ y_val = y[train_split:]
160
+
161
+ def normalize_dataset(data):
162
+ data_min = data.amin(dim=(0, 1), keepdim=True)
163
+ data_max = data.amax(dim=(0, 1), keepdim=True)
164
+ normalized_data = (data - data_min) / (data_max - data_min + 1e-8)
165
+ return normalized_data
166
+
167
+ X_train_norm = normalize_dataset(X_train)
168
+ y_train_norm = normalize_dataset(y_train)
169
+ X_val_norm = normalize_dataset(X_val)
170
+ y_val_norm = normalize_dataset(y_val)
171
+
172
+ train_dataset = TensorDataset(X_train_norm, y_train_norm)
173
+ val_dataset = TensorDataset(X_val_norm, y_val_norm)
174
+
175
+ train_loader = DataLoader(
176
+ train_dataset,
177
+ batch_size=batch_size,
178
+ shuffle=True,
179
+ collate_fn=lambda x: tuple(x_.to(device) for x_ in default_collate(x)),
180
+ )
181
+ return train_loader
182
+
183
+
184
+ if __name__ == "__main__":
185
+ device = torch.device('cuda:1')
186
+ raw_data = torch.load('../../data/processed/striding/data.pt')
187
+
188
+ train_loader = setup_data(data=raw_data, batch_size=2048)
189
+
190
+ lr = 0.001
191
+ adam = torch.optim.Adam(model.parameters(), lr=lr)
192
+ linear_scheduler = lr_scheduler.LinearLR(adam, start_factor=1.0, end_factor=0.5, total_iters=30)
193
+
194
+ history = train(
195
+ n_epochs=100,
196
+ model=model,
197
+ opt=adam,
198
+ scheduler=linear_scheduler,
199
+ loss_fn=torch.nn.HuberLoss(),
200
+ train_loader=train_loader,
201
+ save_path="./best_model.pt"
202
+ )
203
+
204
+ # Save final model
205
+ torch.save(model.state_dict(), "./final_model.pt")
206
+
207
+
208
+
sensor_calibration_data ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 1
2
+ 0.0136, -0.008133, 0.0043
3
+
4
+ 2
5
+ 0.0049, 0.0006, -0.0086
6
+ 0.0006, 0.0037, -0.0122
7
+ 0.0055, 0.0012, -0.0098
8
+
9
+ 3
10
+ 0.0086, -0.0012, 0.0031
11
+ 0.0086, 0.0000, 0.0031
12
+ 0.0086, 0.0000, 0.0024
13
+
14
+ 4
15
+ 0.0000, -0.0031, 0.0061
16
+ 0.0000, -0.0037, 0.0061
17
+ 0.0000, -0.0037, 0.0061
18
+
19
+ 5
20
+ 0.0073, -0.0079, 0.0024
21
+ 0.0067, -0.0079, 0.0024
22
+ 0.0073, -0.0079, 0.0024
23
+
24
+ 7
25
+ -0.0012, -0.0049, -0.0159
26
+ -0.0012, -0.0049, -0.0147
27
+ -0.0012, -0.0049, -0.0153
28
+
29
+ 9
30
+ 0.0018, -0.0061, 0.0000
31
+ 0.0012, -0.0061, 0.0000
32
+ 0.0018, -0.0061, -0.0006
33
+
34
+ 10
35
+ 0.0086, -0.0079, -0.0006
36
+
37
+ 11
38
+ -0.0073, -0.0073, -0.0012