2013-08-29 02:34:34 -03:00
|
|
|
/*
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2012-01-10 19:44:04 -04:00
|
|
|
#include "RangeFinder.h"
|
2014-06-26 23:56:50 -03:00
|
|
|
#include "AP_RangeFinder_analog.h"
|
2014-06-27 00:39:52 -03:00
|
|
|
#include "AP_RangeFinder_PulsedLightLRF.h"
|
2014-06-27 01:03:47 -03:00
|
|
|
#include "AP_RangeFinder_MaxsonarI2CXL.h"
|
2016-04-19 18:32:17 -03:00
|
|
|
#include "AP_RangeFinder_MaxsonarSerialLV.h"
|
2015-07-06 16:24:06 -03:00
|
|
|
#include "AP_RangeFinder_BBB_PRU.h"
|
2015-08-28 06:52:34 -03:00
|
|
|
#include "AP_RangeFinder_LightWareI2C.h"
|
2015-09-07 02:32:06 -03:00
|
|
|
#include "AP_RangeFinder_LightWareSerial.h"
|
2017-12-11 17:53:28 -04:00
|
|
|
#if (CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP || \
|
|
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO) && \
|
|
|
|
defined(HAVE_LIBIIO)
|
2016-04-15 14:31:51 -03:00
|
|
|
#include "AP_RangeFinder_Bebop.h"
|
2017-12-11 17:53:28 -04:00
|
|
|
#endif
|
2016-05-03 23:57:07 -03:00
|
|
|
#include "AP_RangeFinder_MAVLink.h"
|
2016-09-13 00:24:41 -03:00
|
|
|
#include "AP_RangeFinder_LeddarOne.h"
|
2016-11-14 17:47:45 -04:00
|
|
|
#include "AP_RangeFinder_uLanding.h"
|
2017-07-28 09:46:52 -03:00
|
|
|
#include "AP_RangeFinder_TeraRangerI2C.h"
|
2017-03-09 19:38:28 -04:00
|
|
|
#include "AP_RangeFinder_VL53L0X.h"
|
2018-11-17 07:17:51 -04:00
|
|
|
#include "AP_RangeFinder_VL53L1X.h"
|
2018-05-14 02:03:08 -03:00
|
|
|
#include "AP_RangeFinder_NMEA.h"
|
2018-05-16 19:31:22 -03:00
|
|
|
#include "AP_RangeFinder_Wasp.h"
|
2018-05-25 22:59:36 -03:00
|
|
|
#include "AP_RangeFinder_Benewake.h"
|
2019-04-26 04:23:45 -03:00
|
|
|
#include "AP_RangeFinder_Benewake_TFMiniPlus.h"
|
2018-08-29 11:18:49 -03:00
|
|
|
#include "AP_RangeFinder_PWM.h"
|
2019-03-28 09:43:23 -03:00
|
|
|
#include "AP_RangeFinder_BLPing.h"
|
2019-04-08 06:42:46 -03:00
|
|
|
#include "AP_RangeFinder_UAVCAN.h"
|
2019-08-31 08:21:01 -03:00
|
|
|
#include "AP_RangeFinder_Lanbao.h"
|
2012-01-10 19:44:04 -04:00
|
|
|
|
2019-07-09 03:14:52 -03:00
|
|
|
#include <AP_BoardConfig/AP_BoardConfig.h>
|
2019-04-05 06:20:22 -03:00
|
|
|
#include <AP_Logger/AP_Logger.h>
|
2019-07-09 03:14:52 -03:00
|
|
|
#include <AP_SerialManager/AP_SerialManager.h>
|
|
|
|
#include <AP_Vehicle/AP_Vehicle_Type.h>
|
2019-04-05 06:20:22 -03:00
|
|
|
|
2016-04-14 13:42:06 -03:00
|
|
|
extern const AP_HAL::HAL &hal;
|
2016-04-14 17:00:38 -03:00
|
|
|
|
2014-06-26 23:56:50 -03:00
|
|
|
// table of user settable parameters
|
2015-10-25 14:03:46 -03:00
|
|
|
const AP_Param::GroupInfo RangeFinder::var_info[] = {
|
2018-07-04 11:22:17 -03:00
|
|
|
|
|
|
|
// @Group: 1_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
2019-06-10 23:47:56 -03:00
|
|
|
AP_SUBGROUPINFO(params[0], "1_", 25, RangeFinder, AP_RangeFinder_Params),
|
2018-07-04 11:22:17 -03:00
|
|
|
|
|
|
|
// @Group: 1_
|
2018-05-24 23:00:02 -03:00
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
2018-07-04 11:22:17 -03:00
|
|
|
AP_SUBGROUPVARPTR(drivers[0], "1_", 57, RangeFinder, backend_var_info[0]),
|
2018-05-16 19:31:22 -03:00
|
|
|
|
2016-10-16 19:15:06 -03:00
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 1
|
2018-07-04 11:22:17 -03:00
|
|
|
// @Group: 2_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[1], "2_", 27, RangeFinder, AP_RangeFinder_Params),
|
2018-05-16 19:31:22 -03:00
|
|
|
|
2018-05-24 23:00:02 -03:00
|
|
|
// @Group: 2_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
2018-07-04 11:22:17 -03:00
|
|
|
AP_SUBGROUPVARPTR(drivers[1], "2_", 58, RangeFinder, backend_var_info[1]),
|
2015-08-28 06:52:34 -03:00
|
|
|
#endif
|
2015-09-10 07:27:12 -03:00
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 2
|
2018-07-04 11:22:17 -03:00
|
|
|
// @Group: 3_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[2], "3_", 29, RangeFinder, AP_RangeFinder_Params),
|
2018-05-16 19:31:22 -03:00
|
|
|
|
2018-05-24 23:00:02 -03:00
|
|
|
// @Group: 3_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
2018-07-04 11:22:17 -03:00
|
|
|
AP_SUBGROUPVARPTR(drivers[2], "3_", 59, RangeFinder, backend_var_info[2]),
|
2016-07-26 02:47:25 -03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 3
|
2018-07-04 11:22:17 -03:00
|
|
|
// @Group: 4_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[3], "4_", 31, RangeFinder, AP_RangeFinder_Params),
|
2018-05-16 19:31:22 -03:00
|
|
|
|
2018-05-24 23:00:02 -03:00
|
|
|
// @Group: 4_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
2018-07-04 11:22:17 -03:00
|
|
|
AP_SUBGROUPVARPTR(drivers[0], "4_", 60, RangeFinder, backend_var_info[3]),
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 4
|
|
|
|
// @Group: 5_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[4], "5_", 33, RangeFinder, AP_RangeFinder_Params),
|
|
|
|
|
|
|
|
// @Group: 5_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
|
|
|
AP_SUBGROUPVARPTR(drivers[4], "5_", 34, RangeFinder, backend_var_info[4]),
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 5
|
|
|
|
// @Group: 6_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[5], "6_", 35, RangeFinder, AP_RangeFinder_Params),
|
|
|
|
|
|
|
|
// @Group: 6_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
|
|
|
AP_SUBGROUPVARPTR(drivers[5], "6_", 36, RangeFinder, backend_var_info[5]),
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 6
|
|
|
|
// @Group: 7_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[6], "7_", 37, RangeFinder, AP_RangeFinder_Params),
|
|
|
|
|
|
|
|
// @Group: 7_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
|
|
|
AP_SUBGROUPVARPTR(drivers[6], "7_", 38, RangeFinder, backend_var_info[6]),
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 7
|
|
|
|
// @Group: 8_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[7], "8_", 39, RangeFinder, AP_RangeFinder_Params),
|
|
|
|
|
|
|
|
// @Group: 8_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
|
|
|
AP_SUBGROUPVARPTR(drivers[7], "8_", 40, RangeFinder, backend_var_info[7]),
|
2015-09-10 07:27:12 -03:00
|
|
|
#endif
|
2018-05-16 19:31:22 -03:00
|
|
|
|
2018-07-04 11:22:17 -03:00
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 8
|
|
|
|
// @Group: 9_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[8], "9_", 41, RangeFinder, AP_RangeFinder_Params),
|
|
|
|
|
|
|
|
// @Group: 9_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
|
|
|
AP_SUBGROUPVARPTR(drivers[8], "9_", 42, RangeFinder, backend_var_info[8]),
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if RANGEFINDER_MAX_INSTANCES > 9
|
|
|
|
// @Group: A_
|
|
|
|
// @Path: AP_RangeFinder_Params.cpp
|
|
|
|
AP_SUBGROUPINFO(params[9], "A_", 43, RangeFinder, AP_RangeFinder_Params),
|
|
|
|
|
|
|
|
// @Group: A_
|
|
|
|
// @Path: AP_RangeFinder_Wasp.cpp
|
|
|
|
AP_SUBGROUPVARPTR(drivers[9], "A_", 44, RangeFinder, backend_var_info[9]),
|
|
|
|
#endif
|
|
|
|
|
2014-06-26 23:56:50 -03:00
|
|
|
AP_GROUPEND
|
|
|
|
};
|
|
|
|
|
2018-05-16 20:05:50 -03:00
|
|
|
const AP_Param::GroupInfo *RangeFinder::backend_var_info[RANGEFINDER_MAX_INSTANCES];
|
|
|
|
|
2019-07-09 03:14:52 -03:00
|
|
|
RangeFinder::RangeFinder()
|
2015-06-08 00:10:43 -03:00
|
|
|
{
|
|
|
|
AP_Param::setup_object_defaults(this, var_info);
|
|
|
|
|
2018-05-09 04:45:26 -03:00
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
|
|
|
|
if (_singleton != nullptr) {
|
|
|
|
AP_HAL::panic("Rangefinder must be singleton");
|
|
|
|
}
|
|
|
|
#endif // CONFIG_HAL_BOARD == HAL_BOARD_SITL
|
|
|
|
_singleton = this;
|
2015-06-08 00:10:43 -03:00
|
|
|
}
|
|
|
|
|
2018-07-04 11:22:17 -03:00
|
|
|
void RangeFinder::convert_params(void) {
|
|
|
|
if (params[0].type.configured_in_storage()) {
|
|
|
|
// _params[0]._type will always be configured in storage after conversion is done the first time
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ConversionTable {
|
|
|
|
uint8_t old_element;
|
|
|
|
uint8_t new_index;
|
|
|
|
uint8_t instance;
|
|
|
|
};
|
|
|
|
|
|
|
|
const struct ConversionTable conversionTable[] = {
|
2019-11-28 03:00:03 -04:00
|
|
|
// rangefinder 1
|
2018-07-04 11:22:17 -03:00
|
|
|
{0, 0, 0}, //0, TYPE 1
|
|
|
|
{1, 1, 0}, //1, PIN 1
|
|
|
|
{2, 2, 0}, //2, SCALING 1
|
|
|
|
{3, 3, 0}, //3, OFFSET 1
|
|
|
|
{4, 4, 0}, //4, FUNCTION 1
|
|
|
|
{5, 5, 0}, //5, MIN_CM 1
|
|
|
|
{6, 6, 0}, //6, MAX_CM 1
|
|
|
|
{7, 7, 0}, //7, STOP_PIN 1
|
2019-11-28 03:00:03 -04:00
|
|
|
{9, 8, 0}, //9, RMETRIC 1
|
|
|
|
{10, 9, 0}, //10, PWRRNG 1 (previously existed only once for all sensors)
|
|
|
|
{11, 10, 0}, //11, GNDCLEAR 1
|
|
|
|
{23, 11, 0}, //23, ADDR 1
|
|
|
|
{49, 12, 0}, //49, POS 1
|
|
|
|
{53, 13, 0}, //53, ORIENT 1
|
|
|
|
|
|
|
|
// rangefinder 2
|
2018-07-04 11:22:17 -03:00
|
|
|
{12, 0, 1}, //12, TYPE 2
|
|
|
|
{13, 1, 1}, //13, PIN 2
|
|
|
|
{14, 2, 1}, //14, SCALING 2
|
|
|
|
{15, 3, 1}, //15, OFFSET 2
|
|
|
|
{16, 4, 1}, //16, FUNCTION 2
|
|
|
|
{17, 5, 1}, //17, MIN_CM 2
|
|
|
|
{18, 6, 1}, //18, MAX_CM 2
|
|
|
|
{19, 7, 1}, //19, STOP_PIN 2
|
2019-11-28 03:00:03 -04:00
|
|
|
{21, 8, 1}, //21, RMETRIC 2
|
|
|
|
{10, 9, 1}, //10, PWRRNG 1 (previously existed only once for all sensors)
|
|
|
|
{22, 10, 1}, //22, GNDCLEAR 2
|
|
|
|
{24, 11, 1}, //24, ADDR 2
|
|
|
|
{50, 12, 1}, //50, POS 2
|
|
|
|
{54, 13, 1}, //54, ORIENT 2
|
2018-07-04 11:22:17 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
char param_name[17] = {0};
|
|
|
|
AP_Param::ConversionInfo info;
|
|
|
|
info.new_name = param_name;
|
|
|
|
|
|
|
|
#if APM_BUILD_TYPE(APM_BUILD_ArduPlane)
|
|
|
|
info.old_key = 71;
|
|
|
|
#elif APM_BUILD_TYPE(APM_BUILD_ArduCopter)
|
|
|
|
info.old_key = 53;
|
|
|
|
#elif APM_BUILD_TYPE(APM_BUILD_ArduSub)
|
|
|
|
info.old_key = 35;
|
|
|
|
#elif APM_BUILD_TYPE(APM_BUILD_APMrover2)
|
|
|
|
info.old_key = 197;
|
|
|
|
#else
|
|
|
|
params[0].type.save(true);
|
|
|
|
return; // no conversion is supported on this platform
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < ARRAY_SIZE(conversionTable); i++) {
|
|
|
|
uint8_t param_instance = conversionTable[i].instance + 1;
|
|
|
|
uint8_t destination_index = conversionTable[i].new_index;
|
|
|
|
|
|
|
|
info.old_group_element = conversionTable[i].old_element;
|
|
|
|
info.type = (ap_var_type)AP_RangeFinder_Params::var_info[destination_index].type;
|
|
|
|
|
|
|
|
hal.util->snprintf(param_name, sizeof(param_name), "RNGFND%X_%s", param_instance, AP_RangeFinder_Params::var_info[destination_index].name);
|
|
|
|
param_name[sizeof(param_name)-1] = '\0';
|
|
|
|
|
|
|
|
AP_Param::convert_old_parameter(&info, 1.0f, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// force _params[0]._type into storage to flag that conversion has been done
|
|
|
|
params[0].type.save(true);
|
|
|
|
}
|
|
|
|
|
2014-06-26 23:56:50 -03:00
|
|
|
/*
|
|
|
|
initialise the RangeFinder class. We do detection of attached range
|
|
|
|
finders here. For now we won't allow for hot-plugging of
|
|
|
|
rangefinders.
|
|
|
|
*/
|
2019-04-05 06:13:42 -03:00
|
|
|
void RangeFinder::init(enum Rotation orientation_default)
|
2014-06-26 23:56:50 -03:00
|
|
|
{
|
|
|
|
if (num_instances != 0) {
|
|
|
|
// init called a 2nd time?
|
|
|
|
return;
|
|
|
|
}
|
2018-07-04 11:22:17 -03:00
|
|
|
|
|
|
|
convert_params();
|
|
|
|
|
2019-04-05 06:13:42 -03:00
|
|
|
// set orientation defaults
|
|
|
|
for (uint8_t i=0; i<RANGEFINDER_MAX_INSTANCES; i++) {
|
|
|
|
params[i].orientation.set_default(orientation_default);
|
|
|
|
}
|
|
|
|
|
2018-02-23 08:11:47 -04:00
|
|
|
for (uint8_t i=0, serial_instance = 0; i<RANGEFINDER_MAX_INSTANCES; i++) {
|
|
|
|
// serial_instance will be increased inside detect_instance
|
|
|
|
// if a serial driver is loaded for this instance
|
|
|
|
detect_instance(i, serial_instance);
|
2016-10-30 02:24:21 -03:00
|
|
|
if (drivers[i] != nullptr) {
|
2014-06-26 23:56:50 -03:00
|
|
|
// we loaded a driver for this instance, so it must be
|
|
|
|
// present (although it may not be healthy)
|
|
|
|
num_instances = i+1;
|
|
|
|
}
|
2015-04-13 03:03:19 -03:00
|
|
|
|
|
|
|
// initialise status
|
|
|
|
state[i].status = RangeFinder_NotConnected;
|
|
|
|
state[i].range_valid_count = 0;
|
2014-06-05 11:31:15 -03:00
|
|
|
}
|
2014-06-26 23:56:50 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
update RangeFinder state for all instances. This should be called at
|
|
|
|
around 10Hz by main loop
|
|
|
|
*/
|
|
|
|
void RangeFinder::update(void)
|
|
|
|
{
|
|
|
|
for (uint8_t i=0; i<num_instances; i++) {
|
2016-10-30 02:24:21 -03:00
|
|
|
if (drivers[i] != nullptr) {
|
2018-07-04 11:22:17 -03:00
|
|
|
if (params[i].type == RangeFinder_TYPE_NONE) {
|
2014-06-26 23:56:50 -03:00
|
|
|
// allow user to disable a rangefinder at runtime
|
2015-04-13 03:03:19 -03:00
|
|
|
state[i].status = RangeFinder_NotConnected;
|
|
|
|
state[i].range_valid_count = 0;
|
2014-06-26 23:56:50 -03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
drivers[i]->update();
|
|
|
|
}
|
|
|
|
}
|
2019-04-05 06:20:22 -03:00
|
|
|
|
|
|
|
Log_RFND();
|
2014-06-26 23:56:50 -03:00
|
|
|
}
|
2016-04-14 16:59:31 -03:00
|
|
|
|
2016-11-11 17:58:46 -04:00
|
|
|
bool RangeFinder::_add_backend(AP_RangeFinder_Backend *backend)
|
2016-04-14 16:59:31 -03:00
|
|
|
{
|
|
|
|
if (!backend) {
|
2016-11-11 17:58:46 -04:00
|
|
|
return false;
|
2016-04-14 16:59:31 -03:00
|
|
|
}
|
|
|
|
if (num_instances == RANGEFINDER_MAX_INSTANCES) {
|
|
|
|
AP_HAL::panic("Too many RANGERS backends");
|
|
|
|
}
|
|
|
|
|
|
|
|
drivers[num_instances++] = backend;
|
2016-11-11 17:58:46 -04:00
|
|
|
return true;
|
2016-04-14 16:59:31 -03:00
|
|
|
}
|
2016-11-10 22:18:45 -04:00
|
|
|
|
2014-06-26 23:56:50 -03:00
|
|
|
/*
|
|
|
|
detect if an instance of a rangefinder is connected.
|
|
|
|
*/
|
2018-02-23 08:11:47 -04:00
|
|
|
void RangeFinder::detect_instance(uint8_t instance, uint8_t& serial_instance)
|
2014-06-26 23:56:50 -03:00
|
|
|
{
|
2018-07-04 11:22:17 -03:00
|
|
|
enum RangeFinder_Type _type = (enum RangeFinder_Type)params[instance].type.get();
|
2017-08-07 00:04:56 -03:00
|
|
|
switch (_type) {
|
2016-12-03 07:02:03 -04:00
|
|
|
case RangeFinder_TYPE_PLI2C:
|
2017-03-01 00:22:32 -04:00
|
|
|
case RangeFinder_TYPE_PLI2CV3:
|
2018-07-27 07:22:26 -03:00
|
|
|
case RangeFinder_TYPE_PLI2CV3HP:
|
2019-02-11 05:48:05 -04:00
|
|
|
FOREACH_I2C(i) {
|
|
|
|
if (_add_backend(AP_RangeFinder_PulsedLightLRF::detect(i, state[instance], params[instance], _type))) {
|
|
|
|
break;
|
|
|
|
}
|
2016-11-11 17:58:46 -04:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_MBI2C:
|
2019-02-11 05:48:05 -04:00
|
|
|
FOREACH_I2C(i) {
|
|
|
|
if (_add_backend(AP_RangeFinder_MaxsonarI2CXL::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(i, AP_RANGE_FINDER_MAXSONARI2CXL_DEFAULT_ADDR)))) {
|
|
|
|
break;
|
|
|
|
}
|
2017-09-23 19:33:04 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_LWI2C:
|
2018-07-04 11:22:17 -03:00
|
|
|
if (params[instance].address) {
|
2019-07-19 03:56:40 -03:00
|
|
|
// the LW20 needs a long time to boot up, so we delay 1.5s here
|
|
|
|
if (!hal.util->was_watchdog_armed()) {
|
|
|
|
hal.scheduler->delay(1500);
|
|
|
|
}
|
2017-09-23 16:25:32 -03:00
|
|
|
#ifdef HAL_RANGEFINDER_LIGHTWARE_I2C_BUS
|
2018-07-04 11:22:17 -03:00
|
|
|
_add_backend(AP_RangeFinder_LightWareI2C::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(HAL_RANGEFINDER_LIGHTWARE_I2C_BUS, params[instance].address)));
|
2017-09-23 16:25:32 -03:00
|
|
|
#else
|
2019-02-11 05:48:05 -04:00
|
|
|
FOREACH_I2C(i) {
|
|
|
|
if (_add_backend(AP_RangeFinder_LightWareI2C::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(i, params[instance].address)))) {
|
|
|
|
break;
|
|
|
|
}
|
2017-09-23 16:25:32 -03:00
|
|
|
}
|
|
|
|
#endif
|
2015-08-28 06:52:34 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
2017-07-28 09:46:52 -03:00
|
|
|
case RangeFinder_TYPE_TRI2C:
|
2018-07-04 11:22:17 -03:00
|
|
|
if (params[instance].address) {
|
2019-02-11 05:48:05 -04:00
|
|
|
FOREACH_I2C(i) {
|
|
|
|
if (_add_backend(AP_RangeFinder_TeraRangerI2C::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(i, params[instance].address)))) {
|
|
|
|
break;
|
|
|
|
}
|
2017-07-28 09:20:10 -03:00
|
|
|
}
|
2016-12-15 20:53:30 -04:00
|
|
|
}
|
|
|
|
break;
|
2017-03-09 19:38:28 -04:00
|
|
|
case RangeFinder_TYPE_VL53L0X:
|
2019-02-11 05:48:05 -04:00
|
|
|
FOREACH_I2C(i) {
|
|
|
|
if (_add_backend(AP_RangeFinder_VL53L0X::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(i, params[instance].address)))) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (_add_backend(AP_RangeFinder_VL53L1X::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(i, params[instance].address)))) {
|
|
|
|
break;
|
2018-11-17 07:17:51 -04:00
|
|
|
}
|
|
|
|
}
|
2017-03-09 19:38:28 -04:00
|
|
|
break;
|
2019-04-26 04:23:45 -03:00
|
|
|
case RangeFinder_TYPE_BenewakeTFminiPlus:
|
|
|
|
FOREACH_I2C(i) {
|
|
|
|
if (_add_backend(AP_RangeFinder_Benewake_TFMiniPlus::detect(state[instance], params[instance],
|
|
|
|
hal.i2c_mgr->get_device(i, params[instance].address)))) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2019-01-16 18:48:22 -04:00
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS
|
2018-11-06 01:17:19 -04:00
|
|
|
case RangeFinder_TYPE_PX4_PWM:
|
|
|
|
// to ease moving from PX4 to ChibiOS we'll lie a little about
|
|
|
|
// the backend driver...
|
|
|
|
if (AP_RangeFinder_PWM::detect()) {
|
2018-07-04 11:22:17 -03:00
|
|
|
drivers[instance] = new AP_RangeFinder_PWM(state[instance], params[instance], estimated_terrain_height);
|
2018-11-06 01:17:19 -04:00
|
|
|
}
|
|
|
|
break;
|
2015-07-06 16:24:06 -03:00
|
|
|
#endif
|
|
|
|
#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
2016-12-03 07:02:03 -04:00
|
|
|
case RangeFinder_TYPE_BBB_PRU:
|
2017-08-07 00:41:01 -03:00
|
|
|
if (AP_RangeFinder_BBB_PRU::detect()) {
|
2018-07-04 11:22:17 -03:00
|
|
|
drivers[instance] = new AP_RangeFinder_BBB_PRU(state[instance], params[instance]);
|
2015-07-06 16:24:06 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
2014-06-27 02:02:51 -03:00
|
|
|
#endif
|
2016-12-03 07:02:03 -04:00
|
|
|
case RangeFinder_TYPE_LWSER:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_LightWareSerial::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_LightWareSerial(state[instance], params[instance], serial_instance++);
|
2015-09-07 02:32:06 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_LEDDARONE:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_LeddarOne::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_LeddarOne(state[instance], params[instance], serial_instance++);
|
2016-09-13 00:24:41 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_ULANDING:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_uLanding::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_uLanding(state[instance], params[instance], serial_instance++);
|
2016-11-14 17:47:45 -04:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
2016-06-15 23:44:01 -03:00
|
|
|
#if (CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BEBOP || \
|
|
|
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO) && defined(HAVE_LIBIIO)
|
2016-12-03 07:02:03 -04:00
|
|
|
case RangeFinder_TYPE_BEBOP:
|
2017-08-07 00:41:01 -03:00
|
|
|
if (AP_RangeFinder_Bebop::detect()) {
|
2019-05-07 09:35:31 -03:00
|
|
|
drivers[instance] = new AP_RangeFinder_Bebop(state[instance], params[instance]);
|
2016-04-15 14:31:51 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
2016-04-15 14:31:51 -03:00
|
|
|
#endif
|
2016-12-03 07:02:03 -04:00
|
|
|
case RangeFinder_TYPE_MAVLink:
|
2017-08-07 00:41:01 -03:00
|
|
|
if (AP_RangeFinder_MAVLink::detect()) {
|
2018-07-04 11:22:17 -03:00
|
|
|
drivers[instance] = new AP_RangeFinder_MAVLink(state[instance], params[instance]);
|
2016-05-04 00:02:44 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_MBSER:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_MaxsonarSerialLV::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_MaxsonarSerialLV(state[instance], params[instance], serial_instance++);
|
2016-04-19 18:32:17 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_ANALOG:
|
2016-12-03 13:44:06 -04:00
|
|
|
// note that analog will always come back as present if the pin is valid
|
2018-07-04 11:22:17 -03:00
|
|
|
if (AP_RangeFinder_analog::detect(params[instance])) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_analog(state[instance], params[instance]);
|
2014-06-26 23:56:50 -03:00
|
|
|
}
|
2016-12-03 07:02:03 -04:00
|
|
|
break;
|
2018-05-14 02:03:08 -03:00
|
|
|
case RangeFinder_TYPE_NMEA:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_NMEA::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_NMEA(state[instance], params[instance], serial_instance++);
|
2018-05-16 19:31:22 -03:00
|
|
|
}
|
2018-05-28 17:11:53 -03:00
|
|
|
break;
|
2018-05-16 19:31:22 -03:00
|
|
|
case RangeFinder_TYPE_WASP:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_Wasp::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_Wasp(state[instance], params[instance], serial_instance++);
|
2018-05-14 02:03:08 -03:00
|
|
|
}
|
|
|
|
break;
|
2018-05-25 22:59:36 -03:00
|
|
|
case RangeFinder_TYPE_BenewakeTF02:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_Benewake::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_Benewake(state[instance], params[instance], serial_instance++, AP_RangeFinder_Benewake::BENEWAKE_TF02);
|
2018-05-25 22:59:36 -03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RangeFinder_TYPE_BenewakeTFmini:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_Benewake::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_Benewake(state[instance], params[instance], serial_instance++, AP_RangeFinder_Benewake::BENEWAKE_TFmini);
|
2018-05-25 22:59:36 -03:00
|
|
|
}
|
|
|
|
break;
|
2018-08-29 11:18:49 -03:00
|
|
|
case RangeFinder_TYPE_PWM:
|
|
|
|
if (AP_RangeFinder_PWM::detect()) {
|
2018-07-04 11:22:17 -03:00
|
|
|
drivers[instance] = new AP_RangeFinder_PWM(state[instance], params[instance], estimated_terrain_height);
|
2018-08-29 11:18:49 -03:00
|
|
|
}
|
|
|
|
break;
|
2019-03-28 09:43:23 -03:00
|
|
|
case RangeFinder_TYPE_BLPing:
|
2019-07-09 03:14:52 -03:00
|
|
|
if (AP_RangeFinder_BLPing::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_BLPing(state[instance], params[instance], serial_instance++);
|
2019-03-28 09:43:23 -03:00
|
|
|
}
|
|
|
|
break;
|
2019-08-31 08:21:01 -03:00
|
|
|
case RangeFinder_TYPE_Lanbao:
|
|
|
|
if (AP_RangeFinder_Lanbao::detect(serial_instance)) {
|
|
|
|
drivers[instance] = new AP_RangeFinder_Lanbao(state[instance], params[instance], serial_instance++);
|
|
|
|
}
|
|
|
|
break;
|
2016-12-03 07:02:03 -04:00
|
|
|
default:
|
|
|
|
break;
|
2014-06-05 11:31:15 -03:00
|
|
|
}
|
2018-05-16 20:05:50 -03:00
|
|
|
|
|
|
|
// if the backend has some local parameters then make those available in the tree
|
|
|
|
if (drivers[instance] && state[instance].var_info) {
|
|
|
|
backend_var_info[instance] = state[instance].var_info;
|
|
|
|
AP_Param::load_object_from_eeprom(drivers[instance], backend_var_info[instance]);
|
|
|
|
}
|
2012-01-10 19:44:04 -04:00
|
|
|
}
|
|
|
|
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *RangeFinder::get_backend(uint8_t id) const {
|
|
|
|
if (id >= num_instances) {
|
|
|
|
return nullptr;
|
2015-04-13 03:03:19 -03:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
if (drivers[id] != nullptr) {
|
|
|
|
if (drivers[id]->type() == RangeFinder_TYPE_NONE) {
|
|
|
|
// pretend it isn't here; disabled at runtime?
|
|
|
|
return nullptr;
|
|
|
|
}
|
2015-04-13 03:03:19 -03:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return drivers[id];
|
|
|
|
};
|
2015-04-13 03:03:19 -03:00
|
|
|
|
2017-02-09 06:26:57 -04:00
|
|
|
RangeFinder::RangeFinder_Status RangeFinder::status_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return RangeFinder_NotConnected;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->status();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
2019-04-30 07:22:49 -03:00
|
|
|
void RangeFinder::handle_msg(const mavlink_message_t &msg)
|
2017-02-09 06:26:57 -04:00
|
|
|
{
|
|
|
|
uint8_t i;
|
|
|
|
for (i=0; i<num_instances; i++) {
|
2018-07-04 11:22:17 -03:00
|
|
|
if ((drivers[i] != nullptr) && (params[i].type != RangeFinder_TYPE_NONE)) {
|
2016-05-03 23:59:01 -03:00
|
|
|
drivers[i]->handle_msg(msg);
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// return true if we have a range finder with the specified orientation
|
|
|
|
bool RangeFinder::has_orientation(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
return (find_instance(orientation) != nullptr);
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// find first range finder instance with the specified orientation
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *RangeFinder::find_instance(enum Rotation orientation) const
|
2017-02-09 06:26:57 -04:00
|
|
|
{
|
2019-10-23 19:03:55 -03:00
|
|
|
// first try for a rangefinder that is in range
|
2017-02-09 06:26:57 -04:00
|
|
|
for (uint8_t i=0; i<num_instances; i++) {
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = get_backend(i);
|
2019-10-23 19:03:55 -03:00
|
|
|
if (backend != nullptr &&
|
|
|
|
backend->orientation() == orientation &&
|
|
|
|
backend->status() == RangeFinder_Good) {
|
|
|
|
return backend;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2019-10-23 19:03:55 -03:00
|
|
|
}
|
|
|
|
// if none in range then return first with correct orientation
|
|
|
|
for (uint8_t i=0; i<num_instances; i++) {
|
|
|
|
AP_RangeFinder_Backend *backend = get_backend(i);
|
|
|
|
if (backend != nullptr &&
|
|
|
|
backend->orientation() == orientation) {
|
|
|
|
return backend;
|
2017-08-08 02:54:09 -03:00
|
|
|
}
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return nullptr;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t RangeFinder::distance_cm_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->distance_cm();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t RangeFinder::voltage_mv_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->voltage_mv();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int16_t RangeFinder::max_distance_cm_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->max_distance_cm();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int16_t RangeFinder::min_distance_cm_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->min_distance_cm();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int16_t RangeFinder::ground_clearance_cm_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
2015-04-13 03:03:19 -03:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->ground_clearance_cm();
|
2015-04-13 03:03:19 -03:00
|
|
|
}
|
|
|
|
|
2017-02-09 06:26:57 -04:00
|
|
|
bool RangeFinder::has_data_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return false;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->has_data();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t RangeFinder::range_valid_count_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->range_valid_count();
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const Vector3f &RangeFinder::get_pos_offset_orient(enum Rotation orientation) const
|
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return pos_offset_zero;
|
2017-02-09 06:26:57 -04:00
|
|
|
}
|
2017-08-08 02:54:09 -03:00
|
|
|
return backend->get_pos_offset();
|
2017-05-29 14:02:51 -03:00
|
|
|
}
|
|
|
|
|
AP_RangeFinder: support last_reading_ms
Benewake, LeddarOne, LightWareSerial, MAVLink, MaxsonarI2CXL, MaxsonarSerialLV, NMEA, PX4_PWM, uLanding and Wasp already stored the last read time so for these drivers, this change just moves that storage to the state structure
analog, BBB_PRU, Bebop, LightWareI2C, PulsedLightLRF, TeraRangerI2C, VL53L0X did not store the last read time so this was added
2018-08-27 04:02:51 -03:00
|
|
|
uint32_t RangeFinder::last_reading_ms(enum Rotation orientation) const
|
|
|
|
{
|
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return backend->last_reading_ms();
|
|
|
|
}
|
|
|
|
|
2017-08-08 04:32:53 -03:00
|
|
|
MAV_DISTANCE_SENSOR RangeFinder::get_mav_distance_sensor_type_orient(enum Rotation orientation) const
|
2017-05-29 14:02:51 -03:00
|
|
|
{
|
2017-08-08 02:54:09 -03:00
|
|
|
AP_RangeFinder_Backend *backend = find_instance(orientation);
|
|
|
|
if (backend == nullptr) {
|
|
|
|
return MAV_DISTANCE_SENSOR_UNKNOWN;
|
2017-05-29 14:02:51 -03:00
|
|
|
}
|
2017-08-08 04:32:53 -03:00
|
|
|
return backend->get_mav_distance_sensor_type();
|
2017-05-29 14:02:51 -03:00
|
|
|
}
|
2018-05-09 04:45:26 -03:00
|
|
|
|
2019-04-05 06:20:22 -03:00
|
|
|
// Write an RFND (rangefinder) packet
|
|
|
|
void RangeFinder::Log_RFND()
|
|
|
|
{
|
|
|
|
if (_log_rfnd_bit == uint32_t(-1)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
AP_Logger &logger = AP::logger();
|
|
|
|
if (!logger.should_log(_log_rfnd_bit)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-29 21:28:17 -03:00
|
|
|
for (uint8_t i=0; i<RANGEFINDER_MAX_INSTANCES; i++) {
|
|
|
|
const AP_RangeFinder_Backend *s = get_backend(i);
|
|
|
|
if (s == nullptr) {
|
|
|
|
continue;
|
|
|
|
}
|
2019-04-05 06:20:22 -03:00
|
|
|
|
2019-05-29 21:28:17 -03:00
|
|
|
const struct log_RFND pkt = {
|
|
|
|
LOG_PACKET_HEADER_INIT(LOG_RFND_MSG),
|
|
|
|
time_us : AP_HAL::micros64(),
|
|
|
|
instance : i,
|
|
|
|
dist : s->distance_cm(),
|
|
|
|
status : (uint8_t)s->status(),
|
|
|
|
orient : s->orientation(),
|
|
|
|
};
|
|
|
|
AP::logger().WriteBlock(&pkt, sizeof(pkt));
|
|
|
|
}
|
2019-04-05 06:20:22 -03:00
|
|
|
}
|
|
|
|
|
2019-04-10 04:32:15 -03:00
|
|
|
bool RangeFinder::prearm_healthy(char *failure_msg, const uint8_t failure_msg_len) const
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < RANGEFINDER_MAX_INSTANCES; i++) {
|
|
|
|
if ((params[i].type != RangeFinder_TYPE_NONE) && (drivers[i] == nullptr)) {
|
|
|
|
hal.util->snprintf(failure_msg, failure_msg_len, "Rangefinder %d was not detected", i + 1);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-05-09 04:45:26 -03:00
|
|
|
RangeFinder *RangeFinder::_singleton;
|
2019-04-05 06:20:22 -03:00
|
|
|
|
|
|
|
namespace AP {
|
|
|
|
|
|
|
|
RangeFinder *rangefinder()
|
|
|
|
{
|
|
|
|
return RangeFinder::get_singleton();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|