Research

[Research] Visual-Lidar SLAM for UAV

페트론 2020. 10. 8. 17:58

드론에 RGBD 카메라와 Lidar 센서를 부착하여 SLAM을 하는 프로젝트를 진행한다.

 

 

 

 

먼저 개발환경을 세팅해야 하는데,

 

참고한 사이트는 다음과 같다.

 

dnddnjs.gitbooks.io/drone-autonomous-flight/content/

 

Introduction · PIXHAWK와 ROS를 이용한 자율주행 드론

 

dnddnjs.gitbooks.io

시작전에 개발 환경에 대해서 언급해야 겠다.

2020년 10월 8일 기준 드론을 ROS로 구동하기 위한 펌웨어인 PX4는 더 이상 Ubuntu 16.04를 지원하지 않는다. 

예를 들어 Ubuntu 16.04에서는 Gazebo7 버전이 사용되지만, Ubuntu 18.04에서는 Gazebo9 버전이 사용되며, PX4는 Gazebo7을 더 이상 호환하지 않는다. 따라서 위 링크를 참고하되 버전에 대한 수정을 포함하여 진행한다.

 

순서는 다음과 같다.

 

  1. Ubuntu 18.04 설치
  2. ROS Melodic & Gazebo9 설치
  3. PX4 설치
  4. 시뮬레이션 실행 (takeoff)
  5. modulab의 경우

 

1. Ubuntu 18.04 설치

Ubuntu 18.04 설치 관련하여서는 이미 잘 정리해놓은 블로거 분들이 많기 때문에 링크로 대신하겠다.

 

[Ubuntu] 윈도우가 설치된 컴퓨터에 듀얼부팅 우분투 18.04 LTS 설치하기

 

[Ubuntu] 윈도우가 설치된 컴퓨터에 듀얼부팅 우분투 18.04 LTS 설치하기

초보자도 쉽게 따라 할 수 있게 설명합니다. 우분투는 장기 지원버전과 일반 버전이 있습니다. 장기 지원버전은 업데이트가 2~5년동안 지원되는데 반해 일반 버전은 1년도 안됩니다. 18.04는 2021년

haneulinux.tistory.com

 

2. ROS Melodic & Gazebo9 설치

아래 링크를 참고하여 스크립트로 설치 진행.

 

dev.px4.io/master/en/setup/dev_env_linux_ubuntu.html

 

Ubuntu/Debian Linux · PX4 Developer Guide

