Skip to content

Commit ba31054

Browse files
authored
Add RSSI in dBm support, plus LQ, to GHST protocol (PX4#24351)
1 parent 93b8bc1 commit ba31054

5 files changed

Lines changed: 35 additions & 20 deletions

File tree

src/drivers/rc/ghst_rc/GhstRc.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "GhstRc.hpp"
3535

3636
#include <termios.h>
37+
#include <math.h>
3738

3839
GhstRc::GhstRc(const char *device) :
3940
ModuleParams(nullptr),
@@ -174,16 +175,18 @@ void GhstRc::Run()
174175
if (newBytes > 0) {
175176
uint16_t raw_rc_values[input_rc_s::RC_INPUT_MAX_CHANNELS] {};
176177
uint16_t raw_rc_count = 0;
177-
int8_t ghst_rssi = -1;
178+
ghstLinkStatistics_t link_stats = { .rssi_pct = -1, .rssi_dbm = NAN, .link_quality = 0 };
178179

179-
if (ghst_parse(cycle_timestamp, &rcs_buf[0], newBytes, &raw_rc_values[0], &ghst_rssi,
180+
if (ghst_parse(cycle_timestamp, &rcs_buf[0], newBytes, &raw_rc_values[0], &link_stats,
180181
&raw_rc_count, input_rc_s::RC_INPUT_MAX_CHANNELS)
181182
) {
182183
// we have a new GHST frame. Publish it.
183184
input_rc_s input_rc{};
184185
input_rc.timestamp_last_signal = cycle_timestamp;
185186
input_rc.channel_count = math::constrain(raw_rc_count, (uint16_t)0, (uint16_t)input_rc_s::RC_INPUT_MAX_CHANNELS);
186-
input_rc.rssi = ghst_rssi;
187+
input_rc.rssi = link_stats.rssi_pct;
188+
input_rc.link_quality = link_stats.link_quality;
189+
input_rc.rssi_dbm = link_stats.rssi_dbm;
187190
input_rc.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_GHST;
188191

189192
unsigned valid_chans = 0;
@@ -200,13 +203,11 @@ void GhstRc::Run()
200203

201204
if (valid_chans == 0) {
202205
input_rc.rssi = 0;
206+
// can't force link quality to zero here, receiver takes care of this
203207
}
204208

205209
input_rc.rc_lost = (valid_chans == 0);
206210

207-
input_rc.link_quality = -1;
208-
input_rc.rssi_dbm = NAN;
209-
210211
input_rc.timestamp = hrt_absolute_time();
211212
_input_rc_pub.publish(input_rc);
212213
perf_count(_publish_interval_perf);

src/drivers/rc_input/RCInput.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,14 +762,15 @@ void RCInput::Run()
762762

763763
// parse new data
764764
if (newBytes > 0) {
765-
int8_t ghst_rssi = -1;
766-
rc_updated = ghst_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &ghst_rssi,
765+
ghstLinkStatistics_t link_stats = { .rssi_pct = -1, .rssi_dbm = NAN, .link_quality = 0 };
766+
767+
rc_updated = ghst_parse(cycle_timestamp, &_rcs_buf[0], newBytes, &_raw_rc_values[0], &link_stats,
767768
&_raw_rc_count, input_rc_s::RC_INPUT_MAX_CHANNELS);
768769

769770
if (rc_updated) {
770771
// we have a new GHST frame. Publish it.
771772
_input_rc.input_source = input_rc_s::RC_INPUT_SOURCE_PX4FMU_GHST;
772-
int32_t valid_chans = fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, false, false, 0, ghst_rssi);
773+
int32_t valid_chans = fill_rc_in(_raw_rc_count, _raw_rc_values, cycle_timestamp, false, false, 0, link_stats.rssi_pct);
773774

774775
// ghst telemetry works on fmu-v5
775776
// on other Pixhawk (-related) boards we cannot write to the RC UART

src/lib/rc/ghst.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include <termios.h>
5757
#include <string.h>
5858
#include <unistd.h>
59+
#include <math.h>
5960

6061
// TODO: include RSSI dBm to percentage conversion for ghost receiver
6162
#include "spektrum_rssi.h"
@@ -77,8 +78,8 @@ enum class ghst_parser_state_t : uint8_t {
7778
synced
7879
};
7980

80-
// only RSSI frame contains value of RSSI, if it is not received, send last received RSSI
81-
static int8_t ghst_rssi = -1;
81+
// only RSSI frame contains value of RSSI, if it is not received, send last received RSSI/LQ
82+
static ghstLinkStatistics_t last_link_stats = { .rssi_pct = -1, .rssi_dbm = NAN, .link_quality = 0 };
8283

8384
static ghst_frame_t &ghst_frame = rc_decode_buf.ghst_frame;
8485
static uint32_t current_frame_position = 0U;
@@ -89,7 +90,8 @@ static uint16_t prev_rc_vals[GHST_MAX_NUM_CHANNELS];
8990
/**
9091
* parse the current ghst_frame buffer
9192
*/
92-
static bool ghst_parse_buffer(uint16_t *values, int8_t *rssi, uint16_t *num_values, uint16_t max_channels);
93+
static bool ghst_parse_buffer(uint16_t *values, ghstLinkStatistics_t *link_stats, uint16_t *num_values,
94+
uint16_t max_channels);
9395

9496
int ghst_config(int uart_fd)
9597
{
@@ -114,7 +116,7 @@ static uint16_t convert_channel_value(unsigned chan_value);
114116

115117

116118
bool ghst_parse(const uint64_t now, const uint8_t *frame, unsigned len, uint16_t *values,
117-
int8_t *rssi, uint16_t *num_values, uint16_t max_channels)
119+
ghstLinkStatistics_t *link_stats, uint16_t *num_values, uint16_t max_channels)
118120
{
119121
bool success = false;
120122
uint8_t *ghst_frame_ptr = (uint8_t *)&ghst_frame;
@@ -145,7 +147,7 @@ bool ghst_parse(const uint64_t now, const uint8_t *frame, unsigned len, uint16_t
145147
len -= current_len;
146148
frame += current_len;
147149

148-
if (ghst_parse_buffer(values, rssi, num_values, max_channels)) {
150+
if (ghst_parse_buffer(values, link_stats, num_values, max_channels)) {
149151
success = true;
150152
}
151153
}
@@ -182,7 +184,8 @@ static uint16_t convert_channel_value(unsigned int chan_value)
182184
return converted_chan_value;
183185
}
184186

185-
static bool ghst_parse_buffer(uint16_t *values, int8_t *rssi, uint16_t *num_values, uint16_t max_channels)
187+
static bool ghst_parse_buffer(uint16_t *values, ghstLinkStatistics_t *link_stats, uint16_t *num_values,
188+
uint16_t max_channels)
186189
{
187190
uint8_t *ghst_frame_ptr = (uint8_t *)&ghst_frame;
188191

@@ -299,13 +302,16 @@ static bool ghst_parse_buffer(uint16_t *values, int8_t *rssi, uint16_t *num_valu
299302
} else if (ghst_frame.type == static_cast<uint8_t>(ghstFrameType::frameTypeRssi)) {
300303
const ghstPayloadRssi_t *const rssiValues = (ghstPayloadRssi_t *)&ghst_frame.payload;
301304
// TODO: call function for RSSI dBm to percentage conversion for ghost receiver
302-
ghst_rssi = spek_dbm_to_percent(static_cast<int8_t>(rssiValues->rssidBm));
305+
last_link_stats.rssi_pct = spek_dbm_to_percent(static_cast<int8_t>
306+
(rssiValues->rssidBm)); // rssidBm sign inverted (90 = -90dBm)
307+
last_link_stats.rssi_dbm = -rssiValues->rssidBm;
308+
last_link_stats.link_quality = rssiValues->lq; // 0 - 100
303309

304310
} else {
305311
GHST_DEBUG("Frame type: %u", ghst_frame.type);
306312
}
307313

308-
*rssi = ghst_rssi;
314+
*link_stats = last_link_stats;
309315

310316
memcpy(prev_rc_vals, values, sizeof(uint16_t) * GHST_MAX_NUM_CHANNELS);
311317

src/lib/rc/ghst.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ typedef struct {
106106
int txPowerdBm: 8; // Tx power [dBm]
107107
} __attribute__((__packed__)) ghstPayloadRssi_t;
108108

109+
// Link statistics for internal transport
110+
typedef struct {
111+
int8_t rssi_pct;
112+
float rssi_dbm;
113+
int8_t link_quality;
114+
} ghstLinkStatistics_t;
115+
109116
/**
110117
* Configure an UART port to be used for GHST
111118
* @param uart_fd UART file descriptor
@@ -127,7 +134,7 @@ __EXPORT int ghst_config(int uart_fd);
127134
* @return true if channels successfully decoded
128135
*/
129136
__EXPORT bool ghst_parse(const uint64_t now, const uint8_t *frame, unsigned len, uint16_t *values,
130-
int8_t *rssi, uint16_t *num_values, uint16_t max_channels);
137+
ghstLinkStatistics_t *link_stats, uint16_t *num_values, uint16_t max_channels);
131138

132139

133140
/**

src/lib/rc/rc_tests/RCTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ bool RCTest::ghstTest()
159159
uint16_t rc_values[max_channels];
160160
uint16_t num_values = 0;
161161
int line_counter = 1;
162-
int8_t ghst_rssi = -1;
162+
ghstLinkStatistics_t link_stats;
163163
ghst_config(uart_fd);
164164

165165
while (fgets(line, line_size, fp) != nullptr) {
@@ -186,7 +186,7 @@ bool RCTest::ghstTest()
186186
// Pipe the data into the parser
187187
hrt_abstime now = hrt_absolute_time();
188188

189-
bool result = ghst_parse(now, frame, frame_len, rc_values, &ghst_rssi, &num_values, max_channels);
189+
bool result = ghst_parse(now, frame, frame_len, rc_values, &link_stats, &num_values, max_channels);
190190

191191
if (result) {
192192
has_decoded_values = true;

0 commit comments

Comments
 (0)