123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #include "imu_node.h"
- ImuNode::ImuNode(std::string port, unsigned long baud){
- p_buffer = (char *)malloc((UARTBufferLength+2)*sizeof(char));
- p_temp_buf = (uint8_t *)malloc((iBufferSize+2)*sizeof(uint8_t));
- // p_temp_buffer = (char *)malloc(iBufferSize*sizeof(char));
- start = 0;
- end = 0;
- b_exit_ = false;
- read_thread_ = NULL;
- last_time_ = ros::Time::now();
- ori_time_ = ros::Time::now();
- last_pose_ = tf::Pose();
- last_vel_ = geometry_msgs::Twist();
- // port, baudrate, timeout in milliseconds
- try
- {
- my_serial = new serial::Serial(port, baud, serial::Timeout::simpleTimeout(1000));
- if (my_serial->isOpen())
- {
- read_thread_ = new boost::thread(boost::bind(ImuNode::thread_get_data, this));
- }
- }
- catch (serial::IOException &e)
- {
- std::cout << "serial exception: " << e.what() << std::endl;
- b_exit_ = true;
- }
- catch (std::exception &e)
- {
- std::cerr << "Unhandled Exception: " << e.what() << std::endl;
- b_exit_ = true;
- }
- // std::cout<<my_serial.isOpen()<<std::endl;
- odom_pub_ = nh_.advertise<nav_msgs::Odometry>("odom",2);
- }
- ImuNode::~ImuNode(){
- if (!ros::ok)
- {
- b_exit_ = true;
- }
- if (read_thread_!=NULL)
- {
- std::cout<<read_thread_<<" thread waiting to stop."<<std::endl;
- read_thread_->join();
- }
- free(p_buffer);
- free(p_temp_buf);
- }
- void ImuNode::publish_data(){
- if (!b_exit_ && b_connected_)
- {
- // usleep(10 * 1000);
- curr_time_ = ros::Time::now();
- double dt = (curr_time_ - last_time_).toSec();
- // std::vector<uint8_t> buff;
- // my_serial->read(buff, 100);
- // int start_index=0,end_index=100;
- std::unique_lock<std::mutex> lck(mtx);
- if (JY901.CopeSerialData(p_buffer, start, end, 5))
- // if (JY901.CopeSerialData((char *)buff.data(), start_index, end_index, 100))
- {
- // 赋值当前位置与速度
- tf::Vector3 last_pos = last_pose_.getOrigin();
- // 利用加速度计算速度
- // curr_vel_.linear.x = last_vel_.linear.x + dt * (float)JY901.stcAcc.a[0] / 32768 * 16 * 9.8;
- // curr_vel_.linear.y = last_vel_.linear.y + dt * (float)JY901.stcAcc.a[1] / 32768 * 16 * 9.8;
- // curr_vel_.linear.z = last_vel_.linear.z + dt * ((float)JY901.stcAcc.a[2] / 32768 * 16 - 1) * 9.8;
- // 保存原始加速度,用于测试
- curr_vel_.linear.x = (float)JY901.stcAcc.a[0] / 32768 * 16 * 9.8;
- curr_vel_.linear.y = (float)JY901.stcAcc.a[1] / 32768 * 16 * 9.8;
- curr_vel_.linear.z = ((float)JY901.stcAcc.a[2] / 32768 * 16 - 1) * 9.8;
- // 利用陀螺仪生成角速度
- // curr_vel_.angular.x = last_vel_.angular.x + (float)JY901.stcGyro.w[0] / 32768 * 2000 * M_PI / 180.0;
- // curr_vel_.angular.y = last_vel_.angular.y + (float)JY901.stcGyro.w[1] / 32768 * 2000 * M_PI / 180.0;
- // curr_vel_.angular.z = last_vel_.angular.z + (float)JY901.stcGyro.w[2] / 32768 * 2000 * M_PI / 180.0;
- curr_vel_.angular.x = (float)JY901.stcGyro.w[0] / 32768 * 2000 * M_PI / 180.0;
- curr_vel_.angular.y = (float)JY901.stcGyro.w[1] / 32768 * 2000 * M_PI / 180.0;
- curr_vel_.angular.z = (float)JY901.stcGyro.w[2] / 32768 * 2000 * M_PI / 180.0;
- // 利用磁场综合获取角度信息,扩展角度范围从[-pi, pi]到[-2pi, 2pi]
- double angle[3] = {0.0};
- for (size_t i = 0; i < 3; i++)
- {
- angle[i] = (float)JY901.stcAngle.Angle[i] / 32768 * M_PI;
- // if (JY901.stcAngle.Angle[i] * JY901.lastAngle.Angle[i] < 0)
- // {
- // std::cout<<i<<" 反号"<<std::endl;
- // if (JY901.stcAngle.Angle[i] / 32768 * M_PI < -M_PI_2)
- // {
- // std::cout<<"---"<<std::endl;
- // m_angle_status_[i] = 1;
- // }
- // else if (JY901.stcAngle.Angle[i] / 32768 * M_PI > M_PI_2)
- // {
- // std::cout<<"+++"<<std::endl;
- // m_angle_status_[i] = 2;
- // }
- // }
- // if (m_angle_status_[i] == 1)
- // {
- // if (JY901.stcAngle.Angle[i] > 0)
- // {
- // m_angle_status_[i] = 0;
- // }
- // else
- // {
- // angle[i] += M_PI * 2;
- // }
- // }
- // if (m_angle_status_[i] == 2)
- // {
- // if (JY901.stcAngle.Angle[i] < 0)
- // {
- // m_angle_status_[i] == 0;
- // }
- // else
- // {
- // angle[i] -= M_PI * 2;
- // }
- // }
- }
- tf::Quaternion quat;quat.setRPY(angle[0],angle[1],angle[2]);
- curr_pose_.setRotation(quat);
-
- // curr_pose_.setRotation(tf::Quaternion((float)JY901.stcAngle.Angle[0] / 32768 * M_PI,
- // (float)JY901.stcAngle.Angle[1] / 32768 * M_PI,
- // (float)JY901.stcAngle.Angle[2] / 32768 * M_PI));
- // // 积分获得位置信息,存在累计误差
- // curr_pose_.setOrigin(tf::Vector3(last_pos.getX() + (last_vel_.linear.x+curr_vel_.linear.x)/2.0 * dt,
- // last_pos.getY() + (last_vel_.linear.y+curr_vel_.linear.y)/2.0 * dt,
- // last_pos.getZ() + (last_vel_.linear.z+curr_vel_.linear.z)/2.0 * dt));
- curr_pose_.setOrigin(tf::Vector3(1, 0, 0));
- last_vel_ = curr_vel_;
- last_pose_ = curr_pose_;
- //std::cout << "----------- Time: " << (ros::Time::now().toNSec()-ori_time_.toNSec())/1000000 << "-----------" << std::endl;
- printf("Acc: %.4f %.4f %.4f\n", (float)JY901.stcAcc.a[0] / 32768 * 16 * 9.8, (float)JY901.stcAcc.a[1] / 32768 * 16 * 9.8, (float)JY901.stcAcc.a[2] / 32768 * 16 * 9.8);
- printf("Gyro: %.4f %.4f %.4f\n", (float)JY901.stcGyro.w[0] / 32768 * 2000 * M_PI / 180.0, (float)JY901.stcGyro.w[1] / 32768 * 2000 * M_PI / 180.0, (float)JY901.stcGyro.w[2] / 32768 * 2000 * M_PI / 180.0);
- printf("linear: %.4f %.4f %.4f\n", curr_vel_.linear.x, curr_vel_.linear.y, curr_vel_.linear.z);
- //printf("Angle: %.4f %.4f %.4f\n", (float)JY901.stcAngle.Angle[0] / 32768 * M_PI, (float)JY901.stcAngle.Angle[1] / 32768 * M_PI, (float)JY901.stcAngle.Angle[2] / 32768 * M_PI);
- //printf("Ang speed: %.4f %.4f %.4f\n", curr_vel_.angular.x, curr_vel_.angular.y, curr_vel_.angular.z);
- // std::cout<<curr_pose_.getBasis().getRow(0)[0] <<" "<< curr_pose_.getBasis().getRow(0)[1] <<" "<< curr_pose_.getBasis().getRow(0)[2] <<std::endl;
- // std::cout<<curr_pose_.getBasis().getRow(1)[0] <<" "<< curr_pose_.getBasis().getRow(1)[1] <<" "<< curr_pose_.getBasis().getRow(1)[2] <<std::endl;
- // std::cout<<curr_pose_.getBasis().getRow(2)[0] <<" "<< curr_pose_.getBasis().getRow(2)[1] <<" "<< curr_pose_.getBasis().getRow(2)[2] <<std::endl;
- // printf("quaternion: %.4f %.4f %.4f %.4f\n", quat.x(),quat.y(),quat.z(),quat.w());
- }
- else
- {
- curr_vel_.linear = geometry_msgs::Vector3();
- curr_vel_.angular = geometry_msgs::Vector3();
- curr_pose_.setRotation(last_pose_.getRotation());
- curr_pose_.setOrigin(last_pose_.getOrigin());
- printf("failed\n");
- }
- // 发布里程计信息与tf
- nav_msgs::Odometry odom;
- odom.header.frame_id = "odom";
- odom.child_frame_id = "base_link";
- odom.header.stamp = curr_time_;
- tf::poseTFToMsg(curr_pose_, odom.pose.pose);
- odom.twist.twist.linear = curr_vel_.linear;
- odom.twist.twist.angular = curr_vel_.angular;
- odom_pub_.publish(odom);
- tf::StampedTransform tf_msg(curr_pose_, ros::Time::now(), "odom", "base_link");
- tf_broadcaster_.sendTransform(tf_msg);
- // std::cout<<"-----------"<< ros::Time::now().toSec() <<"-----------"<<std::endl;
- // printf("Acc:\t%.3f\t %.3f\t %.3f\t", (float)JY901.stcAcc.a[0] / 32768 * 16 * 9.8, (float)JY901.stcAcc.a[1] / 32768 * 16 * 9.8, (float)JY901.stcAcc.a[2] / 32768 * 16 * 9.8);
- // printf("Gyro:\t%.3f\t %.3f\t %.3f\t", (float)JY901.stcGyro.w[0] / 32768 * 2000 * M_PI / 180.0, (float)JY901.stcGyro.w[1] / 32768 * 2000 * M_PI / 180.0, (float)JY901.stcGyro.w[2] / 32768 * 2000 * M_PI / 180.0);
- // printf("Angle:\t%.3f\t %.3f\t %.3f\r\n", (float)JY901.stcAngle.Angle[0] / 32768 * M_PI, (float)JY901.stcAngle.Angle[1] / 32768 * M_PI, (float)JY901.stcAngle.Angle[2] / 32768 * M_PI);
- // printf("Mag:%d %d %d\r\n", JY901.stcMag.h[0], JY901.stcMag.h[1], JY901.stcMag.h[2]);
- // printf("DStatus:%d %d %d %d\r\n", JY901.stcDStatus.sDStatus[0], JY901.stcDStatus.sDStatus[1], JY901.stcDStatus.sDStatus[2], JY901.stcDStatus.sDStatus[3]);
- last_time_ = curr_time_;
- }
- }
- int main(int argc, char** argv){
- ros::init(argc, argv, "imu_node");
- ImuNode imu("/dev/ttyUSB0", 38400);
- ros::Rate loop_rate(200);
- while (ros::ok())
- {
- if(imu.b_exit_)
- return 1;
- imu.publish_data();
- ros::spinOnce();
- loop_rate.sleep();
- }
- std::cout<<"leave"<<std::endl;
- imu.b_exit_ = true;
- return 1;
- }
|