Skip to content

Commit fda459b

Browse files
authored
Merge pull request #24 from RTGS-Lab/feature/flightcontrol_testing
Abstraction of platform and hardware dependencies for unit testing of Kestrel
2 parents 7a95950 + 7e843c8 commit fda459b

61 files changed

Lines changed: 4229 additions & 568 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitmodules

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,9 @@
128128
[submodule "test/external/googletest"]
129129
path = test/external/googletest
130130
url = https://github.com/google/googletest.git
131-
[submodule "test/external/fff"]
132-
path = test/external/fff
133-
url = https://github.com/meekrosoft/fff.git
134131
[submodule "lib/FlightControl-platform-dependencies"]
135132
path = lib/FlightControl-platform-dependencies
136-
url = https://github.com/gemsiot/FlightControl-platform-dependencies
133+
url = https://github.com/RTGS-Lab/FlightControl-platform-dependencies.git
137134
[submodule "lib/FlightControl-hardware-dependencies"]
138135
path = lib/FlightControl-hardware-dependencies
139-
url = https://github.com/gemsiot/FlightControl-hardware-dependencies
136+
url = https://github.com/RTGS-Lab/FlightControl-hardware-dependencies

lib/Driver_-_Li710

lib/Driver_-_Sensor

src/FlightControl_Demo.cpp

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,23 @@ int configurePowerSave(int desiredPowerSaveMode);
5959
#include <vector>
6060
#include <memory>
6161

62-
#include "hardware/SDI12TalonAdapter.h"
6362
#include "platform/ParticleTimeProvider.h"
63+
#include "platform/ParticleGpio.h"
64+
#include "platform/ParticleSystem.h"
65+
#include "platform/ParticleWire.h"
66+
#include "platform/ParticleCloud.h"
67+
#include "platform/ParticleSerial.h"
68+
69+
#include "hardware/IOExpanderPCAL9535A.h"
70+
#include "hardware/SDI12TalonAdapter.h"
71+
#include "hardware/CurrentSenseAmplifierPAC1934.h"
72+
#include "hardware/LedPCA9634.h"
73+
#include "hardware/RtcMCP79412.h"
74+
#include "hardware/AmbientLightVEML3328.h"
75+
#include "hardware/GpsSFE_UBLOX_GNSS.h"
76+
#include "hardware/HumidityTemperatureAdafruit_SHT4X.h"
77+
#include "hardware/AccelerometerMXC6655.h"
78+
#include "hardware/AccelerometerBMA456.h"
6479

6580
const String firmwareVersion = "2.9.11";
6681
const String schemaVersion = "2.2.9";
@@ -70,16 +85,53 @@ const unsigned long indicatorTimeout = 60000; //Wait for up to 1 minute with ind
7085
const uint64_t balancedDiagnosticPeriod = 3600000; //Report diagnostics once an hour //DEBUG!
7186
int powerSaveMode = 0; //Default to 0, update when configure power save mode is called
7287

