mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-04 21:01:37 +08:00
Added IAdHocNodeStatusUpdater
This commit is contained in:
@@ -16,6 +16,29 @@
|
|||||||
|
|
||||||
namespace uavcan
|
namespace uavcan
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* This optional interface can be implemented by the user in order to update the node status as necessary,
|
||||||
|
* immediately before the next NodeStatus message is emitted by @ref NodeStatusProvider.
|
||||||
|
*/
|
||||||
|
class IAdHocNodeStatusUpdater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This method is invoked by the library from @ref NodeStatusProvider from the library's thread immediately
|
||||||
|
* before the next NodeStatus message is transmitted. The application can implement this method to perform
|
||||||
|
* node status updates only as necessary.
|
||||||
|
* The application is expected to invoke the methods of @ref NodeStatusProvider to update the status
|
||||||
|
* from this method.
|
||||||
|
* Note that this method is only invoked when publication is happening by the timer event.
|
||||||
|
* It will NOT be invoked if the following methods are used to trigger node status publication:
|
||||||
|
* - @ref NodeStatusProvider::startAndPublish()
|
||||||
|
* - @ref NodeStatusProvider::forcePublish()
|
||||||
|
*/
|
||||||
|
virtual void updateNodeStatus() = 0;
|
||||||
|
|
||||||
|
virtual ~IAdHocNodeStatusUpdater() { }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the status and basic information about this node to other network participants.
|
* Provides the status and basic information about this node to other network participants.
|
||||||
*
|
*
|
||||||
@@ -38,6 +61,8 @@ class UAVCAN_EXPORT NodeStatusProvider : private TimerBase
|
|||||||
|
|
||||||
protocol::GetNodeInfo::Response node_info_;
|
protocol::GetNodeInfo::Response node_info_;
|
||||||
|
|
||||||
|
IAdHocNodeStatusUpdater* ad_hoc_status_updater_;
|
||||||
|
|
||||||
INode& getNode() { return node_status_pub_.getNode(); }
|
INode& getNode() { return node_status_pub_.getNode(); }
|
||||||
|
|
||||||
bool isNodeInfoInitialized() const;
|
bool isNodeInfoInitialized() const;
|
||||||
@@ -58,6 +83,7 @@ public:
|
|||||||
, creation_timestamp_(node.getMonotonicTime())
|
, creation_timestamp_(node.getMonotonicTime())
|
||||||
, node_status_pub_(node)
|
, node_status_pub_(node)
|
||||||
, gni_srv_(node)
|
, gni_srv_(node)
|
||||||
|
, ad_hoc_status_updater_(UAVCAN_NULLPTR)
|
||||||
{
|
{
|
||||||
UAVCAN_ASSERT(!creation_timestamp_.isZero());
|
UAVCAN_ASSERT(!creation_timestamp_.isZero());
|
||||||
|
|
||||||
@@ -86,6 +112,15 @@ public:
|
|||||||
void setStatusPublicationPeriod(uavcan::MonotonicDuration period);
|
void setStatusPublicationPeriod(uavcan::MonotonicDuration period);
|
||||||
uavcan::MonotonicDuration getStatusPublicationPeriod() const;
|
uavcan::MonotonicDuration getStatusPublicationPeriod() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the optional handler that is invoked before every node status message is emitted.
|
||||||
|
* By default no handler is installed.
|
||||||
|
* It is allowed to pass a null pointer, that will disable the ad-hoc update feature.
|
||||||
|
* @ref IAdHocNodeStatusUpdater
|
||||||
|
*/
|
||||||
|
void setAdHocNodeStatusUpdater(IAdHocNodeStatusUpdater* updater);
|
||||||
|
IAdHocNodeStatusUpdater* getAdHocNodeStatusUpdater() const { return ad_hoc_status_updater_; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local node health code control.
|
* Local node health code control.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ void NodeStatusProvider::handleTimerEvent(const TimerEvent&)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (ad_hoc_status_updater_ != UAVCAN_NULLPTR)
|
||||||
|
{
|
||||||
|
ad_hoc_status_updater_->updateNodeStatus();
|
||||||
|
}
|
||||||
|
|
||||||
const int res = publish();
|
const int res = publish();
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
@@ -109,6 +114,11 @@ uavcan::MonotonicDuration NodeStatusProvider::getStatusPublicationPeriod() const
|
|||||||
return TimerBase::getPeriod();
|
return TimerBase::getPeriod();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeStatusProvider::setAdHocNodeStatusUpdater(IAdHocNodeStatusUpdater* updater)
|
||||||
|
{
|
||||||
|
ad_hoc_status_updater_ = updater; // Can be nullptr, that's okay
|
||||||
|
}
|
||||||
|
|
||||||
void NodeStatusProvider::setHealth(uint8_t code)
|
void NodeStatusProvider::setHealth(uint8_t code)
|
||||||
{
|
{
|
||||||
node_info_.status.health = code;
|
node_info_.status.health = code;
|
||||||
|
|||||||
@@ -7,6 +7,19 @@
|
|||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
struct AdHocNodeStatusUpdater : public uavcan::IAdHocNodeStatusUpdater
|
||||||
|
{
|
||||||
|
uavcan::uint64_t invokations;
|
||||||
|
|
||||||
|
AdHocNodeStatusUpdater() : invokations(0) { }
|
||||||
|
|
||||||
|
virtual void updateNodeStatus()
|
||||||
|
{
|
||||||
|
invokations++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
TEST(NodeStatusProvider, Basic)
|
TEST(NodeStatusProvider, Basic)
|
||||||
{
|
{
|
||||||
InterlinkedTestNodesWithSysClock nodes;
|
InterlinkedTestNodesWithSysClock nodes;
|
||||||
@@ -60,6 +73,11 @@ TEST(NodeStatusProvider, Basic)
|
|||||||
ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_BROADCASTING_PERIOD_MS),
|
ASSERT_EQ(uavcan::MonotonicDuration::fromMSec(uavcan::protocol::NodeStatus::MAX_BROADCASTING_PERIOD_MS),
|
||||||
nsp.getStatusPublicationPeriod());
|
nsp.getStatusPublicationPeriod());
|
||||||
|
|
||||||
|
AdHocNodeStatusUpdater ad_hoc;
|
||||||
|
ASSERT_EQ(UAVCAN_NULLPTR, nsp.getAdHocNodeStatusUpdater());
|
||||||
|
nsp.setAdHocNodeStatusUpdater(&ad_hoc);
|
||||||
|
ASSERT_EQ(&ad_hoc, nsp.getAdHocNodeStatusUpdater());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initial status publication
|
* Initial status publication
|
||||||
*/
|
*/
|
||||||
@@ -75,6 +93,8 @@ TEST(NodeStatusProvider, Basic)
|
|||||||
ASSERT_EQ(0, status_sub.collector.msg->vendor_specific_status_code);
|
ASSERT_EQ(0, status_sub.collector.msg->vendor_specific_status_code);
|
||||||
ASSERT_GE(1, status_sub.collector.msg->uptime_sec);
|
ASSERT_GE(1, status_sub.collector.msg->uptime_sec);
|
||||||
|
|
||||||
|
ASSERT_EQ(0, ad_hoc.invokations); // Not invoked from startAndPublish()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Altering the vendor-specific status code, forcePublish()-ing it and checking the result
|
* Altering the vendor-specific status code, forcePublish()-ing it and checking the result
|
||||||
*/
|
*/
|
||||||
@@ -90,6 +110,8 @@ TEST(NodeStatusProvider, Basic)
|
|||||||
ASSERT_EQ(1234, status_sub.collector.msg->vendor_specific_status_code);
|
ASSERT_EQ(1234, status_sub.collector.msg->vendor_specific_status_code);
|
||||||
ASSERT_GE(1, status_sub.collector.msg->uptime_sec);
|
ASSERT_GE(1, status_sub.collector.msg->uptime_sec);
|
||||||
|
|
||||||
|
ASSERT_EQ(0, ad_hoc.invokations); // Not invoked from forcePublish()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Explicit node info request
|
* Explicit node info request
|
||||||
*/
|
*/
|
||||||
@@ -113,4 +135,16 @@ TEST(NodeStatusProvider, Basic)
|
|||||||
ASSERT_TRUE(swver == gni_cln.collector.result->getResponse().software_version);
|
ASSERT_TRUE(swver == gni_cln.collector.result->getResponse().software_version);
|
||||||
|
|
||||||
ASSERT_EQ("superluminal_communication_unit", gni_cln.collector.result->getResponse().name);
|
ASSERT_EQ("superluminal_communication_unit", gni_cln.collector.result->getResponse().name);
|
||||||
|
|
||||||
|
ASSERT_EQ(0, ad_hoc.invokations); // No timer-triggered publications happened yet
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timer triggered publication
|
||||||
|
*/
|
||||||
|
EXPECT_EQ(3, nodes.a.getDispatcher().getTransferPerfCounter().getTxTransferCount());
|
||||||
|
|
||||||
|
nodes.spinBoth(nsp.getStatusPublicationPeriod());
|
||||||
|
|
||||||
|
EXPECT_EQ(1, ad_hoc.invokations); // No timer-triggered publications happened yet
|
||||||
|
EXPECT_EQ(4, nodes.a.getDispatcher().getTransferPerfCounter().getTxTransferCount());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user