global_time_sync_slave.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_PROTOCOL_GLOBAL_TIME_SYNC_SLAVE_HPP_INCLUDED
6 #define UAVCAN_PROTOCOL_GLOBAL_TIME_SYNC_SLAVE_HPP_INCLUDED
7 
10 #include <uavcan/protocol/GlobalTimeSync.hpp>
11 #include <uavcan/debug.hpp>
12 #include <cassert>
13 
14 namespace uavcan
15 {
29 {
33 
35 
39  enum State { Update, Adjust } state_;
44 
45  ISystemClock& getSystemClock() const { return sub_.getNode().getSystemClock(); }
46 
48  {
49  UAVCAN_ASSERT(msg.previous_transmission_timestamp_usec > 0);
50  const UtcDuration adjustment = UtcTime::fromUSec(msg.previous_transmission_timestamp_usec) - prev_ts_utc_;
51 
52  UAVCAN_TRACE("GlobalTimeSyncSlave", "Adjustment: usec=%lli snid=%i iface=%i suppress=%i",
53  static_cast<long long>(adjustment.toUSec()),
54  int(msg.getSrcNodeID().get()), int(msg.getIfaceIndex()), int(suppressed_));
55 
56  if (!suppressed_)
57  {
58  getSystemClock().adjustUtc(adjustment);
59  }
60  last_adjustment_ts_ = msg.getMonotonicTimestamp();
61  state_ = Update;
62  }
63 
65  {
66  UAVCAN_TRACE("GlobalTimeSyncSlave", "Update: snid=%i iface=%i",
67  int(msg.getSrcNodeID().get()), int(msg.getIfaceIndex()));
68 
69  prev_ts_utc_ = msg.getUtcTimestamp();
70  prev_ts_mono_ = msg.getMonotonicTimestamp();
71  master_nid_ = msg.getSrcNodeID();
72  prev_iface_index_ = msg.getIfaceIndex();
73  prev_tid_ = msg.getTransferID();
74  state_ = Adjust;
75  }
76 
78  {
79  const MonotonicDuration since_prev_msg = msg.getMonotonicTimestamp() - prev_ts_mono_;
80  UAVCAN_ASSERT(!since_prev_msg.isNegative());
81 
82  const bool needs_init = !master_nid_.isValid() || prev_ts_mono_.isZero();
83  const bool switch_master = msg.getSrcNodeID() < master_nid_;
84  // TODO: Make configurable
85  const bool pub_timeout = since_prev_msg.toMSec() > protocol::GlobalTimeSync::RECOMMENDED_BROADCASTER_TIMEOUT_MS;
86 
87  if (switch_master || pub_timeout || needs_init)
88  {
89  UAVCAN_TRACE("GlobalTimeSyncSlave", "Force update: needs_init=%i switch_master=%i pub_timeout=%i",
90  int(needs_init), int(switch_master), int(pub_timeout));
91  updateFromMsg(msg);
92  }
93  else if (msg.getIfaceIndex() == prev_iface_index_ && msg.getSrcNodeID() == master_nid_)
94  {
95  if (state_ == Adjust)
96  {
97  const bool msg_invalid = msg.previous_transmission_timestamp_usec == 0;
98  const bool wrong_tid = prev_tid_.computeForwardDistance(msg.getTransferID()) != 1;
99  const bool wrong_timing = since_prev_msg.toMSec() > protocol::GlobalTimeSync::MAX_BROADCASTING_PERIOD_MS;
100  if (msg_invalid || wrong_tid || wrong_timing)
101  {
102  UAVCAN_TRACE("GlobalTimeSyncSlave",
103  "Adjustment skipped: msg_invalid=%i wrong_tid=%i wrong_timing=%i",
104  int(msg_invalid), int(wrong_tid), int(wrong_timing));
105  state_ = Update;
106  }
107  }
108  if (state_ == Adjust)
109  {
110  adjustFromMsg(msg);
111  }
112  else
113  {
114  updateFromMsg(msg);
115  }
116  }
117  else
118  {
119  UAVCAN_TRACE("GlobalTimeSyncSlave", "Ignored: snid=%i iface=%i",
120  int(msg.getSrcNodeID().get()), int(msg.getIfaceIndex()));
121  }
122  }
123 
125  {
127  {
128  processMsg(msg);
129  }
130  else
131  {
132  UAVCAN_TRACE("GlobalTimeSyncSlave", "Invalid transfer type %i", int(msg.getTransferType()));
133  }
134  }
135 
136 public:
138  : sub_(node)
139  , state_(Update)
140  , prev_iface_index_(0xFF)
141  , suppressed_(false)
142  { }
143 
149  int start()
150  {
152  }
153 
168  void suppress(bool suppressed) { suppressed_ = suppressed; }
169  bool isSuppressed() const { return suppressed_; }
170 
177  bool isActive() const
178  {
179  const MonotonicDuration since_prev_adj = getSystemClock().getMonotonic() - last_adjustment_ts_;
180  return !last_adjustment_ts_.isZero() &&
181  (since_prev_adj.toMSec() <= protocol::GlobalTimeSync::RECOMMENDED_BROADCASTER_TIMEOUT_MS);
182  }
183 
188  NodeID getMasterNodeID() const { return isActive() ? master_nid_ : NodeID(); }
189 
193  MonotonicTime getLastAdjustmentTime() const { return last_adjustment_ts_; }
194 };
195 
196 }
197 
198 #endif // UAVCAN_PROTOCOL_GLOBAL_TIME_SYNC_SLAVE_HPP_INCLUDED
subscriber.hpp
uavcan::ReceivedDataStructure::getIfaceIndex
uint8_t getIfaceIndex() const
Definition: generic_subscriber.hpp:76
uavcan::GlobalTimeSyncSlave::adjustFromMsg
void adjustFromMsg(const ReceivedDataStructure< protocol::GlobalTimeSync > &msg)
Definition: global_time_sync_slave.hpp:47
uavcan::GlobalTimeSyncSlave::isSuppressed
bool isSuppressed() const
Definition: global_time_sync_slave.hpp:169
uavcan::Noncopyable
Definition: templates.hpp:46
uavcan::DurationBase::toMSec
int64_t toMSec() const
Definition: time.hpp:44
uavcan::NodeID::isValid
bool isValid() const
Definition: transfer.hpp:134
debug.hpp
uavcan::GlobalTimeSyncSlave::isActive
bool isActive() const
Definition: global_time_sync_slave.hpp:177
uavcan::Subscriber
Definition: subscriber.hpp:45
uavcan::UtcTime
Implicitly convertible to/from uavcan.Timestamp.
Definition: time.hpp:191
uavcan::GlobalTimeSyncSlave::updateFromMsg
void updateFromMsg(const ReceivedDataStructure< protocol::GlobalTimeSync > &msg)
Definition: global_time_sync_slave.hpp:64
uavcan::UtcDuration
Definition: time.hpp:189
uavcan::GlobalTimeSyncSlave::State
State
Definition: global_time_sync_slave.hpp:39
uavcan::NodeID
Definition: transfer.hpp:112
uavcan::GlobalTimeSyncSlave::getLastAdjustmentTime
MonotonicTime getLastAdjustmentTime() const
Definition: global_time_sync_slave.hpp:193
uavcan::GlobalTimeSyncSlave::suppress
void suppress(bool suppressed)
Definition: global_time_sync_slave.hpp:168
uavcan::GlobalTimeSyncSlave::getMasterNodeID
NodeID getMasterNodeID() const
Definition: global_time_sync_slave.hpp:188
uavcan::ReceivedDataStructure
Definition: generic_subscriber.hpp:39
uavcan::GlobalTimeSyncSlave::sub_
Subscriber< protocol::GlobalTimeSync, GlobalTimeSyncCallback > sub_
Definition: global_time_sync_slave.hpp:34
uavcan::GlobalTimeSyncSlave::start
int start()
Definition: global_time_sync_slave.hpp:149
UAVCAN_TRACE
#define UAVCAN_TRACE(...)
Definition: libuavcan/libuavcan/include/uavcan/debug.hpp:31
uavcan::Subscriber::start
int start(const Callback &callback)
Definition: subscriber.hpp:83
uavcan::MonotonicDuration
Definition: time.hpp:182
uavcan::GlobalTimeSyncSlave::Update
@ Update
Definition: global_time_sync_slave.hpp:39
uavcan::TransferID
Definition: transfer.hpp:71
uavcan::TimeBase< UtcTime, UtcDuration >::fromUSec
static UtcTime fromUSec(uint64_t us)
Definition: time.hpp:112
uavcan::DurationBase::isNegative
bool isNegative() const
Definition: time.hpp:49
uavcan::GlobalTimeSyncSlave::master_nid_
NodeID master_nid_
Definition: global_time_sync_slave.hpp:40
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::TransferTypeMessageBroadcast
@ TransferTypeMessageBroadcast
Definition: transfer.hpp:22
uavcan::TransferID::computeForwardDistance
int computeForwardDistance(TransferID rhs) const
Definition: uc_transfer.cpp:44
uavcan::GlobalTimeSyncSlave::prev_iface_index_
uint8_t prev_iface_index_
Definition: global_time_sync_slave.hpp:42
uavcan::GlobalTimeSyncSlave::processMsg
void processMsg(const ReceivedDataStructure< protocol::GlobalTimeSync > &msg)
Definition: global_time_sync_slave.hpp:77
uavcan::ReceivedDataStructure::getUtcTimestamp
UtcTime getUtcTimestamp() const
Definition: generic_subscriber.hpp:71
uavcan::GlobalTimeSyncSlave::prev_tid_
TransferID prev_tid_
Definition: global_time_sync_slave.hpp:41
uavcan::ReceivedDataStructure::getTransferID
TransferID getTransferID() const
Definition: generic_subscriber.hpp:74
UAVCAN_EXPORT
#define UAVCAN_EXPORT
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:108
getSystemClock
uavcan::ISystemClock & getSystemClock()
Definition: platform_linux.cpp:8
uavcan::TimeBase::isZero
bool isZero() const
Definition: time.hpp:123
method_binder.hpp
uavcan::INode
Definition: abstract_node.hpp:19
uavcan::GlobalTimeSyncSlave::prev_ts_utc_
UtcTime prev_ts_utc_
Definition: global_time_sync_slave.hpp:36
uavcan::GenericSubscriberBase::getNode
INode & getNode() const
Definition: generic_subscriber.hpp:120
uavcan::ReceivedDataStructure::getTransferType
TransferType getTransferType() const
Definition: generic_subscriber.hpp:73
uavcan::MethodBinder
Definition: method_binder.hpp:20
uavcan::GlobalTimeSyncSlave::last_adjustment_ts_
MonotonicTime last_adjustment_ts_
Definition: global_time_sync_slave.hpp:38
uavcan::GlobalTimeSyncSlave::GlobalTimeSyncSlave
GlobalTimeSyncSlave(INode &node)
Definition: global_time_sync_slave.hpp:137
uavcan::GlobalTimeSyncSlave::prev_ts_mono_
MonotonicTime prev_ts_mono_
Definition: global_time_sync_slave.hpp:37
uavcan::ISystemClock::adjustUtc
virtual void adjustUtc(UtcDuration adjustment)=0
uavcan::ReceivedDataStructure::getMonotonicTimestamp
MonotonicTime getMonotonicTimestamp() const
Definition: generic_subscriber.hpp:67
pyuavcan_v0.introspect.node
node
Definition: introspect.py:398
uavcan::MonotonicTime
Definition: time.hpp:184
uavcan::GlobalTimeSyncSlave
Definition: global_time_sync_slave.hpp:28
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::ReceivedDataStructure::getSrcNodeID
NodeID getSrcNodeID() const
Definition: generic_subscriber.hpp:75
uavcan::ISystemClock
Definition: system_clock.hpp:19
uavcan::GlobalTimeSyncSlave::handleGlobalTimeSync
void handleGlobalTimeSync(const ReceivedDataStructure< protocol::GlobalTimeSync > &msg)
Definition: global_time_sync_slave.hpp:124
uavcan::GlobalTimeSyncSlave::suppressed_
bool suppressed_
Definition: global_time_sync_slave.hpp:43
uavcan::ISystemClock::getMonotonic
virtual MonotonicTime getMonotonic() const =0
uavcan::GlobalTimeSyncSlave::getSystemClock
ISystemClock & getSystemClock() const
Definition: global_time_sync_slave.hpp:45
uavcan::DurationBase::toUSec
int64_t toUSec() const
Definition: time.hpp:43
UAVCAN_ASSERT
#define UAVCAN_ASSERT(x)
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:184


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02