Copyright © 2019-2026 幻思创新 Fancinnov® 版权所有

版本:V2.3
更新日期:2026年2月10日

轨迹飞行教程

1.fcu_core_v2

fcu_core_v2项目架构介绍

fcu_core_v2
|- fcu_core.launch 一键启动launch脚本
|- mavlink 第三方消息库用来传输Mavlink数据
|- rviz_cfg rviz配置文件存放目录
└─ src 功能包源文件
    |- fcu_mission.cpp 任务规划文件
    |- fcu_command.cpp 命令发送文件
    |- fcu_bridge_001.cpp 和飞控之间的通信文件
    |- fcu_bridge_002.cpp
    └─ fcu_bridge_00*.cpp

编译运行

配置电脑环境

实验平台:windows11宿主机 VMware17.5Pro虚拟机里Ubuntu-20.04LTS

安装ROS

终端执行下面命令

wget http://fishros.com/install -O fishros && . fishros

按照下面操作运行
图片
图片
图片
图片
完成之后执行下面指令

sudo apt-get install ros-noetic-serial // 串口库
sudo apt-get install libeigen3-dev // Eigen库是一个开源的C++线性代数库,支持线性代数、矩阵和矢量运算,数值分析及其相关的算法

fcu_core.launch配置参数详解

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.4.1" type="string"/>
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="true" type="bool"/>
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/>
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>

fcu_mission的使用

fcu_mission是fcu_core_v2中进行任务规划的部分,想要规划飞行任务就要先知道自己的定位

所以首先他接收飞控发送过来的odom数据

ros::Subscriber odom001=nh.subscribe<nav_msgs::Odometry>("odom_global_001", 100, odom_global001_handler);

进行坐标变换和四元数到姿态角的转化

void odom_global001_handler(const nav_msgs::Odometry::ConstPtr& odom)
{
  pos_odom_001_x=(float)odom->pose.pose.position.x;//位置点改为FRU坐标
  pos_odom_001_y=-(float)odom->pose.pose.position.y;
  pos_odom_001_z=(float)odom->pose.pose.position.z;
  float quaternion_odom[4]={(float)odom->pose.pose.orientation.w,
                            (float)odom->pose.pose.orientation.x,
                            (float)odom->pose.pose.orientation.y,
                            (float)odom->pose.pose.orientation.z};
  mavlink_quaternion_to_euler(quaternion_odom, &pos_odom_001_roll, &pos_odom_001_pitch, &pos_odom_001_yaw);
}

接下来就是如何规划我们的轨迹,fcu_mission文件中给出四个例程让我们手动规划轨迹。每一个例程都需要使用键盘启动,所以要有一个接收键盘指令的话题

  ros::Subscriber comm=nh.subscribe<std_msgs::Int16>("/fcu_command/command", 100, cmdHandler);

而他的发送方则是fcu_command.cpp,可以看到键盘上每一个按键都对应一个case,我们可以类比着添加自己的任务启动按键

