基于ubuntu18无人机仿真环境搭建
1.安装相关依赖
sudo apt install ninja-build exiftool ninja-build protobuf-compiler libeigen3-dev genromfs xmlstarlet libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
pip2 install pandas jinja2 pyserial cerberus pyulog==0.7.0 numpy toml pyquaternion empy pyyaml
pip3 install packaging numpy empy toml pyyaml jinja2 pyargparse
安装依赖过程比较缓慢,要先换国内的源
2.ros的安装
sudo apt update
sudo apt install ros-melodic-desktop
18.04对应ros版本是melodic,每个版本不一样
设定环境
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc
软件包依赖
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
sudo apt install python-rosdep
sudo rosdep init
安装完成打开终端运行
roscore
运行成功如下
... logging to /home/robin/.ros/log/a5118af0-5474-11ea-8b86-e454e828c524/r
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://robin-G3-3590:34223/
ros_comm version 1.12.14
SUMMARY
========
PARAMETERS
* /rosdistro: kinetic
* /rosversion: 1.12.14
NODES
auto-starting new master
process[master]: started with pid [30244]
ROS_MASTER_URI=http://robin-G3-3590:11311/
setting /run_id to a5118af0-5474-11ea-8b86-e454e828c524
process[rosout-1]: started with pid [30261]
started core service [/rosout]
接下来可以打开下午试一试,再打开一个终端输入
roscore rosrun turtlesim turtlesim_node
然后创建一个自己的工作空间
mkdir -p ~/catkin_ws/src
mkdir -p ~/catkin_ws/scripts
cd catkin_ws/src
catkin_init_workspace
cd ..
catkin_make
3.gazebo的安装
这里先把ros自动下载的gazebo先卸载
sudo apt-get remove gazebo*
sudo apt-get remove libgazebo*
sudo apt-get remove ros-melodic-gazebo*
1.设置计算机以接受来自package.osrfoundation.org的软件
这里一定要设置不然后面px4安装会有问题
sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
cat /etc/apt/sources.list.d/gazebo-stable.list
#如果出现deb http://packages.osrfoundation.org/gazebo/ubuntu-stable xenial main表示没问题
设置密钥
wget https://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
sudo apt-get update
安装9.1版本
sudo apt-get install gazebo9=9.1*
安装完成后运行gazebo如果成功打开则安装成功
安装ros的gazebo的插件
sudo apt install ros-melodic-gazebo9-*
sudo apt install ros-melodic-gazebo-*
测试先运行roscore然后再打开一个终端
rosrun gazebo_ros gazebo
4.MAVROS安装
sudo apt install ros-kinetic-mavros ros-kinetic-mavros-extras # for ros-kinetic
sudo apt install ros-melodic-mavros ros-melodic-mavros-extras # for ros-melodic
wget https://gitee.com/robin_shaun/XTDrone/raw/master/sitl_config/mavros/install_geographiclib_datasets.sh
sudo chmod a+x ./install_geographiclib_datasets.sh
sudo ./install_geographiclib_datasets.sh
最后一步可能会卡着不动,多等一会
5.px4安装
官方给的github在国内实在太慢了,而且容易漏下,我自己本人用github是没有成功过的,这里就用gitee的镜像
这个是github的地址,如果有条件建议最好还是GitHub下,比较方便
git clone https://github.com/PX4/PX4-Autopilot.git
mv PX4-Autopilot PX4_Firmware
cd PX4_Firmware
git checkout -b xtdrone/dev v1.11.0-beta1
git submodule update --init --recursive
make px4_sitl_default gazebo
这个是gitee的
git clone https://gitee.com/robin_shaun/PX4_Firmware
cd PX4_Firmware
git checkout -b xtdrone/dev v1.11.0-beta1
在工作空间下ctrl+h找到隐藏文件 .gitmodules 修改
[submodule "mavlink/include/mavlink/v2.0"]
path = mavlink/include/mavlink/v2.0
url = https://gitee.com/robin_shaun/c_library_v2.git
branch = master
[submodule "src/drivers/uavcan/libuavcan"]
path = src/drivers/uavcan/libuavcan
url = https://gitee.com/robin_shaun/uavcan.git
branch = px4
[submodule "Tools/jMAVSim"]
path = Tools/jMAVSim
url = https://gitee.com/robin_shaun/jMAVSim.git
branch = master
[submodule "Tools/sitl_gazebo"]
path = Tools/sitl_gazebo
url = https://gitee.com/robin_shaun/sitl_gazebo.git
branch = master
[submodule "src/lib/matrix"]
path = src/lib/matrix
url = https://gitee.com/robin_shaun/Matrix.git
branch = master
[submodule "src/lib/ecl"]
path = src/lib/ecl
url = https://gitee.com/robin_shaun/ecl.git
branch = master
[submodule "boards/atlflight/cmake_hexagon"]
path = boards/atlflight/cmake_hexagon
url = https://gitee.com/robin_shaun/cmake_hexagon.git
branch = px4
[submodule "src/drivers/gps/devices"]
path = src/drivers/gps/devices
url = https://gitee.com/robin_shaun/GpsDrivers.git
branch = master
[submodule "src/modules/micrortps_bridge/micro-CDR"]
path = src/modules/micrortps_bridge/micro-CDR
url = https://gitee.com/robin_shaun/micro-CDR.git
branch = px4
[submodule "platforms/nuttx/NuttX/nuttx"]
path = platforms/nuttx/NuttX/nuttx
url = https://gitee.com/robin_shaun/NuttX.git
branch = px4_firmware_nuttx-9.1.0+
[submodule "platforms/nuttx/NuttX/apps"]
path = platforms/nuttx/NuttX/apps
url = https://gitee.com/robin_shaun/NuttX-apps.git
branch = px4_firmware_nuttx-9.1.0+
[submodule "platforms/qurt/dspal"]
path = platforms/qurt/dspal
url = https://gitee.com/robin_shaun/dspal.git
[submodule "Tools/flightgear_bridge"]
path = Tools/flightgear_bridge
url = https://gitee.com/robin_shaun/PX4-FlightGear-Bridge.git
branch = master
[submodule "Tools/jsbsim_bridge"]
path = Tools/jsbsim_bridge
url = https://gitee.com/robin_shaun/px4-jsbsim-bridge.git
[submodule "src/examples/gyro_fft/CMSIS_5"]
path = src/examples/gyro_fft/CMSIS_5
url = https://gitee.com/mirrors/CMSIS_5
执行子模块更新指令
git submodule update --init
更改子模块下的submodule:
cd ~/PX4_Firmware/src/drivers/uavcan/libuavcan
修改.gitmodules:(要先到PX4_Firmware/src/drivers/uavcan/libuavcan这个文件夹中找到.gitmodules这个文件,下面也是同样)
[submodule "dsdl"]
path = dsdl
url = https://gitee.com/robin_shaun/dsdl
branch = legacy-v0
[submodule "libuavcan/dsdl_compiler/pyuavcan"]
path = libuavcan/dsdl_compiler/pyuavcan
url = https://gitee.com/robin_shaun/pyuavcan
[submodule "libuavcan_drivers/kinetis"]
path = libuavcan_drivers/kinetis
url = https://gitee.com/robin_shaun/libuavcan_kinetis.git
git submodule update --init
cd ~/PX4_Firmware/src/drivers/uavcan/libuavcan/libuavcan/dsdl_compiler/pyuavcan
修改.gitmodules:
[submodule "dsdl"]
path = dsdl
url = https://gitee.com/robin_shaun/dsdl
cd ~/PX4_Firmware/Tools/jMAVSim
修改.gitmodules:
[submodule "jMAVlib"]
path = jMAVlib
url = https://gitee.com/robin_shaun/jMAVlib
branch = master
git submodule update --init
cd ~/PX4_Firmware/Tools/sitl_gazebo
修改.gitmodules:
[submodule "external/OpticalFlow"]
path = external/OpticalFlow
url = https://gitee.com/robin_shaun/OpticalFlow
git submodule update --init
cd ~/PX4_Firmware/platforms/qurt/dspal
修改.gitmodules:
[submodule "cmake_hexagon"]
path = cmake_hexagon
url = https://gitee.com/robin_shaun/cmake_hexagon
git submodule update --init
cd ~/PX4_Firmware/Tools/sitl_gazebo/external/OpticalFlow
修改.gitmodules:
[submodule "external/klt_feature_tracker"]
path = external/klt_feature_tracker
url = https://gitee.com/robin_shaun/klt_feature_tracker
git submodule update --init
安装python依赖
cd ~/PX4_Firmware
bash ./Tools/setup/ubuntu.sh --no-nuttx --no-sim-tools
编译
make px4_sitl_default gazebo
设置路径
source ~/catkin_ws/devel/setup.bash
source ~/PX4_Firmware/Tools/setup_gazebo.bash ~/PX4_Firmware/ ~/PX4_Firmware/build/px4_sitl_default
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/PX4_Firmware
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/PX4_Firmware/Tools/sitl_gazebo
source ~/.bashrc
运行命令会打开gazebo
cd ~/PX4_Firmware
roslaunch px4 mavros_posix_sitl.launch
在打开一个终端运行
rostopic echo /mavros/state
若connected: True,则说明MAVROS与SITL通信成功。如果是false,一般是因为.bashrc里的路径写的不对,请仔细检查。
6.地面站安装
sudo usermod -a -G dialout $USER
sudo apt-get remove modemmanager -y
sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y
安装成功后把文件移动到主文件下
chmod +x ./QGroundControl.AppImage
./QGroundControl.AppImage
ros基础
创建ros功能包
1.创建工作空间
工作空间是存放相关开发文件的也就是工程目录
src:代码空间 存放功能包及其配置文件以及launch文件
build:编译空间 编译中所产生的中间文件,即二进制文件
devel :开发空间 编译生成的可执行文件,库,脚
install:安装空间 安装空间,使用安装指令时的默认文件存储位置
创建工作空间
2.创建一个catkin功能包
首先回到工作空间的src目录下,创建catkin功能包
catkin_create_pkg this std_msgs roscpp rospy
后面接的三个东西是这个这个功能包的依赖
这会创建一个名为this的文件夹,这个文件夹包含一个package.xml文件和一个CMakeLists.txt文件
package.xml
文件提供有关功能包的元信息 如作者,依赖的其他功能包等
CMakeLists.txt包
这个文件直接规定了这个package要依赖哪些package,要编译生成哪些目标,如何编译等等
同一个工作空间下不允许出现相同的名称的功能包
- 主文件夹:自己用户名命名的目录下
- catkin_ws可以不同,但后面的src一定要相同
- 要在工作空间的根目录上进行编译
- install,dev功能类似,install更多强调在开发后分享给客户使用的结果文件
- 源码要放在功能包中
- include文件夹:包含头文件等
- source的原因:运行前要设置环境变量
发布者&订阅者的实现
发布者向话题发布Twist类型的话题,订阅者订阅该话题
1.简易发布者代码
#include "ros/ros.h" //该头文件必须包含
#include "std_msgs/String.h" //ros标准消息里面的字符串消息
#include <sstream>
/**
* 在一个话题上发布一个简单的字符串消息
*/
int main(int argc, char *argv[])
{
/**
* ros::init()初始化节点函数需要使用argc和argv,不能缺少这两个参数,与话题重映射等有关的
*/
ros::init(argc, argv, "study"); //节点名为study,随便取
/**
*NodeHandle是与ROS系统通信的主要访问点(句柄),有了它节点就可以“说话了”(在话题上发布消息)
* 构造的第一个NodeHandle将完全初始化该节点,最后一个被析构的NodeHandle将关闭该节点。
*/
ros::NodeHandle n;
/**
* advertise()函数是你告诉ROS你想在给定的话题名上发布特定类型的消息。
* 在这个advertise()调用之后,master节点将通知任何试图订阅这个话题名称的节点,然后他们将与这个节点建立一个对等网络(peer to peer/P2P)连接。
* advertise()括号里面的第一个参数是话题名字,第二个参数是用于发布消息的消息队列的大小。
* <>里面指定消息的类型
*/
ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
/**
* 循环频率10Hz
发布一个消息类型为std_msgs/String,命名为chatter的话题。
定义消息队列大小为1000,即超过1000条消息之后,旧的消息就会丢弃。
*/
ros::Rate loop_rate(10);
int count = 0;
while (ros::ok())
{
/**
* 先创建一个消息对象。然后用数据填充它,最后发布它。
* 要查看消息结构在命令行使用rosmsg show std_msgs/String,其它消息类似
默认roscpp会植入一个SIGINT处理机制,当按下Ctrl-C,就会让ros::ok()返回false,那循环就会结束。
ros::ok() 返回false的几种情况:
SIGINT收到(Ctrl-C)信号
另一个同名节点启动,会先中止之前的同名节点
ros::shutdown()被调用
所有的ros::NodeHandles被销毁
*/
std_msgs::String msg;
std::stringstream ss;
ss << "hello world " << count;
msg.data = ss.str();
/**
* 在终端打印字符串的内容,消息在ROS里面封装成类,类公有函数这些请去wiki上看API文档
*/
ROS_INFO("%s", msg.data.c_str());
/**
* publish()函数是发送消息的函数,参数是消息对象。
* 消息类型要与n.advertise<>里面声明的一致。
*/
chatter_pub.publish(msg);
ros::spinOnce();//触发回调函数的,不订阅消息的话可删
loop_rate.sleep();//以10Hz循环,循环跑太快就在这里睡一会儿
++count;
}
return 0;
}
2.编写订阅节点
#include "ros/ros.h"
#include "std_msgs/String.h"
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
/*
定义回调函数chatterCallback,当收到chatter话题的消息就会调用这个函数。
消息通过boost shared_ptr(共享指针)来传递。
但收到消息,通过ROS_INFO函数显示到终端
*/
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
/*
定义订阅节点,名称为chatter,指定回调函数chatterCallback
但收到消息,则调用函数chatterCallback来处理。
参数1000,定义队列大小,如果处理不够快,超过1000,则丢弃旧的消息。
*/
ros::spin();
//调用此函数才真正开始进入循环处理,直到 ros::ok()返回false才停止。
return 0;
}
3.构建节点
在之前使用catkin_create_pkg创建包learning_rosing,会得到 package.xml 和 CMakeLists.txt两个文件
增加如下代码到CMakeLists.txt:
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
在此位置添加
4.编译并运行
cd ~/catkin_ws
catkin_make
source devel/setuo.bash
再打开一个终端运行
roscore
再再打开一个终端运行
rosrun learning_rosing talker
再再再打开一个终端运行
rosrun learning_rosing listener
运行结果
服务端&客户端的实现
1.服务端节点
打开工作空间中对应的功能包,在src目录下新建一个c++文件 add_two_ints_server.cpp
#include "ros/ros.h"
#include "learning_rosing/AddTwoInts.h"
//learning_rosing/AddTwoInts.h是由编译系统自动根据我们先前创建的srv文件生成的对应该srv文件的头文件。
bool add(beginner_tutorials::AddTwoInts::Request &req,
beginner_tutorials::AddTwoInts::Response &res)
//这个函数提供两个int值求和的服务,int值从request里面获取,而返回数据装入response内,这些数据类型都定义在srv文件内部,函数返回一个boolean值。
{
res.sum = req.a + req.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: [%ld]", (long int)res.sum);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_server");
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService("add_two_ints", add);
//这里,service已经建立起来,并在ROS内发布出来。
ROS_INFO("Ready to add two ints.");
ros::spin();
return 0;
}
2.编写客户端节点
打开工作空间中对应的功能包,在src目录下新建一个c++文件 add_two_ints_client.cpp
#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>
//在C里就是stdlib.h,在c++里就是cstdlib,里面封装了许多函数,例如malloc,free这些
int main(int argc, char **argv)
{
ros::init(argc, argv, "add_two_ints_client");
if (argc != 3)
{
ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
ros::NodeHandle n;
ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
//这段代码为add_two_ints service创建一个client。
//ros::ServiceClient 对象待会用来调用service。
beginner_tutorials::AddTwoInts srv;
srv.request.a = atoll(argv[1]);
srv.request.b = atoll(argv[2]);
/*这里,我们实例化一个由ROS编译系统自动生成的service类,并给其request成员赋值。
一个service类包含两个成员request和response。
同时也包括两个类定义Request和Response。*/
if (client.call(srv))
/*这段代码是在调用service。
由于service的调用是模态过程(调用的时候占用进程阻止其他代码的执行),一旦调用完成,将返回调用结果。
如果service调用成功,call()函数将返回true,srv.response里面的值将是合法的值。
如果调用失败,call()函数将返回false,srv.response里面的值将是非法的。*/
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
return 0;
}
(参考b站up主赵虚左【【Autolabor初级教程】ROS机器人入门】 https://www.bilibili.com/video/BV1Ci4y1L7ZZ/?share_source=copy_web&vd_source=46305e689a1990fcb387e3066edbcdc8)
零碎点
1.int main(int argc,char* argv[ ])
(1)C 语言规定 main 函数的参数只能有两个,还规定 argc 必须是整型变量,argv 必须是指向字符串的指针数组。
(2)argc 是命令行总的参数个数。
(3)char *argv[ ] 是指针数组,数组中的每个元素都是 char * 类型,即数组中每个元素都会指向一个字符串。
————————————————
版权声明:本文为CSDN博主「devilzcl」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37205350/article/details/106048645
XTD安装
git clone https://gitee.com/robin_shaun/XTDrone.git
cd XTDrone
git submodule update --init --recursive
cp sensing/gimbal/gazebo_gimbal_controller_plugin.cpp ~/PX4-Autopilot/Tools/sitl_gazebo/src/
cp sitl_config/init.d-posix/rcS ~/PX4-Autopilot/ROMFS/px4fmu_common/init.d-posix/
cp sitl_config/worlds/* ~/PX4-Autopilot/Tools/sitl_gazebo/worlds/
cp -r sitl_config/models/* ~/PX4-Autopilot/Tools/sitl_gazebo/models/
cp -r sitl_config/launch/* ~/PX4-Autopilot/launch/
避坑
大部分问题是网络问题,一定要换国内源
不要一直在一个终端运行上面的指令
中间会遇到很多问题基本都可以百度到但是还是要准备好百度一整天的准备,每次执行完命令执行下source,
有时候百度不到的问题可以看看报错,很多时候有可能是路径问题
多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!多看官方文档!
参考文献: Introduction · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程
XTDrone: 基于PX4、ROS和Gazebo的无人机通用仿真平台 (gitee.com)
(64条消息) ROS+Gazebo+PX4仿真步骤_chen果冻的博客-CSDN博客
(64条消息) PX4从放弃到精通(二):ubuntu18.04配置px4编译环境及mavros环境_超维空间科技的博客-CSDN博客_px4 ubuntu