草庐IT

[学习记录]realsence d455 +vins-fusion+px4+ego_planner下无人机的悬停与控制

fikimi 2023-08-22 原文

写在前面:持续更新修改......

my env:ubuntu20

my pixhawk:2.4.8

my px4 firmware:1.9.0 stablepx4fmu-v2-1.6.0.px4v

经济型科研方案(有个较好的网络环境):

                     无人机端:250机架——38块钱或者可以更便宜、三叶桨——也很便宜、飞控——2.4.8——五百多、机载板子——jetsonnano(可以选择更便宜但是wifi模块还是要强)、电池也很便宜。

                     地面站:电脑一台

无人机端的机载板子主要用于通信,传输数据,全部算法都在电脑上跑(手动滑稽)。

关于带宽问题,使用压缩图即可

关于网络出错等问题,几乎都可以通过修改dns与/etc/hosts解决。

-------------------------------------------------------------分割符-----------------------------------------------------

整体步骤整理,整体的步骤来自(注意看里面的readme.txt):https://github.com/ZJU-FAST-Lab/Fast-Drone-250https://github.com/ZJU-FAST-Lab/Fast-Drone-250

Step1: 安装 realsence2 驱动,把ros自带的和源码都安装了,并检测和imu数据与camera数据。

参考GitHub - IntelRealSense/realsense-ros: Intel(R) RealSense(TM) ROS Wrapper for D400 series, SR300 Camera and T265 Tracking ModuleIntel(R) RealSense(TM) ROS Wrapper for D400 series, SR300 Camera and T265 Tracking Module - GitHub - IntelRealSense/realsense-ros: Intel(R) RealSense(TM) ROS Wrapper for D400 series, SR300 Camera and T265 Tracking Modulehttps://github.com/IntelRealSense/realsense-ros

Step2:安装vins-fustion,并测试结果

参考GitHub - HKUST-Aerial-Robotics/VINS-Fusion: An optimization-based multi-sensor state estimatorhttps://github.com/HKUST-Aerial-Robotics/VINS-Fusion

如果遇到一些问题还能参考:<解决方法>ubuntu20+ros+opencv4运行vinfusion_fikimi的博客-CSDN博客

Step3:仿真环境安装,并解决px4 和机载板卡与笔记本的实机通信问题,连接方式等

ubuntu18+jetson nano +px4+ros <——>QGC+ubuntu20+ros(关于仿真和实物运行的持续记录心得)_fikimi的博客-CSDN博客

notice:关于在px4 的sd卡写入marlink 命令或者QGC的mavlink控制台修改帧率问题:通过telem2 连接,硬件写/dev/ttyS2,通过telem1 连接,写/dev/ttyS1,通过usb 则写/dev/ttyACM0

mavlink stream -d /dev/ttyS2 -s ATTITUDE_QUATERNION -r 200
mavlink stream -d /dev/ttyS2 -s HIGHRES_IMU -r 200

Step4:(这里可以写个shell,省得一条一条按,关于shell运行ssh的方法可以查expect的用法)

drone0-terminal1:roslaunch px4_realsense_bridge mypx4.launch

drone0-terminal2:roslaunch realsense2_camera rs_camera.launch

ubuntu-terminal1:roscore

ubuntu-terminal2:roslaunch vins vins_fusion.launch

ubuntu-terminal3:roslaunch vins rviz.launch

ubuntu-terminal4:roslaunch px4ctrl run_ctrl.launch

ubuntu-terminal5:sh shfiles/takeoff.sh

其中,在遥控器(飞行模式上是通道5,都设置为自稳模式)上将模式转为Autohover(通道5)模式,,通道6拨动一下(根据遥控器可以进行修改),然后将油门推到中位,再在ubuntu-terminal5:中运行sh shfiles/takeoff.sh。

注意:Fast-lab的Fast-drone-250中包px4ctrl的readme.txt中需要详细阅读

-------------------------------------------------------------分割符-----------------------------------------------------------

(控制方法:除了使用px4ctrl,还可以借鉴px4 vio的官方的方法(或者把官方vio中的odom用vins-fusion替代注意话题的对应,tf树的转换)rosrun rqt_tf_tree rqt_tf_tree )

controller.cpp部分代码注释(有误可以指出并交流):       