switch(buf[0]){
      case 'p':
        printf("执行路径\n");
        cmd.data=0;
        command.publish(cmd);
        break;
      case 'a':
        printf("解锁\n");
        cmd.data=1;
        command.publish(cmd);
        break;
      case 'd':
        printf("锁定\n");
        cmd.data=2;
        command.publish(cmd);
        break;
      case 't':
        printf("起飞\n");
        cmd.data=3;
        command.publish(cmd);
        break;
      case 'l':
        printf("降落\n");
        cmd.data=4;
        command.publish(cmd);
        break;
      ***

在fcu_mission中,键入指令的处理函数也是需要考虑的一环,同样使用switch case语句来进行处理

void cmdHandler(const std_msgs::Int16::ConstPtr& cmd){
  switch(cmd->data){
    case 0:
        enable_path=true;
        break;
    ***

飞行任务的具体规划我们提供了四个例程

if(enable_track){
      theta+=M_PI/20/200;

      px1=1.0*cosf(theta)+2;
      py1=1.0*sinf(theta)+2;
      pz1=0.6;

      px2=1.0*cosf(theta+M_PI*2/6)+2;
      py2=1.0*sinf(theta+M_PI*2/6)+2;
      pz2=0.6;

      px3=1.0*cosf(theta+M_PI*4/6)+2;
      py3=1.0*sinf(theta+M_PI*4/6)+2;
      pz3=0.6;

      px4=1.0*cosf(theta+M_PI*6/6)+2;
      py4=1.0*sinf(theta+M_PI*6/6)+2;
      pz4=0.6;

      px5=1.0*cosf(theta+M_PI*8/6)+2;
      py5=1.0*sinf(theta+M_PI*8/6)+2;
      pz5=0.6;

      px6=1.0*cosf(theta+M_PI*10/6)+2;
      py6=1.0*sinf(theta+M_PI*10/6)+2;
      pz6=0.6;
    }

首先根据theta==0的时候的初始位置摆放好飞机,启动,连接,检查心跳包,解锁"a",起飞"t",绕圆'r',停止's'。

和绕圆任务类似,具体逻辑看代码

switch (path_track_status)
      {
        case ReadyToGoal:
          switch(goal_point)
          {
            case 0:
            SetGoal(1,0.5,0.5,0);
            break;
            case 1:
            SetGoal(1,1.0,1.0,0);
            break;
            case 2:
            SetGoal(1,1.5,1.0,0);
            break;
            case 3:
            SetGoal(1,2.0,1.0,0);
            break;
            case 4:
            SetGoal(1,2.5,1.0,0);
            break;
            case 5:
            SetGoal(1,2.5,2.0,0);
            break;
            case 6:
            SetGoal(1,2.0,2.0,0);
            break;
            case 7:
            SetGoal(1,1.5,2.0,0);
            break;
            case 8:
            SetGoal(1,1.0,2.0,0);
            break;
            case 9:
            SetGoal(1,0.5,2.0,0);
            break;
          }
          path_track_status = ExecutingGoal;
          break;
        case ExecutingGoal:
          if(IsReachGoal(1,0.1))
          {
            path_track_status = ReadyToGoal;
            goal_point++;
            break;
          }
          // std::cout << "Not Finish yet..." << std::endl;
          break;

首先根据goal_point==0的时候的初始位置摆放好飞机,启动,连接,检查心跳包,解锁"a",起飞"t",执行路径'p',停止's'。

        switch(enable_pos){
          case 0:
              px1=pos_takeoff_001_x; py1=pos_takeoff_001_y; pz1=0.0f;
              px2=pos_takeoff_002_x; py2=pos_takeoff_002_y; pz2=0.0f;
              px3=pos_takeoff_003_x; py3=pos_takeoff_003_y; pz3=0.0f;
              px4=pos_takeoff_004_x; py4=pos_takeoff_004_y; pz4=0.0f;
              px5=pos_takeoff_005_x; py5=pos_takeoff_005_y; pz5=0.0f;
              px6=pos_takeoff_006_x; py6=pos_takeoff_006_y; pz6=0.0f;
              break;
          case 1:
              px=1.0;
              py=1.0;
              pz=1.0;

              px1=pos_takeoff_001_x+px; py1=pos_takeoff_001_y+py; pz1=pz;
              px2=pos_takeoff_002_x+px; py2=pos_takeoff_002_y+py; pz2=pz;
              px3=pos_takeoff_003_x+px; py3=pos_takeoff_003_y+py; pz3=pz;
              px4=pos_takeoff_004_x+px; py4=pos_takeoff_004_y+py; pz4=pz;
              px5=pos_takeoff_005_x+px; py5=pos_takeoff_005_y+py; pz5=pz;
              px6=pos_takeoff_006_x+px; py6=pos_takeoff_006_y+py; pz6=pz;

              break;

可以摆放飞机,启动,连接,检查心跳包,解锁"a",起飞"t",执行位置点"1"(1~4)。

根据fcu_command的enable_pos来进行定点飞行,pos_takeoff_001_x和pos_takeoff_001_y是起飞时候的位置,而px和py都是根据起飞点位置的偏移量,进行相加之后就是绝对位置目标点,所以我们可以看到,最终publish的都是绝对目标点。

追踪飞行分别为前视追踪和下视追踪,分别对应带有前视摄像机的无人机和下视摄像头的机载电脑无人机,机载电脑运行着fcu_core_v2的程序和aruco检测程序。
在远程主机中,我们摁下按键触发指令,就会向飞控发送追踪指令。
图片
飞控再将消息转发至机载电脑,从而开启追踪和下发追踪指令。具体流程图如下
图片

定时器执行函数

在fcu_mission中,我们只需要将规划的目标点位置姿态传出去就可以了,这一步通过定时器实现

  ros::Timer timer_mission_001 = nh.createTimer(ros::Duration(0.1),execute_mission_001,false);

我们创建了一个100ms的定时器,以这个周期运行execute_mission_001的函数

void execute_mission_001(const ros::TimerEvent &event){
  if(get_pos_cmd){
      return;
  }
  if(set_goal&&!use_goal_001){
    return;
  }
  //发布mission
  mission_001.layout.dim.push_back(std_msgs::MultiArrayDimension());
  mission_001.layout.dim[0].label = "mission_001";
  mission_001.layout.dim[0].size = 11;
  mission_001.layout.dim[0].stride = 1;
  mission_001.data.resize(11);
  mission_001.data[0]=yaw;//rad
  mission_001.data[1]=yaw_rate;//rad/s
  mission_001.data[2]=px1;//x
  mission_001.data[3]=py1;//y
  mission_001.data[4]=pz1;//z
  mission_001.data[5]=vx;//vx
  mission_001.data[6]=vy;//vy
  mission_001.data[7]=vz;//vz
  mission_001.data[8]=ax;//ax
  mission_001.data[9]=ay;//ay
  mission_001.data[10]=az;//az
  mission_pub_001.publish(mission_001);
  use_goal_001=false;     
}

这个函数就是填充数据然后发送,最重要的是publish这一步,其实就是将我们规划好的目标点通过话题发送给fcu_bridge再发送给飞控。

rviz_plugin的使用

除掉直接使用fcu_mission.cpp进行任务规划,我们还可以rviz_plugin进行任务规划,这个插件的源代码放在fcu_core_rviz_swarm_goals_plugin中。通过rviz自动加载我们的自定义插件,然后通过rviz中发布的点进行任务规划,然后点击执行路径按钮,任务就会发送给fcu_mission.cpp,再通过fcu_mission.cpp进行任务规划,所以本质上还是使用了fcu_mission.cpp。

界面介绍

图片

这个部分是RVIZ原生的功能,用于选择在"显示界面"中展示的可视化组件。具体介绍可以参考RVIZ官方文档

这是我们的自定义界面,源代码放在fcu_core_rviz_swarm_goals_plugin


功能介绍

按钮区域

图片

第一行和第二行的按钮作用不再赘述,具体实现就是使用槽函数将对应消息发送到/fcu_command/command话题上面,和fcu_command节点所做的事别无二致。

第三行和第四行是新加的控制按钮,就是以按钮的方式控制飞机的前进后退左转右转。
使用方法:1. 由于该控制仅对指定id的飞机生效,所以首先观察当前目标飞机id,确保控制飞机的id正确。
图片
2. 接着确保该飞机至少有一个目标点
图片
3. 然后点击执行路径按钮,飞机会飞向该目标点,此时前进后退左转右转的功能就是控制该飞机的目标点的移动,飞机跟随目标点移动,即可实现前后左右移动的效果。


循环轨迹

如下图所示就是一个checkbox,如果需要循环执行哪个飞机的目标点就勾选对应飞机的循环checkbox即可
图片


首先映入眼帘的是矩形构成的墙体,这个墙体是可以移动的,我们在控制界面的这一行能够决定这个矩形墙体的两个对角线上的点。

图片

图片


下发目标点

  1. 选择[2D Nav Goal]

图片

  1. 在显示界面点击并拖拽鼠标给出yaw轴姿态

图片

此时已经将该目标点加入到待执行列表中。

图片

  1. 点击[执行路径]即可下发目标点给飞控,[停止轨迹]即可停止下发目标点;
    双击“待执行列表”中的目标点(x,y,z,yaw皆可),再点击[清除单个目标点]即可删除该目标点。点击[清除全部目标点]即可清空所有目标点。

图片

点击执行目标点之后,飞机会实时监测飞机是否到达目标点,到达目标点之后将会自动执行下一个目标点,直到"待执行列表"里的最后一个目标点执行完毕。

既然要判断飞机是否抵达目标点,那就需要给定一个允许误差阈值,这个阈值就是我们通过rviz界面设置的,具体如下(单位m)

图片

  1. 设置默认高度,使用2D Navl Goal添加目标点的时候只能进行设置xy和yaw,z轴的高度使用的是默认值,这时候就需要我们有修改z轴默认高度的功能,如下所示(单位m)

图片

fcu_bridge_00x的使用

fcu_bridge_00x和fcu_mission,fcu_command统一规划不同,每一个bridge文件只对应一个飞机,下面代码解析只真对fcu_bridge_001.cpp,对于其他bridge文件也适用。

  1. 与飞控之间的直接通信

打开并配置串口/网络

  if(mav_chan==MAVLINK_COMM_0){
    try{
    //设置串口属性,并打开串口
        ser.setPort(usb_port.c_str());
        ser.setBaudrate(BAUDRATE);
        serial::Timeout to = serial::Timeout::simpleTimeout(5000);
        ser.setTimeout(to);
        ser.open();
    }catch (serial::IOException& e)
    {
        printf("Unable to open port \n");
        return -1;
    }

    //检测串口是否已经打开,并给出提示信息
    if(ser.isOpen())
    {
        printf("Serial Port initialized\n");
    }
    else
    {
        return -1;
    }
  }else{
    socket_cli=socket(AF_INET, SOCK_STREAM, 0);
    if(socket_cli < 0){
      printf("socket error!\n");
      return -1;
    }

    memset(&drone_addr, 0, sizeof(drone_addr));
    drone_addr.sin_family      = AF_INET;
    drone_addr.sin_port        = htons(DRONE_PORT);
    drone_addr.sin_addr.s_addr = inet_addr(drone_ip.c_str());
    printf("fcu_bridge 001 connecting...\n");

    get_drone=connect(socket_cli, (struct sockaddr*)&drone_addr, sizeof(drone_addr));

    if(get_drone<0){
      printf("fcu_bridge 001 connect error!\n");
      return -1;
    }else{
      printf("fcu_bridge 001 connect succeed!\n");
    }
  }

使用环形缓冲队列进行数据的写入和读取,最终将数据在flush_data()函数中发送出去/在parse_data()函数中读取进来。

  1. 话题发布与订阅

由于直接与飞控通信,他还需要将飞控的数据处理之后以话题的方式发布出去。

  gnss_global = nh.advertise<sensor_msgs::NavSatFix>("gnss_global_001",100);
  imu_global = nh.advertise<sensor_msgs::Imu>("imu_global_001",100);
  odom_global = nh.advertise<nav_msgs::Odometry>("odom_global_001",100);
  gnss_001=nh.subscribe<sensor_msgs::NavSatFix>("gnss_global_001", 100, gnssHandler, ros::TransportHints().tcpNoDelay());
  odom=nh.subscribe<nav_msgs::Odometry>("odometry_001", 100, odomHandler, ros::TransportHints().tcpNoDelay());
  cmd=nh.subscribe<std_msgs::Int16>("command", 100, cmdHandler, ros::TransportHints().tcpNoDelay());
  mission=nh.subscribe<std_msgs::Float32MultiArray>("mission_001", 100, missionHandler, ros::TransportHints().tcpNoDelay());
  path_global = nh.advertise<nav_msgs::Path>("path_global_001", 100);
  goal=nh.advertise<geometry_msgs::PoseStamped>("goal_001", 100);
  motion=nh.subscribe<geometry_msgs::PoseStamped>("motion_001", 100, motionHandler, ros::TransportHints().tcpNoDelay());
  command = nh.advertise<std_msgs::Int16>("command",100);
  path_target_pub = nh.advertise<nav_msgs::Path>("path_target_001", 100);
  1. 位置控制更改为速度控制

launch文件中的simple_target==true,这就意味着是简单的位置控制,如果要更改为速度控制就需要将simple_target改为false。

        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="true" type="bool"/>
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/> // 更改为true

2.UWB套件使用fcu_core_v2

实验平台:windows11宿主机 VMware17.5Pro虚拟机里Ubuntu-20.04LTS

从github拉取源码

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2工程并按照readme.md进行编译
readme

launch文件参数修改

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.4.1" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="true" type="bool"/>
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/>
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>

pos_takeoff_001_x和pos_takeoff_001_y是起飞时候的位置,而px和py都是根据起飞点位置的偏移量,进行相加之后就是绝对位置目标点,所以我们可以看到,最终publish的都是绝对目标点。

系统测试

在UWB套件中,不论是绕圆轨迹、多点飞行还是定点飞行,坐标系都是UWB的全局坐标系,但是定点飞行中,我们的demo程序记住了起飞点,并对起飞点设置了目标偏移量,实现了飞行相对于任意起飞点,飞行一段位移的效果

        switch(enable_pos){
          case 0:
              px1=pos_takeoff_001_x; py1=pos_takeoff_001_y; pz1=0.0f;
              px2=pos_takeoff_002_x; py2=pos_takeoff_002_y; pz2=0.0f;
              px3=pos_takeoff_003_x; py3=pos_takeoff_003_y; pz3=0.0f;
              px4=pos_takeoff_004_x; py4=pos_takeoff_004_y; pz4=0.0f;
              px5=pos_takeoff_005_x; py5=pos_takeoff_005_y; pz5=0.0f;
              px6=pos_takeoff_006_x; py6=pos_takeoff_006_y; pz6=0.0f;
              break;
          case 1:
              px=1.0;
              py=1.0;
              pz=1.0;

              px1=pos_takeoff_001_x+px; py1=pos_takeoff_001_y+py; pz1=pz;
              px2=pos_takeoff_002_x+px; py2=pos_takeoff_002_y+py; pz2=pz;
              px3=pos_takeoff_003_x+px; py3=pos_takeoff_003_y+py; pz3=pz;
              px4=pos_takeoff_004_x+px; py4=pos_takeoff_004_y+py; pz4=pz;
              px5=pos_takeoff_005_x+px; py5=pos_takeoff_005_y+py; pz5=pz;
              px6=pos_takeoff_006_x+px; py6=pos_takeoff_006_y+py; pz6=pz;

              break;

根据fcu_command的enable_pos来进行定点飞行,pos_takeoff_001_x和pos_takeoff_001_y是起飞时候的位置,而px和py都是根据起飞点位置的偏移量,进行相加之后就是绝对位置目标点,所以我们可以看到,最终publish的都是绝对目标点。

将
theta = 0
代入
px1=1.0*cosf(theta)+2;
py1=1.0*sinf(theta)+2;
  1. 按复位键重启无人机
  2. 开启四个基站
  3. 观察无人机以及基站的LED6状态
  4. 当LED6快速闪烁时,表明无人机UWB定位正常,高精度UWB定位系统工作正常,可进行下一步操作。否则,请重启无人机和基站,再次尝试。

图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包
图片
与此同时,系统会自动弹出RViz界面(下图坐标点仅供参考,以实际运行效果为准),如下图所示。
图片
RViz是一个三维可视化平台,可用于无人机位置及飞行轨迹的图形化显示。
图中右侧3D视图区中坐标轴图案代表世界坐标系,其中红轴为X轴,绿轴为Y轴,蓝轴为Z轴。
图中的红点代表无人机在世界坐标系中的位置。

飞行测试

图片

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

按照上述步骤将无人机放置初始坐标。

无人机解锁

(1)对于基础款(无论有无UWB)的飞机,用户需要确保起落架(机架的腿部)成X形,分别位于四个电机的正下方,不可以有偏移

(2)对于没有搭载高精度GNSS模组的机型
特别注意!在FanciSwarm无人机启动提示音结束后,将飞机垂直拿起(拿起一次即可),拿到距离地面超过1m后放下。如果激光测距工作正常,解锁才能顺利进行,否则FanciSwarm 会发出“滴滴滴."的报警音,同时,固件强制锁定,不允许起飞。对于Pro款飞机,如果配置了SLAM定高(如何配置在激光雷达SLAM的pdf教程中详细展开),是不需要拿到距离地面超过1m。

(3)对于搭载高精度GNSS模组的机型
特别注意!首次开机使用时,请耐心等待,当GNSS模组蓝色LED灯长亮时,表明当前环境的GNSS信号良好,解锁才能顺利进行;当GNSS模组上的蓝色LED灯未保持长亮状态时,若尝试进行硬件解锁操作,FanciSwarm系统会发出连续的"滴滴滴.."报警声,同时,固件强制锁定,不允许起飞。

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,Mcontroller 右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行轨迹

直接在终端输入“r”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“运行”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始飞圆轨迹。

停止运行轨迹

直接在终端输入“s”,接着点击“回车键”(无需输入“s”后立即点击),界面会打印“停止”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机停止飞圆轨迹,并保持悬停状态。

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始降落,并着陆。

锁定无人机

等待FanciSwarm™ 无人机着陆后,直接在终端输入“d”,接着点击“回车键”(无需输入“d”后立即点击),界面会打印“锁定”字样,如下图所示:

图片

此时,FanciSwarm™ 电调指示灯熄灭,同时Mcontroller 右侧LED绿灯熄灭、LED红灯点亮。FanciSwarm™ 无人机完成锁定。

关闭无人机和基站

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机和基站,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个UWB轨迹飞行过程已完成。

3.GNSS套件使用fcu_core_v2

实验平台:windows11宿主机 VMware17.5Pro虚拟机里Ubuntu-20.04LTS

从github拉取源码(如果之前按照教程做过则不必重复)

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2和quadrotor_msgs
readme

launch文件参数修改

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.0.201" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="false" type="bool"/> // use_uwb改为false
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/>
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>

系统测试

在GNSS套件中,不论是绕圆轨迹、多点飞行还是定点飞行,坐标系都是GNSS的全局坐标系(以飞机GNSS连接到卫星那一刻的坐标点为原点,坐标轴为"北东天"),但是定点飞行中,我们的demo程序记住了起飞点,并对起飞点设置了目标偏移量,实现了飞行相对于任意起飞点,飞行一段位移的效果

        switch(enable_pos){
          case 0:
              px1=pos_takeoff_001_x; py1=pos_takeoff_001_y; pz1=0.0f;
              px2=pos_takeoff_002_x; py2=pos_takeoff_002_y; pz2=0.0f;
              px3=pos_takeoff_003_x; py3=pos_takeoff_003_y; pz3=0.0f;
              px4=pos_takeoff_004_x; py4=pos_takeoff_004_y; pz4=0.0f;
              px5=pos_takeoff_005_x; py5=pos_takeoff_005_y; pz5=0.0f;
              px6=pos_takeoff_006_x; py6=pos_takeoff_006_y; pz6=0.0f;
              break;
          case 1:
              px=1.0;
              py=1.0;
              pz=1.0;

              px1=pos_takeoff_001_x+px; py1=pos_takeoff_001_y+py; pz1=pz;
              px2=pos_takeoff_002_x+px; py2=pos_takeoff_002_y+py; pz2=pz;
              px3=pos_takeoff_003_x+px; py3=pos_takeoff_003_y+py; pz3=pz;
              px4=pos_takeoff_004_x+px; py4=pos_takeoff_004_y+py; pz4=pz;
              px5=pos_takeoff_005_x+px; py5=pos_takeoff_005_y+py; pz5=pz;
              px6=pos_takeoff_006_x+px; py6=pos_takeoff_006_y+py; pz6=pz;

              break;

pos_takeoff_001_x和pos_takeoff_001_y是起飞时候的位置,而px和py都是根据起飞点位置的偏移量,进行相加之后就是绝对位置目标点,所以我们可以看到,最终publish的都是绝对目标点。

在空旷露天环境下!!!!

  1. 按复位键重启无人机
  2. 开启rtk基站(插上电)
  3. 观察无人机以及基站的LED状态
    rtk基站蓝色灯不亮 -> rtk蓝色灯亮 : 锁定卫星成功
    无人机上的rtk模块的蓝色灯不亮 -> rtk蓝色灯常亮 : 锁定卫星成功
    无人机上的rtk模块的绿色灯不亮 -> rtk绿色灯常亮 : 进入rtk定位模式
    图片
    图片

图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包
可以看到心跳包最后两个参数为sat卫星数量和gnss定位精度
对于带有RTK基站的套件来说gnss定位精度要到达5才可解锁起飞
对于没有带RTK基站的GNSS套件来说gnss定位精度要到达2才可解锁起飞
图片
与此同时,系统会自动弹出RViz界面(下图坐标点仅供参考,以实际运行效果为准),如下图所示。
图片
RViz是一个三维可视化平台,可用于无人机位置及飞行轨迹的图形化显示。
图中右侧3D视图区中坐标轴图案代表世界坐标系,其中红轴为X轴,绿轴为Y轴,蓝轴为Z轴。
图中的红点代表无人机在世界坐标系中的位置。

  1. 测试过程要观察运行过程中rtk基站和无人机的rtk模组灯光正常,否则需要重启rtk基站和无人机。

飞行测试

在空旷露天环境下,启动无人机电源,使用虚拟机连接无人机,此时终端应该有飞机的心跳包,其中包括GNSS搜寻到的卫星数量,静止状态下,卫星数量要保证在20左右定位状态要到达2,那代表信号良好,可以起飞。

注意:第一次飞行需要在交流群里的工程师指导下进行

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

无人机解锁

对于搭载高精度GNSS模组的机型
特别注意!首次开机使用时,请耐心等待,当GNSS模组蓝色LED灯长亮时,表明当前环境的GNSS信号良好,解锁才能顺利进行;当GNSS模组上的蓝色LED灯未保持长亮状态时,若尝试进行硬件解锁操作,FanciSwarm系统会发出连续的"滴滴滴.."报警声,同时,固件强制锁定,不允许起飞。

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,Mcontroller 右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行轨迹

直接在终端输入“r”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“运行”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始飞圆轨迹。

停止运行轨迹

直接在终端输入“s”,接着点击“回车键”(无需输入“s”后立即点击),界面会打印“停止”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机停止飞圆轨迹,并保持悬停状态。

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始降落,并着陆。

锁定无人机

等待FanciSwarm™ 无人机着陆后,直接在终端输入“d”,接着点击“回车键”(无需输入“d”后立即点击),界面会打印“锁定”字样。

此时,FanciSwarm™ 电调指示灯熄灭,同时Mcontroller 右侧LED绿灯熄灭、LED红灯点亮。FanciSwarm™ 无人机完成锁定。

关闭无人机和基站

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机和基站,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个GNSS轨迹飞行过程已完成。

4.深度相机套件使用fcu_core_v2

实验平台:windows11宿主机 VMware17.5Pro虚拟机里Ubuntu-20.04LTS

从github拉取源码(如果之前按照教程做过则不必重复)

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2和quadrotor_msgs
readme

launch文件参数修改

对于VINS套件来说,set_goal==true意味着用于发送ego避障目标点,而set_goal==false意味着用于发送普通非避障目标点。

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.0.201" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="false" type="bool"/> // use_uwb改为false
        <param name="set_goal" value="true" type="bool"/> // set_goal改为true
        <param name="simple_target" value="true" type="bool"/>
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>

系统测试

在VINS套件中,定点飞行的坐标系是ego的全局坐标系(以机载电脑ego程序启动那一刻的坐标点为原点,坐标轴为飞机的"前右上"),在定点飞行中,我们的demo程序记住了起飞点,并对起飞点设置了目标偏移量,实现了飞行相对于任意起飞点,飞行一段位移的效果

        switch(enable_pos){
          case 0:
              px1=pos_takeoff_001_x; py1=pos_takeoff_001_y; pz1=0.0f;
              px2=pos_takeoff_002_x; py2=pos_takeoff_002_y; pz2=0.0f;
              px3=pos_takeoff_003_x; py3=pos_takeoff_003_y; pz3=0.0f;
              px4=pos_takeoff_004_x; py4=pos_takeoff_004_y; pz4=0.0f;
              px5=pos_takeoff_005_x; py5=pos_takeoff_005_y; pz5=0.0f;
              px6=pos_takeoff_006_x; py6=pos_takeoff_006_y; pz6=0.0f;
              break;
          case 1:
              px=1.0;
              py=1.0;
              pz=1.0;

              px1=pos_takeoff_001_x+px; py1=pos_takeoff_001_y+py; pz1=pz;
              px2=pos_takeoff_002_x+px; py2=pos_takeoff_002_y+py; pz2=pz;
              px3=pos_takeoff_003_x+px; py3=pos_takeoff_003_y+py; pz3=pz;
              px4=pos_takeoff_004_x+px; py4=pos_takeoff_004_y+py; pz4=pz;
              px5=pos_takeoff_005_x+px; py5=pos_takeoff_005_y+py; pz5=pz;
              px6=pos_takeoff_006_x+px; py6=pos_takeoff_006_y+py; pz6=pz;

              break;

pos_takeoff_001_x和pos_takeoff_001_y是起飞时候的位置,而px和py都是根据起飞点位置的偏移量,进行相加之后就是绝对位置目标点,所以我们可以看到,最终publish的都是绝对目标点。

将无人机放到地面上启动,如下图所示代表ego已经成功启动
VNC连接机载电脑的远程画面/连接显示屏的画面:
图片
fcu_core_v2的rviz画面:
图片

将无人机提起移动一段距离再放下,如下图所示轨迹正常
图片

使用2D Nav Goal工具发布一个目标点,如下图所示规划正常

图片
图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包,即成功连接。
图片

飞行测试

保证起飞的起点和终点一米以内不可以有障碍物,确保slam定位是否正常,否则不能解锁

飞行测试注意以下事项:

完成上述检查后可以起飞无人机,如果只连接远程电脑ros,没有连接遥控器,那么默认就在电脑控制模式中,如果既连接了机载电脑又连接了遥控器,应注意,ch7位于中间档位时飞机受遥控器控制,ch7档位位于下方时,飞机受电脑控制

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

按照上述步骤将无人机放置初始坐标。

无人机解锁

我们使用"global_gnss_001"这个话题作为SLAM是否正常启动的标志位
我们可以使用下面命令查看话题内容从而判断SLAM是否正常启动rostopic echo /fcu_bridge_001/global_gnss_001
还没启动/不正常启动:
图片
正常启动:
图片

也可以使用手机APP连接飞控查看

图片

图片

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,Mcontroller 右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行目标点

直接在终端输入“1”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点1”字样,如下图所示:

图片

回到初始目标点

直接在终端输入“4”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点4”字样,如下图所示:

图片

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始降落,并着陆。

关闭无人机

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个SLAM单机飞行过程已完成。

5.激光雷达SLAM套件使用fcu_core_v2

实验平台:windows11宿主机 VMware17.5Pro虚拟机里Ubuntu-20.04LTS

从github拉取源码(如果之前按照教程做过则不必重复)

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2和quadrotor_msgs
readme

launch文件参数修改

对于SLAM套件来说,set_goal==true意味着用于发送ego避障目标点,而set_goal==false意味着用于发送普通非避障目标点。

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/Odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.0.201" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="false" type="bool"/> // use_uwb改为false
        <param name="set_goal" value="true" type="bool"/> // set_goal改为true
        <param name="simple_target" value="true" type="bool"/>
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>

系统测试

在SLAM套件中,定点飞行的坐标系是ego的全局坐标系(以机载电脑ego程序启动那一刻的坐标点为原点,坐标轴为飞机的"前右上"),在定点飞行中,我们的demo程序记住了起飞点,并对起飞点设置了目标偏移量,实现了飞行相对于任意起飞点,飞行一段位移的效果

        switch(enable_pos){
          case 0:
              px1=pos_takeoff_001_x; py1=pos_takeoff_001_y; pz1=0.0f;
              px2=pos_takeoff_002_x; py2=pos_takeoff_002_y; pz2=0.0f;
              px3=pos_takeoff_003_x; py3=pos_takeoff_003_y; pz3=0.0f;
              px4=pos_takeoff_004_x; py4=pos_takeoff_004_y; pz4=0.0f;
              px5=pos_takeoff_005_x; py5=pos_takeoff_005_y; pz5=0.0f;
              px6=pos_takeoff_006_x; py6=pos_takeoff_006_y; pz6=0.0f;
              break;
          case 1:
              px=1.0;
              py=1.0;
              pz=1.0;

              px1=pos_takeoff_001_x+px; py1=pos_takeoff_001_y+py; pz1=pz;
              px2=pos_takeoff_002_x+px; py2=pos_takeoff_002_y+py; pz2=pz;
              px3=pos_takeoff_003_x+px; py3=pos_takeoff_003_y+py; pz3=pz;
              px4=pos_takeoff_004_x+px; py4=pos_takeoff_004_y+py; pz4=pz;
              px5=pos_takeoff_005_x+px; py5=pos_takeoff_005_y+py; pz5=pz;
              px6=pos_takeoff_006_x+px; py6=pos_takeoff_006_y+py; pz6=pz;

              break;

pos_takeoff_001_x和pos_takeoff_001_y是起飞时候的位置,而px和py都是根据起飞点位置的偏移量,进行相加之后就是绝对位置目标点,所以我们可以看到,最终publish的都是绝对目标点。

将无人机放到地面上启动,如下图所示代表ego已经成功启动
VNC连接机载电脑的远程画面/连接显示屏的画面:
图片
fcu_core_v2的rviz画面:
图片

将无人机提起移动一段距离再放下,如下图所示轨迹正常
图片

使用2D Nav Goal工具发布一个目标点,如下图所示规划正常

图片
图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包,即成功连接。
图片

飞行测试

保证起飞的起点和终点一米以内不可以有障碍物,确保slam定位是否正常,否则不能解锁

飞行测试注意以下事项:

完成上述检查后可以起飞无人机,如果只连接远程电脑ros,没有连接遥控器,那么默认就在电脑控制模式中,如果既连接了机载电脑又连接了遥控器,应注意,ch7位于中间档位时飞机受遥控器控制,ch7档位位于下方时,飞机受电脑控制

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

按照上述步骤将无人机放置初始坐标。

无人机解锁

(1)对于开启了SLAM定高的SLAM套件机型
我们使用"global_gnss_001"这个话题作为SLAM是否正常启动的标志位
我们可以使用下面命令查看话题内容从而判断SLAM是否正常启动rostopic echo /fcu_bridge_001/global_gnss_001
还没启动/不正常启动:
图片
正常启动:
图片

(2)对于没有开启SLAM定高的SLAM套件机型(默认为激光定高)
则需要在FanciSwarm无人机启动提示音结束后,将飞机垂直拿起(拿起一次即可),拿到距离地面超过1m后放下。如果激光测距工作正常,解锁才能顺利进行,否则FanciSwarm 会发出“滴滴滴."的报警音,同时,固件强制锁定,不允许起飞。

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,Mcontroller 右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行目标点

直接在终端输入“1”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点1”字样,如下图所示:

图片

回到初始目标点

直接在终端输入“4”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点4”字样,如下图所示:

图片

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始降落,并着陆。

关闭无人机

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个SLAM单机飞行过程已完成。

集群飞行教程

1.使用fcu_core_v2集群飞行(以UWB套件为例,GNSS套件可参照)

实验平台:windows11宿主机 VMware17.5Pro虚拟机里Ubuntu-20.04LTS

配置联网模块

集群飞行需要所有无人机都连接到同一个局域网。
这时候就需要我们对Mlink-esp Wi-Fi模块进行IP配置。

使用Mlink-esp调试器配置

注: Mlink-esp调试器为新增配件,这将大大简化组网配置步骤。FanciSwarm™ 集群套件用户如果手中缺少该配件,可通过之前的购买渠道向幻思创新申请,申请通过后将免费给您寄送。

该方法需要首先将Mlink-esp Wi-Fi模块与Mlink-esp调试器连接,接着将Mlink-esp调试器通过USB接口与电脑连接,操作步骤共分为以下6步:

  1. 连接Mlink-esp调试器

将Mlink-esp Wi-Fi模块从FanciSwarm™ 无人机上取下,按照下图所示,将Mlink-esp Wi-Fi模块与Mlink-esp调试器连接。
特别注意,请勿接反,接反必烧!

图片

  1. 下载串口助手

下载并解压该文件,得到sscom5.13.1.exe文件,在电脑上双击安装即可。

  1. 打开串口助手并连接Mlink-esp调试器

打开上一步下载的串口助手软件,将Mlink-esp调试器与电脑连接。

  1. 设置串口助手

如下图所示,首先点击端口号处的下拉按键,接着选中第一行“......USB-SERIAL CH340” , 最后在输入框输入AT指令,见下步。

图片

  1. 发送AT指令

在输入框中依次输入以下AT指令并发送:
(1)重启模块。输入以下指令并发送:

AT+RST\r\n

(2)恢复出厂设置。输入以下指令并发送:

AT+RESTORE\r\n

(3)设置为Station模式(默认是AP模式)。输入以下指令并发送:

AT+CWMODE_DEF=1\r\n

(4)设置要连接的路由器名称和密码。输入以下指令并发送:
特别注意,WiFi名称不能为中文名。
(例:AT+CWJAP_DEF="Fancinnov","Mcontroller"\r\n)

AT+CWJAP_DEF="WiFi名称","WiFi密码"\r\n

若串口助手接收界面显示“WIFI CONNECTED”则说明组网模块成功连接路由器,“WIFI GOT IP”代表模块分配到了IP。否则,请再次尝试,直到连接成功。

(5)查询ip地址。输入以下指令并发送:

AT+CIFSR\r\n

上述指令成功发送后,串口助手接收界面会显示路由器分配到该组网模块的ip地址。

(6)设置固定的IP地址。输入以下指令并发送:

AT+CIPSTA_DEF="ip","网关","子网掩码"\r\n

例:上步查询到的ip地址为“192.168.0.2”,则应发送的指令如下:AT+CIPSTA_DEF="192.168.0.100","192.168.0.254","255.255.255.0"(注:均为英文符号)其中”192.168.0.100" 中的100 可为1-254中的任何值,但要确保不和其他连接该路由器的设备IP重复,建议写100以上的值。

(7)查询此时的IP地址是否设置成功。输入以下指令并发送:

AT+CIFSR\r\n

若串口助手返回的IP地址与上步设置的一致,则IP设置成功。请牢记该IP地址。

特别说明
(1)配合App使用说明时,首先打开App,然后手机连接目标路由器Wi-Fi,接着点击首界面右上方数传连接按钮,最后在输入框输入配置的组网模块IP即可。

  1. 至此,Mlink-esp组网模块配置完成。

导入ROS工程

在此之前我们都是使用单架无人机飞行,接下来的集群飞行和单机飞行相似,但也有不同的地方:

从github拉取源码(如果之前按照教程做过则不必重复)

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2和quadrotor_msgs
readme

launch文件参数修改

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.0.201" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="true" type="bool"/>
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/>
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>
        <node pkg="fcu_core" type="fcu_bridge_002" name="fcu_bridge_002" output="screen" >
        <remap from="~odometry_002" to="odometry_002"/>
        <remap from="~imu_global_002" to="imu_global_002"/>
        <remap from="~odom_global_002" to="odom_global_002"/>
        <remap from="~path_global_002" to="path_global_002"/>
        <remap from="~path_target_002" to="path_target_002"/>
        <remap from="~motion_002" to="motion_002"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_002" to="/fcu_mission/mission_002"/>
        <param name="DRONE_IP" value="192.168.0.202" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="true" type="bool"/>
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/>
    </node>
    <node pkg="fcu_core" type="fcu_bridge_003" name="fcu_bridge_003" output="screen" >
        <remap from="~odometry_003" to="odometry_003"/>
        <remap from="~imu_global_003" to="imu_global_003"/>
        <remap from="~odom_global_003" to="odom_global_003"/>
        <remap from="~path_global_003" to="path_global_003"/>
        <remap from="~path_target_003" to="path_target_003"/>
        <remap from="~motion_003" to="motion_003"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_003" to="/fcu_mission/mission_003"/>
        <param name="DRONE_IP" value="192.168.0.203" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/>
        <param name="use_uwb" value="true" type="bool"/>
        <param name="set_goal" value="false" type="bool"/>
        <param name="simple_target" value="true" type="bool"/>
    </node>

系统测试

  1. 按复位键重启各个无人机
  2. 开启四个基站
  3. 观察各个无人机以及基站的LED6状态
  4. 当LED6快速闪烁时,表明无人机UWB定位正常,高精度UWB定位系统工作正常,可进行下一步操作。否则,请重启无人机和基站,再次尝试。

图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包
图片
与此同时,系统会自动弹出RViz界面(下图坐标点仅供参考,以实际运行效果为准),如下图所示。
图片
RViz是一个三维可视化平台,可用于无人机位置及飞行轨迹的图形化显示。
图中右侧3D视图区中坐标轴图案代表世界坐标系,其中红轴为X轴,绿轴为Y轴,蓝轴为Z轴。
图中的红点代表无人机在世界坐标系中的位置。

图片

飞行测试

在启动FanciSwarm™ 无人机的集群飞行之前,用户必须通过ROS对每一架无人机进行单独的试飞测试,以验证其运行状态无异常。只有当所有参与集群飞行的无人机均通过此测试,确认运行正常无误后,方可安全地执行多架无人机的集群飞行任务。

图片

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

按照上述步骤将无人机放置初始坐标。

无人机解锁
图片

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,三架FanciSwarm™右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,三架FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行轨迹

直接在终端输入“r”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“运行”字样,如下图所示:

图片

此时,三架FanciSwarm™ 无人机开始飞圆轨迹。

停止运行轨迹

直接在终端输入“s”,接着点击“回车键”(无需输入“s”后立即点击),界面会打印“停止”字样,如下图所示:

图片

此时,三架FanciSwarm™ 无人机停止飞圆轨迹,并保持悬停状态。

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,三架FanciSwarm™ 无人机开始降落,并着陆。

锁定无人机

等待FanciSwarm™ 无人机着陆后,直接在终端输入“d”,接着点击“回车键”(无需输入“d”后立即点击),界面会打印“锁定”字样,如下图所示:

图片

此时,三架FanciSwarm™ 电调指示灯熄灭,同时Mcontroller 右侧LED绿灯熄灭、LED红灯点亮。三架FanciSwarm™ 无人机完成锁定。

关闭无人机和基站

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机和基站,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个UWB集群轨迹飞行过程已完成。

图片

2.深度相机(VINS定位)套件多机飞行(以两架无人机为例)

请观看完VINS单机飞行之后再来看
在确保每一架无人机单机的单机飞行没有问题之后,我们就可以进行多机飞行

配置联网模块

集群飞行需要所有无人机都连接到同一个局域网。
这时候就需要我们对Mlink-esp Wi-Fi模块进行IP配置。

使用Mlink-esp调试器配置

注: Mlink-esp调试器为新增配件,这将大大简化组网配置步骤。FanciSwarm™ 集群套件用户如果手中缺少该配件,可通过之前的购买渠道向幻思创新申请,申请通过后将免费给您寄送。

该方法需要首先将Mlink-esp Wi-Fi模块与Mlink-esp调试器连接,接着将Mlink-esp调试器通过USB接口与电脑连接,操作步骤共分为以下6步:

  1. 连接Mlink-esp调试器

将Mlink-esp Wi-Fi模块从FanciSwarm™ 无人机上取下,按照下图所示,将Mlink-esp Wi-Fi模块与Mlink-esp调试器连接。
特别注意,请勿接反,接反必烧!

图片

  1. 下载串口助手

下载并解压该文件,得到sscom5.13.1.exe文件,在电脑上双击安装即可。

  1. 打开串口助手并连接Mlink-esp调试器

打开上一步下载的串口助手软件,将Mlink-esp调试器与电脑连接。

  1. 设置串口助手

如下图所示,首先点击端口号处的下拉按键,接着选中第一行“......USB-SERIAL CH340” , 最后在输入框输入AT指令,见下步。

图片

  1. 发送AT指令

在输入框中依次输入以下AT指令并发送:
(1)重启模块。输入以下指令并发送:

AT+RST\r\n

(2)恢复出厂设置。输入以下指令并发送:

AT+RESTORE\r\n

(3)设置为Station模式(默认是AP模式)。输入以下指令并发送:

AT+CWMODE_DEF=1\r\n

(4)设置要连接的路由器名称和密码。输入以下指令并发送:
特别注意,WiFi名称不能为中文名。
(例:AT+CWJAP_DEF="Fancinnov","Mcontroller"\r\n)

AT+CWJAP_DEF="WiFi名称","WiFi密码"\r\n

若串口助手接收界面显示“WIFI CONNECTED”则说明组网模块成功连接路由器,“WIFI GOT IP”代表模块分配到了IP。否则,请再次尝试,直到连接成功。

(5)查询ip地址。输入以下指令并发送:

AT+CIFSR\r\n

上述指令成功发送后,串口助手接收界面会显示路由器分配到该组网模块的ip地址。

(6)设置固定的IP地址。输入以下指令并发送:

AT+CIPSTA_DEF="ip","网关","子网掩码"\r\n

例:上步查询到的ip地址为“192.168.0.2”,则应发送的指令如下:AT+CIPSTA_DEF="192.168.0.100","192.168.0.254","255.255.255.0"(注:均为英文符号)其中”192.168.0.100" 中的100 可为1-254中的任何值,但要确保不和其他连接该路由器的设备IP重复,建议写100以上的值。

(7)查询此时的IP地址是否设置成功。输入以下指令并发送:

AT+CIFSR\r\n

若串口助手返回的IP地址与上步设置的一致,则IP设置成功。请牢记该IP地址。

导入ROS工程

在此之前我们都是使用单架无人机飞行,接下来的集群飞行和单机飞行相似,但也有不同的地方:

从github拉取源码(如果之前按照教程做过则不必重复)

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2和quadrotor_msgs
readme

launch文件参数修改

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.0.201" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/> // offboard更改为false
        <param name="use_uwb" value="false" type="bool"/> // use_uwb更改为false
        <param name="set_goal" value="true" type="bool"/> // set_goal更改为true
        <param name="simple_target" value="true" type="bool"/> // simple_target更改为true
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>
        <node pkg="fcu_core" type="fcu_bridge_002" name="fcu_bridge_002" output="screen" >
        <remap from="~odometry_002" to="odometry_002"/>
        <remap from="~imu_global_002" to="imu_global_002"/>
        <remap from="~odom_global_002" to="odom_global_002"/>
        <remap from="~path_global_002" to="path_global_002"/>
        <remap from="~path_target_002" to="path_target_002"/>
        <remap from="~motion_002" to="motion_002"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_002" to="/fcu_mission/mission_002"/>
        <param name="DRONE_IP" value="192.168.0.202" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/> // offboard更改为false
        <param name="use_uwb" value="false" type="bool"/> // use_uwb更改为false
        <param name="set_goal" value="true" type="bool"/> // set_goal更改为true
        <param name="simple_target" value="true" type="bool"/> // simple_target更改为true
    </node>

系统测试

将无人机放到地面上启动,启动顺序一定按照ID逆序启动,比如两级飞机就要先启动1号飞机,再启动0号飞机,如下图所示代表ego已经成功启动
VNC连接机载电脑的远程画面:
图片
fcu_core_v2的rviz:
图片

将无人机提起一段高度再放下,如下图所示轨迹正常
图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包,即成功连接。
图片

飞行测试

保证起飞的起点和终点一米以内不可以有障碍物

飞行测试注意以下事项:

完成上述检查后可以起飞无人机,如果只连接远程电脑ros,没有连接遥控器,那么默认就在电脑控制模式中,如果既连接了机载电脑又连接了遥控器,应注意,ch7位于中间档位时飞机受遥控器控制,ch7档位位于下方时,飞机受电脑控制

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

按照上述步骤将无人机放置初始坐标。

无人机解锁

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,Mcontroller 右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行目标点

直接在终端输入“1”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点1”字样,如下图所示:

图片

回到初始目标点

直接在终端输入“4”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点4”字样,如下图所示:

图片

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始降落,并着陆。

关闭无人机

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个VINS套件的SLAM多机飞行过程已完成。

3.激光雷达(Fasterlio定位)套件多机飞行(以两架无人机为例)

请观看完SLAM单机飞行之后再来看
在确保每一架无人机单机的单机飞行没有问题之后,我们就可以进行多机飞行

配置联网模块

集群飞行需要所有无人机都连接到同一个局域网。
这时候就需要我们对Mlink-esp Wi-Fi模块进行IP配置。

使用Mlink-esp调试器配置

注: Mlink-esp调试器为新增配件,这将大大简化组网配置步骤。FanciSwarm™ 集群套件用户如果手中缺少该配件,可通过之前的购买渠道向幻思创新申请,申请通过后将免费给您寄送。

该方法需要首先将Mlink-esp Wi-Fi模块与Mlink-esp调试器连接,接着将Mlink-esp调试器通过USB接口与电脑连接,操作步骤共分为以下6步:

  1. 连接Mlink-esp调试器

将Mlink-esp Wi-Fi模块从FanciSwarm™ 无人机上取下,按照下图所示,将Mlink-esp Wi-Fi模块与Mlink-esp调试器连接。
特别注意,请勿接反,接反必烧!

图片

  1. 下载串口助手

下载并解压该文件,得到sscom5.13.1.exe文件,在电脑上双击安装即可。

  1. 打开串口助手并连接Mlink-esp调试器

打开上一步下载的串口助手软件,将Mlink-esp调试器与电脑连接。

  1. 设置串口助手

如下图所示,首先点击端口号处的下拉按键,接着选中第一行“......USB-SERIAL CH340” , 最后在输入框输入AT指令,见下步。

图片

  1. 发送AT指令

在输入框中依次输入以下AT指令并发送:
(1)重启模块。输入以下指令并发送:

AT+RST\r\n

(2)恢复出厂设置。输入以下指令并发送:

AT+RESTORE\r\n

(3)设置为Station模式(默认是AP模式)。输入以下指令并发送:

AT+CWMODE_DEF=1\r\n

(4)设置要连接的路由器名称和密码。输入以下指令并发送:
特别注意,WiFi名称不能为中文名。
(例:AT+CWJAP_DEF="Fancinnov","Mcontroller"\r\n)

AT+CWJAP_DEF="WiFi名称","WiFi密码"\r\n

若串口助手接收界面显示“WIFI CONNECTED”则说明组网模块成功连接路由器,“WIFI GOT IP”代表模块分配到了IP。否则,请再次尝试,直到连接成功。

(5)查询ip地址。输入以下指令并发送:

AT+CIFSR\r\n

上述指令成功发送后,串口助手接收界面会显示路由器分配到该组网模块的ip地址。

(6)设置固定的IP地址。输入以下指令并发送:

AT+CIPSTA_DEF="ip","网关","子网掩码"\r\n

例:上步查询到的ip地址为“192.168.0.2”,则应发送的指令如下:AT+CIPSTA_DEF="192.168.0.100","192.168.0.254","255.255.255.0"(注:均为英文符号)其中”192.168.0.100" 中的100 可为1-254中的任何值,但要确保不和其他连接该路由器的设备IP重复,建议写100以上的值。

(7)查询此时的IP地址是否设置成功。输入以下指令并发送:

AT+CIFSR\r\n

若串口助手返回的IP地址与上步设置的一致,则IP设置成功。请牢记该IP地址。

导入ROS工程

在此之前我们都是使用单架无人机飞行,接下来的集群飞行和单机飞行相似,但也有不同的地方:

从github拉取源码(如果之前按照教程做过则不必重复)

创建工作空间

mkdir -p ~/ros_ws/src

拉取fcu_core_v2和quadrotor_msgs
readme

launch文件参数修改

    <node pkg="fcu_core" type="fcu_bridge_001" name="fcu_bridge_001" output="screen" >
        <remap from="~odometry_001" to="/vins_estimator/odometry"/>
        <remap from="~imu_global_001" to="imu_global_001"/>
        <remap from="~odom_global_001" to="odom_global_001"/>
        <remap from="~path_global_001" to="path_global_001"/>
        <remap from="~path_target_001" to="path_target_001"/>
        <remap from="~goal_001" to="/move_base_simple/goal"/>
        <remap from="~motion_001" to="motion_001"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_001" to="/fcu_mission/mission_001"/>
        <param name="DRONE_IP" value="192.168.0.201" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/> // offboard更改为false
        <param name="use_uwb" value="false" type="bool"/> // use_uwb更改为false
        <param name="set_goal" value="true" type="bool"/> // set_goal更改为true
        <param name="simple_target" value="true" type="bool"/> // simple_target更改为true
        <param name="odom_init_x" value="0.0"/> <!-- FLU坐标系 -->
        <param name="odom_init_y" value="0.0"/>
        <param name="odom_init_z" value="0.0"/>
    </node>
        <node pkg="fcu_core" type="fcu_bridge_002" name="fcu_bridge_002" output="screen" >
        <remap from="~odometry_002" to="odometry_002"/>
        <remap from="~imu_global_002" to="imu_global_002"/>
        <remap from="~odom_global_002" to="odom_global_002"/>
        <remap from="~path_global_002" to="path_global_002"/>
        <remap from="~path_target_002" to="path_target_002"/>
        <remap from="~motion_002" to="motion_002"/>
        <remap from="~command" to="/fcu_command/command"/>
        <remap from="~mission_002" to="/fcu_mission/mission_002"/>
        <param name="DRONE_IP" value="192.168.0.202" type="string"/>  // 更改为自己飞机的mlink的ip地址
        <param name="USB_PORT" value="/dev/ttyACM0" type="string"/>
        <param name="channel" value="1"/>
        <param name="offboard" value="false" type="bool"/> // offboard更改为false
        <param name="use_uwb" value="false" type="bool"/> // use_uwb更改为false
        <param name="set_goal" value="true" type="bool"/> // set_goal更改为true
        <param name="simple_target" value="true" type="bool"/> // simple_target更改为true
    </node>

系统测试

将无人机放到地面上启动,启动顺序一定按照ID逆序启动,比如两级飞机就要先启动1号飞机,再启动0号飞机,如下图所示代表ego已经成功启动
VNC连接机载电脑的远程画面:
图片
fcu_core_v2的rviz:
图片

将无人机提起移动一段距离再放下,如下图所示轨迹正常
图片

catkin_make
source ./devel/setup.bash

接着运行ros程序

roslaunch fcu_core fcu_core.launch

出现下面打印即是收到心跳包,即成功连接。
图片

飞行测试

保证起飞的起点和终点一米以内不可以有障碍物

飞行测试注意以下事项:

完成上述检查后可以起飞无人机,如果只连接远程电脑ros,没有连接遥控器,那么默认就在电脑控制模式中,如果既连接了机载电脑又连接了遥控器,应注意,ch7位于中间档位时飞机受遥控器控制,ch7档位位于下方时,飞机受电脑控制

图片

我们为了方便用户测试,开发了一套简单指令如下:
"a": 解锁
"d": 上锁
"t": 起飞
"l": 降落
工程运行后,直接在Ubuntu终端中输入:指令字符+回车,即可完成对应指令的下发。

按照上述步骤将无人机放置初始坐标。

无人机解锁

上述检查完成后,直接在终端输入“a”,接着点击“回车键”(无需输入“a”后立即点击),界面会打印“解锁”字样,如下图所示:

图片

此时,Mcontroller 右侧LED绿灯将点亮,并伴随着启动声音。FanciSwarm™ 无人机完成解锁。

一键起飞

直接在终端输入“t”,接着点击“回车键”(无需输入“t”后立即点击),界面会打印“起飞”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机起飞到一定高度(FanciSwarm App中设置的起飞高度)并悬停。

开始运行目标点

直接在终端输入“1”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点1”字样,如下图所示:

图片

回到初始目标点

直接在终端输入“4”,接着点击“回车键”(无需输入“r”后立即点击),界面会打印“位置点4”字样,如下图所示:

图片

一键降落

直接在终端输入“l”,接着点击“回车键”(无需输入“l”后立即点击),界面会打印“降落”字样,如下图所示:

图片

此时,FanciSwarm™ 无人机开始降落,并着陆。

关闭无人机

FanciSwarm™ 无人机锁定后,如果不继续飞行,请及时关闭无人机,并拔掉电池,以避免电量损耗,节省电池电量。

至此,整个激光雷达套件的SLAM多机飞行过程已完成。