Go to the documentation of this file.00001 #include "tcm3_compass_driver_node.h"
00002 #include <cmath>
00003 #include <numeric>
00004
00005
00006 Tcm3CompassDriverNode::Tcm3CompassDriverNode(ros::NodeHandle &nh) : iri_base_driver::IriBaseNodeDriver<Tcm3CompassDriver>(nh)
00007 {
00008
00009 this->loop_rate_ = 30;
00010
00011
00012 this->tcm3_publisher_ = this->public_node_handle_.advertise<iri_common_drivers_msgs::compass3axis>("tcm3", 100);
00013
00014 data_counter_ = 0;
00015 vheading_.reserve(10);
00016 vpitch_.reserve(10);
00017 vroll_.reserve(10);
00018 covariance_buffer_length_ = 10;
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 }
00030
00031 void Tcm3CompassDriverNode::mainNodeThread(void)
00032 {
00033
00034 this->driver_.lock();
00035
00036 driver_.getData(heading_,pitch_,roll_,distortion_);
00037
00038 if(vheading_.size() <= covariance_buffer_length_)
00039 {
00040 vheading_.push_back(heading_);
00041 vpitch_.push_back(pitch_);
00042 vroll_.push_back(roll_);
00043 }else{
00044 vheading_.pop_back();
00045 vpitch_.pop_back();
00046 vroll_.pop_back();
00047 vheading_.insert(vheading_.begin(),heading_);
00048 vpitch_.insert(vpitch_.begin(),pitch_);
00049 vroll_.insert(vroll_.begin(),roll_);
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059 compass3axis_msg_.header.stamp = ros::Time::now();
00060 compass3axis_msg_.header.frame_id = driver_.config_.frame_id;
00061
00062
00063
00064 compass3axis_msg_.angles[0] = heading_;
00065 compass3axis_msg_.angles[1] = pitch_;
00066 compass3axis_msg_.angles[2] = roll_;
00067
00068
00069
00070
00071
00072
00073
00074
00075 for(uint i=0;i<9;i++) compass3axis_msg_.covariances[i] = 999;
00076
00077 double sigma_head = 0.0, sigma_pitch = 0.0, sigma_roll = 0.0;
00078
00079 if(abs(pitch_) < 70.0 || abs(roll_) < 70.0)
00080 sigma_head = 0.5;
00081 else
00082 sigma_head = 0.8;
00083
00084 sigma_pitch = 0.2;
00085
00086 if(abs(pitch_) < 65.0)
00087 sigma_roll = 0.2;
00088 else if(abs(pitch_) >= 65.0 && abs(pitch_) < 80.0)
00089 sigma_roll = 0.5;
00090 else
00091 sigma_roll = 1.0;
00092
00093 compass3axis_msg_.covariances[0]=pow(sigma_head,2);
00094 compass3axis_msg_.covariances[4]=pow(sigma_pitch,2);
00095 compass3axis_msg_.covariances[8]=pow(sigma_roll,2);
00096
00097
00098 double limit = 80.0 * M_PI/180.0;
00099 compass3axis_msg_.alarms[0] = distortion_;
00100 compass3axis_msg_.alarms[1] = (pitch_ > -limit && pitch_ < limit ) ? false: true;
00101 compass3axis_msg_.alarms[2] = (roll_ > -limit && roll_ < limit ) ? false: true;
00102
00103
00104
00105
00106
00107
00108 this->tcm3_publisher_.publish(compass3axis_msg_);
00109
00110
00111
00112
00113 this->driver_.unlock();
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 void Tcm3CompassDriverNode::postNodeOpenHook(void)
00125 {
00126 }
00127
00128 void Tcm3CompassDriverNode::addNodeDiagnostics(void)
00129 {
00130 }
00131
00132 void Tcm3CompassDriverNode::addNodeOpenedTests(void)
00133 {
00134 }
00135
00136 void Tcm3CompassDriverNode::addNodeStoppedTests(void)
00137 {
00138 }
00139
00140 void Tcm3CompassDriverNode::addNodeRunningTests(void)
00141 {
00142 }
00143
00144 void Tcm3CompassDriverNode::reconfigureNodeHook(int level)
00145 {
00146 }
00147
00148 Tcm3CompassDriverNode::~Tcm3CompassDriverNode()
00149 {
00150
00151 }
00152
00153
00154 int main(int argc,char *argv[])
00155 {
00156 return driver_base::main<Tcm3CompassDriverNode>(argc,argv,"tcm3_compass_driver_node");
00157 }
00158
00159 void Tcm3CompassDriverNode::covarianceMatrix(vector <double> x,
00160 vector <double> y,
00161 vector <double> z,
00162 vector <double> & matrix)
00163 {
00164 matrix[0] = covariance(x,x);
00165 matrix[1] = covariance(x,y);
00166 matrix[2] = covariance(x,z);
00167 matrix[3] = covariance(y,x);
00168 matrix[4] = covariance(y,y);
00169 matrix[5] = covariance(y,z);
00170 matrix[6] = covariance(z,x);
00171 matrix[7] = covariance(z,y);
00172 matrix[8] = covariance(z,z);
00173 }
00174
00175 double Tcm3CompassDriverNode::covariance(vector <double> x, vector <double> y)
00176 {
00177 double sum=0.0, x_avg=0.0, y_avg=0.0;
00178
00179 x_avg = std::accumulate(x.begin(), x.end(), 0)/(double)x.size();
00180 y_avg = std::accumulate(y.begin(), y.end(), 0)/(double)y.size();
00181
00182 for(uint i=0;i<x.size();i++)
00183 sum += (x[i]-x_avg)*(y[i]-y_avg);
00184
00185 return ( sum/(double)x.size() );
00186 }
00187
00188
00189
00190
00191