@@ -66,71 +66,44 @@ AFBRS50::~AFBRS50()
66
66
Argus_DestroyHandle (_hnd);
67
67
68
68
perf_free (_sample_perf);
69
- perf_free (_comms_errors);
70
- perf_free (_not_ready_perf);
69
+ perf_free (_callback_error);
70
+ perf_free (_process_measurement_error);
71
+ perf_free (_status_not_ready_perf);
72
+ perf_free (_trigger_fail_perf);
71
73
}
72
74
73
75
status_t AFBRS50::measurementReadyCallback (status_t status, argus_hnd_t *hnd)
74
76
{
75
77
// Called from the SPI comms thread context
78
+ STATE state = STATE::COLLECT;
76
79
77
80
if (up_interrupt_context ()) {
78
81
// We cannot be in interrupt context
79
- g_dev->recordCommsError ();
80
- return ERROR_FAIL;
82
+ g_dev->recordCallbackError ();
83
+ status = ERROR_FAIL;
84
+ state = STATE::TRIGGER;
81
85
}
82
86
83
87
if ((g_dev == nullptr ) || (status != STATUS_OK)) {
84
- g_dev->recordCommsError ();
85
- return ERROR_FAIL;
88
+ g_dev->recordCallbackError ();
89
+ status = ERROR_FAIL;
90
+ state = STATE::TRIGGER;
86
91
}
87
92
88
- g_dev->scheduleCollect ( );
93
+ g_dev->schedule (state );
89
94
90
95
return status;
91
96
}
92
97
93
- void AFBRS50::scheduleCollect ( )
98
+ void AFBRS50::schedule (STATE state )
94
99
{
95
- _state = STATE::COLLECT ;
100
+ _state = state ;
96
101
ScheduleNow ();
97
102
}
98
103
99
- void AFBRS50::recordCommsError ()
104
+ void AFBRS50::recordCallbackError ()
100
105
{
101
- perf_count (_comms_errors);
102
- }
103
-
104
- void AFBRS50::processMeasurement ()
105
- {
106
- perf_count (_sample_perf);
107
-
108
- argus_results_t res{};
109
- status_t evaluate_status = Argus_EvaluateData (_hnd, &res);
110
-
111
- if ((evaluate_status != STATUS_OK) || (res.Status != STATUS_OK)) {
112
- perf_count (_comms_errors);
113
- return ;
114
- }
115
-
116
- uint32_t result_mm = res.Bin .Range / (Q9_22_ONE / 1000 );
117
- float distance = static_cast <float >(result_mm) / 1000 .f ;
118
- int8_t quality = res.Bin .SignalQuality ;
119
-
120
- // Signal quality indicates 100% for good signals, 50% and lower for weak signals.
121
- // 1% is an errored signal (not reliable). Signal Quality of 0% is unknown.
122
- if (quality == 1 ) {
123
- quality = 0 ;
124
- }
125
-
126
- if (distance > _max_distance) {
127
- distance = 0.0 ;
128
- quality = 0 ;
129
- }
130
-
131
- _current_distance = distance;
132
- _current_quality = quality;
133
- _px4_rangefinder.update (((res.TimeStamp .sec * 1000000ULL ) + res.TimeStamp .usec ), distance, quality);
106
+ perf_count (_callback_error);
134
107
}
135
108
136
109
int AFBRS50::init ()
@@ -235,6 +208,9 @@ int AFBRS50::init()
235
208
236
209
void AFBRS50::Run ()
237
210
{
211
+ perf_end (_loop_perf);
212
+ perf_begin (_loop_perf);
213
+
238
214
if (_parameter_update_sub.updated ()) {
239
215
parameter_update_s param_update;
240
216
_parameter_update_sub.copy (¶m_update);
@@ -264,15 +240,14 @@ void AFBRS50::Run()
264
240
// Enable interrupt on falling edge
265
241
px4_arch_configgpio (BROADCOM_AFBR_S50_S2PI_IRQ);
266
242
267
- // TODO: delay after configure?
268
243
_state = STATE::TRIGGER;
269
244
ScheduleDelayed (_measurement_inverval);
270
245
}
271
246
break ;
272
247
273
248
case STATE::TRIGGER: {
274
249
if (Argus_GetStatus (_hnd) != STATUS_IDLE) {
275
- perf_count (_not_ready_perf );
250
+ perf_count (_status_not_ready_perf );
276
251
ScheduleDelayed (_measurement_inverval / 4 );
277
252
return ;
278
253
}
@@ -281,22 +256,19 @@ void AFBRS50::Run()
281
256
status_t status = Argus_TriggerMeasurement (_hnd, measurementReadyCallback);
282
257
283
258
if (status != STATUS_OK) {
284
- perf_count (_not_ready_perf);
285
- // Reschedule another trigger
259
+ perf_count (_trigger_fail_perf);
286
260
_state = STATE::TRIGGER;
287
- ScheduleDelayed (_measurement_inverval / 4 );
261
+ ScheduleDelayed (1_ms); // Try again immediately
288
262
}
289
263
290
264
// We don't reschedule, the trigger callback will schedule a collect
291
265
}
292
266
break ;
293
267
294
268
case STATE::COLLECT: {
295
- // Process and publish the measurement
296
- processMeasurement ();
297
-
298
- // Change measurement rate and mode based on range
299
- updateMeasurementRateFromRange ();
269
+ if (processMeasurement ()) {
270
+ updateMeasurementRateFromRange ();
271
+ }
300
272
301
273
_state = STATE::TRIGGER;
302
274
@@ -316,41 +288,76 @@ void AFBRS50::Run()
316
288
}
317
289
}
318
290
319
- // TODO: fix this logic
320
- // Require 3 readings on same side of fence to mode switch
321
- // Require 3_s after ground_contact in vehicle_land_detected before switching to long range mode
291
+ bool AFBRS50::processMeasurement ()
292
+ {
293
+ perf_count (_sample_perf);
294
+
295
+ argus_results_t res{};
296
+ status_t evaluate_status = Argus_EvaluateData (_hnd, &res);
297
+
298
+ if ((evaluate_status != STATUS_OK) || (res.Status != STATUS_OK)) {
299
+ perf_count (_process_measurement_error);
300
+ return 0 ;
301
+ }
302
+
303
+ uint32_t result_mm = res.Bin .Range / (Q9_22_ONE / 1000 );
304
+ float distance = static_cast <float >(result_mm) / 1000 .f ;
305
+ int8_t quality = res.Bin .SignalQuality ;
306
+
307
+ // Signal quality indicates 100% for good signals, 50% and lower for weak signals.
308
+ // 1% is an errored signal (not reliable). Signal Quality of 0% is unknown.
309
+ if (quality == 1 ) {
310
+ quality = 0 ;
311
+ }
312
+
313
+ if (distance > _max_distance * 1 .5f ) {
314
+ distance = 0.0 ;
315
+ quality = 0 ;
316
+ }
317
+
318
+ _current_distance = distance;
319
+ _current_quality = quality;
320
+ _px4_rangefinder.update (((res.TimeStamp .sec * 1000000ULL ) + res.TimeStamp .usec ), distance, quality);
321
+ return 1 ;
322
+ }
323
+
324
+ // TODO: Require 3 consecutive readings on same side of fence to mode switch
322
325
void AFBRS50::updateMeasurementRateFromRange ()
323
326
{
324
- // only update mode if _current_distance is a valid measurement and if the last rate switch was more than 1 second ago
325
- if ((_current_distance > 0 ) && (_current_quality > 0 ) && (( hrt_absolute_time () - _last_rate_switch) > 1_s)) {
327
+ bool valid_distance = ( _current_distance > 0 ) && (_current_quality > 0 );
328
+ bool switch_allowed = hrt_elapsed_time (& _last_rate_switch) > 1_s;
326
329
327
- status_t status = STATUS_OK;
330
+ if (valid_distance && switch_allowed) {
328
331
329
- if (( _current_distance >= (_p_sens_afbr_thresh.get () + _p_sens_afbr_hyster.get ()))
330
- && ( _current_rate != ( uint32_t ) _p_sens_afbr_l_rate.get ())) {
332
+ bool above_threshold = _current_distance >= (_p_sens_afbr_thresh.get () + _p_sens_afbr_hyster.get ());
333
+ bool in_long_range_mode = _current_rate == _p_sens_afbr_l_rate.get ();
331
334
332
- _current_rate = (uint32_t )_p_sens_afbr_l_rate.get ();
333
- status = setRateAndDfm (_current_rate, DFM_MODE_8X);
335
+ bool below_threshold = _current_distance <= (_p_sens_afbr_thresh.get () - _p_sens_afbr_hyster.get ());
336
+ bool in_short_range_mode = _current_rate == _p_sens_afbr_s_rate.get ();
337
+
338
+ if (above_threshold && !in_long_range_mode) {
339
+
340
+ _current_rate = _p_sens_afbr_l_rate.get ();
341
+ auto status = setRateAndDfm (_current_rate, DFM_MODE_8X);
334
342
335
343
if (status != STATUS_OK) {
336
- PX4_ERR (" set_rate status not okay: %i " , ( int ) status);
344
+ PX4_ERR (" set_rate status not okay: %ld " , status);
337
345
338
346
} else {
339
- PX4_INFO (" switched to long range rate: %i " , ( int ) _current_rate);
347
+ PX4_INFO (" switched to long range rate: %d " , _current_rate);
340
348
_last_rate_switch = hrt_absolute_time ();
341
349
}
342
350
343
- } else if ((_current_distance <= (_p_sens_afbr_thresh.get () - _p_sens_afbr_hyster.get ()))
344
- && (_current_rate != (uint32_t )_p_sens_afbr_s_rate.get ())) {
351
+ } else if (below_threshold && !in_short_range_mode) {
345
352
346
- _current_rate = ( uint32_t ) _p_sens_afbr_s_rate.get ();
347
- status = setRateAndDfm (_current_rate, DFM_MODE_OFF);
353
+ _current_rate = _p_sens_afbr_s_rate.get ();
354
+ auto status = setRateAndDfm (_current_rate, DFM_MODE_OFF);
348
355
349
356
if (status != STATUS_OK) {
350
- PX4_ERR (" set_rate status not okay: %i " , ( int ) status);
357
+ PX4_ERR (" set_rate status not okay: %ld " , status);
351
358
352
359
} else {
353
- PX4_INFO (" switched to short range rate: %i " , ( int ) _current_rate);
360
+ PX4_INFO (" switched to short range rate: %d " , _current_rate);
354
361
_last_rate_switch = hrt_absolute_time ();
355
362
}
356
363
}
@@ -441,8 +448,11 @@ argus_mode_t AFBRS50::argusModeFromParameter()
441
448
void AFBRS50::printInfo ()
442
449
{
443
450
perf_print_counter (_sample_perf);
444
- perf_print_counter (_comms_errors);
445
- perf_print_counter (_not_ready_perf);
451
+ perf_print_counter (_callback_error);
452
+ perf_print_counter (_process_measurement_error);
453
+ perf_print_counter (_status_not_ready_perf);
454
+ perf_print_counter (_trigger_fail_perf);
455
+ perf_print_counter (_loop_perf);
446
456
PX4_INFO_RAW (" distance: %.3fm\n " , (double )_current_distance);
447
457
PX4_INFO_RAW (" rate: %u Hz\n " , (uint)(1000000 / _measurement_inverval));
448
458
}
0 commit comments