73-
Kestrel logger(true);
88+
ParticleTimeProvider realTimeProvider;
89+
ParticleGpio realGpio;
90+
ParticleSystem realSystem;
91+
ParticleWire realWire;
92+
ParticleCloud realCloud;
93+
ParticleUSBSerial realSerialDebug;
94+
ParticleHardwareSerial realSerialSdi12;
95+
96+
IOExpanderPCAL9535A realIoOB(0x20); //0x20 is the PCAL Base address
97+
IOExpanderPCAL9535A realIoTalon(0x21);
98+
CurrentSenseAmplifierPAC1934 realCsaAlpha(2,2,2,2,0x18);
99+
CurrentSenseAmplifierPAC1934 realCsaBeta(2,10,10,10,0x14);
100+
LedPCA9634 realLed(0x52);
101+
RtcMCP79412 realRtc;
102+
AmbientLightVEML3328 realAls;
103+
GpsSFE_UBLOX_GNSS realGps;
104+
HumidityTemperatureAdafruit_SHT4X realTempHumidity;
105+
AccelerometerMXC6655 realAccel;
106+
AccelerometerBMA456 realBackupAccel;
107+
108+
Kestrel logger(realTimeProvider,
109+
realGpio,
110+
realSystem,
111+
realWire,
112+
realCloud,
113+
realSerialDebug,
114+
realSerialSdi12,
115+
realIoOB,
116+
realIoTalon,
117+
realCsaAlpha,
118+
realCsaBeta,
119+
realLed,
120+
realRtc,
121+
realAls,
122+
realGps,
123+
realTempHumidity,
124+
realAccel,
125+
realBackupAccel,
126+
true);
74127
KestrelFileHandler fileSys(logger);
75128
Gonk battery(5); //Instantiate with defaults, manually set to port 5
76129
AuxTalon aux(0, 0x14); //Instantiate AUX talon with deaults - null port and hardware v1.4
77130
I2CTalon i2c(0, 0x21); //Instantiate I2C talon with alt - null port and hardware v2.1
78131
SDI12Talon sdi12(0, 0x14); //Instantiate SDI12 talon with alt - null port and hardware v1.4
79-
PCAL9535A ioAlpha(0x20);
80-
PCAL9535A ioBeta(0x21);
81132
SDI12TalonAdapter realSdi12(sdi12);
82-
ParticleTimeProvider realTimeProvider;
133+
IOExpanderPCAL9535A ioAlpha(0x20);
134+
IOExpanderPCAL9535A ioBeta(0x21);
83135

84136
String globalNodeID = ""; //Store current node ID
85137

@@ -122,7 +174,7 @@ Hedorah gas(0, 0, 0x10); //Instantiate CO2 sensor with default ports and v1.0 ha
122174
LI710 et(realTimeProvider, realSdi12, 0, 0); //Instantiate ET sensor with default ports and unknown version, pass over SDI12 Talon interface
123175
BaroVue10 campPressure(sdi12, 0, 0x00); // Instantiate Barovue10 with default ports and v0.0 hardware
124176

125-
const uint8_t numSensors = 7; //Number must match the number of objects defined in `sensors` array
177+
const uint8_t numSensors = 8; //Number must match the number of objects defined in `sensors` array
126178

