00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00036
00037 #include <sstream>
00038 #include <settlerlib/interval_calc.h>
00039 #include <ros/console.h>
00040
00041 #define INTERVAL_DEBUG(fmt, ...) \
00042 ROS_DEBUG_NAMED("IntervalCalc", fmt,##__VA_ARGS__)
00043
00044
00045 using namespace std;
00046 using namespace settlerlib;
00047
00048 calibration_msgs::Interval IntervalCalc::computeLatestInterval(const SortedDeque<DeflatedConstPtr>& signal,
00049 const std::vector<double>& tolerances,
00050 ros::Duration max_spacing)
00051 {
00052 if (max_spacing < ros::Duration(0,0))
00053 {
00054 ROS_WARN("max_spacing is negative (%.3f). Should be positive", max_spacing.toSec());
00055 max_spacing = -max_spacing;
00056 }
00057
00058 if (signal.size() == 0)
00059 {
00060 ROS_WARN("Can't compute range of an empty signal");
00061 return calibration_msgs::Interval();
00062 }
00063
00064 std::deque<DeflatedConstPtr>::const_reverse_iterator rev_it = signal.rbegin();
00065
00066 assert(*rev_it);
00067
00068 const unsigned int N = (*rev_it)->channels_.size();
00069
00070 assert(tolerances.size() == N);
00071 vector<double> channel_max( (*rev_it)->channels_ );
00072 vector<double> channel_min( (*rev_it)->channels_ );
00073 vector<double> channel_range(N);
00074
00075 calibration_msgs::Interval result;
00076 result.end = (*signal.rbegin())->header.stamp;
00077 result.start = result.end;
00078
00079
00080 INTERVAL_DEBUG("Starting to walk along interval:");
00081 while( rev_it != signal.rend() )
00082 {
00083 if ( (*rev_it)->channels_.size() != N)
00084 {
00085 ROS_WARN("Num channels has changed. Cutting off interval prematurely ");
00086 return result;
00087 }
00088
00089 ros::Duration cur_step = result.start - (*rev_it)->header.stamp;
00090 if ( cur_step > max_spacing)
00091 {
00092 INTERVAL_DEBUG("Difference between interval.start and it.stamp is [%.3fs]"
00093 "Exceeds [%.3fs]", cur_step.toSec(), max_spacing.toSec());
00094 return result;
00095 }
00096
00097 ostringstream max_debug;
00098 ostringstream min_debug;
00099 ostringstream range_debug;
00100 max_debug << " max: ";
00101 min_debug << " min: ";
00102 range_debug << " range:";
00103 for (unsigned int i=0; i<N; i++)
00104 {
00105 channel_max[i] = fmax( channel_max[i], (*rev_it)->channels_[i] );
00106 channel_min[i] = fmin( channel_min[i], (*rev_it)->channels_[i] );
00107 channel_range[i] = channel_max[i] - channel_min[i];
00108
00109 max_debug << " " << channel_max[i];
00110 min_debug << " " << channel_min[i];
00111 range_debug << " " << channel_range[i];
00112 }
00113
00114 INTERVAL_DEBUG("Current stats:\n%s\n%s\n%s",
00115 max_debug.str().c_str(),
00116 min_debug.str().c_str(),
00117 range_debug.str().c_str());
00118
00119 for (unsigned int i=0; i<N; i++)
00120 {
00121 if (channel_range[i] > tolerances[i])
00122 {
00123 INTERVAL_DEBUG("Channel %u range is %.3f. Exceeds tolerance of %.3f", i, channel_range[i], tolerances[i]);
00124 return result;
00125 }
00126 }
00127
00128 result.start = (*rev_it)->header.stamp;
00129
00130 rev_it++;
00131 }
00132 return result;
00133 }