mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 04:33:34 +08:00
Configurable priority for service calls; plus a minor collateral refactoring
This commit is contained in:
@@ -67,6 +67,12 @@ public:
|
||||
sender_.allowAnonymousTransfers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Priority of outgoing transfers.
|
||||
*/
|
||||
TransferPriority getPriority() const { return sender_.getPriority(); }
|
||||
void setPriority(const TransferPriority prio) { sender_.setPriority(prio); }
|
||||
|
||||
INode& getNode() const { return node_; }
|
||||
};
|
||||
|
||||
|
||||
@@ -65,24 +65,6 @@ public:
|
||||
return BaseType::publish(message, TransferTypeMessageBroadcast, NodeID::Broadcast, tid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns priority of outgoing transfers.
|
||||
*/
|
||||
TransferPriority getPriority() const
|
||||
{
|
||||
return BaseType::getTransferSender().getPriority();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to change the priority of outgoing transfers.
|
||||
* Note that only High, Normal and Low priorities can be used; Service priority is not available for messages.
|
||||
* If the priority value is invalid, an assertion failure will be generated, and the value will not be updated.
|
||||
*/
|
||||
void setPriority(const TransferPriority prio)
|
||||
{
|
||||
BaseType::getTransferSender().setPriority(prio);
|
||||
}
|
||||
|
||||
static MonotonicDuration getDefaultTxTimeout() { return MonotonicDuration::fromMSec(10); }
|
||||
|
||||
/**
|
||||
@@ -97,6 +79,8 @@ public:
|
||||
using BaseType::getMaxTxTimeout;
|
||||
using BaseType::getTxTimeout;
|
||||
using BaseType::setTxTimeout;
|
||||
using BaseType::getPriority;
|
||||
using BaseType::setPriority;
|
||||
using BaseType::getNode;
|
||||
};
|
||||
|
||||
|
||||
@@ -208,6 +208,9 @@ public:
|
||||
* reference invalidates once the callback returns. If you want to use this object after the callback execution,
|
||||
* you need to copy it somewhere.
|
||||
*
|
||||
* Note that by default, service client objects use lower priority than message publishers. Use @ref setPriority()
|
||||
* to override the default if necessary.
|
||||
*
|
||||
* @tparam DataType_ Service data type.
|
||||
*
|
||||
* @tparam Callback_ Service response will be delivered through the callback of this type.
|
||||
@@ -303,6 +306,7 @@ public:
|
||||
, publisher_(node, getDefaultRequestTimeout())
|
||||
, callback_(callback)
|
||||
{
|
||||
setPriority(TransferPriority::MiddleLower);
|
||||
setRequestTimeout(getDefaultRequestTimeout());
|
||||
#if UAVCAN_DEBUG
|
||||
UAVCAN_ASSERT(getRequestTimeout() == getDefaultRequestTimeout()); // Making sure default values are OK
|
||||
@@ -398,6 +402,14 @@ public:
|
||||
publisher_.setTxTimeout(timeout);
|
||||
request_timeout_ = max(timeout, publisher_.getTxTimeout()); // No less than TX timeout
|
||||
}
|
||||
|
||||
/**
|
||||
* Priority of outgoing request transfers.
|
||||
* The remote server is supposed to use the same priority for the response, but it's not guaranteed by
|
||||
* the specification.
|
||||
*/
|
||||
TransferPriority getPriority() const { return publisher_.getPriority(); }
|
||||
void setPriority(const TransferPriority prio) { publisher_.setPriority(prio); }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
|
||||
/// This priority is used by default
|
||||
static const TransferPriority Default;
|
||||
static const TransferPriority MiddleLower;
|
||||
static const TransferPriority OneHigherThanLowest;
|
||||
static const TransferPriority OneLowerThanHighest;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ const uint8_t TransferPriority::NumericallyMax;
|
||||
const uint8_t TransferPriority::NumericallyMin;
|
||||
|
||||
const TransferPriority TransferPriority::Default((1U << BitLen) / 2);
|
||||
const TransferPriority TransferPriority::MiddleLower((1U << BitLen) / 2 + (1U << BitLen) / 4);
|
||||
const TransferPriority TransferPriority::OneHigherThanLowest(NumericallyMax - 1);
|
||||
const TransferPriority TransferPriority::OneLowerThanHighest(NumericallyMin + 1);
|
||||
|
||||
|
||||
@@ -387,6 +387,59 @@ TEST(ServiceClient, Empty)
|
||||
}
|
||||
|
||||
|
||||
TEST(ServiceClient, Priority)
|
||||
{
|
||||
InterlinkedTestNodesWithSysClock nodes;
|
||||
|
||||
// Type registration
|
||||
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||
uavcan::DefaultDataTypeRegistrator<root_ns_a::EmptyService> _registrator;
|
||||
|
||||
// Initializing
|
||||
typedef uavcan::ServiceClient<root_ns_a::EmptyService,
|
||||
typename ServiceCallResultHandler<root_ns_a::EmptyService>::Binder > ClientType;
|
||||
ServiceCallResultHandler<root_ns_a::EmptyService> handler;
|
||||
ClientType client(nodes.b);
|
||||
client.setCallback(handler.bind());
|
||||
|
||||
// Calling
|
||||
root_ns_a::EmptyService::Request request;
|
||||
|
||||
client.setPriority(0);
|
||||
ASSERT_LT(0, client.call(1, request)); // OK
|
||||
|
||||
client.setPriority(10);
|
||||
ASSERT_LT(0, client.call(1, request)); // OK
|
||||
|
||||
client.setPriority(20);
|
||||
ASSERT_LT(0, client.call(1, request)); // OK
|
||||
|
||||
client.setPriority(31);
|
||||
ASSERT_LT(0, client.call(1, request)); // OK
|
||||
|
||||
// Validating
|
||||
ASSERT_EQ(4, nodes.can_a.read_queue.size());
|
||||
|
||||
uavcan::Frame frame;
|
||||
|
||||
ASSERT_TRUE(frame.parse(nodes.can_a.read_queue.front()));
|
||||
nodes.can_a.read_queue.pop();
|
||||
ASSERT_EQ(0, frame.getPriority().get());
|
||||
|
||||
ASSERT_TRUE(frame.parse(nodes.can_a.read_queue.front()));
|
||||
nodes.can_a.read_queue.pop();
|
||||
ASSERT_EQ(10, frame.getPriority().get());
|
||||
|
||||
ASSERT_TRUE(frame.parse(nodes.can_a.read_queue.front()));
|
||||
nodes.can_a.read_queue.pop();
|
||||
ASSERT_EQ(20, frame.getPriority().get());
|
||||
|
||||
ASSERT_TRUE(frame.parse(nodes.can_a.read_queue.front()));
|
||||
nodes.can_a.read_queue.pop();
|
||||
ASSERT_EQ(31, frame.getPriority().get());
|
||||
}
|
||||
|
||||
|
||||
TEST(ServiceClient, Sizes)
|
||||
{
|
||||
using namespace uavcan;
|
||||
|
||||
Reference in New Issue
Block a user