added adc to UavcanNode and uavcan handler FC side. Added custom dsdl message for adc::Report and a uORB topic for analog voltage/current

This commit is contained in:
Jacob Dahl
2020-08-13 14:49:59 -08:00
parent f19a18798b
commit 8031b94f32
11 changed files with 222 additions and 4 deletions
+1
View File
@@ -41,6 +41,7 @@ set(msg_files
adc_report.msg
airspeed.msg
airspeed_validated.msg
analog_voltage_current.msg
battery_status.msg
camera_capture.msg
camera_trigger.msg
+4
View File
@@ -0,0 +1,4 @@
uint64 timestamp # time since system start (microseconds)
uint16[2] voltage
uint16[2] current
+4 -3
View File
@@ -126,14 +126,15 @@ px4_add_module(
actuators/hardpoint.cpp
# Sensors
sensors/sensor_bridge.cpp
sensors/differential_pressure.cpp
sensors/adc.cpp
sensors/airspeed.cpp
sensors/baro.cpp
sensors/battery.cpp
sensors/airspeed.cpp
sensors/differential_pressure.cpp
sensors/flow.cpp
sensors/gnss.cpp
sensors/mag.cpp
sensors/sensor_bridge.cpp
DEPENDS
px4_uavcan_dsdlc
@@ -0,0 +1,6 @@
uint2 UNITS_RAW = 0
uint2 UNITS_MV = 1
uint2 UNITS_MA = 2
uint2[2] unit_type
int16[2] values # TODO: do we want to include all of the ADC measurements or just two for voltage/current on power port?
+84
View File
@@ -0,0 +1,84 @@
/****************************************************************************
*
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include <drivers/drv_hrt.h>
#include "adc.hpp"
const char *const UavcanAdcBridge::NAME = "adc";
UavcanAdcBridge::UavcanAdcBridge(uavcan::INode &node) :
UavcanCDevSensorBridgeBase("uavcan_airspeed", "/dev/uavcan/adc", "/dev/adc", ORB_ID(analog_voltage_current)),
_sub_adc_data(node)
{ }
int UavcanAdcBridge::init()
{
int res = device::CDev::init();
if (res < 0) {
return res;
}
res = _sub_adc_data.start(AdcCbBinder(this, &UavcanAdcBridge::adc_sub_cb));
if (res < 0) {
DEVICE_LOG("failed to start uavcan sub: %d", res);
return res;
}
return 0;
}
void
UavcanAdcBridge::adc_sub_cb(const
uavcan::ReceivedDataStructure<com::volansi::equipment::adc::Report> &msg)
{
analog_voltage_current_s report{};
static constexpr int numIndices = 2;
static constexpr uint16_t mV = com::volansi::equipment::adc::Report::UNITS_MV;
static constexpr uint16_t mA = com::volansi::equipment::adc::Report::UNITS_MA;
for (int i = 0; i < numIndices; i++) {
// TODO: do we want to publish raw ADC values? What about temperature?
if (msg.unit_type[i] == mV) {
report.voltage[i] = msg.values[i];
} else if (msg.unit_type[i] == mA) {
report.current[i] = msg.values[i];
}
}
publish(msg.getSrcNodeID().get(), &report);
}
+66
View File
@@ -0,0 +1,66 @@
/****************************************************************************
*
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @author RJ Gritter <rjgritter657@gmail.com>
*/
#pragma once
#include "sensor_bridge.hpp"
#include <uORB/topics/analog_voltage_current.h>
#include <com/volansi/equipment/adc/Report.hpp>
class UavcanAdcBridge : public UavcanCDevSensorBridgeBase
{
public:
static const char *const NAME;
UavcanAdcBridge(uavcan::INode &node);
const char *get_name() const override { return NAME; }
int init() override;
private:
void adc_sub_cb(const uavcan::ReceivedDataStructure<com::volansi::equipment::adc::Report> &msg);
typedef uavcan::MethodBinder < UavcanAdcBridge *,
void (UavcanAdcBridge::*)
(const uavcan::ReceivedDataStructure<com::volansi::equipment::adc::Report> &) >
AdcCbBinder;
uavcan::Subscriber<com::volansi::equipment::adc::Report, AdcCbBinder> _sub_adc_data;
};
@@ -38,6 +38,7 @@
#include "sensor_bridge.hpp"
#include <cassert>
#include "adc.hpp"
#include "differential_pressure.hpp"
#include "baro.hpp"
#include "battery.hpp"
@@ -58,6 +59,7 @@ void IUavcanSensorBridge::make_all(uavcan::INode &node, List<IUavcanSensorBridge
list.add(new UavcanBatteryBridge(node));
list.add(new UavcanAirspeedBridge(node));
list.add(new UavcanDifferentialPressureBridge(node));
list.add(new UavcanAdcBridge(node));
}
/*
+31
View File
@@ -81,6 +81,7 @@ UavcanNode::UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &sys
_air_data_static_temperature_publisher(_node),
_raw_air_data_publisher(_node),
_range_sensor_measurement(_node),
_adc_report_publisher(_node),
_cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": cycle time")),
_interval_perf(perf_alloc(PC_INTERVAL, MODULE_NAME": cycle interval")),
_reset_timer(_node)
@@ -330,6 +331,7 @@ void UavcanNode::Run()
PX4_ERR("node spin error %i", spin_res);
}
send_adc_measurements();
send_battery_info();
send_raw_air_data();
send_static_pressure();
@@ -529,6 +531,35 @@ void UavcanNode::send_gnss_fix2()
}
}
void UavcanNode::send_adc_measurements()
{
// vehicle_gps_position -> uavcan::equipment::gnss::Fix2
if (_adc_report_sub.updated()) {
adc_report_s adc_report;
if (_adc_report_sub.copy(&adc_report)) {
// We could probably convince people an ADC uavcan data type
// would be useful to have in tree...
com::volansi::equipment::adc::Report report{};
int32_t adc1_units = 0;
int32_t adc2_units = 0;
(void)param_get(param_find("ADC1_UNIT_TYPE"), &adc1_units);
(void)param_get(param_find("ADC2_UNIT_TYPE"), &adc2_units);
report.unit_type[0] = (unsigned)adc1_units;
report.unit_type[1] = (unsigned)adc2_units;
// Always indices 0 and 1?
report.values[0] = adc_report.raw_data[0];
report.values[1] = adc_report.raw_data[1];
_adc_report_publisher.broadcast(report);
}
}
}
void UavcanNode::print_info()
{
pthread_mutex_lock(&_node_mutex);
+8 -1
View File
@@ -64,6 +64,7 @@
#include <uavcan/equipment/gnss/Fix2.hpp>
#include <uavcan/equipment/power/BatteryInfo.hpp>
#include <uavcan/equipment/range_sensor/Measurement.hpp>
#include <com/volansi/equipment/adc/Report.hpp>
#include <lib/parameters/param.h>
@@ -71,10 +72,11 @@
#include <uORB/Subscription.hpp>
#include <uORB/SubscriptionCallback.hpp>
#include <uORB/topics/adc_report.h>
#include <uORB/topics/battery_status.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/differential_pressure.h>
#include <uORB/topics/distance_sensor.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_baro.h>
#include <uORB/topics/sensor_mag.h>
#include <uORB/topics/vehicle_gps_position.h>
@@ -152,6 +154,7 @@ private:
void send_magnetic_field_strength2();
void send_gnss_fix2();
void send_range_sensor_measurement();
void send_adc_measurements();
px4::atomic_bool _task_should_exit{false}; ///< flag to indicate to tear down the CAN driver
@@ -183,6 +186,8 @@ private:
uavcan::Publisher<uavcan::equipment::air_data::StaticTemperature> _air_data_static_temperature_publisher;
uavcan::Publisher<uavcan::equipment::air_data::RawAirData> _raw_air_data_publisher;
uavcan::Publisher<uavcan::equipment::range_sensor::Measurement> _range_sensor_measurement;
uavcan::Publisher<com::volansi::equipment::adc::Report> _adc_report_publisher;
hrt_abstime _last_static_temperature_publish{0};
@@ -199,6 +204,8 @@ private:
uORB::SubscriptionCallbackWorkItem _sensor_baro_sub{this, ORB_ID(sensor_baro)};
uORB::SubscriptionCallbackWorkItem _sensor_mag_sub{this, ORB_ID(sensor_mag)};
uORB::SubscriptionCallbackWorkItem _vehicle_gps_position_sub{this, ORB_ID(vehicle_gps_position)};
uORB::SubscriptionCallbackWorkItem _adc_report_sub{this, ORB_ID(adc_report)};
perf_counter_t _cycle_perf;
perf_counter_t _interval_perf;
@@ -0,0 +1,6 @@
uint2 UNITS_RAW = 0
uint2 UNITS_MV = 1
uint2 UNITS_MA = 2
uint2[2] unit_type
int16[2] values # TODO: do we want to include all of the ADC measurements or just two for voltage/current on power port?
@@ -50,3 +50,13 @@ PARAM_DEFINE_INT32(CANNODE_NODE_ID, 120);
* @group UAVCAN
*/
PARAM_DEFINE_INT32(CANNODE_BITRATE, 1000000);
/**
* Units associated with ADC measurement.
* 0 - raw
* 1 - mV
* 2 - mA
* @group UAVCAN
*/
PARAM_DEFINE_INT32(ADC1_UNIT_TYPE, 1);
PARAM_DEFINE_INT32(ADC2_UNIT_TYPE, 2);