Skip to content

Commit 4fabe17

Browse files
committed
new NRA protocol fro radars from nanoradar
1 parent 45e252d commit 4fabe17

8 files changed

+194
-4
lines changed

docs/Rangefinder.md

+13-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,19 @@ Following rangefinders are supported:
2323
* NRA15/NRA24 - experimental, UART version
2424

2525
#### NRA15/NRA24
26-
NRA15/NRA24 from nanoradar need special firmware provided by nanoradar, just ask for firmware for ardupilot.
27-
Communication protocol is USD1_V0 which is used by old US-D1 from ainstein company.
26+
NRA15/NRA24 from nanoradar use US-D1_V0 or NRA protocol, it depends which firmware you use. Radar can be set by firmware
27+
to two different resolutions. See table below.
28+
29+
| Radar | Protocol | Resolution | Name in configurator |
30+
|-------|----------|-----------------|-----------------------|
31+
| NRA15 | US-D1_V0 | 0-30m (+-4cm) | USD1_V0 |
32+
| NRA15 | NRA | 0-30m (+-4cm) | NRA15/NRA24 |
33+
| NRA15 | NRA | 0-100m (+-10cm) | NRA15/NRA24 |
34+
| NRA24 | US-D1_V0 | 0-50m (+-4cm) | USD1_V0 |
35+
| NRA24 | US-D1_V0 | 0-200m (+-10cm) | USD1_V0 |
36+
| NRA24 | NRA | 0-50m (+-4cm) | NRA15/NRA24 |
37+
| NRA24 | NRA | 0-200m (+-10cm) | NRA15/NRA24 |
38+
2839

2940
## Connections
3041

