Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions msg/SensorGps.msg
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ uint32 SYSTEM_ERROR_CPU_OVERLOAD = 32
uint32 SYSTEM_ERROR_OUTPUT_CONGESTION = 64
uint32 system_error # General errors with the connected GPS receiver

uint16 diff_age # Differential correction age [seconds]. 0xFFFF = unavailable.

uint8 ANTENNA_STATUS_UNKNOWN = 0
uint8 ANTENNA_STATUS_INIT = 1
uint8 ANTENNA_STATUS_OK = 2
uint8 ANTENNA_STATUS_SHORT = 3
uint8 ANTENNA_STATUS_OPEN = 4
uint8 antenna_status # Antenna supervisor state

uint8 ANTENNA_POWER_UNKNOWN = 0
uint8 ANTENNA_POWER_OFF = 1
uint8 ANTENNA_POWER_ON = 2
uint8 antenna_power # Antenna power status

float32 heading # heading angle of XYZ body frame rel to NED. Set to NaN if not available and updated (used for dual antenna GPS), (rad, [-PI, PI])
float32 heading_offset # heading offset of dual antenna array in body frame. Set to NaN if not applicable. (rad, [-PI, PI])
float32 heading_accuracy # heading accuracy (rad, [0, 2PI])
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/gps/devices
Submodule devices updated 2 files
+53 −12 src/ubx.cpp
+7 −4 src/ubx.h
2 changes: 1 addition & 1 deletion src/drivers/uavcan/libdronecan/dsdl
39 changes: 39 additions & 0 deletions src/drivers/uavcan/sensors/gnss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ UavcanGnssBridge::UavcanGnssBridge(uavcan::INode &node, NodeInfoPublisher *node_
UavcanSensorBridgeBase("uavcan_gnss", ORB_ID(sensor_gps), node_info_publisher),
_node(node),
_sub_auxiliary(node),
_sub_quality(node),
_sub_fix(node),
_sub_fix2(node),
_sub_gnss_heading(node),
Expand Down Expand Up @@ -90,6 +91,13 @@ UavcanGnssBridge::init()
return res;
}

res = _sub_quality.start(QualityCbBinder(this, &UavcanGnssBridge::gnss_quality_sub_cb));

if (res < 0) {
PX4_WARN("GNSS quality sub failed %i", res);
return res;
}

res = _sub_fix.start(FixCbBinder(this, &UavcanGnssBridge::gnss_fix_sub_cb));

if (res < 0) {
Expand Down Expand Up @@ -152,6 +160,13 @@ UavcanGnssBridge::gnss_auxiliary_sub_cb(const uavcan::ReceivedDataStructure<uavc
_last_gnss_auxiliary_vdop = msg.vdop;
}

void
UavcanGnssBridge::gnss_quality_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Quality> &msg)
{
_last_gnss_quality_timestamp = hrt_absolute_time();
_last_quality = msg;
}