Development Environment on Ubuntu LTS / Debian Linux The supported/tested Linux OS versions for PX4 development are Ubuntu Linux LTS 18.04 (Bionic Beaver) and 20.04 (Focal Fossa). These allow you to build for the most PX4 targets (NuttX based hardware, Qua

dev.px4.io

 

pre-packages install

sudo apt-get install python3-pip
pip install future

sudo apt-get install ros-melodic-libgeographic-dev 
sudo apt-get install ros-melodic-geographic-msgs ros-melodic-geographic-info 

 

## Download the script in a bash shell:
$ wget https://raw.githubusercontent.com/PX4/Devguide/master/build_scripts/ubuntu_sim_ros_melodic.sh

## Run the script:
$ bash ubuntu_sim_ros_melodic.sh

 

이 후, gazebo를 다시 실행하려 하면 의존성 패키지 에러가 발생한다. 

이를 예방하기 위해 아래 명령어로 의존성 패키지를 설치한다.

 

sudo apt install libgstreamer1.0-dev
sudo apt install gstreamer1.0-plugins-good
sudo apt install gstreamer1.0-plugins-bad
sudo apt install gstreamer1.0-plugins-ugly

 

3. PX4 설치

이제 PX4 Firmware를 설치한다.

cd <path>
git clone https://github.com/PX4/Firmware.git
cd Firmware
git submodule update --init --recursive

 

이제 시뮬레이션을 돌려보자.

 

4. 시뮬레이션 실행 (takeoff)

이제 드론을 한번 띄워보자.

참고할 링크는 다음과 같다.

INSTALLING ROS GAZEBO MAVROS AND PX4

 

$ no_sim=1 make px4_sitl_default gazebo

$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo

$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris.world

 

Gazebo가 켜지면 드론을 추가해준다.

 

이 후, sitl에서 gazebo와 연결되면 다음 명령어를 통해 드론을 띄워본다.

 

pxh> commander takeoff

 

 

5. modulab의 경우

Software In The Loop(SITL)

 

Software In The Loop(SITL) · PIXHAWK와 ROS를 이용한 자율주행 드론

 

dnddnjs.gitbooks.io

 

다음 명령어를 통해 드론을 띄울 수 있다.

 

# terminal_1
$ roscore

# terminal_2
$ cd ~/Firmware
$ make px4_sitl_default gazebo

# terminal_3
$ roslaunch modudculab_ros ctrl_pos_gazebo.launch

# terminal_4
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

 

6.  가상의 실내환경

실내 지도작성이 목적이기 때문에 실내환경을 가져와 보도록 하겠다.

참고 링크는 다음과 같다.

 

Gazebo Worlds

 

Gazebo Worlds · PX4 Developer Guide

No results matching ""

dev.px4.io

Gazebo Simulation > Loading a Specific World

 

Gazebo Simulation · PX4 Developer Guide

Gazebo is a powerful 3D simulation environment for autonomous robots that is particularly suitable for testing object-avoidance and computer vision. This page describes its use with SITL and a single vehicle. Gazebo can also be used with HITL and for multi

dev.px4.io

 

다음 명령어를 사용하여 warehous map을 가져올 수 있다.

 

# terminal_1
$ roscore

# terminal_2
$ cd ~/Firmware
$ make px4_sitl_default gazebo___warehouse   ## "_" 가 총 3개 인 것에 주의

# terminal_3
$ roslaunch modudculab_ros ctrl_pos_gazebo.launch

# terminal_4
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

 

7. 다운로드 Gazebo 모델 데이터

 

Gazebo의 더 다양한 환경을 얻기 위해 데이터를 다운로드 한다.

아래 두 개 링크를 참고하였으며,

sdf 파일이 들어 있는 폴더들을

"~/.gazebo/models"

폴더로 옮겨주면 gazebo를 켰을 때, 인식이 되게 된다.

 

github.com/osrf/gazebo_models

 

osrf/gazebo_models

Model database. Contribute to osrf/gazebo_models development by creating an account on GitHub.

github.com

data.nvision2.eecs.yorku.ca/3DGEMS/

 

3DGEMS - 3D Gazebo Models

3DGEMS 3D Gazebo Models Examples of 3D models in the dataset ABOUT This dataset contains 270+ 3D models to be used in Gazebo simulation for robotic applications. All models are in sdf format and ready to be used in Gazebo. The main purpose of this dataset

data.nvision2.eecs.yorku.ca

 

3DGEMS 에서는 기존에 만들어진 world도 제공한다. 

이를 열기 위해서는 다음의 명령어를 사용한다. 

 

$ gazebo "world 파일의 경로"/"world 파일의 이름"

 

8. 개발환경 만들기 (재난환경 및 드론)

 

3DGEMS 의 world 파일들을

"~/Firmware/Tools/sitl_gazebo/worlds"로 옮긴다.

 

다음 명령어를 이용해 3DFEMS 의 world 중 하나인 offic_earthquake.world를 연다.

"sudo"를 사용하는 이유는 world에 변화를 준 뒤, 저장하기 위해서이다.

관리자 권한이 없으면 저장할 수 없다.

 

$ sudo gazebo ~/Firmware/Tools/sitl_gazebo/worlds/office_earthquake.world

 

그리고 3DR iris를 추가한 뒤, 다른 이름으로 저장한다.

혹시 3DR iris가 안보인다면 아래 명령어를 통해 model path를 인식시킨 뒤 gazebo 를 다시 켜보면 된다.

 

$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo

$ sudo gazebo ~/Firmware/Tools/sitl_gazebo/worlds/office_earthquake.world

 

이 후, 다음 명령어를 통해 새로만든 world를 실행시키면 iris가 존재하는 것을 확인할 수 있다.

 

$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo

$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_office_earthquake.world

 

9. 드론 주행시키기

 

이제 아래 명령어를 통해 드론을 띄울 수 있게 되었다.

 

# terminal_1
$ roscore

# terminal_2
$ cd ~/Firmware
$ no_sim=1 make px4_sitl_default gazebo

# terminal_3
$ cd ~/Firmware
$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_office_earthquake.world

# terminal_4
$ roslaunch modudculab_ros ctrl_pos_gazebo.launch

# terminal_5
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

 

 

그리고 다음 코드를 통해 주행시킬 수 있다.

#include <ros/ros.h>
#include <std_msgs/String.h> 
#include <stdio.h>

#include "geometry_msgs/PoseStamped.h"
#include "geometry_msgs/Vector3Stamped.h"

int count = 1;
int proc = 0;
void poseCallback(const geometry_msgs::PoseStamped::ConstPtr& pose_msg,ros::Publisher _pub) {
   float x = pose_msg->pose.position.x; 
   float y = pose_msg->pose.position.y; 
   float z = pose_msg->pose.position.z; 
   //ROS_INFO("x = %f", x);
   //ROS_INFO("y = %f", y);
   //ROS_INFO("z = %f", z);

   geometry_msgs::PoseStamped msg;
   
   if(!proc) {
      msg.header.stamp = ros::Time::now();
      msg.header.seq=count;
      msg.header.frame_id = 1;
      msg.pose.position.x = 0.0;//0.001*some_object.position_x;
      msg.pose.position.y = 0.0;//0.001*some_object.position_y;
      msg.pose.position.z = 1.0;//0.001*some_object.position_z;
      msg.pose.orientation.x = 0;
      msg.pose.orientation.y = 0;
      msg.pose.orientation.z = 0;
      msg.pose.orientation.w = 1;

      if(x > -0.1 && x < 0.1 && y > -0.1 && y < 0.1 && z > 0.9 && z < 1.1) proc++;
   }
   else if(proc == 1) {
      msg.header.stamp = ros::Time::now();
      msg.header.seq=count;
      msg.header.frame_id = 1;
      msg.pose.position.x = 5.0;//0.001*some_object.position_x;
      msg.pose.position.y = 0.0;//0.001*some_object.position_y;
      msg.pose.position.z = 1.0;//0.001*some_object.position_z;
      msg.pose.orientation.x = 0;
      msg.pose.orientation.y = 0;
      msg.pose.orientation.z = 0;
      msg.pose.orientation.w = 1;

      if(x > 4.9 && x < 5.1 && y > -0.1 && y < 0.1 && z > 0.9 && z < 1.1) proc++;
   }
   else if(proc == 2) {
      msg.header.stamp = ros::Time::now();
      msg.header.seq=count;
      msg.header.frame_id = 1;
      msg.pose.position.x = 5.0;//0.001*some_object.position_x;
      msg.pose.position.y = 10.0;//0.001*some_object.position_y;
      msg.pose.position.z = 1.0;//0.001*some_object.position_z;
      msg.pose.orientation.x = 0;
      msg.pose.orientation.y = 0;
      msg.pose.orientation.z = 0;
      msg.pose.orientation.w = 1;

      if(x > 4.9 && x < 5.1 && y > 9.9 && y < 10.1 && z > 0.9 && z < 1.1) proc++;
   }
   else if(proc == 3) {
      msg.header.stamp = ros::Time::now();
      msg.header.seq=count;
      msg.header.frame_id = 1;
      msg.pose.position.x = -5.0;//0.001*some_object.position_x;
      msg.pose.position.y = 10.0;//0.001*some_object.position_y;
      msg.pose.position.z = 1.0;//0.001*some_object.position_z;
      msg.pose.orientation.x = 0;
      msg.pose.orientation.y = 0;
      msg.pose.orientation.z = 0;
      msg.pose.orientation.w = 1;

      if(x < -4.9 && x > -5.1 && y > 9.9 && y < 10.1 && z > 0.9 && z < 1.1) proc++;
   }   
   else if(proc == 4) {
      msg.header.stamp = ros::Time::now();
      msg.header.seq=count;
      msg.header.frame_id = 1;
      msg.pose.position.x = -5.0;//0.001*some_object.position_x;
      msg.pose.position.y = 0.0;//0.001*some_object.position_y;
      msg.pose.position.z = 1.0;//0.001*some_object.position_z;
      msg.pose.orientation.x = 0;
      msg.pose.orientation.y = 0;
      msg.pose.orientation.z = 0;
      msg.pose.orientation.w = 1;

      if(x < -4.9 && x > -5.1 && y > -0.1 && y < 0.1 && z > 0.9 && z < 1.1) proc++;
   }   
   else if(proc == 5) {
      msg.header.stamp = ros::Time::now();
      msg.header.seq=count;
      msg.header.frame_id = 1;
      msg.pose.position.x = 0.0;//0.001*some_object.position_x;
      msg.pose.position.y = 0.0;//0.001*some_object.position_y;
      msg.pose.position.z = 1.0;//0.001*some_object.position_z;
      msg.pose.orientation.x = 0;
      msg.pose.orientation.y = 0;
      msg.pose.orientation.z = 0;
      msg.pose.orientation.w = 1;

      if(x > -0.1 && x < 0.1 && y > -0.1 && y < 0.1 && z > 0.9 && z < 1.1) proc=0;
   }   


   _pub.publish(msg);
   ros::spinOnce();
   count++;   

   ROS_INFO("proc = %d", proc);
}

int main(int argc, char **argv)
{
   // ros initialize
   ros::init(argc, argv, "nav_route");
   ros::NodeHandle n;

   // ros publisher
   ros::Publisher chatter_pub = n.advertise<geometry_msgs::PoseStamped>("/mavros/setpoint_position/local",100);

   // ros subscriber
   ros::Subscriber pose_sub = n.subscribe<geometry_msgs::PoseStamped>("/mavros/local_position/pose", 100, boost::bind(poseCallback, _1, chatter_pub));

   ros::spin();
      
   return 0;
}

 

guithub는 다음과 같다.

github.com/suho0515/ros_uav

 

suho0515/ros_uav

Contribute to suho0515/ros_uav development by creating an account on GitHub.

github.com

 

10. hector_slam 설치

이제 hector_slam을 설치해본다.

 

일단 hector_slam 에서는 QT4를 쓰기 때문에, 다음 명령어를 통해 QT4를 설치한다.

 

$ sudo apt-get install qt4-default 

 

이 후에, 다음 명령어를 통해 hector_slam을 설치한다.

$ cd ~/catkin_ws/src
$ git clone git clone https://github.com/tu-darmstadt-ros-pkg/hector_slam.git
$ cd ~/catkin_ws
$ catkin build
$ source devel/setup.bash

 

11. 드론에 lidar 센서 달기

Firmware 모델 중 lidar 센서가 달린 iris model을 불러와 개발환경을 만들어 준다.

모델 명은 "iris with rplidar lidar" 이다.

 

 

12. 드론 trajectory

아래 명령어로  trajectory를 수행할 수 있다.

 

# terminal_1
$ roscore

# terminal_2
$ cd ~/Firmware
$ no_sim=1 make px4_sitl_default gazebo

# terminal_3
$ cd ~/Firmware
$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_with_rplidar_lidar_office_earthquake.world

# terminal_4
$ roslaunch ros_uav ctrl_traj_gazebo.launch 

# terminal_5
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

 

13. RViz에 Lidar 센서 출력

 

"ctrl_traj_gazebo.launch" 같은 작업할 launch 파일에 다음 내용을 추가한다.

lidar 센서의 rplidar_link는 독립적인 상태이기 때문에 map frame과 연결시켜주기 위한 작업이다.

 

<node pkg="tf" type="static_transform_publisher" name="map_rplidar_link_broadcaster" args="0 0 0 0 0 0 map rplidar_link 10"/>

 

그리고 아래 명령어를 실행하면 결과를 확인할 수 있다.

 

# terminal_1
$ roscore

# terminal_2
$ cd ~/Firmware
$ no_sim=1 make px4_sitl_default gazebo

# terminal_3
$ cd ~/Firmware
$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_with_rplidar_lidar_office_earthquake.world

# terminal_4
$ roslaunch ros_uav ctrl_traj_gazebo.launch 

# terminal_5
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

 

14. GMapping

 

Hector SLAM을 적용하려 하였으나 역시 적용하기가 마냥 쉽지 않았다. 따라서 GMapping을 먼저 수행해보았다.

 

다음 명령어를 통해 진행한다.

 

# terminal_1
$ roscore

# terminal_2
$ rviz

# terminal_3
$ cd ~/Firmware
$ no_sim=1 make px4_sitl_default gazebo

# terminal_4
$ cd ~/Firmware
$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_with_rplidar_lidar_office_earthquake.world

# terminal_5
$ roslaunch ros_uav ctrl_traj_gazebo.launch 

# terminal_6
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

# terminal_7
$ rosrun tf static_transform_publisher 0 0 0 0 0 0 base_link rplidar_link 100

# terminal_8
$ rosrun gmapping slam_gmapping scan:=/laser/scan

 

 

 

15. Depth Camera 추가하기

 

PX4 Firmware 안에 존재하는 depth camera 모델 (iris_triple_depth_camera.sdf) 를 참고하여 

아래 라인을 iris_rplidar.sdf에 추가한 뒤, Gazebo에서 아래 모델을 불러와 world를 저장한다.

    <model name="front_camera">
    <pose>0.1 0 -0.03 0 1.07 0</pose>
    <link name="link">
      <inertial>
        <pose>0.01 0.025 0.025 0 0 0</pose>
        <mass>0.01</mass>
        <inertia>
          <ixx>4.15e-6</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>2.407e-6</iyy>
          <iyz>0</iyz>
          <izz>2.407e-6</izz>
        </inertia>
      </inertial>
      <visual name="visual">
        <pose>0 0 0 0 0 0</pose>
        <geometry>
          <mesh>
            <uri>model://realsense_camera/meshes/realsense.dae</uri>
          </mesh>
        </geometry>
      </visual>
      <sensor name="depth_camera" type="depth">
        <update_rate>20</update_rate>
        <camera>
          <horizontal_fov>1.02974</horizontal_fov>
          <image>
            <format>R8G8B8</format>
            <width>64</width>
            <height>48</height>
          </image>
          <clip>
            <near>0.5</near>
            <far>18</far>
          </clip>
        </camera>
        <plugin filename="libgazebo_ros_openni_kinect.so" name="camera_controller">
          <cameraName>camera_front</cameraName>
          <alwaysOn>true</alwaysOn>
          <updateRate>20</updateRate>
          <pointCloudCutoff>0.2</pointCloudCutoff>
          <pointCloudCutoffMax>20</pointCloudCutoffMax>
          <imageTopicName>rgb/image_raw</imageTopicName>
          <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName>
          <depthImageTopicName>depth/image_raw</depthImageTopicName>
          <depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName>
          <pointCloudTopicName>depth/points</pointCloudTopicName>
          <frameName>front_camera_link</frameName>
          <distortion_k1>0.0</distortion_k1>
          <distortion_k2>0.0</distortion_k2>
          <distortion_k3>0.0</distortion_k3>
          <distortion_t1>0.0</distortion_t1>
          <distortion_t2>0.0</distortion_t2>
        </plugin>
      </sensor>
    </link>
  </model>

    <joint name="depth_camera_joint_front" type="revolute">
      <child>front_camera::link</child>
      <parent>iris::base_link</parent>
      <axis>
        <xyz>0 0 1</xyz>
        <limit>
          <upper>0</upper>
          <lower>0</lower>
        </limit>
      </axis>
    </joint>

 

그리고 launch 파일에 base_link 프레임과 rplidar_link 프레임, front_camera_link 프레임을 연결해주기 위해 다음 구문을 추가한다.

참고로 arguments를 본인 환경에 맞추어 다 수정해주어야 한다. 

 

<node pkg="tf" type="static_transform_publisher" name="base_link_rplidar_link_broadcaster" args="0 0 0 0 0 0 base_link rplidar_link 10"/>

<node pkg="tf" type="static_transform_publisher" name="base_link_front_camera_link_broadcaster" args="0 0 0 -1.5708 0 -2.61799 base_link front_camera_link 10"/>

 

이 후, 다음과 같이 코드를 실행한 뒤, PointCloud2를 디스플레이 하면 다음과 같은 결과를 얻을 수 있다.

 

# terminal_1
$ roscore

# terminal_2
$ rviz

# terminal_3
$ cd ~/Firmware
$ no_sim=1 make px4_sitl_default gazebo

# terminal_4
$ cd ~/Firmware
$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_with_rplidar_lidar_depthcamera_down_office_earthquake.world

# terminal_5
$ roslaunch ros_uav mavros_teleop_key.launch

# terminal_6
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

# terminal_7
$ rosrun gmapping slam_gmapping scan:=/laser/scan

 

 

16. Octomap 실행

 

Octomap은 용량이 큰 3D Data로 맵핑을 할 수 있는 대표적인 오픈소스다. 이를 이용해보자.

 

Octomap 설치는 다음 명령어를 통해 진행한다.

    $ sudo apt-get install ros-indigo-octomap ros-indigo-octomap-mapping
    $ rosdep install octomap_mapping
    $ rosmake octomap_mapping

 

Octomap의 frame은 world 이므로 map 프레임과 world 프레임을 이어줄 필요가 있다.

다음 구문을 launch 파일에 추가해주자.

 

<node pkg="tf" type="static_transform_publisher" name="world_map_broadcaster" args="0 0 0 0 0 0 world map 10"/>

 

이 후, 다음 명령어를 통해 프로그램을 실행한다.

 

# terminal_1
$ roscore

# terminal_2
$ rviz

# terminal_3
$ cd ~/Firmware
$ no_sim=1 make px4_sitl_default gazebo

# terminal_4
$ cd ~/Firmware
$ source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
$ roslaunch gazebo_ros empty_world.launch  world_name:=$(pwd)/Tools/sitl_gazebo/worlds/iris_with_rplidar_lidar_depthcamera_down_office_earthquake.world

# terminal_5
$ roslaunch ros_uav mavros_teleop_key.launch

# terminal_6
$ rosrun mavros mavsafety arm
$ rosrun mavros mavsys mode -c OFFBOARD

# terminal_7
$ rosrun gmapping slam_gmapping scan:=/laser/scan

# terminal_8
$ roslaunch octomap_server octomap_tracking_server.launch frame_id:="world" cloud_in:="/camera_front/depth/points"
or
$ roslaunch octomap_server octomap_mapping.launch frame_id:="world" cloud_in:="/camera_front/depth/points"
# 차이점은?

 

17. Jetson Nano Ubuntu 18.04 설치

시뮬레이션으로 돌려보니 /tf 값이 너무 완벽할 정도로 안정적이다.

이대로는 실험 진행이 불가능하니 이제는 실제 드론을 사용할 때다. 

먼저 Jetson Nano에 Ubuntu 18.04를 설치하자. 

 

다음 링크를 참고하자.

opencourse.tistory.com/223

 

Jetson Nano(젯슨나노) - Ubuntu 기본설치와 5V 4a 전원 어댑터 설치하기

젯슨나노의 경우 기본적으로 그래픽 칩셋이 있다보니 풀 그놈(GNOME) 환경을 사용하고 있습니다. 그러나 사용을 좀해보니 몇가지 답답한 문제가 있길래 추가로 포스팅 합니다. 먼저 5v 2a의 전원 ��

opencourse.tistory.com

 

전원을 켤 때에는 J48 두 개의 핀을 연결해야 하는데, 그에 관해서는 아래 링크를 참고하자.

 

m.blog.naver.com/PostView.nhn?blogId=junghoon5000&logNo=221701091923&proxyReferer=https:%2F%2Fwww.google.com%2F

 

젯슨 나노 Jetson Nano 전원 연결!

​​안녕하세요! 많은 분들이 엔비디아 젯슨 나노에 대해서 궁금한 부분들이 종종 있는 것 같아서, 궁금한 ...

blog.naver.com

18. 이 후 셋팅

하... 이 부분에서 거진 일주일을 소모했다.

 

시뮬레이션 부분에서 사용한 드론의 펌웨어는 "px4"이다. 

하지만 내가 사용하는 실제 드론에서의 펌웨어는 "ardupilot" 이었기 때문에,

px4와 관련된 내용이 먹힐리가 없었다.

 

그래서 px4 펌웨어로 새로 설치하고 캘리브레이션도 다시 수행하고 시도하려 하였다.

하지만 큰 문제가 몇가지 있었다.

 

1. px4에서 GPS 센서 없이 조작하기가 매우 까다롭다. 파라미터에서 GPS를 쓰지 않도록 하는게 매우 힘든 것이다.

2. GPS 센서를 쓰지 않도록 어찌어찌 성공했다. 너무 정신이 없어서 제대로 기록하지 못한것이 아쉽지만, 가능은 하다. 하지만 모든 세팅이 끝난 후, 제어기 쪽 전원이 4.7v여서 구동이 불가능하다는 에러를 계속 접했다. 제어기는 전원이 5v 이상이여야 안정적이지만 실제 제어기의 전원이 4.7v여서 생기는 에러인 것이다.
해결해보려 했지만, 최종적으로는 해당 오류는 px4에서 존재하는 에러이며, ardupilot에서는 이러한 문제가 없는 것으로 확인하였다. 관련된 링크가 있었는데, 역시나 정신없는 와중에 기록하지 못했다.

 

그래서 결국 다시 ardupilot 펌웨어를 다시 설치하게 되었다. 이 때도 과정이 순탄친 않았다.

 

1. calibration

캘리브레이션을 하는 과정이 복잡했는데, 결국에는 성공했다.

사실 어떤 툴로 캘리브레이션에 성공했는지 정확히 기억이 나진 않는다.

QGroundControl / APM Planner 2 / Mission Planner 등등 상황에 따라 필요한 것들은 다 썼던 것 같다.

그래도 역시 가장 UI가 깔끔한 QGroundControl 가 주가 되었던거 같다.

 

2. power calibration

배터리를 캘리브레이션 하는 과정도 고역이었다. 성공하긴 했는데 어찌했는지 모르겠다.

기억 나는 것은 QGroundControl에 usb를 꽂고 "calibration" 버튼을 누른 후에 usb를 빼고 배터리를 꽂으면

각각 비프음과 함께 캘리브레이션이 수행되고, 마지막 긴 비프음 후에 배터리를 다시 뺏다 꽂으면 되었던 것이다.

그런데 대부분의 시도에서 마지막 긴 비프음이 들리지 않고, 배터리 셀 개수를 의미하는 3번의 비프음이 길게 테스트해봤을 때는 30분 넘도록 삑삑거렸던 것 같다. 

어쩌다 되긴 했는데 어떻게 된건진 모르겠다.

 

3. hardware safety switch

원래 드론에는 safety switch를 부착하여 긴급상황시에 드론을 정지시키는 기능을 수행하게 된다.

하지만 내 경우에는 safety switch가 없는 하드웨어를 사용하고 있었기 때문에 아래 링크와 같이 

BRD_SAFETYENABLE 를 0으로 설정하여 해결하였다.

 

ardupilot.org/copter/docs/common-safety-switch-pixhawk.html

 

Safety Switch — Copter documentation

If the safety switch is held down for the first few seconds after a Pixhawk is powered up, the I/O firmware is reloaded. This is normally not required but in some rare cases is required after a firmware upload if you hear the “Start up Failed” sound af

ardupilot.org

 아마 더 자세한 내용들도 있을 것 같지만, 일단 현재는 이 내용으로 진행하도록 하겠다.

 

 

 

19. ardupilot gazebo 시뮬레이션 환경 구축

실제 로봇으로 개발을 수행하려 했는데, 드론을 조작하는 부분의 코드 개발이 생각보다 변수가 많다.

이대로 실제 드론으로 작업하면 사고가 많을 것으로 예상되어 일전에 사용한 px4 펌웨어의 SITL이 아닌

Ardupilot의 SITL 환경을 구축하게 되었다.

 

먼저 다음 링크를 참고해 Ardupilot Firmware를 설치한다.

ardupilot.org/dev/index.html

 

Welcome to the ArduPilot Development Site — Dev documentation

ArduPilot is the leading open source autopilot system supporting multi-copters, traditional helicopters, fixed wing aircraft, rovers, submarines and antenna trackers. We pride ourselves on being versatile (rich in features with support for a large number o

ardupilot.org

 

이후에 다음 링크를 참고하여 Ardupilot Gazebo 시뮬레이션 환경을 설치한다.

 

ardupilot.org/dev/docs/using-gazebo-simulator-with-sitl.html

 

Using Gazebo Simulator with SITL — Dev documentation

In another terminal window, enter the ArduCopter directory and start the SITL simulation: Note ROS is commonly used together with Gazebo, but this is out of the scope of this article. If you are using ROS, some packages to consider using are: - mavros (for

ardupilot.org

 

이 후에 gazebo에 Ardupilot의 모델과 월드 정보를 알려주기 위해 다음 작업을 수행한다.

다음 링크를 참고했다.

github.com/khancyr/ardupilot_gazebo

 

khancyr/ardupilot_gazebo

Contribute to khancyr/ardupilot_gazebo development by creating an account on GitHub.

github.com

 

echo 'source /usr/share/gazebo/setup.sh' >> ~/.bashrc
# Set Path of Gazebo Models (Adapt the path to where to clone the repo)

echo 'export GAZEBO_MODEL_PATH=~/ardupilot_gazebo/models' >> ~/.bashrc
# Set Path of Gazebo Worlds (Adapt the path to where to clone the repo)

echo 'export GAZEBO_RESOURCE_PATH=~/ardupilot_gazebo/worlds:${GAZEBO_RESOURCE_PATH}' >> ~/.bashrc
source ~/.bashrc

 

이후에 다음 명령어를 통해 시뮬레이션 환경을 불러올 수 있다.

# terminal_1
$ gazebo --verbose worlds/iris_arducopter_runway.world 

# teminal_2
$ cd ~/ardupilot/ArduCopter
$ ../Tools/autotest/sim_vehicle.py -f gazebo-iris --console --map

 

이 후에 다음 링크를 참조해 mavros의 apm.launch 파일의 fcu_url을 바꾸어 준다.

 

<arg name="fcu_url" default="udp://127.0.0.1:14551@14555" />

 

ardupilot.org/dev/docs/ros-sitl.html

 

ROS with SITL — Dev documentation

Connect ArduPilot to ROS First, a good ROS habit is to always work in a workspace directory, so create one: Open a terminal mkdir -p ardupilot_ws/src cd ardupilot_ws catkin init cd src OK ROS is ready to use, let’s launch an SITL instance. Refer to Setti

ardupilot.org

이 후, 다음 명령어들을 통해 ardupilot gazebo와 mavros를 구동시킬 수 있다.

 

# terminal_1
$ roscore

# teminal_2
$ gazebo --verbose worlds/iris_arducopter_runway.world 

# teminal_3
$ cd ~/ardupilot/ArduCopter
$ ../Tools/autotest/sim_vehicle.py -f gazebo-iris --console --map

# teminal_4
$ roslaunch mavros apm.launch

# terminal_5
$ rosrun mavros mavsys mode -c GUIDED_NOGPS
$ rosrun mavros mavsafety arm

 

반응형