Skip to content

Commit e28af73

Browse files
zyunlammpkarpov-ui
andauthored
Add more telem attributes (#65)
* Add more telem attributes * Add faster telem rate * Set coding rate to 8 * Add work * fix tilt comment / code * Add kf velocity --------- Co-authored-by: Michael K <mkarpov2@illinois.edu>
1 parent cea1a41 commit e28af73

File tree

4 files changed

+58
-21
lines changed

4 files changed

+58
-21
lines changed

MIDAS/src/hardware/telemetry_backend.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ ErrorCode TelemetryBackend::init() {
6161
if (!rf95.setFrequency(RF95_FREQ)) {
6262
return ErrorCode::RadioSetFrequencyFailed;
6363
}
64-
rf95.setSignalBandwidth(125000);
64+
rf95.setSignalBandwidth(250000);
6565
rf95.setCodingRate4(8);
66-
rf95.setSpreadingFactor(10);
66+
rf95.setSpreadingFactor(8);
6767
rf95.setPayloadCRC(true);
6868
/*
6969
* The default transmitter power is 13dBm, using PA_BOOST.

MIDAS/src/telemetry.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
#include "telemetry.h"
44

5+
inline long map(long x, long in_min, long in_max, long out_min, long out_max) {
6+
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
7+
}
8+
59

610
/**
711
* @brief This function maps an input value onto within a particular range into a fixed point value of a certin binary
@@ -28,16 +32,17 @@ T inv_convert_range(float val, float range) {
2832
*
2933
* @return tuple with packed data
3034
*/
31-
std::tuple<uint16_t, uint16_t, uint16_t> pack_highg_tilt(HighGData const& highg, uint8_t tilt) {
35+
std::tuple<uint16_t, uint16_t, uint16_t, uint16_t> pack_highg_tilt(HighGData const& highg, uint16_t tilt) {
3236
uint16_t ax = (uint16_t)inv_convert_range<int16_t>(highg.ax, 32);
3337
uint16_t ay = (uint16_t)inv_convert_range<int16_t>(highg.ay, 32);
3438
uint16_t az = (uint16_t)inv_convert_range<int16_t>(highg.az, 32);
3539

3640
uint16_t x = (ax & 0xfffc) | ((tilt >> 0) & 0x3);
3741
uint16_t y = (ay & 0xfffc) | ((tilt >> 2) & 0x3);
3842
uint16_t z = (az & 0xfffc) | ((tilt >> 4) & 0x3);
43+
uint16_t q = (tilt >> 6) & 15;
3944

40-
return {x,y,z};
45+
return {x,y,z,q};
4146
}
4247

4348
/**
@@ -52,7 +57,7 @@ Telemetry::Telemetry(TelemetryBackend&& backend) : backend(std::move(backend)) {
5257
* @param led led state to transmit
5358
*/
5459
void Telemetry::transmit(RocketData& rocket_data, LEDController& led) {
55-
static_assert(sizeof(TelemetryPacket) == 20);
60+
// static_assert(sizeof(TelemetryPacket) == 20);
5661

5762
TelemetryPacket packet = makePacket(rocket_data);
5863
led.toggle(LED::BLUE);
@@ -83,20 +88,30 @@ TelemetryPacket Telemetry::makePacket(RocketData& data) {
8388
HighGData highg = data.high_g.getRecentUnsync();
8489
PyroState pyro = data.pyro.getRecentUnsync();
8590
Orientation orientation = data.orientation.getRecentUnsync();
91+
KalmanData kalman = data.kalman.getRecentUnsync();
8692

8793
packet.lat = gps.latitude;
8894
packet.lon = gps.longitude;
8995
packet.alt = (((int16_t) gps.altitude) & 0xfffe) | (received_count & 0x0001); // Convert range of value so that we can also account for negative altitudes
9096
packet.baro_alt = inv_convert_range<int16_t>(barometer.altitude, 1 << 17);
9197

92-
auto [ax,ay,az] = pack_highg_tilt(highg, map(static_cast<long>(orientation.tilt * 100),0, 314, 0, 63));
98+
auto [ax,ay,az, tilt_extra] = pack_highg_tilt(highg, map(static_cast<long>(orientation.tilt * 100),0, 314, 0, 1023));
9399
packet.highg_ax = ax;
94100
packet.highg_ay = ay;
95101
packet.highg_az = az;
96102
packet.batt_volt = inv_convert_range<uint8_t>(voltage.voltage, 16);
103+
104+
const float max_volts = 12;
105+
packet.pyro |= ((((uint16_t) (continuity.pins[0] / max_volts * 127)) & 0x7F) << (0 * 7));
106+
packet.pyro |= ((((uint16_t) (continuity.pins[1] / max_volts * 127)) & 0x7F) << (1 * 7));
107+
packet.pyro |= ((((uint16_t) (continuity.pins[2] / max_volts * 127)) & 0x7F) << (2 * 7));
108+
packet.pyro |= ((((uint16_t) (continuity.pins[3] / max_volts * 127)) & 0x7F) << (3 * 7));
109+
packet.pyro |= tilt_extra << 28;
110+
97111
static_assert(FSMState::FSM_STATE_COUNT < 16);
98112
uint8_t sat_count = gps.satellite_count < 8 ? gps.satellite_count : 7;
99113
packet.fsm_callsign_satcount = ((uint8_t)fsm) | (sat_count << 4);
114+
packet.kf_vx = kalman.velocity.vx;
100115

101116
#ifdef IS_SUSTAINER
102117
packet.fsm_callsign_satcount |= (1 << 7);

MIDAS/src/telemetry_packet.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ struct TelemetryPacket {
1818
uint16_t highg_az; //14 bit signed ax [-16,16) 2 bit tilt angle
1919
uint8_t batt_volt;
2020

21-
2221
// If callsign bit (highest bit of fsm_callsign_satcount) is set, the callsign is KD9ZMJ
2322
//
2423
// If callsign bit (highest bit of fsm_callsign_satcount) is not set, the callsign is KD9ZPM
2524

2625
uint8_t fsm_callsign_satcount; //4 bit fsm state, 1 bit is_sustainer_callsign, 3 bits sat count
27-
};
26+
uint16_t kf_vx; // 16 bit meters/second
27+
uint32_t pyro; // 7 bit continuity 4 bit tilt
28+
} __attribute__((packed));
2829

2930

3031
// Commands transmitted from ground station to rocket

ground/src/feather/main.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#define VoltagePin 14
3434
// #define LED 13 // Blinks on receipt
3535

36-
float RF95_FREQ = 420;
36+
float RF95_FREQ = 426.15;
3737
float SUSTAINER_FREQ = 426.15;
3838
float BOOSTER_FREQ = 425.15;
3939
float GROUND_FREQ = 420;
@@ -75,13 +75,20 @@ float convert_range(T val, float range) {
7575
struct TelemetryPacket {
7676
int32_t lat;
7777
int32_t lon;
78-
int16_t alt;
79-
int16_t baro_alt;
78+
uint16_t alt; //15 bit meters, 1 bit command ack
79+
uint16_t baro_alt;
8080
uint16_t highg_ax; //14 bit signed ax [-16,16) 2 bit tilt angle
81-
uint16_t highg_ay; //1bit sign 13 bit unsigned [0,16) 2 bit tilt angle
82-
uint16_t highg_az; //1bit sign 13 bit unsigned [0,16) 2 bit tilt angle
81+
uint16_t highg_ay; //14 bit signed ax [-16,16) 2 bit tilt angle
82+
uint16_t highg_az; //14 bit signed ax [-16,16) 2 bit tilt angle
8383
uint8_t batt_volt;
84-
uint8_t fsm_satcount;
84+
85+
// If callsign bit (highest bit of fsm_callsign_satcount) is set, the callsign is KD9ZMJ
86+
//
87+
// If callsign bit (highest bit of fsm_callsign_satcount) is not set, the callsign is KD9ZPM
88+
89+
uint8_t fsm_callsign_satcount; //4 bit fsm state, 1 bit is_sustainer_callsign, 3 bits sat count
90+
uint16_t kf_vx; // 16 bit meters/second
91+
uint32_t pyro; // 7 bit continuity 4 bit tilt
8592
float RSSI = 0.0;
8693
};
8794

@@ -100,7 +107,9 @@ struct FullTelemetryData {
100107
float freq;
101108
float rssi;
102109
float sat_count;
110+
float pyros[4];
103111
bool is_sustainer;
112+
uint16_t kf_vx
104113
};
105114

106115

@@ -166,20 +175,25 @@ void EnqueuePacket(const TelemetryPacket& packet, float frequency) {
166175
data.longitude = ConvertGPS(packet.lon);
167176
data.barometer_altitude = convert_range<int16_t>(packet.baro_alt, 1 << 17);
168177
int tilt = decodeLastTwoBits(packet.highg_ax, packet.highg_ay, packet.highg_az);
178+
tilt |= (packet.pyro >> 28 & (0xF)) << 6;
169179
int16_t ax = packet.highg_ax & 0xfffc;
170180
int16_t ay = packet.highg_ay & 0xfffc;
171181
int16_t az = packet.highg_az & 0xfffc;
172182
data.highG_ax = convert_range<int16_t>(ax, 32);
173183
data.highG_ay = convert_range<int16_t>(ay, 32);
174184
data.highG_az = convert_range<int16_t>(az, 32);
175-
data.tilt_angle = tilt; //convert_range(tilt, 180); // [-90, 90]
185+
data.tilt_angle = tilt / 1023. * 180; // Returns tilt angle in range [0, 180]
176186
data.battery_voltage = convert_range(packet.batt_volt, 16);
177-
data.sat_count = packet.fsm_satcount >> 4 & 0b0111;
178-
data.is_sustainer = (packet.fsm_satcount >> 7);
179-
data.FSM_State = packet.fsm_satcount & 0b1111;
187+
data.sat_count = packet.fsm_callsign_satcount >> 4 & 0b0111;
188+
data.is_sustainer = (packet.fsm_callsign_satcount >> 7);
189+
data.FSM_State = packet.fsm_callsign_satcount & 0b1111;
190+
data.pyros[0] = ((float) ((packet.pyro >> 0) & (0x7F)) / 127.) * 12.;
191+
data.pyros[1] = ((float) ((packet.pyro >> 7) & (0x7F)) / 127.) * 12.;
192+
data.pyros[2] = ((float) ((packet.pyro >> 14) & (0x7F)) / 127.) * 12.;
193+
data.pyros[3] = ((float) ((packet.pyro >> 21) & (0x7F)) / 127.) * 12.;
180194

181195
// kinda hacky but it will work
182-
if (packet.fsm_satcount == static_cast<uint8_t>(-1)) {
196+
if (packet.fsm_callsign_satcount == static_cast<uint8_t>(-1)) {
183197
data.FSM_State = static_cast<uint8_t>(-1);
184198
}
185199

@@ -239,7 +253,12 @@ void printPacketJson(FullTelemetryData const& packet) {
239253
printJSONField("frequency", packet.freq);
240254
printJSONField("RSSI", packet.rssi);
241255
printJSONField("sat_count", packet.sat_count);
242-
printJSONField("is_sustainer", packet.is_sustainer, false);
256+
printJSONField("kf_velocity", packet.kf_vx);
257+
printJSONField("is_sustainer", packet.is_sustainer);
258+
printJSONField("pyro_a", packet.pyros[0]);
259+
printJSONField("pyro_b", packet.pyros[1]);
260+
printJSONField("pyro_c", packet.pyros[2]);
261+
printJSONField("pyro_d", packet.pyros[3], false);
243262
Serial.println("}}");
244263
}
245264

@@ -344,8 +363,10 @@ void setup() {
344363
rf95.setCodingRate4(8);
345364
rf95.setSpreadingFactor(8);
346365
rf95.setPayloadCRC(true);
347-
rf95.setSignalBandwidth(125000);
366+
367+
rf95.setSignalBandwidth(250000);
348368
rf95.setPreambleLength(8);
369+
349370
Serial.print(R"({"type": "freq_success", "frequency":)");
350371
Serial.print(current_freq);
351372
Serial.println("}");

0 commit comments

Comments
 (0)