28 return sqrt(a.
x()*a.
x() + a.
y()*a.
y() + a.
z()*a.
z());
32 node_(n), curr_imu_reading_(new
sensor_msgs::Imu()) {
65 ROS_INFO(
"Compass Estimator Started");
70 ROS_WARN(
"Waiting for IMU data, no gyroscope data available)");
72 ROS_WARN(
"Waiting for mag data, no magnetometer data available, Filter not initialized");
76 ROS_WARN(
"Gyroscope data being receieved too slow or not at all");
82 ROS_WARN(
"Magnetometer data being receieved too slow or not at all");
90 geometry_msgs::Vector3 gyro_vector;
91 geometry_msgs::Vector3 gyro_vector_transformed;
92 gyro_vector = data->angular_velocity;
104 ROS_WARN(
"Missed transform between base_link and %s", data->header.frame_id.c_str());
112 double yaw_gyro_reading = gyro_vector_transformed.z;
134 geometry_msgs::Vector3 imu_mag = data->vector;
135 geometry_msgs::Vector3 imu_mag_transformed;
138 if ( std::isnan(data->vector.x) ||
139 std::isnan(data->vector.y) ||
140 std::isnan(data->vector.z) ) {
144 imu_mag.x = data->vector.x;
145 imu_mag.y = data->vector.y;
146 imu_mag.z = data->vector.z;
153 ROS_WARN(
"Missed transform between base_link and %s", data->header.frame_id.c_str());
163 double mag_x = imu_mag_transformed.x -
mag_zero_x_;
164 double mag_y = imu_mag_transformed.y -
mag_zero_y_;
165 double mag_z = imu_mag_transformed.z;
169 calib_mag = calib_mag /
magn(calib_mag);
170 mag_x = calib_mag.
x();
171 mag_y = calib_mag.
y();
172 mag_z = calib_mag.
z();
174 geometry_msgs::Vector3Stamped calibrated_mag;
176 calibrated_mag.header.frame_id =
"imu_link";
178 calibrated_mag.vector.x = calib_mag.
x();
179 calibrated_mag.vector.y = calib_mag.
y();
180 calibrated_mag.vector.z = calib_mag.
z();
188 curr_imu_meas = curr_imu_meas * transform;
194 double c_r, c_p, c_y;
195 temp.
getRPY(c_r, c_p, c_y);
196 double cos_pitch = cos(c_p);
197 double sin_pitch = sin(c_p);
198 double cos_roll = cos(c_r);
199 double sin_roll = sin(c_r);
200 double t_mag_x = mag_x * cos_pitch + mag_z * sin_pitch;
201 double t_mag_y = mag_x * sin_roll * sin_pitch + mag_y * cos_roll - mag_z * sin_roll * cos_pitch;
202 double head_x = t_mag_x;
203 double head_y = t_mag_y;
206 double heading_meas = atan2(head_x, head_y);
220 if (abs(innovation) > M_PI)
223 curr_heading_ = heading_prediction_ + kalman_gain * (innovation);
227 std_msgs::Float32 raw_heading_float;
228 raw_heading_float.data = heading_meas;
245 o_imu_reading = o_imu_reading * transform;
256 sensor_msgs::Imu publish_imu;
258 o_imu_reading = o_imu_reading * (transform.inverse());
262 std_msgs::Float32 curr_heading_float;
263 curr_heading_float.data = compass_heading;
272 ROS_INFO(
"Magnetometer data received. Compass estimator initialized");
275 int main(
int argc,
char **argv) {
double heading_variance_prediction_
ros::Publisher raw_compass_pub_
static tf::Quaternion createQuaternionFromRPY(double roll, double pitch, double yaw)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
double magn(tf::Vector3 a)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void declCallback(const std_msgs::Float32 &data)
static double getYaw(const Quaternion &bt_q)
bool gyro_update_complete_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
static void vector3TFToMsg(const Vector3 &bt_v, geometry_msgs::Vector3 &msg_v)
int main(int argc, char **argv)
ROSCPP_DECL void spin(Spinner &spinner)
double curr_heading_variance_
double heading_prediction_
TFSIMD_FORCE_INLINE const tfScalar & x() const
void debugCallback(const ros::TimerEvent &)
void imuCallback(sensor_msgs::ImuPtr data)
static void vector3MsgToTF(const geometry_msgs::Vector3 &msg_v, Vector3 &bt_v)
TFSIMD_FORCE_INLINE const tfScalar & z() const
sensor_msgs::ImuPtr curr_imu_reading_
static void quaternionMsgToTF(const geometry_msgs::Quaternion &msg, Quaternion &bt)
void getRPY(tfScalar &roll, tfScalar &pitch, tfScalar &yaw, unsigned int solution_number=1) const
ros::Publisher compass_pub_
static void quaternionTFToMsg(const Quaternion &bt, geometry_msgs::Quaternion &msg)
TFSIMD_FORCE_INLINE const tfScalar & y() const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
tf::TransformListener listener_
double yaw_meas_variance_
void repackageImuPublish(tf::StampedTransform)
IMUCompass(ros::NodeHandle &n)
double last_measurement_update_time_
void initFilter(double heading_meas)
double last_motion_update_time_
void magCallback(const geometry_msgs::Vector3StampedConstPtr &data)
double heading_prediction_variance_
ros::Subscriber decl_sub_