void
UavcanGnssBridge::gnss_fix_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Fix> &msg)
{
Expand Down Expand Up @@ -557,6 +572,30 @@ void UavcanGnssBridge::process_fixx(const uavcan::ReceivedDataStructure<FixType>
sensor_gps.selected_rtcm_instance = _selected_rtcm_instance;
sensor_gps.rtcm_injection_rate = _rtcm_injection_rate;

// Apply cached Quality message fields (if received within last 2s)
if (hrt_elapsed_time(&_last_gnss_quality_timestamp) < 2_s) {
sensor_gps.noise_per_ms = _last_quality.noise;
sensor_gps.automatic_gain_control = _last_quality.agc;
sensor_gps.jamming_state = _last_quality.jamming_state;
sensor_gps.jamming_indicator = _last_quality.jamming_indicator;
sensor_gps.spoofing_state = _last_quality.spoofing_state;
sensor_gps.authentication_state = _last_quality.auth_state;
sensor_gps.diff_age = _last_quality.diff_age;
sensor_gps.antenna_status = _last_quality.antenna_status;
sensor_gps.antenna_power = _last_quality.antenna_power;
sensor_gps.system_error = _last_quality.system_errors;

sensor_gnss_status_s sensor_gnss_status{};
sensor_gnss_status.timestamp = hrt_absolute_time();
sensor_gnss_status.device_id = sensor_gps.device_id;
sensor_gnss_status.quality_available = true;
sensor_gnss_status.quality_corrections = _last_quality.corrections_quality;
sensor_gnss_status.quality_receiver = _last_quality.system_status_summary;
sensor_gnss_status.quality_gnss_signals = _last_quality.gnss_signal_quality;
sensor_gnss_status.quality_post_processing = _last_quality.post_processing_quality;
_sensor_gnss_status_pub.publish(sensor_gnss_status);
}

publish(msg.getSrcNodeID().get(), &sensor_gps);
}

Expand Down
13 changes: 13 additions & 0 deletions src/drivers/uavcan/sensors/gnss.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@
#include <uORB/SubscriptionMultiArray.hpp>
#include <uORB/PublicationMulti.hpp>
#include <uORB/topics/sensor_gps.h>
#include <uORB/topics/sensor_gnss_status.h>
#include <uORB/topics/gps_inject_data.h>
#include <uORB/topics/gps_dump.h>

#include <uavcan/uavcan.hpp>
#include <uavcan/equipment/gnss/Auxiliary.hpp>
#include <uavcan/equipment/gnss/Fix.hpp>
#include <uavcan/equipment/gnss/Fix2.hpp>
#include <uavcan/equipment/gnss/Quality.hpp>
#include <ardupilot/gnss/MovingBaselineData.hpp>
#include <ardupilot/gnss/RelPosHeading.hpp>
#include <uavcan/equipment/gnss/RTCMStream.hpp>
Expand Down Expand Up @@ -82,6 +84,7 @@ class UavcanGnssBridge : public UavcanSensorBridgeBase
* GNSS fix message will be reported via this callback.
*/
void gnss_auxiliary_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Auxiliary> &msg);
void gnss_quality_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Quality> &msg);
void gnss_fix_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Fix> &msg);
void gnss_fix2_sub_cb(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Fix2> &msg);
void gnss_relative_sub_cb(const uavcan::ReceivedDataStructure<ardupilot::gnss::RelPosHeading> &msg);
Expand All @@ -106,6 +109,10 @@ class UavcanGnssBridge : public UavcanSensorBridgeBase
void (UavcanGnssBridge::*)(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Auxiliary> &) >
AuxiliaryCbBinder;

typedef uavcan::MethodBinder < UavcanGnssBridge *,
void (UavcanGnssBridge::*)(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Quality> &) >
QualityCbBinder;

typedef uavcan::MethodBinder < UavcanGnssBridge *,
void (UavcanGnssBridge::*)(const uavcan::ReceivedDataStructure<uavcan::equipment::gnss::Fix> &) >
FixCbBinder;
Expand All @@ -129,6 +136,7 @@ class UavcanGnssBridge : public UavcanSensorBridgeBase
uavcan::INode &_node;

uavcan::Subscriber<uavcan::equipment::gnss::Auxiliary, AuxiliaryCbBinder> _sub_auxiliary;
uavcan::Subscriber<uavcan::equipment::gnss::Quality, QualityCbBinder> _sub_quality;
uavcan::Subscriber<uavcan::equipment::gnss::Fix, FixCbBinder> _sub_fix;
uavcan::Subscriber<uavcan::equipment::gnss::Fix2, Fix2CbBinder> _sub_fix2;
uavcan::Subscriber<ardupilot::gnss::RelPosHeading, RelPosHeadingCbBinder> _sub_gnss_heading;
Expand All @@ -143,6 +151,11 @@ class UavcanGnssBridge : public UavcanSensorBridgeBase
float _last_gnss_auxiliary_hdop{0.0f};
float _last_gnss_auxiliary_vdop{0.0f};

uint64_t _last_gnss_quality_timestamp{0};
uavcan::equipment::gnss::Quality _last_quality{};

uORB::PublicationMulti<sensor_gnss_status_s> _sensor_gnss_status_pub{ORB_ID(sensor_gnss_status)};

uORB::SubscriptionMultiArray<gps_inject_data_s, gps_inject_data_s::MAX_INSTANCES> _orb_inject_data_sub{ORB_ID::gps_inject_data};
hrt_abstime _last_rtcm_injection_time{0}; ///< time of last rtcm injection
uint8_t _selected_rtcm_instance{0}; ///< uorb instance that is being used for RTCM corrections
Expand Down
115 changes: 115 additions & 0 deletions src/drivers/uavcannode/Publishers/GnssQuality.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/****************************************************************************
*
* Copyright (c) 2024 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.
*
****************************************************************************/