src/main/CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ main_sources(COMMON_SRC
482482
io/rangefinder.h
483483
io/rangefinder_msp.c
484484
io/rangefinder_benewake.c
485-
io/rangefinder_usd1_v0.c
485+
io/rangefinder_usd1_v0.c
486+
io/rangefinder_nanoradar.c
486487
io/rangefinder_fake.c
487488
io/opflow.h
488489
io/opflow_cxof.c

src/main/fc/settings.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tables:
77
values: ["NONE", "AUTO", "MPU6000", "MPU6500", "MPU9250", "BMI160", "ICM20689", "BMI088", "ICM42605", "BMI270","LSM6DXX", "FAKE"]
88
enum: accelerationSensor_e
99
- name: rangefinder_hardware
10-
values: ["NONE", "SRF10", "VL53L0X", "MSP", "BENEWAKE", "VL53L1X", "US42", "TOF10120_I2C", "FAKE", 'USD1_V0']
10+
values: ["NONE", "SRF10", "VL53L0X", "MSP", "BENEWAKE", "VL53L1X", "US42", "TOF10120_I2C", "FAKE", 'USD1_V0', 'NRA15/NRA24']
1111
enum: rangefinderType_e
1212
- name: mag_hardware
1313
values: ["NONE", "AUTO", "HMC5883", "AK8975", "MAG3110", "AK8963", "IST8310", "QMC5883", "MPU9250", "IST8308", "LIS3MDL", "MSP", "RM3100", "VCM5883", "MLX90393", "FAKE"]

src/main/io/rangefinder.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
extern virtualRangefinderVTable_t rangefinderMSPVtable;
3333
extern virtualRangefinderVTable_t rangefinderBenewakeVtable;
3434
extern virtualRangefinderVTable_t rangefinderUSD1Vtable;
35+
extern virtualRangefinderVTable_t rangefinderNanoradarVtable; //NRA15/NRA24
3536
extern virtualRangefinderVTable_t rangefinderFakeVtable;
3637

3738
void mspRangefinderReceiveNewData(uint8_t * bufferPtr);

src/main/io/rangefinder_nanoradar.c

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* This file is part of INAV Project.
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
6+
* You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*
8+
* Alternatively, the contents of this file may be used under the terms
9+
* of the GNU General Public License Version 3, as described below:
10+
*
11+
* This file is free software: you may copy, redistribute and/or modify
12+
* it under the terms of the GNU General Public License as published by the
13+
* Free Software Foundation, either version 3 of the License, or (at your
14+
* option) any later version.
15+
*
16+
* This file is distributed in the hope that it will be useful, but
17+
* WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
19+
* Public License for more details.
20+
*
21+
* You should have received a copy of the GNU General Public License
22+
* along with this program. If not, see http://www.gnu.org/licenses/.
23+
*/
24+
25+
#include <stdbool.h>
26+
#include <ctype.h>
27+
28+
#include "platform.h"
29+
#include "io/serial.h"
30+
#include "drivers/time.h"
31+
32+
#if defined(USE_RANGEFINDER_NANORADAR)
33+
#include "drivers/rangefinder/rangefinder_virtual.h"
34+
35+
#define NANORADAR_HDR 0xAA // Header Byte
36+
#define NANORADAR_END 0x55
37+
38+
#define NANORADAR_COMMAND_TARGET_INFO 0x70C
39+
40+
typedef struct __attribute__((packed)) {
41+
uint8_t header0;
42+
uint8_t header1;
43+
uint8_t commandH;
44+
uint8_t commandL;
45+
uint8_t index; // Target ID
46+
uint8_t rcs; // The section of radar reflection
47+
uint8_t rangeH; // Target distance high 8 bi
48+
uint8_t rangeL; // Target distance low 8 bit
49+
uint8_t rsvd1;
50+
uint8_t info; // VrelH Rsvd1 RollCount
51+
uint8_t vrelL;
52+
uint8_t SNR; // Signal-Noise Ratio
53+
uint8_t end0;
54+
uint8_t end1;
55+
} nanoradarPacket_t;
56+
57+
#define NANORADAR_PACKET_SIZE sizeof(nanoradarPacket_t)
58+
#define NANORADAR_TIMEOUT_MS 2000 // 2s
59+
60+
static bool hasNewData = false;
61+
static bool hasEverData = false;
62+
static serialPort_t * serialPort = NULL;
63+
static serialPortConfig_t * portConfig;
64+
static uint8_t buffer[NANORADAR_PACKET_SIZE];
65+
static unsigned bufferPtr;
66+
67+
static int32_t sensorData = RANGEFINDER_NO_NEW_DATA;
68+
static timeMs_t lastProtocolActivityMs;
69+
70+
static bool nanoradarRangefinderDetect(void)
71+
{
72+
portConfig = findSerialPortConfig(FUNCTION_RANGEFINDER);
73+
if (!portConfig) {
74+
return false;
75+
}
76+
77+
return true;
78+
}
79+
80+
static void nanoradarRangefinderInit(void)
81+
{
82+
if (!portConfig) {
83+
return;
84+
}
85+
86+
serialPort = openSerialPort(portConfig->identifier, FUNCTION_RANGEFINDER, NULL, NULL, 115200, MODE_RXTX, SERIAL_NOT_INVERTED);
87+
if (!serialPort) {
88+
return;
89+
}
90+
91+
lastProtocolActivityMs = 0;
92+
}
93+
94+
static void nanoradarRangefinderUpdate(void)
95+
{
96+
97+
nanoradarPacket_t *nanoradarPacket = (nanoradarPacket_t *)buffer;
98+
while (serialRxBytesWaiting(serialPort) > 0) {
99+
uint8_t c = serialRead(serialPort);
100+
101+
if (bufferPtr < NANORADAR_PACKET_SIZE) {
102+
buffer[bufferPtr++] = c;
103+
}
104+
105+
if ((bufferPtr == 1) && (nanoradarPacket->header0 != NANORADAR_HDR)) {
106+
bufferPtr = 0;
107+
continue;
108+
}
109+
110+
if ((bufferPtr == 2) && (nanoradarPacket->header1 != NANORADAR_HDR)) {
111+
bufferPtr = 0;
112+
continue;
113+
}
114+
115+
//only target info packet we are interested
116+
if (bufferPtr == 4) {
117+
uint16_t command = nanoradarPacket->commandH + (nanoradarPacket->commandL * 0x100);
118+
119+
if (command != NANORADAR_COMMAND_TARGET_INFO) {
120+
bufferPtr = 0;
121+
continue;
122+
}
123+
}
124+
125+
// Check for complete packet
126+
if (bufferPtr == NANORADAR_PACKET_SIZE) {
127+
if (nanoradarPacket->end0 == NANORADAR_END && nanoradarPacket->end1 == NANORADAR_END) {
128+
// Valid packet
129+
hasNewData = true;
130+
hasEverData = true;
131+
lastProtocolActivityMs = millis();
132+
133+
sensorData = ((nanoradarPacket->rangeH * 0x100) + nanoradarPacket->rangeL);
134+
}
135+
136+
// Prepare for new packet
137+
bufferPtr = 0;
138+
}
139+
}
140+
}
141+
142+
static int32_t nanoradarRangefinderGetDistance(void)
143+
{
144+
int32_t altitude = (sensorData > 0) ? (sensorData) : RANGEFINDER_OUT_OF_RANGE;
145+
146+
if (hasNewData) {
147+
hasNewData = false;
148+
return altitude;
149+
}
150+
else {
151+
//keep last value for timeout, because radar sends data only if change
152+
if ((millis() - lastProtocolActivityMs) < NANORADAR_TIMEOUT_MS) {
153+
return altitude;
154+
}
155+
156+
return hasEverData ? RANGEFINDER_OUT_OF_RANGE : RANGEFINDER_NO_NEW_DATA;
157+
}
158+
}
159+
160+
virtualRangefinderVTable_t rangefinderNanoradarVtable = {
161+
.detect = nanoradarRangefinderDetect,
162+
.init = nanoradarRangefinderInit,
163+
.update = nanoradarRangefinderUpdate,
164+
.read = nanoradarRangefinderGetDistance
165+
};
166+
167+
#endif

src/main/sensors/rangefinder.c

+8
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ static bool rangefinderDetect(rangefinderDev_t * dev, uint8_t rangefinderHardwar
129129
rangefinderHardware = RANGEFINDER_USD1_V0;
130130
rescheduleTask(TASK_RANGEFINDER, TASK_PERIOD_MS(RANGEFINDER_VIRTUAL_TASK_PERIOD_MS));
131131
}
132+
#endif
133+
break;
134+
case RANGEFINDER_NANORADAR:
135+
#if defined(USE_RANGEFINDER_NANORADAR)
136+
if (virtualRangefinderDetect(dev, &rangefinderNanoradarVtable)) {
137+
rangefinderHardware = RANGEFINDER_NANORADAR;
138+
rescheduleTask(TASK_RANGEFINDER, TASK_PERIOD_MS(RANGEFINDER_VIRTUAL_TASK_PERIOD_MS));
139+
}
132140
#endif
133141
break;
134142

src/main/sensors/rangefinder.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef enum {
3232
RANGEFINDER_TOF10102I2C = 7,
3333
RANGEFINDER_FAKE = 8,
3434
RANGEFINDER_USD1_V0 = 9,
35+
RANGEFINDER_NANORADAR = 10,
3536
} rangefinderType_e;
3637

3738
typedef struct rangefinderConfig_s {

src/main/target/common.h

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#define USE_RANGEFINDER_US42
8585
#define USE_RANGEFINDER_TOF10120_I2C
8686
#define USE_RANGEFINDER_USD1_V0
87+
#define USE_RANGEFINDER_NANORADAR
8788

8889
// Allow default optic flow boards
8990
#define USE_OPFLOW

0 commit comments

Comments
 (0)