00001 00002 #include <time.h> 00003 #include <rtt/RTT.hpp> 00004 00005 #include <rtt_rosclock/rtt_rosclock.h> 00006 #include <rtt_rosclock/rtt_rosclock_sim_clock_activity.h> 00007 #include <rtt_rosclock/rtt_rosclock_sim_clock_thread.h> 00008 00009 namespace rtt_rosclock { 00010 boost::shared_ptr<rtt_rosclock::SimClockThread> sim_clock_thread; 00011 } 00012 00013 const ros::Time rtt_rosclock::host_now() 00014 { 00015 if(SimClockThread::GetInstance() && SimClockThread::GetInstance()->simTimeEnabled()) { 00016 return rtt_now(); 00017 } 00018 00019 #ifdef __XENO__ 00020 // Use Xenomai 2.6 feature to get the NTP-synched real-time clock 00021 timespec ts = {0,0}; 00022 int ret = clock_gettime(CLOCK_HOST_REALTIME, &ts); 00023 if(ret) { 00024 RTT::log(RTT::Error) << "Could not query CLOCK_HOST_REALTIME (" << CLOCK_HOST_REALTIME <<"): "<< errno << RTT::endlog(); 00025 return rtt_rosclock::rtt_now(); 00026 } 00027 00028 return ros::Time(ts.tv_sec, ts.tv_nsec); 00029 #else 00030 return ros::Time::now(); 00031 #endif 00032 } 00033 00034 const ros::Time rtt_rosclock::host_wall_now() 00035 { 00036 #ifdef __XENO__ 00037 // Use Xenomai 2.6 feature to get the NTP-synched real-time clock 00038 timespec ts = {0,0}; 00039 int ret = clock_gettime(CLOCK_HOST_REALTIME, &ts); 00040 if(ret) { 00041 RTT::log(RTT::Error) << "Could not query CLOCK_HOST_REALTIME (" << CLOCK_HOST_REALTIME <<"): "<< errno << RTT::endlog(); 00042 return rtt_rosclock::rtt_wall_now(); 00043 } 00044 00045 return ros::Time(ts.tv_sec, ts.tv_nsec); 00046 #else 00047 ros::WallTime now(ros::WallTime::now()); 00048 return ros::Time(now.sec, now.nsec); 00049 #endif 00050 } 00051 00052 const ros::Time rtt_rosclock::rtt_now() 00053 { 00054 // count the zeros... -987654321-- 00055 const uint64_t one_E9 = 1000000000ULL; 00056 // NOTE: getNSecs returns wall time, getTicks returns offset time 00057 #ifdef __XENO__ 00058 uint64_t nsec64 = RTT::os::TimeService::Instance()->getNSecs(); //RTT::os::TimeService::Instance()->getNSecs(); 00059 #else 00060 uint64_t nsec64 = RTT::os::TimeService::ticks2nsecs(RTT::os::TimeService::Instance()->getTicks()); //RTT::os::TimeService::Instance()->getNSecs(); 00061 #endif 00062 uint32_t sec32_part = nsec64 / one_E9; 00063 uint32_t nsec32_part = nsec64 % one_E9; 00064 //RTT::log(RTT::Error) << "sec: " << sec32 << " nsec: " << nsec32 << RTT::endlog(); 00065 return ros::Time(sec32_part, nsec32_part); 00066 } 00067 00068 const ros::Time rtt_rosclock::rtt_wall_now() 00069 { 00070 const uint64_t one_E9 = 1000000000ll; 00071 // NOTE: getNSecs returns wall time, getTicks returns offset time 00072 uint64_t nsec64 = RTT::os::TimeService::Instance()->getNSecs(); 00073 uint64_t sec64_part = nsec64 / one_E9; 00074 uint64_t nsec64_part = nsec64 % one_E9; 00075 //RTT::log(RTT::Error) << "sec: " << sec32 << " nsec: " << nsec32 << RTT::endlog(); 00076 return ros::Time(sec64_part, nsec64_part); 00077 } 00078 00079 const RTT::Seconds rtt_rosclock::host_offset_from_rtt() 00080 { 00081 return (rtt_rosclock::host_wall_now() - rtt_rosclock::rtt_wall_now()).toSec(); 00082 } 00083 00084 void rtt_rosclock::use_ros_clock_topic() 00085 { 00086 SimClockThread::Instance()->useROSClockTopic(); 00087 } 00088 00089 void rtt_rosclock::use_manual_clock() 00090 { 00091 SimClockThread::Instance()->useManualClock(); 00092 } 00093 00094 const bool rtt_rosclock::set_sim_clock_activity(RTT::TaskContext *t) 00095 { 00096 if (!t) return false; 00097 return t->setActivity(new SimClockActivity(t->getPeriod())); 00098 } 00099 00100 const bool rtt_rosclock::enable_sim() 00101 { 00102 return SimClockThread::Instance()->start(); 00103 } 00104 00105 const bool rtt_rosclock::disable_sim() 00106 { 00107 return SimClockThread::Instance()->stop(); 00108 } 00109 00110 void rtt_rosclock::update_sim_clock(const ros::Time new_time) 00111 { 00112 SimClockThread::Instance()->updateClock(new_time); 00113 }