imu_node.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "imu_node.h"
  2. ImuNode::ImuNode(std::string port, unsigned long baud){
  3. p_buffer = (char *)malloc((UARTBufferLength+2)*sizeof(char));
  4. p_temp_buf = (uint8_t *)malloc((iBufferSize+2)*sizeof(uint8_t));
  5. // p_temp_buffer = (char *)malloc(iBufferSize*sizeof(char));
  6. start = 0;
  7. end = 0;
  8. b_exit_ = false;
  9. read_thread_ = NULL;
  10. last_time_ = ros::Time::now();
  11. ori_time_ = ros::Time::now();
  12. last_pose_ = tf::Pose();
  13. last_vel_ = geometry_msgs::Twist();
  14. // port, baudrate, timeout in milliseconds
  15. try
  16. {
  17. my_serial = new serial::Serial(port, baud, serial::Timeout::simpleTimeout(1000));
  18. if (my_serial->isOpen())
  19. {
  20. read_thread_ = new boost::thread(boost::bind(ImuNode::thread_get_data, this));
  21. }
  22. }
  23. catch (serial::IOException &e)
  24. {
  25. std::cout << "serial exception: " << e.what() << std::endl;
  26. b_exit_ = true;
  27. }
  28. catch (std::exception &e)
  29. {
  30. std::cerr << "Unhandled Exception: " << e.what() << std::endl;
  31. b_exit_ = true;
  32. }
  33. // std::cout<<my_serial.isOpen()<<std::endl;
  34. odom_pub_ = nh_.advertise<nav_msgs::Odometry>("odom",2);
  35. }
  36. ImuNode::~ImuNode(){
  37. if (!ros::ok)
  38. {
  39. b_exit_ = true;
  40. }
  41. if (read_thread_!=NULL)
  42. {
  43. std::cout<<read_thread_<<" thread waiting to stop."<<std::endl;
  44. read_thread_->join();
  45. }
  46. free(p_buffer);
  47. free(p_temp_buf);
  48. }
  49. void ImuNode::publish_data(){
  50. if (!b_exit_ && b_connected_)
  51. {
  52. // usleep(10 * 1000);
  53. curr_time_ = ros::Time::now();
  54. double dt = (curr_time_ - last_time_).toSec();
  55. // std::vector<uint8_t> buff;
  56. // my_serial->read(buff, 100);
  57. // int start_index=0,end_index=100;
  58. std::unique_lock<std::mutex> lck(mtx);
  59. if (JY901.CopeSerialData(p_buffer, start, end, 5))
  60. // if (JY901.CopeSerialData((char *)buff.data(), start_index, end_index, 100))
  61. {
  62. // 赋值当前位置与速度
  63. tf::Vector3 last_pos = last_pose_.getOrigin();
  64. // 利用加速度计算速度
  65. // curr_vel_.linear.x = last_vel_.linear.x + dt * (float)JY901.stcAcc.a[0] / 32768 * 16 * 9.8;
  66. // curr_vel_.linear.y = last_vel_.linear.y + dt * (float)JY901.stcAcc.a[1] / 32768 * 16 * 9.8;
  67. // curr_vel_.linear.z = last_vel_.linear.z + dt * ((float)JY901.stcAcc.a[2] / 32768 * 16 - 1) * 9.8;
  68. // 保存原始加速度,用于测试
  69. curr_vel_.linear.x = (float)JY901.stcAcc.a[0] / 32768 * 16 * 9.8;
  70. curr_vel_.linear.y = (float)JY901.stcAcc.a[1] / 32768 * 16 * 9.8;
  71. curr_vel_.linear.z = ((float)JY901.stcAcc.a[2] / 32768 * 16 - 1) * 9.8;
  72. // 利用陀螺仪生成角速度
  73. // curr_vel_.angular.x = last_vel_.angular.x + (float)JY901.stcGyro.w[0] / 32768 * 2000 * M_PI / 180.0;
  74. // curr_vel_.angular.y = last_vel_.angular.y + (float)JY901.stcGyro.w[1] / 32768 * 2000 * M_PI / 180.0;
  75. // curr_vel_.angular.z = last_vel_.angular.z + (float)JY901.stcGyro.w[2] / 32768 * 2000 * M_PI / 180.0;
  76. curr_vel_.angular.x = (float)JY901.stcGyro.w[0] / 32768 * 2000 * M_PI / 180.0;
  77. curr_vel_.angular.y = (float)JY901.stcGyro.w[1] / 32768 * 2000 * M_PI / 180.0;
  78. curr_vel_.angular.z = (float)JY901.stcGyro.w[2] / 32768 * 2000 * M_PI / 180.0;
  79. // 利用磁场综合获取角度信息,扩展角度范围从[-pi, pi]到[-2pi, 2pi]
  80. double angle[3] = {0.0};
  81. for (size_t i = 0; i < 3; i++)
  82. {
  83. angle[i] = (float)JY901.stcAngle.Angle[i] / 32768 * M_PI;
  84. // if (JY901.stcAngle.Angle[i] * JY901.lastAngle.Angle[i] < 0)
  85. // {
  86. // std::cout<<i<<" 反号"<<std::endl;
  87. // if (JY901.stcAngle.Angle[i] / 32768 * M_PI < -M_PI_2)
  88. // {
  89. // std::cout<<"---"<<std::endl;
  90. // m_angle_status_[i] = 1;
  91. // }
  92. // else if (JY901.stcAngle.Angle[i] / 32768 * M_PI > M_PI_2)
  93. // {
  94. // std::cout<<"+++"<<std::endl;
  95. // m_angle_status_[i] = 2;
  96. // }
  97. // }
  98. // if (m_angle_status_[i] == 1)
  99. // {
  100. // if (JY901.stcAngle.Angle[i] > 0)
  101. // {
  102. // m_angle_status_[i] = 0;
  103. // }
  104. // else
  105. // {
  106. // angle[i] += M_PI * 2;
  107. // }
  108. // }
  109. // if (m_angle_status_[i] == 2)
  110. // {
  111. // if (JY901.stcAngle.Angle[i] < 0)
  112. // {
  113. // m_angle_status_[i] == 0;
  114. // }
  115. // else
  116. // {
  117. // angle[i] -= M_PI * 2;
  118. // }
  119. // }
  120. }
  121. tf::Quaternion quat;quat.setRPY(angle[0],angle[1],angle[2]);
  122. curr_pose_.setRotation(quat);
  123. // curr_pose_.setRotation(tf::Quaternion((float)JY901.stcAngle.Angle[0] / 32768 * M_PI,
  124. // (float)JY901.stcAngle.Angle[1] / 32768 * M_PI,
  125. // (float)JY901.stcAngle.Angle[2] / 32768 * M_PI));
  126. // // 积分获得位置信息,存在累计误差
  127. // curr_pose_.setOrigin(tf::Vector3(last_pos.getX() + (last_vel_.linear.x+curr_vel_.linear.x)/2.0 * dt,
  128. // last_pos.getY() + (last_vel_.linear.y+curr_vel_.linear.y)/2.0 * dt,
  129. // last_pos.getZ() + (last_vel_.linear.z+curr_vel_.linear.z)/2.0 * dt));
  130. curr_pose_.setOrigin(tf::Vector3(1, 0, 0));
  131. last_vel_ = curr_vel_;
  132. last_pose_ = curr_pose_;
  133. //std::cout << "----------- Time: " << (ros::Time::now().toNSec()-ori_time_.toNSec())/1000000 << "-----------" << std::endl;
  134. 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);
  135. 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);
  136. printf("linear: %.4f %.4f %.4f\n", curr_vel_.linear.x, curr_vel_.linear.y, curr_vel_.linear.z);
  137. //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);
  138. //printf("Ang speed: %.4f %.4f %.4f\n", curr_vel_.angular.x, curr_vel_.angular.y, curr_vel_.angular.z);
  139. // std::cout<<curr_pose_.getBasis().getRow(0)[0] <<" "<< curr_pose_.getBasis().getRow(0)[1] <<" "<< curr_pose_.getBasis().getRow(0)[2] <<std::endl;
  140. // std::cout<<curr_pose_.getBasis().getRow(1)[0] <<" "<< curr_pose_.getBasis().getRow(1)[1] <<" "<< curr_pose_.getBasis().getRow(1)[2] <<std::endl;
  141. // std::cout<<curr_pose_.getBasis().getRow(2)[0] <<" "<< curr_pose_.getBasis().getRow(2)[1] <<" "<< curr_pose_.getBasis().getRow(2)[2] <<std::endl;
  142. // printf("quaternion: %.4f %.4f %.4f %.4f\n", quat.x(),quat.y(),quat.z(),quat.w());
  143. }
  144. else
  145. {
  146. curr_vel_.linear = geometry_msgs::Vector3();
  147. curr_vel_.angular = geometry_msgs::Vector3();
  148. curr_pose_.setRotation(last_pose_.getRotation());
  149. curr_pose_.setOrigin(last_pose_.getOrigin());
  150. printf("failed\n");
  151. }
  152. // 发布里程计信息与tf
  153. nav_msgs::Odometry odom;
  154. odom.header.frame_id = "odom";
  155. odom.child_frame_id = "base_link";
  156. odom.header.stamp = curr_time_;
  157. tf::poseTFToMsg(curr_pose_, odom.pose.pose);
  158. odom.twist.twist.linear = curr_vel_.linear;
  159. odom.twist.twist.angular = curr_vel_.angular;
  160. odom_pub_.publish(odom);
  161. tf::StampedTransform tf_msg(curr_pose_, ros::Time::now(), "odom", "base_link");
  162. tf_broadcaster_.sendTransform(tf_msg);
  163. // std::cout<<"-----------"<< ros::Time::now().toSec() <<"-----------"<<std::endl;
  164. // 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);
  165. // 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);
  166. // 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);
  167. // printf("Mag:%d %d %d\r\n", JY901.stcMag.h[0], JY901.stcMag.h[1], JY901.stcMag.h[2]);
  168. // printf("DStatus:%d %d %d %d\r\n", JY901.stcDStatus.sDStatus[0], JY901.stcDStatus.sDStatus[1], JY901.stcDStatus.sDStatus[2], JY901.stcDStatus.sDStatus[3]);
  169. last_time_ = curr_time_;
  170. }
  171. }
  172. int main(int argc, char** argv){
  173. ros::init(argc, argv, "imu_node");
  174. ImuNode imu("/dev/ttyUSB0", 38400);
  175. ros::Rate loop_rate(200);
  176. while (ros::ok())
  177. {
  178. if(imu.b_exit_)
  179. return 1;
  180. imu.publish_data();
  181. ros::spinOnce();
  182. loop_rate.sleep();
  183. }
  184. std::cout<<"leave"<<std::endl;
  185. imu.b_exit_ = true;
  186. return 1;
  187. }