127179
Sensor* const sensors[numSensors] = {
128180
&fileSys,
@@ -131,8 +183,8 @@ Sensor* const sensors[numSensors] = {
131183
&sdi12,
132184
&battery,
133185
&logger, //Add sensors after this line
134-
&et
135-
// &haar,
186+
&et,
187+
&haar
136188
// &soil1,
137189
// &apogeeSolar,
138190

@@ -289,13 +341,13 @@ void setup() {
289341
// fileSys.writeToSD(initDiagnostic, "Dummy.txt");
290342

291343
#ifndef RAPID_START //Only do this if not rapid starting
292-
while((!Particle.connected() || logger.gps.getFixType() == 0) && (millis() - startTime) < maxConnectTime) { //Wait while at least one of the remote systems is not connected
344+
while((!Particle.connected() || logger.m_gps.getFixType() == 0) && (millis() - startTime) < maxConnectTime) { //Wait while at least one of the remote systems is not connected
293345
if(Particle.connected()) {
294346
logger.setIndicatorState(IndicatorLight::CELL, IndicatorMode::PASS); //If cell is connected, set to PASS state
295347
if(WAIT_GPS == false) break; //If not told to wait for GPS, break out after cell is connected
296348
}
297-
if(logger.gps.getTimeValid() == true) {
298-
if(logger.gps.getFixType() >= 2 && logger.gps.getFixType() <= 4 && logger.gps.getGnssFixOk()) { //If you get a 2D fix or better, pass GPS
349+
if(logger.m_gps.getTimeValid() == true) {
350+
if(logger.m_gps.getFixType() >= 2 && logger.m_gps.getFixType() <= 4 && logger.m_gps.getGnssFixOk()) { //If you get a 2D fix or better, pass GPS
299351
logger.setIndicatorState(IndicatorLight::GPS, IndicatorMode::PASS);
300352
}
301353
else {
@@ -312,7 +364,7 @@ void setup() {
312364
logger.setIndicatorState(IndicatorLight::CELL, IndicatorMode::ERROR); //If cell still not connected, display error
313365
// Particle.disconnect(); //DEBUG!
314366
}
315-
if(logger.gps.getFixType() >= 2 && logger.gps.getFixType() <= 4 && logger.gps.getGnssFixOk()) { //Make fix report is in range and fix is OK
367+
if(logger.m_gps.getFixType() >= 2 && logger.m_gps.getFixType() <= 4 && logger.m_gps.getGnssFixOk()) { //Make fix report is in range and fix is OK
316368
logger.setIndicatorState(IndicatorLight::GPS, IndicatorMode::PASS); //Catches connection of GPS is second device to connect
317369
}
318370
else {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @file AccelerometerBMA456.cpp
3+
* @brief Implementation of the AccelerometerBMA456 class.
4+
*
5+
* © 2025 Regents of the University of Minnesota. All rights reserved.
6+
*/
7+
8+
#include "AccelerometerBMA456.h"
9+
10+
AccelerometerBMA456::AccelerometerBMA456() : accel() {
11+
// Default constructor, nothing to initialize here
12+
}
13+
14+
int AccelerometerBMA456::begin() {
15+
return accel.begin();
16+
}
17+
18+
float AccelerometerBMA456::getAccel(uint8_t axis, uint8_t range) {
19+
float x, y, z;
20+
accel.getAcceleration(&x, &y, &z);
21+
switch(axis)
22+
{
23+
case 0:
24+
return x;
25+
case 1:
26+
return y;
27+
case 2:
28+
return z;
29+
default:
30+
return x;
31+
}
32+
}
33+
34+
int AccelerometerBMA456::updateAccelAll() {
35+
accel.initialize();
36+
return 0;
37+
}
38+
39+
float AccelerometerBMA456::getTemp() {
40+
return accel.getTemperature();
41+
}
42+
43+
float* AccelerometerBMA456::getData() { //unimplemented
44+
return 0;
45+
}
46+
47+
float* AccelerometerBMA456::getOffset() { //unimplemented
48+
return 0;
49+
}
50+
51+
void AccelerometerBMA456::setOffset(float offsetX, float offsetY, float offsetZ) { //unimplemented
52+
}

src/hardware/AccelerometerBMA456.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @file AccelerometerBMA456.h
3+
* @brief Concrete implementation of IAccelerometer using BMA456
4+
*
5+
* Adapts the BMA456 accelerometer to the IAccelerometer interface
6+
* for dependency injection and testing.
7+
*
8+
* © 2025 Regents of the University of Minnesota. All rights reserved.
9+
*/
10+
11+
#ifndef ACCELEROMETER_BMA456_H
12+
#define ACCELEROMETER_BMA456_H
13+
14+
#include "IAccelerometer.h"
15+
#include "arduino_bma456.h"
16+
17+
/**
18+
* @brief Concrete implementation of IAccelerometer using BMA456
19+
*/
20+
class AccelerometerBMA456 : public IAccelerometer {
21+
public:
22+
/**
23+
* @brief Constructor
24+
*/
25+
AccelerometerBMA456();
26+
~AccelerometerBMA456() override = default;
27+
28+
int begin() override;
29+
float getAccel(uint8_t axis, uint8_t range = 0) override;
30+
int updateAccelAll() override;
31+
float getTemp() override;
32+
float* getData() override;
33+
float* getOffset() override;
34+
void setOffset(float offsetX, float offsetY, float offsetZ) override;
35+
36+
private:
37+
BMA456 accel; // The concrete BMA456 instance
38+
};
39+
40+
#endif // ACCELEROMETER_BMA456_H

0 commit comments

Comments
 (0)