time_manager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Daniel Koch and James Jackson, BYU MAGICC Lab.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * * Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
38 
39 namespace mavrosflight
40 {
41 
43  comm_(comm),
44  offset_alpha_(0.95),
45  offset_ns_(0),
46  offset_(0.0),
47  initialized_(false)
48 {
50 
51  ros::NodeHandle nh;
53 }
54 
55 void TimeManager::handle_mavlink_message(const mavlink_message_t &msg)
56 {
57  int64_t now_ns = ros::Time::now().toNSec();
58 
59  if (msg.msgid == MAVLINK_MSG_ID_TIMESYNC)
60  {
61  mavlink_timesync_t tsync;
62  mavlink_msg_timesync_decode(&msg, &tsync);
63 
64  if (tsync.tc1 > 0) // check that this is a response, not a request
65  {
66  int64_t offset_ns = (tsync.ts1 + now_ns - 2*tsync.tc1) / 2;
67 
68  if (!initialized_ || std::abs(offset_ns_ - offset_ns) > 1e7) // if difference > 10ms, use it directly
69  {
70  offset_ns_ = offset_ns;
71  ROS_INFO("Detected time offset of %0.3f s.", offset_ns/1e9);
72  ROS_DEBUG("FCU time: %0.3f, System time: %0.3f", tsync.tc1*1e-9, tsync.ts1*1e-9);
73  initialized_ = true;
74  }
75  else // otherwise low-pass filter the offset
76  {
77  offset_ns_ = offset_alpha_*offset_ns + (1.0 - offset_alpha_)*offset_ns_;
78  }
79  }
80  }
81 }
82 
84 {
85  if (!initialized_)
86  return ros::Time::now();
87 
88  int64_t boot_ns = (int64_t)boot_ms*1000000;
89 
90  int64_t ns = boot_ns + offset_ns_;
91  if (ns < 0)
92  {
93  ROS_ERROR_THROTTLE(1, "negative time calculated from FCU: boot_ns=%ld, offset_ns=%ld. Using system time",
94  boot_ns, offset_ns_);
95  return ros::Time::now();
96  }
97  ros::Time now;
98  now.fromNSec(ns);
99  return now;
100 }
101 
103 {
104  if (!initialized_)
105  return ros::Time::now();
106 
107  int64_t boot_ns = (int64_t) boot_us * 1000;
108 
109  int64_t ns = boot_ns + offset_ns_;
110  if (ns < 0)
111  {
112  ROS_ERROR_THROTTLE(1, "negative time calculated from FCU: boot_ns=%ld, offset_ns=%ld. Using system time",
113  boot_ns, offset_ns_);
114  return ros::Time::now();
115  }
116  ros::Time now;
117  now.fromNSec(ns);
118  return now;
119 }
120 
122 {
123  mavlink_message_t msg;
124  mavlink_msg_timesync_pack(1, 50, &msg, 0, ros::Time::now().toNSec());
125  comm_->send_message(msg);
126 }
127 
128 } // namespace mavrosflight
Time & fromNSec(uint64_t t)
void register_mavlink_listener(MavlinkListenerInterface *const listener)
Register a listener for mavlink messages.
void timer_callback(const ros::TimerEvent &event)
TimeManager(MavlinkComm *comm)
#define ROS_INFO(...)
#define ROS_ERROR_THROTTLE(period,...)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
ros::Time get_ros_time_ms(uint32_t boot_ms)
uint64_t toNSec() const
virtual void handle_mavlink_message(const mavlink_message_t &msg)
The handler function for mavlink messages to be implemented by derived classes.
ros::Time get_ros_time_us(uint64_t boot_us)
static Time now()
void send_message(const mavlink_message_t &msg)
Send a mavlink message.
#define ROS_DEBUG(...)


rosflight
Author(s): Daniel Koch , James Jackson
autogenerated on Wed Jul 3 2019 20:00:13