35 #ifndef _CAN_APPROXIMATE_TIME_H_ 36 #define _CAN_APPROXIMATE_TIME_H_ 40 #include <can_msgs/Frame.h> 70 typedef can_msgs::Frame::ConstPtr
Type;
71 typedef boost::function<void(const std::vector<Type> &vec)>
Callback;
75 if (
id & 0x80000000) {
76 if (!(
id & ~0x9FFFFFFF)) {
86 static bool ValidId(uint32_t
id,
bool extended)
88 return extended ? !(
id & ~0x1FFFFFFF) : !(
id & ~0x7FF);
90 static bool ValidId(
const Type &msg) {
return ValidId(msg->id, msg->is_extended); }
91 static uint32_t
BuildId(uint32_t
id,
bool extended)
93 return extended ? ((
id & 0x1FFFFFFF) | 0x80000000) : (
id & 0x7FF);
95 static uint32_t
BuildId(
const Type &msg) {
return BuildId(msg->id, msg->is_extended); }
109 std::vector<uint32_t> ids(2);
114 for (
size_t i = 0; i < ids.size(); i++) {
116 vector_[i].has_dropped_messages =
false;
118 vector_[i].warned_about_incorrect_bound =
false;
134 std::vector<uint32_t> ids(3);
140 for (
size_t i = 0; i < ids.size(); i++) {
142 vector_[i].has_dropped_messages =
false;
144 vector_[i].warned_about_incorrect_bound =
false;
161 std::vector<uint32_t> ids(4);
168 for (
size_t i = 0; i < ids.size(); i++) {
170 vector_[i].has_dropped_messages =
false;
172 vector_[i].warned_about_incorrect_bound =
false;
190 std::vector<uint32_t> ids(5);
198 for (
size_t i = 0; i < ids.size(); i++) {
200 vector_[i].has_dropped_messages =
false;
202 vector_[i].warned_about_incorrect_bound =
false;
205 ApproximateTime(uint32_t queue_size,
Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6)
221 std::vector<uint32_t> ids(6);
230 for (
size_t i = 0; i < ids.size(); i++) {
232 vector_[i].has_dropped_messages =
false;
234 vector_[i].warned_about_incorrect_bound =
false;
237 ApproximateTime(uint32_t queue_size,
Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6, uint32_t id7)
254 std::vector<uint32_t> ids(7);
264 for (
size_t i = 0; i < ids.size(); i++) {
266 vector_[i].has_dropped_messages =
false;
268 vector_[i].warned_about_incorrect_bound =
false;
271 ApproximateTime(uint32_t queue_size,
Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6, uint32_t id7, uint32_t id8)
289 std::vector<uint32_t> ids(8);
300 for (
size_t i = 0; i < ids.size(); i++) {
302 vector_[i].has_dropped_messages =
false;
304 vector_[i].warned_about_incorrect_bound =
false;
307 ApproximateTime(uint32_t queue_size,
Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6, uint32_t id7, uint32_t id8, uint32_t id9)
326 std::vector<uint32_t> ids(9);
338 for (
size_t i = 0; i < ids.size(); i++) {
340 vector_[i].has_dropped_messages =
false;
342 vector_[i].warned_about_incorrect_bound =
false;
349 if (msg->is_rtr || msg->is_error)
return;
350 ROS_WARN_COND(!
ValidId(msg),
"Processed CAN message with invalid id: 0x%X (%s)", msg->id, msg->is_extended ?
"extended" :
"standard");
351 for (
size_t i = 0; i <
vector_.size(); i++) {
354 ROS_INFO(
"Id 0x%X: %u.%u",
BuildId(msg), msg->header.stamp.sec, msg->header.stamp.nsec);
356 std::deque<Type>& deque =
vector_[i].deque;
357 deque.push_back(msg);
358 if (deque.size() == (size_t)1) {
371 std::vector<Type>& past =
vector_[i].past;
375 {
for (
size_t i = 0; i <
vector_.size(); i++) {
381 vector_[i].has_dropped_messages =
true;
384 for (
size_t i = 0; i <
vector_.size(); i++) {
417 for (
size_t i = 0; i <
vector_.size(); i++) {
418 vector_[i].inter_message_lower_bounds = lower_bound;
429 vector_[i].inter_message_lower_bounds = lower_bound;
447 if (
vector_[i].warned_about_incorrect_bound) {
450 std::deque<Type>& deque =
vector_[i].deque;
451 std::vector<Type>& v =
vector_[i].past;
453 ros::Time msg_time = deque.back()->header.stamp;
455 if (deque.size() == (size_t)1) {
460 previous_msg_time = v.back()->header.stamp;
463 previous_msg_time = deque[deque.size()-2]->header.stamp;
465 if (msg_time < previous_msg_time) {
466 ROS_WARN_STREAM(
"Messages of type " << i <<
" arrived out of order (will print only once)");
467 vector_[i].warned_about_incorrect_bound =
true;
468 }
else if ((msg_time - previous_msg_time) <
vector_[i].inter_message_lower_bounds) {
469 ROS_WARN_STREAM(
"Messages of type " << i <<
" arrived closer (" << (msg_time - previous_msg_time)
470 <<
") than the lower bound you provided (" <<
vector_[i].inter_message_lower_bounds
471 <<
") (will print only once)");
472 vector_[i].warned_about_incorrect_bound =
true;
479 std::deque<Type>& deque =
vector_[i].deque;
490 std::deque<Type>& deque =
vector_[i].deque;
491 std::vector<Type>& vector =
vector_[i].past;
493 vector.push_back(deque.front());
503 for (
size_t i = 0; i <
vector_.size(); i++) {
512 std::vector<Type>& v =
vector_[i].past;
513 std::deque<Type>& q =
vector_[i].deque;
515 while (num_messages > 0) {
516 q.push_front(v.back());
529 std::vector<Type>& v =
vector_[i].past;
530 std::deque<Type>& q =
vector_[i].deque;
532 q.push_front(v.back());
543 std::vector<Type>& v =
vector_[i].past;
544 std::deque<Type>& q =
vector_[i].deque;
546 q.push_front(v.back());
563 std::vector<Type> candidate;
564 for (
size_t i = 0; i <
vector_.size(); i++) {
565 candidate.push_back(
vector_[i].candidate);
570 for (
size_t i = 0; i <
vector_.size(); i++) {
577 for (
size_t i = 0; i <
vector_.size(); i++) {
602 time =
vector_[0].deque.front()->header.stamp;
604 for (
size_t i = 1; i <
vector_.size(); i++) {
606 if ((t < time) ^ end) {
623 std::vector<Type>& v =
vector_[i].past;
624 std::deque<Type>& q =
vector_[i].deque;
627 ros::Time last_msg_time = v.back()->header.stamp;
628 ros::Time msg_time_lower_bound = last_msg_time +
vector_[i].inter_message_lower_bounds;
630 return msg_time_lower_bound;
634 ros::Time current_msg_time = q.front()->header.stamp;
635 return current_msg_time;
658 std::vector<ros::Time> virtual_times(
vector_.size());
659 for (
size_t i = 0; i <
vector_.size(); i++) {
663 time = virtual_times[0];
665 for (
size_t i = 0; i <
vector_.size(); i++) {
666 if ((virtual_times[i] < time) ^ end) {
667 time = virtual_times[i];
684 uint32_t end_index, start_index;
687 for (uint32_t i = 0; i < (uint32_t)
vector_.size(); i++) {
688 if (i != end_index) {
691 vector_[i].has_dropped_messages =
false;
703 if (
vector_[end_index].has_dropped_messages) {
734 if (start_index ==
pivot_) {
748 std::vector<int> num_virtual_moves(9,0);
751 uint32_t end_index, start_index;
767 for (
size_t i = 0; i <
vector_.size(); i++) {
768 recover(i, num_virtual_moves[i]);
770 (void)num_non_empty_deques_before_virtual_search;
780 num_virtual_moves[start_index]++;
814 #endif // _CAN_APPROXIMATE_TIME_H_
void getVirtualCandidateBoundary(uint32_t &index, ros::Time &time, bool end)
void getCandidateStart(uint32_t &start_index, ros::Time &start_time)
void getCandidateEnd(uint32_t &end_index, ros::Time &end_time)
ros::Time getVirtualTime(size_t i)
static bool ValidId(uint32_t id)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5)
void processMsg(const Type &msg)
bool has_dropped_messages
static bool ValidId(uint32_t id, bool extended)
ros::Time candidate_start_
static const uint32_t NO_PIVOT
std::vector< VectorData > vector_
void recoverAndDelete(size_t i)
void getVirtualCandidateEnd(uint32_t &end_index, ros::Time &end_time)
void getVirtualCandidateStart(uint32_t &start_index, ros::Time &start_time)
static uint32_t BuildId(const Type &msg)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4)
void dequeDeleteFront(size_t i)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6, uint32_t id7, uint32_t id8)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6)
ros::Duration max_interval_duration_
void setAgePenalty(double age_penalty)
void getCandidateBoundary(uint32_t &index, ros::Time &time, bool end)
void setInterMessageLowerBound(size_t i, ros::Duration lower_bound)
void dequeMoveFrontToPast(size_t i)
bool warned_about_incorrect_bound
#define ROS_WARN_STREAM(args)
static uint32_t BuildId(uint32_t id, bool extended)
void setMaxIntervalDuration(ros::Duration max_interval_duration)
void setInterMessageLowerBound(ros::Duration lower_bound)
#define ROS_WARN_COND(cond,...)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6, uint32_t id7)
static bool ValidId(const Type &msg)
uint32_t num_non_empty_deques_
void recover(size_t i, size_t num_messages)
ApproximateTime(uint32_t queue_size, Callback callback, uint32_t id1, uint32_t id2, uint32_t id3, uint32_t id4, uint32_t id5, uint32_t id6, uint32_t id7, uint32_t id8, uint32_t id9)
can_msgs::Frame::ConstPtr Type
ros::Duration inter_message_lower_bounds
void checkInterMessageBound(size_t i)
boost::function< void(const std::vector< Type > &vec)> Callback