#pragma once

#include "UavcanPublisherBase.hpp"

#include <uavcan/equipment/gnss/Quality.hpp>

#include <uORB/Subscription.hpp>
#include <uORB/SubscriptionCallback.hpp>
#include <uORB/topics/sensor_gps.h>
#include <uORB/topics/sensor_gnss_status.h>

namespace uavcannode
{

class GnssQuality :
public UavcanPublisherBase,
public uORB::SubscriptionCallbackWorkItem,
private uavcan::Publisher<uavcan::equipment::gnss::Quality>
{
public:
GnssQuality(px4::WorkItem *work_item, uavcan::INode &node) :
UavcanPublisherBase(uavcan::equipment::gnss::Quality::DefaultDataTypeID),
uORB::SubscriptionCallbackWorkItem(work_item, ORB_ID(sensor_gps)),
uavcan::Publisher<uavcan::equipment::gnss::Quality>(node)
{
this->setPriority(uavcan::TransferPriority::Default);
}

void PrintInfo() override
{
if (uORB::SubscriptionCallbackWorkItem::advertised()) {
printf("\t%s -> %s:%d\n",
uORB::SubscriptionCallbackWorkItem::get_topic()->o_name,
uavcan::equipment::gnss::Quality::getDataTypeFullName(),
id());
}
}

void BroadcastAnyUpdates() override
{
using uavcan::equipment::gnss::Quality;

sensor_gps_s gps;

if (uORB::SubscriptionCallbackWorkItem::update(&gps)) {
uavcan::equipment::gnss::Quality quality{};

quality.noise = gps.noise_per_ms;
quality.agc = gps.automatic_gain_control;
quality.jamming_state = gps.jamming_state;
quality.jamming_indicator = gps.jamming_indicator;
quality.spoofing_state = gps.spoofing_state;
quality.auth_state = gps.authentication_state;
quality.diff_age = gps.diff_age;
quality.antenna_status = gps.antenna_status;
quality.antenna_power = gps.antenna_power;
quality.system_errors = gps.system_error;

quality.corrections_quality = 255;
quality.system_status_summary = 255;
quality.gnss_signal_quality = 255;
quality.post_processing_quality = 255;

sensor_gnss_status_s status;

if (_sensor_gnss_status_sub.copy(&status) && status.quality_available) {
quality.corrections_quality = status.quality_corrections;
quality.system_status_summary = status.quality_receiver;
quality.gnss_signal_quality = status.quality_gnss_signals;
quality.post_processing_quality = status.quality_post_processing;
}

uavcan::Publisher<uavcan::equipment::gnss::Quality>::broadcast(quality);

uORB::SubscriptionCallbackWorkItem::registerCallback();
}
}

private:
uORB::Subscription _sensor_gnss_status_sub{ORB_ID(sensor_gnss_status)};
};
} // namespace uavcannode
2 changes: 2 additions & 0 deletions src/drivers/uavcannode/UavcanNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#if defined(CONFIG_UAVCANNODE_GNSS_FIX)
#include "Publishers/GnssFix2.hpp"
#include "Publishers/GnssAuxiliary.hpp"
#include "Publishers/GnssQuality.hpp"
#endif // CONFIG_UAVCANNODE_GNSS_FIX

#if defined(CONFIG_UAVCANNODE_INDICATED_AIR_SPEED)
Expand Down Expand Up @@ -385,6 +386,7 @@ int UavcanNode::init(uavcan::NodeID node_id, UAVCAN_DRIVER::BusEvent &bus_events
#if defined(CONFIG_UAVCANNODE_GNSS_FIX)
_publisher_list.add(new GnssFix2(this, _node));
_publisher_list.add(new GnssAuxiliary(this, _node));
_publisher_list.add(new GnssQuality(this, _node));
#endif // CONFIG_UAVCANNODE_GNSS_FIX

#if defined(CONFIG_UAVCANNODE_MAGNETIC_FIELD_STRENGTH)
Expand Down
Loading