mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-12 16:43:34 +08:00
GlobalTimeSyncSlave message validation test
This commit is contained in:
@@ -163,3 +163,114 @@ TEST(GlobalTimeSyncSlave, Basic)
|
||||
ASSERT_FALSE(gtss.isActive());
|
||||
ASSERT_FALSE(gtss.getMasterNodeID().isValid());
|
||||
}
|
||||
|
||||
|
||||
#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || (BYTE_ORDER != LITTLE_ENDIAN)
|
||||
# error "This test cannot be executed on this platform"
|
||||
#endif
|
||||
|
||||
static uavcan::Frame makeSyncMsg(uavcan::uint64_t usec, uavcan::NodeID snid, uavcan::TransferID tid)
|
||||
{
|
||||
uavcan::Frame frame(uavcan::protocol::GlobalTimeSync::DefaultDataTypeID, uavcan::TransferTypeMessageBroadcast,
|
||||
snid, uavcan::NodeID::Broadcast, 0, tid, true);
|
||||
EXPECT_EQ(8, frame.setPayload(reinterpret_cast<uint8_t*>(&usec), 8)); // Assuming little endian
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void broadcastSyncMsg(CanIfaceMock& iface, uavcan::uint64_t usec, uavcan::NodeID snid, uavcan::TransferID tid)
|
||||
{
|
||||
const uavcan::Frame frame = makeSyncMsg(usec, snid, tid);
|
||||
uavcan::CanFrame can_frame;
|
||||
ASSERT_TRUE(frame.compile(can_frame));
|
||||
iface.pushRx(can_frame);
|
||||
}
|
||||
|
||||
|
||||
TEST(GlobalTimeSyncSlave, Validation)
|
||||
{
|
||||
SystemClockMock slave_clock;
|
||||
slave_clock.monotonic = 1000000;
|
||||
slave_clock.preserve_utc = true;
|
||||
|
||||
CanDriverMock slave_can(3, slave_clock);
|
||||
for (int i = 0; i < slave_can.getNumIfaces(); i++)
|
||||
{
|
||||
slave_can.ifaces.at(i).enable_utc_timestamping = true;
|
||||
}
|
||||
|
||||
TestNode node(slave_can, slave_clock, 64);
|
||||
|
||||
uavcan::GlobalTimeSyncSlave gtss(node);
|
||||
uavcan::Publisher<uavcan::protocol::GlobalTimeSync> gts_pub(node);
|
||||
|
||||
ASSERT_LE(0, gtss.start());
|
||||
ASSERT_FALSE(gtss.isActive());
|
||||
ASSERT_FALSE(gtss.getMasterNodeID().isValid());
|
||||
ASSERT_EQ(0, slave_clock.utc);
|
||||
|
||||
/*
|
||||
* Update/adjust/update
|
||||
*/
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 0, 8, 0); // Locked on this
|
||||
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 0); // Ignored
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 1000, 8, 1); // Adjust 1000 ahead
|
||||
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 1); // Ignored
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
ASSERT_TRUE(gtss.isActive());
|
||||
ASSERT_EQ(8, gtss.getMasterNodeID().get());
|
||||
ASSERT_EQ(1000, slave_clock.utc);
|
||||
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 2000, 8, 2); // Update
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
ASSERT_EQ(1000, slave_clock.utc);
|
||||
std::cout << slave_clock.monotonic << std::endl;
|
||||
|
||||
/*
|
||||
* TID jump simulates a frame loss
|
||||
*/
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 3000, 8, 4); // Adjustment skipped - expected TID 3, update instead
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
ASSERT_TRUE(gtss.isActive());
|
||||
ASSERT_EQ(8, gtss.getMasterNodeID().get());
|
||||
ASSERT_EQ(1000, slave_clock.utc);
|
||||
std::cout << slave_clock.monotonic << std::endl;
|
||||
|
||||
/*
|
||||
* Valid adjustment - continuing from TID 4
|
||||
*/
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 3000, 8, 5); // Slave UTC was 1000, master reports 3000 --> shift ahead
|
||||
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 5);
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
ASSERT_TRUE(gtss.isActive());
|
||||
ASSERT_EQ(8, gtss.getMasterNodeID().get());
|
||||
ASSERT_EQ(3000, slave_clock.utc);
|
||||
std::cout << slave_clock.monotonic << std::endl;
|
||||
|
||||
/*
|
||||
* Update, then very long delay with correct TID
|
||||
*/
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 2000, 8, 6); // Valid update, slave UTC is 3000
|
||||
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 6);
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
slave_clock.monotonic += 5000000;
|
||||
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 5000, 8, 7); // Adjustment skipped
|
||||
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 7);
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
broadcastSyncMsg(slave_can.ifaces.at(0), 5000, 8, 0); // Valid adjustment now
|
||||
broadcastSyncMsg(slave_can.ifaces.at(1), 2000, 8, 0);
|
||||
ASSERT_LE(0, node.spin(uavcan::MonotonicDuration::fromMSec(1)));
|
||||
|
||||
ASSERT_TRUE(gtss.isActive());
|
||||
ASSERT_EQ(8, gtss.getMasterNodeID().get());
|
||||
ASSERT_EQ(5000, slave_clock.utc);
|
||||
std::cout << slave_clock.monotonic << std::endl;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
bool rx_failure;
|
||||
uint64_t num_errors;
|
||||
uavcan::ISystemClock& iclock;
|
||||
bool enable_utc_timestamping;
|
||||
|
||||
CanIfaceMock(uavcan::ISystemClock& iclock)
|
||||
: writeable(true)
|
||||
@@ -49,6 +50,7 @@ public:
|
||||
, rx_failure(false)
|
||||
, num_errors(0)
|
||||
, iclock(iclock)
|
||||
, enable_utc_timestamping(false)
|
||||
{ }
|
||||
|
||||
void pushRx(const uavcan::CanFrame& frame)
|
||||
@@ -131,7 +133,7 @@ public:
|
||||
out_frame = frame.frame;
|
||||
out_ts_monotonic = frame.time;
|
||||
}
|
||||
out_ts_utc = uavcan::UtcTime();
|
||||
out_ts_utc = enable_utc_timestamping ? iclock.getUtc() : uavcan::UtcTime();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user