0

阿木币

0

精华

182 小时

在线时间

技术大V

Rank: 4

发表于 2020-5-20 11:47:18 3346 浏览 1 回复

[仿真开发] ROS_PX4_gazebo学习记录

本帖最后由 chasing 于 2020-5-21 19:21 编辑

本文CSDN地址为 https://blog.csdn.net/qq_15390133/article/details/106205463
在官方程序上(PX4 wiki上为offboard起飞到2m高度) 进行更改,实现首先起飞到固定点(x=1,y=2,z=5), 然后按照给定角度飞行。

补充:最终实现效果链接为

1.

2.

3. PX4_ROS_gazebo多机仿真(画圆)


注意事项:

1. ROS程序订阅的的消息为/mavros/imu/data,而非/mavros/imu/data_raw。
2. ROS程序发布的给定姿态topic为/mavros/setpoint_raw/attitude,而非/mavros/setpoint_attitude/attitude。
3. 姿态解算部分参考了Ardupilot中的函数。


效果图为:见文末!

ROS程序代码为:代码未经自己加工,仅供参考,提供思路用

  1. /**
  2. * @file offb_node.cpp
  3. * @brief Offboard control example node, written with MAVROS version 0.19.x, PX4 Pro Flight
  4. * Stack and tested in Gazebo SITL
  5. */

  6. #include <ros/ros.h>
  7. #include <geometry_msgs/PoseStamped.h>
  8. #include <mavros_msgs/CommandBool.h>
  9. #include <mavros_msgs/SetMode.h>
  10. #include <mavros_msgs/State.h>
  11. #include <mavros_msgs/Thrust.h>
  12. #include <geometry_msgs/TwistStamped.h>
  13. #include <mavros_msgs/AttitudeTarget.h>
  14. #include <sensor_msgs/Imu.h>
  15. #include <eigen3/Eigen/Core>
  16. #include <eigen3/Eigen/Geometry>

  17. mavros_msgs::State current_state;
  18. void state_cb(const mavros_msgs::State::ConstPtr& msg){
  19.     current_state = *msg;
  20. }

  21. struct attitude_quat{
  22.     float q1;
  23.     float q2;
  24.     float q3;
  25.     float q4;
  26. };

  27. float _roll,_pitch,_yaw;
  28. struct attitude_quat att_quat;
  29. sensor_msgs::Imu current_imudata;
  30. Eigen::Quaternionf current_imu_quat;

  31. float get_euler_roll(float q1,float q2,float q3,float q4)
  32. {
  33.     return (atan2f(2.0f*(q1*q2 + q3*q4), 1.0f - 2.0f*(q2*q2 + q3*q3)));
  34. }

  35. // get euler pitch angle
  36. float get_euler_pitch(float q1,float q2,float q3,float q4)
  37. {
  38.     return asin(2.0f*(q1*q3 - q4*q2));
  39. }

  40. // get euler yaw angle
  41. float get_euler_yaw(float q1,float q2,float q3,float q4)
  42. {
  43.     return atan2f(2.0f*(q1*q4 + q2*q3), 1.0f - 2.0f*(q3*q3 + q4*q4));
  44. }

  45. // create eulers from a quaternion
  46. void to_euler(float &roll, float &pitch, float &yaw)
  47. {
  48.     roll = get_euler_roll(current_imudata.orientation.w,current_imudata.orientation.x,current_imudata.orientation.y,current_imudata.orientation.z);
  49.     pitch = get_euler_pitch(current_imudata.orientation.w,current_imudata.orientation.x,current_imudata.orientation.y,current_imudata.orientation.z);
  50.     yaw = get_euler_yaw(current_imudata.orientation.w,current_imudata.orientation.x,current_imudata.orientation.y,current_imudata.orientation.z);
  51. }

  52. void imu_cb(const sensor_msgs::Imu::ConstPtr& msg){
  53.     current_imudata = *msg;
  54.     current_imu_quat.w() = current_imudata.orientation.w;
  55.     current_imu_quat.x() = current_imudata.orientation.x;
  56.     current_imu_quat.y() = current_imudata.orientation.y;
  57.     current_imu_quat.z() = current_imudata.orientation.z;
  58.     to_euler(_roll,_pitch,_yaw);
  59.    // ROS_INFO("PASS THE IMU DATA %f",current_imudata.orientation.w);
  60. }

  61. void from_euler(float roll, float pitch, float yaw)
  62. {
  63.     const float cr2 = cosf(roll*0.5f);
  64.     const float cp2 = cosf(pitch*0.5f);
  65.     const float cy2 = cosf(yaw*0.5f);
  66.     const float sr2 = sinf(roll*0.5f);
  67.     const float sp2 = sinf(pitch*0.5f);
  68.     const float sy2 = sinf(yaw*0.5f);

  69.     att_quat.q1 = cr2*cp2*cy2 + sr2*sp2*sy2;
  70.     att_quat.q2 = sr2*cp2*cy2 - cr2*sp2*sy2;
  71.     att_quat.q3 = cr2*sp2*cy2 + sr2*cp2*sy2;
  72.     att_quat.q4 = cr2*cp2*sy2 - sr2*sp2*cy2;
  73. }



  74. int main(int argc, char **argv)
  75. {
  76.     ros::init(argc, argv, "offb_node");
  77.     ros::NodeHandle nh;

  78.     ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>
  79.             ("mavros/state", 10, state_cb);
  80.     ros::Publisher local_attitude_pub = nh.advertise<mavros_msgs::AttitudeTarget>("mavros/setpoint_raw/attitude",10);
  81.     ros::Subscriber imu_attitude_sub = nh.subscribe<sensor_msgs::Imu>("mavros/imu/data",10,imu_cb);
  82.     ros::Publisher local_pos_pub = nh.advertise<geometry_msgs::PoseStamped>
  83.             ("mavros/setpoint_position/local", 10);
  84.     ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>
  85.             ("mavros/cmd/arming");
  86.     ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>
  87.             ("mavros/set_mode");

  88.     //the setpoint publishing rate MUST be faster than 2Hz
  89.     ros::Rate rate(20.0);

  90.     // wait for FCU connection
  91.     while(ros::ok() && !current_state.connected){
  92.         ros::spinOnce();
  93.         rate.sleep();
  94.     }

  95.     geometry_msgs::PoseStamped pose;
  96.     pose.pose.position.x = 1;
  97.     pose.pose.position.y = 2;
  98.     pose.pose.position.z = 5;

  99.     float roll_deg = 12;
  100.     float pitch_deg = 15;
  101.     float yaw_deg = 0;

  102.     from_euler(roll_deg*M_PI/180, pitch_deg*M_PI/180, yaw_deg*M_PI/180);

  103.     mavros_msgs::AttitudeTarget attitude_raw;
  104.     attitude_raw.orientation.w = att_quat.q1;
  105.     attitude_raw.orientation.x = att_quat.q2;
  106.     attitude_raw.orientation.y = att_quat.q3;
  107.     attitude_raw.orientation.z = att_quat.q4;
  108.     attitude_raw.thrust = 0.8;
  109.     attitude_raw.type_mask = 0b00000111;

  110.     pose.pose.orientation.w = att_quat.q1;
  111.     pose.pose.orientation.x = att_quat.q2;
  112.     pose.pose.orientation.y = att_quat.q3;
  113.     pose.pose.orientation.z = att_quat.q4;

  114.     mavros_msgs::SetMode offb_set_mode;
  115.     offb_set_mode.request.custom_mode = "OFFBOARD";

  116.     mavros_msgs::CommandBool arm_cmd;
  117.     arm_cmd.request.value = true;

  118.     ros::Time last_request = ros::Time::now();
  119.     int16_t step_counter = 0;
  120.     int8_t step_one = 1;
  121.     Eigen::Matrix3f _rotMatrix;
  122.     Eigen::Vector3f eular_angle;
  123.     while(ros::ok()){
  124.         _rotMatrix = current_imu_quat.toRotationMatrix();
  125.         eular_angle = _rotMatrix.eulerAngles(2,1,0);
  126.         if(!(step_counter%20))
  127.             ROS_INFO("Imu_data = %f %f %f", _roll*180/M_PI,_pitch*180/M_PI,_yaw*180/M_PI);
  128.         if( current_state.mode != "OFFBOARD" &&
  129.             (ros::Time::now() - last_request > ros::Duration(5.0))){
  130.             if( set_mode_client.call(offb_set_mode) &&
  131.                 offb_set_mode.response.mode_sent){
  132.                 ROS_INFO("Offboard enabled");
  133.             }
  134.             last_request = ros::Time::now();
  135.         } else {

  136.             if( !current_state.armed &&
  137.                 (ros::Time::now() - last_request > ros::Duration(5.0)))
  138.                 {
  139.                 if( arming_client.call(arm_cmd) &&
  140.                     arm_cmd.response.success){
  141.                     ROS_INFO("Vehicle armed");
  142.                 }
  143.                 last_request = ros::Time::now();
  144.                 ROS_INFO("try to arm");
  145.             }
  146.             else{
  147.                 if(step_counter<400){
  148.                     step_one = 1;
  149.                 }     
  150.                 else
  151.                 {
  152.                     step_one = 0;
  153.                 }
  154.                
  155.             }
  156.         }

  157.         if(step_one){
  158.             local_pos_pub.publish(pose);
  159.         }   
  160.         else
  161.         {
  162.             local_attitude_pub.publish(attitude_raw);
  163.         }
  164.         ros::spinOnce();
  165.         rate.sleep();
  166.         step_counter++;
  167.     }

  168.     return 0;
  169. }
复制代码
20200519004857784.png

评分

参与人数 3阿木币 +3 收起 理由
amov_msq + 1
admin + 1
风帆 + 1

查看全部评分


扫一扫浏览分享
回复

使用道具 举报

131

阿木币

0

精华

272 小时

在线时间

管理员

Rank: 9Rank: 9Rank: 9

发表于 2020-5-22 21:30:50 来自手机
赞定一个
回复

使用道具 举报

返回列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表