Skip to content

Commit 1eb91f2

Browse files
authored
Detailed WFB-ng facts available for OSD (#41)
* 1st attempt to use wfb-cli msgpack socket * Use public JSON api instead of private msgpack one See svpcom/wfb-ng#382 * Document WFB stats facts in README
1 parent 812414f commit 1eb91f2

File tree

9 files changed

+331
-14
lines changed

9 files changed

+331
-14
lines changed

.github/workflows/build.yml

+2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ jobs:
5353
tee /etc/apt/sources.list.d/70-radxa.list <<< "deb [signed-by=/usr/share/keyrings/radxa-archive-keyring.gpg] https://radxa-repo.github.io/bullseye/ bullseye main"
5454
tee /etc/apt/sources.list.d/80-rockchip.list <<< "deb [signed-by=/usr/share/keyrings/radxa-archive-keyring.gpg] https://radxa-repo.github.io/bullseye rockchip-bullseye main"
5555
56+
rm -r /boot/* #save space
5657
apt-get update
58+
apt clean
5759
apt-get install -y cmake g++ git pkg-config librockchip-mpp-dev libcairo-dev libdrm-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libspdlog-dev nlohmann-json3-dev
5860
apt clean
5961

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ set(SOURCE_FILES
2121
src/mavlink.c
2222
src/main.cpp
2323
src/main.h
24+
src/wfbcli.hpp
25+
src/wfbcli.cpp
2426
src/scheduling_helper.hpp
2527
src/gstrtpreceiver.cpp
2628
src/gstrtpreceiver.h)

README.md

+46
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,49 @@ Currently implemented fact categories are grouped by Mavlink message types:
107107

108108
More can be easily added later. You can use `DebugWidget` to inspect the current raw value of the fact(s).
109109

110+
Pixelpilot is also able to connect to WFB-ng statistics API and extract some of the facts from there.
111+
Receiving packets statistics (each fact has "id" tag - channel name, eg "video"/"mavlink"/"tunnel" etc):
112+
113+
| Fact | Type | Description |
114+
|:------------------------------|:-----|:-------------------------------------|
115+
| `wfbcli.rx.packets.all` | uint | Number of packets received |
116+
| `wfbcli.rx.packets.all_bytes` | uint | Number of bytes received |
117+
| `wfbcli.rx.packets.dec_err` | uint | Number of packets lost |
118+
| `wfbcli.rx.packets.dec_ok` | uint | Number of good packets |
119+
| `wfbcli.rx.packets.fec_rec` | uint | Number of packets recovered with FEC |
120+
121+
Receiving per-antenna statistics (each fact has "id" - channel name and "ant_id" - antenna number tags)
122+
| Fact | Type | Description |
123+
|:-------------------------------|:-------|:------------------------------------------------|
124+
| `wfbcli.rx.ant_stats.freq` | uint | Antenna frequency, MHz, eg 5800 |
125+
| `wfbcli.rx.ant_stats.mcs` | uint | MCS value for this antenna |
126+
| `wfbcli.rx.ant_stats.bw` | uint | Bandwidth value for antenna (MHz) |
127+
| `wfbcli.rx.ant_stats.pkt_recv` | uint | Number of WiFi packets received by this antenna |
128+
| `wfbcli.rx.ant_stats.rssi_avg` | int | Average RSSI for this antenna |
129+
| `wfbcli.rx.ant_stats.snr_avg` | double | Average SNR for this antenna |
130+
131+
Transmitting packets stats (same tags as receiving packets):
132+
133+
| Fact | Type | Description |
134+
|:-----------------------------------|:-----|:-----------------------------------------|
135+
| `wfbcli.tx.packets.injected` | uint | Number of successfully injected packets |
136+
| `wfbcli.tx.packets.injected_bytes` | uint | Number of successfully injected bytes |
137+
| `wfbcli.tx.packets.dropped` | uint | Number of dropped packets |
138+
| `wfbcli.tx.packets.truncated` | uint | Number of truncated (?) packets |
139+
| `wfbcli.tx.packets.fec_timeouts` | uint | ? |
140+
| `wfbcli.tx.packets.incoming` | uint | Even TX interface may receive, n packets |
141+
| `wfbcli.tx.packets.incoming_bytes` | uint | Even TX interface may receive, n bytes |
142+
143+
Transmitting per-antenna stats (same tags as receiving antennas):
144+
145+
| Fact | Type | Description |
146+
|:-------------------------------|:-----|:-------------------------------------------|
147+
| `wfbcli.tx.ant_stats.pkt_sent` | uint | Number packets sent through this antenna |
148+
| `wfbcli.tx.ant_stats.pkt_drop` | uint | Number packets dropped by this antenna |
149+
| `wfbcli.tx.ant_stats.lat_avg` | uint | Average injection latency for this antenna |
150+
151+
#### Widgets
152+
110153
Currently we have generic widgets and more ad-hoc specific ones. Generic widgets normally can be used
111154
to display any fact (as long as datatype matches):
112155

@@ -171,6 +214,9 @@ Pixelpilot starts several threads:
171214
* MAVLINK_THREAD (if OSD and mavlink configured):
172215
reads mavlink packets from UDP, decodes and updates `osd_vars` (without any mutex).
173216
The loop yields on UDP read.
217+
* WFBCLI_THREAD (if OSD is enabled):
218+
connects to the local WFB instance stats API, reads JSON stats messages and publishes OSD facts.
219+
The loop yields on TCP read.
174220
* OSD_THREAD (if OSD is enabled):
175221
takes `drm_fd`, `output_list` and JSON config as thread parameters,
176222
receives Facts through mutex-with-timeout-protected `std::queue`, feeds Facts to widgets and

config_osd.json

+41-9
Original file line numberDiff line numberDiff line change
@@ -304,32 +304,64 @@
304304
"name": "Dump raw facts to the scren (remove `--` from `type` to enable)",
305305
"type": "---DebugWidget",
306306
"x": 10,
307-
"y": -100,
307+
"y": -200,
308308
"facts": [
309309
{
310310
"name": "mavlink.heartbeet.base_mode.armed"
311311
},
312312
{
313-
"name": "mavlink.radio_status.rssi",
313+
"name": "wfbcli.rx.packets.all",
314314
"tags": {
315-
"sysid": "3",
316-
"compid": "68"
315+
"id": "video rx"
317316
}
318317
},
319318
{
320-
"name": "mavlink.gps_raw.lat"
319+
"name": "wfbcli.rx.packets.lost",
320+
"tags": {
321+
"id": "video rx"
322+
}
321323
},
322324
{
323-
"name": "mavlink.gps_raw.lon"
325+
"name": "wfbcli.rx.ant_stats.freq",
326+
"tags": {
327+
"id": "video rx",
328+
"ant_id": "0"
329+
}
324330
},
325331
{
326-
"name": "mavlink.gps_raw.fix_type"
332+
"name": "wfbcli.rx.ant_stats.mcs",
333+
"tags": {
334+
"id": "video rx",
335+
"ant_id": "0"
336+
}
327337
},
328338
{
329-
"name": "mavlink.global_position_int.lat"
339+
"name": "wfbcli.rx.ant_stats.rssi_avg",
340+
"tags": {
341+
"id": "video rx",
342+
"ant_id": "0"
343+
}
344+
},
345+
{
346+
"name": "wfbcli.rx.ant_stats.freq",
347+
"tags": {
348+
"id": "video rx",
349+
"ant_id": "1"
350+
}
330351
},
331352
{
332-
"name": "mavlink.global_position_int.lon"
353+
"name": "wfbcli.rx.ant_stats.mcs",
354+
"tags": {
355+
"id": "video rx",
356+
"ant_id": "1"
357+
}
358+
},
359+
{
360+
"name": "wfbcli.rx.ant_stats.rssi_avg",
361+
"tags": {
362+
"id": "video rx",
363+
"ant_id": "1"
364+
}
333365
}
334366
]
335367
},

src/main.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extern "C" {
4646

4747
#include "osd.h"
4848
#include "osd.hpp"
49+
#include "wfbcli.hpp"
4950
#include "dvr.h"
5051
#include "gstrtpreceiver.h"
5152
#include "scheduling_helper.hpp"
@@ -353,6 +354,7 @@ void sig_handler(int signum)
353354
spdlog::info("Received signal {}", signum);
354355
signal_flag++;
355356
mavlink_thread_signal++;
357+
wfb_thread_signal++;
356358
osd_thread_signal++;
357359
if (dvr != NULL) {
358360
dvr->shutdown();
@@ -544,6 +546,7 @@ int main(int argc, char **argv)
544546
bool dvr_filenames_with_sequence = false;
545547
uint16_t listen_port = 5600;
546548
uint16_t mavlink_port = 14550;
549+
uint16_t wfb_port = 8103;
547550
uint16_t mode_width = 0;
548551
uint16_t mode_height = 0;
549552
uint32_t mode_vrefresh = 0;
@@ -704,6 +707,11 @@ int main(int argc, char **argv)
704707
continue;
705708
}
706709

710+
__OnArgument("--wfb-api-port") {
711+
wfb_port = atoi(__ArgValue);
712+
continue;
713+
}
714+
707715
__OnArgument("--version") {
708716
printf("PixelPilot Rockchip %d.%d\n", APP_VERSION_MAJOR, APP_VERSION_MINOR);
709717
return 0;
@@ -785,7 +793,7 @@ int main(int argc, char **argv)
785793
ret = pthread_cond_init(&video_cond, NULL);
786794
assert(!ret);
787795

788-
pthread_t tid_frame, tid_display, tid_osd, tid_mavlink, tid_dvr;
796+
pthread_t tid_frame, tid_display, tid_osd, tid_mavlink, tid_dvr, tid_wfbcli;
789797
if (dvr_template != NULL) {
790798
dvr_thread_params args;
791799
args.filename_template = dvr_template;
@@ -817,6 +825,11 @@ int main(int argc, char **argv)
817825
ret = pthread_create(&tid_mavlink, NULL, __MAVLINK_THREAD__, &signal_flag);
818826
assert(!ret);
819827
}
828+
wfb_thread_params *wfb_args = (wfb_thread_params *)malloc(sizeof *wfb_args);
829+
wfb_args->port = wfb_port;
830+
ret = pthread_create(&tid_wfbcli, NULL, __WFB_CLI_THREAD__, wfb_args);
831+
assert(!ret);
832+
820833
osd_thread_params *args = (osd_thread_params *)malloc(sizeof *args);
821834
args->fd = drm_fd;
822835
args->out = output_list;
@@ -853,6 +866,8 @@ int main(int argc, char **argv)
853866
assert(!ret);
854867
}
855868
if (enable_osd) {
869+
ret = pthread_join(tid_wfbcli, NULL);
870+
assert(!ret);
856871
ret = pthread_join(tid_osd, NULL);
857872
assert(!ret);
858873
}

src/osd.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,7 @@ void osd_add_double_fact(void *batch, char const *name, osd_tag *tags, int n_tag
16991699
facts->push_back(Fact(FactMeta(std::string(name), fact_tags), value));
17001700
};
17011701

1702-
void osd_add_str_fact(void *batch, char const *name, osd_tag *tags, int n_tags, char *value) {
1702+
void osd_add_str_fact(void *batch, char const *name, osd_tag *tags, int n_tags, const char *value) {
17031703
std::vector<Fact> *facts = static_cast<std::vector<Fact> *>(batch);
17041704
FactTags fact_tags;
17051705
mk_tags(tags, n_tags, &fact_tags);
@@ -1733,7 +1733,7 @@ void osd_publish_double_fact(char const *name, osd_tag *tags, int n_tags, double
17331733
publish(Fact(FactMeta(std::string(name), fact_tags), value));
17341734
};
17351735

1736-
void osd_publish_str_fact(char const *name, osd_tag *tags, int n_tags, char *value) {
1736+
void osd_publish_str_fact(char const *name, osd_tag *tags, int n_tags, const char *value) {
17371737
FactTags fact_tags;
17381738
mk_tags(tags, n_tags, &fact_tags);
17391739
publish(Fact(FactMeta(std::string(name), fact_tags), std::string(value)));

src/osd.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,14 @@ void osd_add_bool_fact(void *batch, char const *name, osd_tag *tags, int n_tags,
9393
void osd_add_int_fact(void *batch, char const *name, osd_tag *tags, int n_tags, long value);
9494
void osd_add_uint_fact(void *batch, char const *name, osd_tag *tags, int n_tags, ulong value);
9595
void osd_add_double_fact(void *batch, char const *name, osd_tag *tags, int n_tags, double value);
96-
void osd_add_str_fact(void *batch, char const *name, osd_tag *tags, int n_tags, char *value);
96+
void osd_add_str_fact(void *batch, char const *name, osd_tag *tags, int n_tags, const char *value);
9797

9898
// Publish individual facts
9999
void osd_publish_bool_fact(char const *name, osd_tag *tags, int n_tags, bool value);
100100
void osd_publish_int_fact(char const *name, osd_tag *tags, int n_tags, long value);
101101
void osd_publish_uint_fact(char const *name, osd_tag *tags, int n_tags, ulong value);
102102
void osd_publish_double_fact(char const *name, osd_tag *tags, int n_tags, double value);
103-
void osd_publish_str_fact(char const *name, osd_tag *tags, int n_tags, char *value);
103+
void osd_publish_str_fact(char const *name, osd_tag *tags, int n_tags, const char *value);
104104
#ifdef __cplusplus
105105
}
106106
#endif

0 commit comments

Comments
 (0)