//推力估计模型,计算thr2acc_
//输入参数:估计的加速度
bool 
LinearControl::estimateThrustModel(
    const Eigen::Vector3d &est_a,
    const Parameter_t &param)
{
  ros::Time t_now = ros::Time::now();
  while (timed_thrust_.size() >= 1)
  {
    // Choose data before 35~45ms ago
    std::pair<ros::Time, double> t_t = timed_thrust_.front();
    double time_passed = (t_now - t_t.first).toSec();
    if (time_passed > 0.045) // 45ms
    {
      // printf("continue, time_passed=%f\n", time_passed);
      timed_thrust_.pop();
      continue;
    }
    if (time_passed < 0.035) // 35ms
    {
      // printf("skip, time_passed=%f\n", time_passed);
      return false;
    }

    /***********************************************************/
    /* Recursive least squares algorithm with vanishing memory */
    /***********************************************************/
    double thr = t_t.second;//取出后就弹出
    timed_thrust_.pop();
    //非精准推理模型:thr2acc = est_a(2)/thr
    /***********************************/
    /* Model: est_a(2) = thr2acc_ * thr */
    /***********************************/
    //kLQR,you can print it to see
    double gamma = 1 / (rho2_ + thr * P_ * thr);
    double K = gamma * P_ * thr;
    thr2acc_ = thr2acc_ + K * (est_a(2) - thr * thr2acc_);
    P_ = (1 - K * thr) * P_ / rho2_;

    //printf("%6.3f,%6.3f,%6.3f,%6.3f\n", thr2acc_, gamma, K, P_);
    //fflush(stdout);
    // debug_msg_.thr2acc = thr2acc_;
    return true;
  }
  return false;
}
/* 
  compute u.thrust and u.q, controller gains and other parameters are in param_ 
  u就是q和thrust等等,根据输入的odom和imu信息计算u
  debug
*/
quadrotor_msgs::Px4ctrlDebug
LinearControl::calculateControl(const Desired_State_t &des,
    const Odom_Data_t &odom,
    const Imu_Data_t &imu, 
    Controller_Output_t &u)
{
  /* WRITE YOUR CODE HERE */
      //compute disired acceleration
      Eigen::Vector3d des_acc(0.0, 0.0, 0.0);
      Eigen::Vector3d Kp,Kv;//增益,pid的p,比例增益
      Kp << param_.gain.Kp0, param_.gain.Kp1, param_.gain.Kp2;//先把参数中的增益加进去
      Kv << param_.gain.Kv0, param_.gain.Kv1, param_.gain.Kv2;
      //输入偏差x常数
      des_acc = des.a + Kv.asDiagonal() * (des.v - odom.v) + Kp.asDiagonal() * (des.p - odom.p);//asDiagonal对角化伪表达
      //增量
      des_acc += Eigen::Vector3d(0,0,param_.gra);
      //推力计算转换,z方向加速度占比计算
      u.thrust = computeDesiredCollectiveThrustSignal(des_acc);
      double roll,pitch,yaw,yaw_imu;
      double yaw_odom = fromQuaternion2yaw(odom.q);//根据四元数计算出欧拉角,ros的odom消息机制为ZYX,无人机的是ZXY
      double sin = std::sin(yaw_odom);
      double cos = std::cos(yaw_odom);
      //跟着把roll yaw pitch 算出来
      roll = (des_acc(0) * sin - des_acc(1) * cos )/ param_.gra;
      pitch = (des_acc(0) * cos + des_acc(1) * sin )/ param_.gra;
      //yaw = fromQuaternion2yaw(des.q);
      yaw_imu = fromQuaternion2yaw(imu.q);//一个道理,把imu的yaw算出来
      // Eigen::Quaterniond q = Eigen::AngleAxisd(yaw,Eigen::Vector3d::UnitZ())
      //   * Eigen::AngleAxisd(roll,Eigen::Vector3d::UnitX())
      //   * Eigen::AngleAxisd(pitch,Eigen::Vector3d::UnitY());

      //旋转向量(AngleAxisd)初始化,des为旋转角,Eigen::Vector3d::UnitZ()表示绕z轴转.Z-Y-X
      //odom.q 接受的话题是Z-Y-X 
      //odom.q.inverse()表示 odom.q的共轭,并且单位化
      Eigen::Quaterniond q = Eigen::AngleAxisd(des.yaw,Eigen::Vector3d::UnitZ())
        * Eigen::AngleAxisd(pitch,Eigen::Vector3d::UnitY())
        * Eigen::AngleAxisd(roll,Eigen::Vector3d::UnitX());
      u.q = imu.q * odom.q.inverse() * q;// Align with FCU frame

  /* WRITE YOUR CODE HERE */
  //used for debug。可以自己添加
   debug_msg_.des_p_x = des.p(0);
   debug_msg_.des_p_y = des.p(1);
   debug_msg_.des_p_z = des.p(2);
 
  debug_msg_.des_v_x = des.v(0);
  debug_msg_.des_v_y = des.v(1);
  debug_msg_.des_v_z = des.v(2);
  
  debug_msg_.des_a_x = des_acc(0);
  debug_msg_.des_a_y = des_acc(1);
  debug_msg_.des_a_z = des_acc(2);
  
  debug_msg_.des_q_x = u.q.x();
  debug_msg_.des_q_y = u.q.y();
  debug_msg_.des_q_z = u.q.z();
  debug_msg_.des_q_w = u.q.w();
  
  debug_msg_.des_thr = u.thrust;
  
  // Used for thrust-accel mapping estimation 推力加速度映射估计
  timed_thrust_.push(std::pair<ros::Time, double>(ros::Time::now(), u.thrust));
  while (timed_thrust_.size() > 100)
  {
    timed_thrust_.pop();
  }
  return debug_msg_;
}

-----------------------------------------------------------------分割符--------------------------------------------------------

有关[学习记录]realsence d455 +vins-fusion+px4+ego_planner下无人机的悬停与控制的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  5. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  6. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  7. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  8. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  9. ruby-on-rails - ruby 新手,有人可以帮我从控制台破译这个错误吗? - 2

    我真的只是不确定这意味着什么或我应该做什么才能让网页在我的本地主机上运行。现在它只是显示一个错误,上面写着“我们很抱歉,但出了点问题。”当我运行railsserver并在chrome中打开localhost:3000时。这是控制台输出:StartedGET"/users/sign_in"for127.0.0.1at2013-07-0512:07:07-0400ProcessingbyDevise::SessionsController#newasHTMLCompleted500InternalServerErrorin55msNoMethodError(undefinedmethod`

  10. ruby-on-rails - Rails 控制台的 YAML 输出 - 2

    在Rails控制台中执行类似yGrau.all的命令时,我得到这些奇怪的!binary字符串而不是属性名称。知道如何解决这个问题吗?谢谢。irb(main):003:0>yGrau.all←[1m←[36mGrauLoad(0.0ms)←[0m←[1mSELECT"graus".*FROM"gr←[1m←[35mEXPLAIN(0.0ms)←[0mEXPLAINQUERYPLANSELECT"grauEXPLAINfor:SELECT"graus".*FROM"graus"0|0|0|SCANTABLEgraus(~1000000rows)----!ruby/object:Grauat

随机推荐