mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-06-27 10:50:35 +08:00
Merge branch 'dynamic_node_id'
This commit is contained in:
@@ -60,6 +60,15 @@ public:
|
||||
MonotonicDuration getTxTimeout() const { return tx_timeout_; }
|
||||
void setTxTimeout(MonotonicDuration tx_timeout);
|
||||
|
||||
/**
|
||||
* By default, attempt to send a transfer from passive mode will result in an error @ref ErrPassive.
|
||||
* This option allows to enable sending anonymous transfers from passive mode.
|
||||
*/
|
||||
void allowAnonymousTransfers()
|
||||
{
|
||||
sender_->allowAnonymousTransfers();
|
||||
}
|
||||
|
||||
INode& getNode() const { return node_; }
|
||||
};
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
TransferID getTransferID() const { return safeget<TransferID, &IncomingTransfer::getTransferID>(); }
|
||||
NodeID getSrcNodeID() const { return safeget<NodeID, &IncomingTransfer::getSrcNodeID>(); }
|
||||
uint8_t getIfaceIndex() const { return safeget<uint8_t, &IncomingTransfer::getIfaceIndex>(); }
|
||||
bool isAnonymousTransfer() const { return safeget<bool, &IncomingTransfer::isAnonymousTransfer>(); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -200,6 +201,15 @@ protected:
|
||||
return genericStart(&Dispatcher::registerServiceResponseListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, anonymous transfers will be ignored.
|
||||
* This option allows to enable reception of anonymous transfers.
|
||||
*/
|
||||
void allowAnonymousTransfers()
|
||||
{
|
||||
forwarder_->allowAnonymousTransfers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate the subscription.
|
||||
* Dispatcher core will remove this instance from the subscribers list.
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
*/
|
||||
using BaseType::init;
|
||||
|
||||
using BaseType::allowAnonymousTransfers;
|
||||
using BaseType::getTransferSender;
|
||||
using BaseType::getMinTxTimeout;
|
||||
using BaseType::getMaxTxTimeout;
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
return BaseType::startAsMessageListener();
|
||||
}
|
||||
|
||||
using BaseType::allowAnonymousTransfers;
|
||||
using BaseType::stop;
|
||||
using BaseType::getFailureCount;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_CLIENT_HPP_INCLUDED
|
||||
#define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_CLIENT_HPP_INCLUDED
|
||||
|
||||
#include <uavcan/node/subscriber.hpp>
|
||||
#include <uavcan/node/publisher.hpp>
|
||||
#include <uavcan/node/timer.hpp>
|
||||
#include <uavcan/util/method_binder.hpp>
|
||||
#include <uavcan/build_config.hpp>
|
||||
#include <uavcan/protocol/dynamic_node_id/Allocation.hpp>
|
||||
#include <uavcan/protocol/HardwareVersion.hpp>
|
||||
|
||||
namespace uavcan
|
||||
{
|
||||
/**
|
||||
* This class implements client-side logic of dynamic node ID allocation procedure.
|
||||
*
|
||||
* Once started, the object will be publishing dynamic node ID allocation requests at the default frequency defined
|
||||
* by the specification, until a Node ID is granted by the allocator.
|
||||
*
|
||||
* If the local node is equipped with redundant CAN interfaces, all of them will be used for publishing requests
|
||||
* and listening for responses.
|
||||
*
|
||||
* Once dynamic allocation is complete (or not needed anymore), the object can be deleted.
|
||||
*/
|
||||
class DynamicNodeIDAllocationClient : private TimerBase
|
||||
{
|
||||
typedef MethodBinder<DynamicNodeIDAllocationClient*,
|
||||
void (DynamicNodeIDAllocationClient::*)
|
||||
(const ReceivedDataStructure<protocol::dynamic_node_id::Allocation>&)>
|
||||
AllocationCallback;
|
||||
|
||||
Publisher<protocol::dynamic_node_id::Allocation> dnida_pub_;
|
||||
Subscriber<protocol::dynamic_node_id::Allocation, AllocationCallback> dnida_sub_;
|
||||
|
||||
uint8_t unique_id_[protocol::HardwareVersion::FieldTypes::unique_id::MaxSize];
|
||||
NodeID preferred_node_id_;
|
||||
NodeID allocated_node_id_;
|
||||
NodeID allocator_node_id_;
|
||||
|
||||
void terminate();
|
||||
|
||||
virtual void handleTimerEvent(const TimerEvent&);
|
||||
|
||||
void handleAllocation(const ReceivedDataStructure<protocol::dynamic_node_id::Allocation>& msg);
|
||||
|
||||
public:
|
||||
DynamicNodeIDAllocationClient(INode& node)
|
||||
: TimerBase(node)
|
||||
, dnida_pub_(node)
|
||||
, dnida_sub_(node)
|
||||
{ }
|
||||
|
||||
/**
|
||||
* @param hardware_version Hardware version information, where unique_id must be set correctly.
|
||||
* @param preferred_node_id Node ID that the application would like to take; set to broadcast (zero) if
|
||||
* the application doesn't have any preference (this is default).
|
||||
* @return Zero on success
|
||||
* Negative error code on failure
|
||||
* -ErrLogic if 1. the node is not in passive mode or 2. the client is already started
|
||||
*/
|
||||
int start(const protocol::HardwareVersion& hardware_version, const NodeID preferred_node_id = NodeID::Broadcast);
|
||||
|
||||
/**
|
||||
* Use this method to determine when allocation is complete.
|
||||
*/
|
||||
bool isAllocationComplete() const { return getAllocatedNodeID().isUnicast(); }
|
||||
|
||||
/**
|
||||
* This method allows to retrieve the node ID that was allocated to the local node.
|
||||
* If no node ID was allocated yet, the returned node ID will be invalid (non-unicast).
|
||||
* @return If allocation is complete, a valid unicast node ID will be returned.
|
||||
* If allocation is not complete yet, a non-unicast node ID will be returned.
|
||||
*/
|
||||
NodeID getAllocatedNodeID() const { return allocated_node_id_; }
|
||||
|
||||
/**
|
||||
* This method allows to retrieve node ID of the allocator that granted our Node ID.
|
||||
* If no node ID was allocated yet, the returned node ID will be invalid (non-unicast).
|
||||
* @return If allocation is complete, a valid unicast node ID will be returned.
|
||||
* If allocation is not complete yet, an non-unicast node ID will be returned.
|
||||
*/
|
||||
NodeID getAllocatorNodeID() const { return allocator_node_id_; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_ALLOCATION_CLIENT_HPP_INCLUDED
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <uavcan/build_config.hpp>
|
||||
#include <cstdarg>
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11)
|
||||
# error UAVCAN_CPP_VERSION
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
: canio_(driver, allocator, sysclock)
|
||||
, sysclock_(sysclock)
|
||||
, outgoing_transfer_reg_(otr)
|
||||
, self_node_id_(NodeID::Broadcast) // Default
|
||||
, self_node_id_is_set_(false)
|
||||
{ }
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
{
|
||||
UAVCAN_ASSERT((transfer_type == TransferTypeMessageBroadcast) == dst_node_id.isBroadcast());
|
||||
UAVCAN_ASSERT(data_type_id.isValid());
|
||||
UAVCAN_ASSERT(src_node_id != dst_node_id);
|
||||
UAVCAN_ASSERT(src_node_id.isUnicast() ? (src_node_id != dst_node_id) : true);
|
||||
UAVCAN_ASSERT(frame_index <= MaxIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,11 @@ public:
|
||||
*/
|
||||
virtual void release() { }
|
||||
|
||||
/**
|
||||
* Whether this is a anonymous transfer
|
||||
*/
|
||||
virtual bool isAnonymousTransfer() const { return false; }
|
||||
|
||||
MonotonicTime getMonotonicTimestamp() const { return ts_mono_; }
|
||||
UtcTime getUtcTimestamp() const { return ts_utc_; }
|
||||
TransferType getTransferType() const { return transfer_type_; }
|
||||
@@ -68,6 +73,7 @@ class UAVCAN_EXPORT SingleFrameIncomingTransfer : public IncomingTransfer
|
||||
public:
|
||||
explicit SingleFrameIncomingTransfer(const RxFrame& frm);
|
||||
virtual int read(unsigned offset, uint8_t* data, unsigned len) const;
|
||||
virtual bool isAnonymousTransfer() const;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -93,6 +99,7 @@ class UAVCAN_EXPORT TransferListenerBase : public LinkedListNode<TransferListene
|
||||
MapBase<TransferBufferManagerKey, TransferReceiver>& receivers_;
|
||||
ITransferBufferManager& bufmgr_;
|
||||
TransferPerfCounter& perf_;
|
||||
bool allow_anonymous_transfers_;
|
||||
|
||||
class TimedOutReceiverPredicate
|
||||
{
|
||||
@@ -119,17 +126,25 @@ protected:
|
||||
, receivers_(receivers)
|
||||
, bufmgr_(bufmgr)
|
||||
, perf_(perf)
|
||||
, allow_anonymous_transfers_(false)
|
||||
{ }
|
||||
|
||||
virtual ~TransferListenerBase() { }
|
||||
|
||||
void handleReception(TransferReceiver& receiver, const RxFrame& frame, TransferBufferAccessor& tba);
|
||||
void handleAnonymousTransferReception(const RxFrame& frame);
|
||||
|
||||
virtual void handleIncomingTransfer(IncomingTransfer& transfer) = 0;
|
||||
|
||||
public:
|
||||
const DataTypeDescriptor& getDataTypeDescriptor() const { return data_type_; }
|
||||
|
||||
/**
|
||||
* By default, anonymous transfers will be ignored.
|
||||
* This option allows to enable reception of anonymous transfers.
|
||||
*/
|
||||
void allowAnonymousTransfers() { allow_anonymous_transfers_ = true; }
|
||||
|
||||
void cleanup(MonotonicTime ts);
|
||||
|
||||
virtual void handleFrame(const RxFrame& frame);
|
||||
|
||||
@@ -25,6 +25,7 @@ class UAVCAN_EXPORT TransferSender
|
||||
const TransferCRC crc_base_;
|
||||
CanIOFlags flags_;
|
||||
uint8_t iface_mask_;
|
||||
bool allow_anonymous_transfers_;
|
||||
|
||||
Dispatcher& dispatcher_;
|
||||
|
||||
@@ -46,6 +47,7 @@ public:
|
||||
, crc_base_(data_type.getSignature().toTransferCRC())
|
||||
, flags_(CanIOFlags(0))
|
||||
, iface_mask_(AllIfacesMask)
|
||||
, allow_anonymous_transfers_(false)
|
||||
, dispatcher_(dispatcher)
|
||||
{ }
|
||||
|
||||
@@ -59,6 +61,15 @@ public:
|
||||
iface_mask_ = iface_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anonymous transfers (i.e. transfers that don't carry a valid Source Node ID) can be sent if
|
||||
* the local node is configured in passive mode (i.e. the node doesn't have a valid Node ID).
|
||||
* By default, this class will return an error if it is asked to send a transfer while the
|
||||
* node is configured in passive mode. However, if this option is enabled, it will be possible
|
||||
* to send anonymous transfers from passive mode.
|
||||
*/
|
||||
void allowAnonymousTransfers() { allow_anonymous_transfers_ = true; }
|
||||
|
||||
/**
|
||||
* Send with explicit Transfer ID.
|
||||
* Should be used only for service responses, where response TID should match request TID.
|
||||
|
||||
Reference in New Issue
Block a user