diff --git a/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_pix.docx b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_pix.docx new file mode 100644 index 0000000..eed9c47 Binary files /dev/null and b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_pix.docx differ diff --git a/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_pix.pdf b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_pix.pdf new file mode 100644 index 0000000..9c32b7b Binary files /dev/null and b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_pix.pdf differ diff --git a/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_rac.docx b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_rac.docx new file mode 100644 index 0000000..7272637 Binary files /dev/null and b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_rac.docx differ diff --git a/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_rac.pdf b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_rac.pdf new file mode 100644 index 0000000..7e88570 Binary files /dev/null and b/基础编程/e10.基于MAVSDK的无人机控制实验/Readme_rac.pdf differ diff --git a/基础编程/e10.基于MAVSDK的无人机控制实验/code/Python38Run.bat b/基础编程/e10.基于MAVSDK的无人机控制实验/code/Python38Run.bat new file mode 100644 index 0000000..ad265a4 --- /dev/null +++ b/基础编程/e10.基于MAVSDK的无人机控制实验/code/Python38Run.bat @@ -0,0 +1,5 @@ +if not defined PSP_PATH ( + SET PSP_PATH=C:\PX4PSP + SET PSP_PATH_LINUX=/mnt/c/PX4PSP +) +start cmd.exe /k "echo Python3.8 environment has been set with openCV+pymavlink+numpy+pyulog etc. && echo You can use pip or pip3 command to install other libraries && echo Put Python38Run.bat into your code folder && echo Use the command: 'python XXX.py' to run the script with Python && SET PATH=%PSP_PATH%\Python38;%PSP_PATH%\Python38\Scripts;%CD%;%PATH%" diff --git a/基础编程/e10.基于MAVSDK的无人机控制实验/code/offboard_position_ned.py b/基础编程/e10.基于MAVSDK的无人机控制实验/code/offboard_position_ned.py new file mode 100644 index 0000000..94fad34 --- /dev/null +++ b/基础编程/e10.基于MAVSDK的无人机控制实验/code/offboard_position_ned.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +""" +Caveat when attempting to run the examples in non-gps environments: + +`drone.offboard.stop()` will return a `COMMAND_DENIED` result because it +requires a mode switch to HOLD, something that is currently not supported in a +non-gps environment. +""" + +import asyncio + +from mavsdk import System +from mavsdk.offboard import (OffboardError, PositionNedYaw) +import ReqCopterSim +import time + +# mavsdk-python的使用方法见:https://mavsdk.mavlink.io/main/en/python/quickstart.html +# 本平台使用1.2.0版本的mavsdk,因为更高版本无法直接用Python启动,还需运行server +# 接口文档见:http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/ + +async def run(): + """ Does Offboard control using position NED coordinates. """ + + + # 创建一个CopterSim状态获取实例,并监听2s钟,获取当前所有CopterSim列表数据 + req = ReqCopterSim.ReqCopterSim() + + # 下面展示,如何使用本接口,不需要知道目标电脑IP的情况下,能够连上远程电脑的CopterSim + CopterID=1 # 计划仿真的飞机ID + TargetPort = 20100 + CopterID*2 -1 # 对应CopterSim的发送端口 + + # 获取CopterSim所在电脑的IP地址 + TargetIP = req.getSimIpID(CopterID) + print('Target IP is: ',TargetIP) + + # 请求CopterSim将UDP模式转换为MAVLink_Full,便于本例程的Mavlink控制 + req.sendReSimUdpMode(CopterID,UDP_mode=2) + + # 向CopterSim发送请求,发送MAVLink数据到本电脑 + req.sendReSimIP(CopterID) + + time.sleep(2) + + print('开始连接Mavsdk') + + # 下面开始用mavsdk来控制飞机 + drone = System() # 创建一个mavsdk实例 + + # 等待连接上飞控,这里指定任意IP和20100系列端口,类似udp://0.0.0.0:20101 + await drone.connect(system_address="udp://:"+str(TargetPort)) + + + print("Waiting for drone to connect...") + # 等待完全确认连接 + async for state in drone.core.connection_state(): + if state.is_connected: + print(f"-- Connected to drone!") + break + + print("Waiting for drone to have a global position estimate...") + # 等待获取健康状态,这里通过查询telemray收集到的数据,请阅读如下文档了解telemray下有哪些数据 + # http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/plugins/telemetry.html + async for health in drone.telemetry.health(): + # health()函数见:http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/plugins/telemetry.html#mavsdk.telemetry.Telemetry.health + if health.is_global_position_ok and health.is_home_position_ok: + # health的数据定义见:http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/plugins/telemetry.html#mavsdk.telemetry.Health + # 查询得到:is_local_position_ok (bool) – True if the local position estimate is good enough to fly in ‘position control’ mode + print("-- Global position estimate OK") + break + + print("-- Arming") + # 等待解锁飞控 + # 见:http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/plugins/action.html + await drone.action.arm() + + print("-- Setting initial setpoint") + # http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/plugins/offboard.html + # http://mavsdk-python-docs.s3-website.eu-central-1.amazonaws.com/plugins/offboard.html#mavsdk.offboard.Offboard.set_position_ned + await drone.offboard.set_position_ned(PositionNedYaw(0.0, 0.0, 0.0, 0.0)) + + print("-- Starting offboard") + try: + await drone.offboard.start() + except OffboardError as error: + print(f"Starting offboard mode failed \ + with error code: {error._result.result}") + print("-- Disarming") + await drone.action.disarm() + return + + print("-- Go 0m North, 0m East, -5m Down \ + within local coordinate system") + await drone.offboard.set_position_ned( + PositionNedYaw(0.0, 0.0, -5.0, 0.0)) + await asyncio.sleep(10) + + print("-- Go 5m North, 0m East, -5m Down \ + within local coordinate system, turn to face East") + await drone.offboard.set_position_ned( + PositionNedYaw(5.0, 0.0, -5.0, 90.0)) + await asyncio.sleep(10) + + print("-- Go 5m North, 10m East, -5m Down \ + within local coordinate system") + await drone.offboard.set_position_ned( + PositionNedYaw(5.0, 10.0, -5.0, 90.0)) + await asyncio.sleep(15) + + print("-- Go 0m North, 10m East, 0m Down \ + within local coordinate system, turn to face South") + await drone.offboard.set_position_ned( + PositionNedYaw(0.0, 10.0, 0.0, 180.0)) + await asyncio.sleep(10) + + print("-- Stopping offboard") + try: + await drone.offboard.stop() + except OffboardError as error: + print(f"Stopping offboard mode failed \ + with error code: {error._result.result}") + + +if __name__ == "__main__": + # Run the asyncio loop + asyncio.run(run()) \ No newline at end of file diff --git a/基础编程/e11.基于MAVROS的无人机控制实验/Readme.docx b/基础编程/e11.基于MAVROS的无人机控制实验/Readme.docx new file mode 100644 index 0000000..0498038 Binary files /dev/null and b/基础编程/e11.基于MAVROS的无人机控制实验/Readme.docx differ diff --git a/基础编程/e11.基于MAVROS的无人机控制实验/Readme.pdf b/基础编程/e11.基于MAVROS的无人机控制实验/Readme.pdf new file mode 100644 index 0000000..e568dc3 Binary files /dev/null and b/基础编程/e11.基于MAVROS的无人机控制实验/Readme.pdf differ diff --git a/基础编程/e11.基于MAVROS的无人机控制实验/code/Ros12OneUav.py b/基础编程/e11.基于MAVROS的无人机控制实验/code/Ros12OneUav.py new file mode 100644 index 0000000..a95a3bb --- /dev/null +++ b/基础编程/e11.基于MAVROS的无人机控制实验/code/Ros12OneUav.py @@ -0,0 +1,41 @@ +import PX4MavCtrlV4ROS as PX4MavCtrl +import time + + +# 创建一个ROS控制实例,针对飞机1 +mav = PX4MavCtrl.PX4MavCtrler(CopterID=1) +time.sleep(1) + +print('进入offboard并解锁') +mav.initOffboard() +time.sleep(1) + + +# 飞机起飞到0.1米前,0.8米高 +print('发送起飞命令') +mav.SendPosNED(0.1,0,-0.8) +time.sleep(10) + +print('PosE',mav.uavPosNED) +print('VelE',mav.uavVelNED) +print('Euler',mav.uavAngEular) +print('Quaternion',mav.uavAngQuatern) +print('Rate',mav.uavAngRate) + +time.sleep(1) +print('Start control.') + +# 下面开始你的控制算法 +# mav.SendPosNED(x,y,z,yaw) 发送期望位置点,NED地球坐标系 +# mav.SendVelNED(vx,vy,vz,yawrate) 发送速度,NED地球坐标系 +# mav.SendVelFRD(vx,vy,vz,yawrate) 发送速度,FRD机体坐标系,通常而言,设定vx和yawrate即可,前进速度和偏航速度。 +# mav.SendPosVelNED(PosE=[0,0,0],VelE=[0,0,0],yaw,yawrate) 同时控制飞机位置和速度 + + +# 下面仅展示使用SendVelFRD控制的例子,会撞墙,为正常现象 + +print('开始速度控制') + +# 向前0.1m/s飞,并缓慢调转方向 +mav.SendVelFRD(0.1,0,0,0.05) + diff --git a/基础编程/e11.基于MAVROS的无人机控制实验/code/RosSwitch.bat b/基础编程/e11.基于MAVROS的无人机控制实验/code/RosSwitch.bat new file mode 100644 index 0000000..9e0506f --- /dev/null +++ b/基础编程/e11.基于MAVROS的无人机控制实验/code/RosSwitch.bat @@ -0,0 +1,16 @@ +@echo off +wsl -d RflySim-20.04 -e bash -lic "echo Current version is ROS$ROS_VERSION" + +SET /P ROSVer=New ROS Version 1 or 2: +if %ROSVer% EQU 1 ( + ECHO Switch to ROS1 + wsl -d RflySim-20.04 ~/ros_switch.sh 1 + +) ELSE ( + ECHO Switch to ROS2 + wsl -d RflySim-20.04 ~/ros_switch.sh 2 +) +wsl --shutdown +ECHO Successful. +ECHO Press any key to exit. +pause \ No newline at end of file diff --git a/基础编程/e11.基于MAVROS的无人机控制实验/code/SITLRunROS.bat b/基础编程/e11.基于MAVROS的无人机控制实验/code/SITLRunROS.bat new file mode 100644 index 0000000..deda439 --- /dev/null +++ b/基础编程/e11.基于MAVROS的无人机控制实验/code/SITLRunROS.bat @@ -0,0 +1,157 @@ +@ECHO OFF + +REM Run script as administrator +%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c ""%~s0"" ::","","runas",1)(window.close)&&exit + + +REM The text start with 'REM' is annotation, the following options are corresponding to Options on CopterSim +REM This script use UDPSIMMODE=2 for MAVLink FULL control + +REM Set the path of the RflySim tools +if not defined PSP_PATH ( + SET PSP_PATH=C:\PX4PSP + SET PSP_PATH_LINUX=/mnt/c/PX4PSP +) + +REM Start index of vehicle number (should larger than 0) +REM This option is useful for simulation with multi-computers +SET /a START_INDEX=1 + +REM Total vehicle Number to auto arrange position +REM SET /a TOTOAL_COPTER=8 + +REM Set the vehicleType/ClassID of vehicle 3D display in RflySim3D +SET /a CLASS_3D_ID=-1 + +REM Set use DLL model name or not, use number index or name string +REM This option is useful for simulation with other types of vehicles instead of multicopters +set DLLModel=0 + +REM Check if DLLModel is a name string, if yes, copy the DLL file to CopterSim folder +SET /A DLLModelVal=DLLModel +if %DLLModelVal% NEQ %DLLModel% ( + REM Copy the latest dll file to CopterSim folder + copy /Y "%~dp0"\%DLLModel%.dll %PSP_PATH%\CopterSim\external\model\%DLLModel%.dll +) + +REM Set the simulation mode on CopterSim, use number index or name string +REM e.g., SimMode=2 equals to SimMode=PX4_SITL_RFLY +set SimMode=2 + +REM Set the vehicle-model (airframe) of PX4 SITL simulation, the default airframe is a quadcopter: iris +REM Check folder Firmware\ROMFS\px4fmu_common\init.d-posix for supported airframes (Note: You can also create your airframe file here) +REM E.g., fixed-wing aircraft: PX4SitlFrame=plane; small cars: PX4SitlFrame=rover +set PX4SitlFrame=iris + + +REM Set the map, use index or name of the map on CopterSim +REM e.g., UE4_MAP=1 equals to UE4_MAP=Grasslands +SET UE4_MAP=Grasslands + +REM Set the origin x,y position (m) and yaw angle (degree) at the map +SET /a ORIGIN_POS_X=0 +SET /a ORIGIN_POS_Y=0 +SET /a ORIGIN_YAW=0 + +REM Set the interval between two vehicle, unit:m +SET /a VEHICLE_INTERVAL=2 + + +REM Set broadcast to other computer; IS_BROADCAST=0: only this computer, IS_BROADCAST=1: broadcast; +REM or use IP address to increase speed, e.g., IS_BROADCAST=192.168.3.1 +REM Note: in IP mode, IS_BROADCAST=0 equals to IS_BROADCAST=127.0.0.1, IS_BROADCAST=1 equals to IS_BROADCAST=255.255.255.255 +REM You can also use a IP list with seperator "," or ";" to specify IPs to send, e.g., 127.0.0.1,192.168.1.4,192.168.1.5 +SET IS_BROADCAST=0 + +REM Set UDP data mode; 0: UDP_FULL, 1:UDP_Simple, 2: Mavlink_Full, 3: Mavlink_simple. input number or string +REM 4:Mavlink_NoSend, 5:Mavlink_NoGPS, 6:Mavlink_Vision (NoGPS and set PX4 EKF) +SET UDPSIMMODE=2 + + +:Top +ECHO. +ECHO --------------------------------------- +REM Max vehicle number 50 +SET /a MAX_VEHICLE=50 +SET /a VehicleNum=1 + +SET /A VehicleTotalNum=%VehicleNum% + %START_INDEX% - 1 +if not defined TOTOAL_COPTER ( + SET /A TOTOAL_COPTER=%VehicleTotalNum% +) + +set /a sqrtNum=1 +set /a squareNum=1 +:loopSqrt +set /a squareNum=%sqrtNum% * %sqrtNum% +if %squareNum% EQU %TOTOAL_COPTER% ( + goto loopSqrtEnd +) +if %squareNum% GTR %TOTOAL_COPTER% ( + goto loopSqrtEnd +) +set /a sqrtNum=%sqrtNum%+1 +goto loopSqrt +:loopSqrtEnd + + +REM QGCPath +tasklist|find /i "QGroundControl.exe" || start %PSP_PATH%\QGroundControl\QGroundControl.exe -noComPix +ECHO Start QGroundControl + +REM UE4Path +cd /d %PSP_PATH%\RflySim3D +tasklist|find /i "RflySim3D.exe" || start %PSP_PATH%\RflySim3D\RflySim3D.exe +choice /t 5 /d y /n >nul + + +tasklist|find /i "CopterSim.exe" && taskkill /im "CopterSim.exe" +ECHO Kill all CopterSims + + +REM CptSmPath +cd /d %PSP_PATH%\CopterSim + + +set /a cntr=%START_INDEX% +set /a endNum=%VehicleTotalNum%+1 + +:loopBegin +set /a PosXX=((%cntr%-1) / %sqrtNum%)*%VEHICLE_INTERVAL% + %ORIGIN_POS_X% +set /a PosYY=((%cntr%-1) %% %sqrtNum%)*%VEHICLE_INTERVAL% + %ORIGIN_POS_Y% +start /realtime CopterSim.exe 1 %cntr% %CLASS_3D_ID% %DLLModel% %SimMode% %UE4_MAP% %IS_BROADCAST% %PosXX% %PosYY% %ORIGIN_YAW% 1 %UDPSIMMODE% +choice /t 1 /d y /n >nul +set /a cntr=%cntr%+1 + +if %cntr% EQU %endNum% goto loopEnd +goto loopBegin +:loopEnd + +REM Set ToolChainType 1:Win10WSL 3:Cygwin +SET /a ToolChainType=1 + +if "%IS_BROADCAST%" == "0" ( + SET IS_BROADCAST=0 +) else ( + SET IS_BROADCAST=1 +) + +SET WINDOWSPATH=%PATH% +if %ToolChainType% EQU 1 ( + wsl -d RflySim-20.04 -e bash -lic "echo Starting PX4 Build; cd %PSP_PATH_LINUX%/Firmware; ./BkFile/EnvOri.sh; make px4_sitl_default; ./Tools/sitl_multiple_run_rfly.sh %VehicleNum% %START_INDEX% %PX4SitlFrame%;~/mavros_run.sh %START_INDEX%,%VehicleNum%; pkill -x px4 || true" + wsl --shutdown +) else ( + REM CYGPath + cd /d %PSP_PATH%\CygwinToolchain + CALL setPX4Env.bat + bash -l -i -c 'echo Starting SITL SIMULATION; cd %PSP_PATH_LINUX%/Firmware; ./BkFile/EnvOri.sh; pwd; make px4_sitl_default; ./Tools/sitl_multiple_run_rfly.sh %VehicleNum% %START_INDEX% %PX4SitlFrame%; pkill -x px4 || true;' +) +SET PATH=%WINDOWSPATH% + + +REM kill all applications when press a key +tasklist|find /i "CopterSim.exe" && taskkill /im "CopterSim.exe" +tasklist|find /i "QGroundControl.exe" && taskkill /f /im "QGroundControl.exe" +tasklist|find /i "RflySim3D.exe" && taskkill /f /im "RflySim3D.exe" + +ECHO Start End. diff --git a/基础编程/e11.基于MAVROS的无人机控制实验/code/WinWSL.bat b/基础编程/e11.基于MAVROS的无人机控制实验/code/WinWSL.bat new file mode 100644 index 0000000..3cd2942 --- /dev/null +++ b/基础编程/e11.基于MAVROS的无人机控制实验/code/WinWSL.bat @@ -0,0 +1,12 @@ +@echo off +REM Set the path of the RflySim tools +if not defined PSP_PATH ( + SET PSP_PATH=C:\PX4PSP + SET PSP_PATH_LINUX=/mnt/c/PX4PSP +) +cd /d %PSP_PATH%\VcXsrv +tasklist|find /i "vcxsrv.exe" >nul || Xlaunch.exe -run config1.xlaunch + +cd /d %~dp0 +wsl -d RflySim-20.04 + diff --git a/基础编程/e6.ROS环境下python测试实验/Readme.pdf b/基础编程/e6.ROS环境下python测试实验/Readme.pdf new file mode 100644 index 0000000..8a910e7 Binary files /dev/null and b/基础编程/e6.ROS环境下python测试实验/Readme.pdf differ diff --git a/基础编程/e6.ROS环境下python测试实验/RosSwitch.bat b/基础编程/e6.ROS环境下python测试实验/RosSwitch.bat new file mode 100644 index 0000000..db74472 --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/RosSwitch.bat @@ -0,0 +1,16 @@ +@echo off +wsl -d RflySim-20.04 -e bash -lic "echo Current version is ROS$ROS_VERSION" + +SET /P ROSVer=New ROS Version 1 or 2: +if %ROSVer% EQU 1 ( + ECHO Switch to ROS1 + wsl -d RflySim-20.04 ~/ros_switch.sh 1 + +) ELSE ( + ECHO Switch to ROS2 + wsl -d RflySim-20.04 ~/ros_switch.sh 2 +) +wsl --shutdown +ECHO Successful. +ECHO Press any key to exit. +pause diff --git a/基础编程/e6.ROS环境下python测试实验/WinWSL.bat b/基础编程/e6.ROS环境下python测试实验/WinWSL.bat new file mode 100644 index 0000000..3cd2942 --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/WinWSL.bat @@ -0,0 +1,12 @@ +@echo off +REM Set the path of the RflySim tools +if not defined PSP_PATH ( + SET PSP_PATH=C:\PX4PSP + SET PSP_PATH_LINUX=/mnt/c/PX4PSP +) +cd /d %PSP_PATH%\VcXsrv +tasklist|find /i "vcxsrv.exe" >nul || Xlaunch.exe -run config1.xlaunch + +cd /d %~dp0 +wsl -d RflySim-20.04 + diff --git a/基础编程/e6.ROS环境下python测试实验/WslGUI.bat b/基础编程/e6.ROS环境下python测试实验/WslGUI.bat new file mode 100644 index 0000000..8437ae7 --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/WslGUI.bat @@ -0,0 +1,21 @@ +@echo off + +REM Set the path of the RflySim tools +if not defined PSP_PATH ( + SET PSP_PATH=C:\PX4PSP + SET PSP_PATH_LINUX=/mnt/c/PX4PSP +) + +tasklist|find /i "vcxsrv.exe" >nul && taskkill /f /IM "vcxsrv.exe" >nul +tasklist|find /i "vcxsrv.exe" >nul && taskkill /f /IM "vcxsrv.exe" >nul + +cd /d %PSP_PATH%\VcXsrv +Xlaunch.exe -run config.xlaunch + +choice /t 1 /d y /n >nul + +cd /d %~dp0 +wsl -d RflySim-20.04 ~/StartUI.sh +choice /t 1 /d y /n >nul +tasklist|find /i "vcxsrv.exe" && taskkill /f /IM "vcxsrv.exe" +wsl --shutdown diff --git a/基础编程/e6.ROS环境下python测试实验/code/hello.cpp b/基础编程/e6.ROS环境下python测试实验/code/hello.cpp new file mode 100644 index 0000000..1aa9764 --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/code/hello.cpp @@ -0,0 +1,13 @@ +#include "ros/ros.h" + +int main(int argc, char *argv[]) +{ + //执行 ros 节点初始化 + ros::init(argc,argv,"hello"); + //创建 ros 节点句柄(非必须) + ros::NodeHandle n; + + ROS_INFO("hello SLAm!"); + + return 0; +} diff --git a/基础编程/e6.ROS环境下python测试实验/code/listener.py b/基础编程/e6.ROS环境下python测试实验/code/listener.py new file mode 100644 index 0000000..096658a --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/code/listener.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +import rospy +from std_msgs.msg import String + +def callback(data): + rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data) + +def listener(): + + # In ROS, nodes are uniquely named. If two nodes with the same + # node are launched, the previous one is kicked off. The + # anonymous=True flag means that rospy will choose a unique + # name for our 'listener' node so that multiple listeners can + # run simultaneously. + rospy.init_node('listener', anonymous=True) + + rospy.Subscriber("chatter", String, callback) + + # spin() simply keeps python from exiting until this node is stopped + rospy.spin() + +if __name__ == '__main__': + listener() diff --git a/基础编程/e6.ROS环境下python测试实验/code/talker.py b/基础编程/e6.ROS环境下python测试实验/code/talker.py new file mode 100644 index 0000000..767cb15 --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/code/talker.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python + +import rospy +from std_msgs.msg import String + +def talker(): + pub = rospy.Publisher('chatter', String, queue_size=10) + rospy.init_node('talker', anonymous=True) + rate = rospy.Rate(10) # 10hz + while not rospy.is_shutdown(): + hello_str = "hello world %s" % rospy.get_time() + rospy.loginfo(hello_str) + pub.publish(hello_str) + rate.sleep() + +if __name__ == '__main__': + try: + talker() + except rospy.ROSInterruptException: + pass diff --git a/基础编程/e6.ROS环境下python测试实验/install-ROS-ubuntu.sh b/基础编程/e6.ROS环境下python测试实验/install-ROS-ubuntu.sh new file mode 100644 index 0000000..3c94a1e --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/install-ROS-ubuntu.sh @@ -0,0 +1,225 @@ +#!/usr/bin/env bash +echo "---------- $0 start ----------" +set -e +# set -x + +ROS_WS_ROOT=$HOME/ardupilot-ws +AP_GZ_ROOT=$HOME/ardupilot_gz_ws + +red=`tput setaf 1` +green=`tput setaf 2` +reset=`tput sgr0` + +sep="##############################################" + + +function heading() { + echo "$sep" + echo $* + echo "$sep" +} + +ASSUME_YES=false + +function maybe_prompt_user() { + if $ASSUME_YES; then + return 0 + else + read -p "$1" + if [[ $REPLY =~ ^[Yy]$ ]]; then + return 0 + else + return 1 + fi + fi +} + +function usage +{ + echo "Usage: ./installROS.sh [[-p package] | [-h]]" + echo "Install ROS1" + echo "This script will select the ROS distribution according to the OS being used" + echo "Installs desktop-full as default base package; Use -p to override" + echo "-p | --package ROS package to install" + echo " Multiple usage allowed" + echo " Must include one of the following:" + echo " ros-base" + echo " desktop" + echo " desktop-full" + echo "-h | --help This message" +} + +function shouldInstallPackages +{ + echo "${red}Your package list did not include a recommended base package${reset}" + echo "Please include one of the following:" + echo " ros-base" + echo " desktop" + echo " desktop-full" + echo "" + echo "ROS not installed" +} + +function package_is_installed() { + dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -c "ok installed" +} + +# Iterate through command line inputs +packages=() +while [ "$1" != "" ]; do + case $1 in + -p | --package ) shift + packages+=("$1") + ;; + -h | --help ) usage + exit + ;; + * ) usage + exit 1 + esac + shift +done + +# Install lsb-release as it is needed to check Ubuntu version +if ! package_is_installed "lsb-release"; then + heading "Installing lsb-release" + sudo apt install lsb-release -y + echo "Done!" +fi + +# Checking Ubuntu release to adapt software version to install +RELEASE_CODENAME=$(lsb_release -c -s) +PYTHON_V="python3" # starting from ubuntu 20.04, python isn't symlink to default python interpreter + + +# echo $RELEASE_CODENAME + +if [ ${RELEASE_CODENAME} == 'bionic' ] ; then + #Ubuntu 18.04 - Melodic + ROS_VERSION="melodic" + PYTHON_V="python2" + heading "${green}Detected Ubuntu 18.04, installing ROS Melodic${reset}" +elif [ ${RELEASE_CODENAME} == 'buster' ]; then + #RPi Buster - Melodic + ROS_VERSION="melodic" + PYTHON_V="python2" + heading "${green}Detected RPi Buster, installing ROS Melodic${reset}" +elif [ ${RELEASE_CODENAME} == 'focal' ]; then + #Ubuntu 20.04 - Noetic + ROS_VERSION="noetic" + PYTHON_V="python3" + heading "${green}Detected Ubuntu 20.04, installing ROS Noetic${reset}" +elif [ ${RELEASE_CODENAME} == 'jammy' ]; then + #Ubuntu 22.04 - unsupported only ROS2 + heading "${red}Currently only ROS1 is supported. This Ubuntu release can only be used with ROS2.${reset}" + exit 1 +else + # We assume an unsupported OS is being used. + heading "${red}Unsupported OS detected. Please refer to the ROS webpage to find how to install ROS1 on your system if at all possible.${reset}" + exit 1 +fi + +# Check to see if other packages were specified +# If not, set the default base package +if [ ${#packages[@]} -eq 0 ] ; then + packages+="desktop-full" +fi +echo "Packages to install: "${packages[@]} +# Check to see if we have a ROS base kinda thingie +hasBasePackage=false +for package in "${packages[@]}"; do + if [[ $package == "ros-base" ]]; then + delete=ros-base + packages=( "${packages[@]/$delete}" ) + packages+=" ros-${ROS_VERSION}-ros-base" + hasBasePackage=true + break + elif [[ $package == "desktop" ]]; then + delete=desktop + packages=( "${packages[@]/$delete}" ) + packages+=" ros-${ROS_VERSION}-desktop" + hasBasePackage=true + break + elif [[ $package == "desktop-full" ]]; then + delete=desktop-full + packages=( "${packages[@]/$delete}" ) + packages+=" ros-${ROS_VERSION}-desktop-full" + hasBasePackage=true + break + fi +done +if [ $hasBasePackage == false ] ; then + shouldInstallPackages + exit 1 +fi + +heading "${green}Adding Repositories and source lists${reset}" +#Lets start instaling stuff +sudo apt install software-properties-common -y +sudo apt-add-repository universe +sudo apt-add-repository multiverse +sudo apt-add-repository restricted + +# Setup sources.lst +sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' +# Setup keys +sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 +# If you experience issues connecting to the keyserver, you can try substituting hkp://pgp.mit.edu:80 or hkp://keyserver.ubuntu.com:80 in the previous command. +# Installation + +heading "${green}Updating apt${reset}" +sudo apt update + +heading "${green}Installing ROS${reset}" +# Here we loop through any packages passed on the command line +# Install packages ... +for package in "${packages[@]}"; do + sudo apt install $package -y +done + +# install other needed packages +sudo apt install build-essential cmake -y + +# +# To find available packages: +# apt-cache search ros-melodic +# +# Initialize rosdep + +heading "${green}Installing rosdep${reset}" + +sudo apt install ${PYTHON_V}-rosdep -y +# Certificates are messed up on earlier version Jetson for some reason +# Do not know if it is an issue with the Xavier, test by commenting out +# sudo c_rehash /etc/ssl/certs +# Initialize rosdep + +heading "${green}Initializaing rosdep${reset}" + +sudo rosdep init || true +# To find available packages, use: +rosdep update +# Use this to install dependencies of packages in a workspace +# rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y +# Environment Setup - Don't add /opt/ros/${ROS_VERSION}/setup.bash if it's already in bashrc +# if maybe_prompt_user "Do you want to add ROS_HOSTNAME and ROS_MASTER_URI to your .bashrc [N/y]?" ; then +# heading "${green}Adding setup.bash, ROS_MASTER_URI and ROS_HOSTNAME to .bashrc ${reset}" +# grep -q -F "ROS_HOSTNAME=$HOSTNAME.local" ~/.bashrc || echo "ROS_HOSTNAME=$HOSTNAME.local" >> ~/.bashrc +# grep -q -F "ROS_MASTER_URI=http://$HOSTNAME.local:11311" ~/.bashrc || echo "ROS_MASTER_URI=http://$HOSTNAME.local:11311" >> ~/.bashrc +# grep -q -F "source /opt/ros/${ROS_VERSION}/setup.bash" ~/.bashrc || echo "source /opt/ros/${ROS_VERSION}/setup.bash" >> ~/.bashrc +# source ~/.bashrc +# fi + +heading "${green}Installing rosinstall tools${reset}" + +sudo apt install ${PYTHON_V}-rosinstall ${PYTHON_V}-rosinstall-generator ${PYTHON_V}-wstool ${PYTHON_V}-catkin-tools -y + +pip3 install rospkg +pip3 install catkin-tools +pip3 install roslibpy + +# 安装必要的库 +pip3 install open3d==0.10.0 mavsdk==1.2.0 + +# 安装其他必要库 +sudo apt install libgoogle-glog-dev \ No newline at end of file diff --git a/基础编程/e6.ROS环境下python测试实验/名称-ROS环境部署和安装测试实验.txt b/基础编程/e6.ROS环境下python测试实验/名称-ROS环境部署和安装测试实验.txt new file mode 100644 index 0000000..e69de29 diff --git a/基础编程/e6.ROS环境下python测试实验/测试方法.txt b/基础编程/e6.ROS环境下python测试实验/测试方法.txt new file mode 100644 index 0000000..ef8b02d --- /dev/null +++ b/基础编程/e6.ROS环境下python测试实验/测试方法.txt @@ -0,0 +1,27 @@ +0.运行Desktop\RflyTools\RosSwitch快捷方式或本文件夹“RosSwitch.bat” +确认当前ROS环境,如果不是ROS1,则切换到ROS1 + +一、ROS1程序调控 +1. 运行Desktop\RflyTools\WslGUI快捷方式或文件夹“WslGUI.bat”,打开一个GUI窗口。 +2. 在其中,按下CTRL+ALT+T的快捷键,打开一个终端。输入 +roscore +来启动ROS Master +3. 按下CTRL+ALT+T的快捷键,打开一个新终端。输入 +rosrun turtlesim turtlesim_node +来启动小海龟仿真器 +4. 按下CTRL+ALT+T的快捷键,打开一个新终端。输入 +rosrun turtlesim turtle_teleop_key +启动海龟键盘控制节点 +5. 通过键盘方向键,就能控制海龟运动了。 +其中上下键,控制前进。 +左右键控制方向。 + +注:第一句指令将启动一个蓝色背景的海龟仿真器,第二句指令将启动一个键盘控制节点,在该终端中点击键盘上的“上下左右”按键,就可以控制小海龟运动了。 + + +二、ROS1环境部署 +1. 找一台Ubuntu电脑或者虚拟机。 +2. 拷贝install-ROS-ubuntu.sh到系统中,并运行,就能自动部署环境。 +3. 加载ROS1环境,输入如下命令即可 +source /opt/ros/noetic/setup.bash +4. 按“一、ROS1程序调控”中的步骤,测试ROS环境是否安装正确。 \ No newline at end of file diff --git a/基础编程/e7.Offboard模式介绍及控制实验/Readme.docx b/基础编程/e7.Offboard模式介绍及控制实验/Readme.docx new file mode 100644 index 0000000..d1d70ab Binary files /dev/null and b/基础编程/e7.Offboard模式介绍及控制实验/Readme.docx differ diff --git a/基础编程/e7.Offboard模式介绍及控制实验/Readme.pdf b/基础编程/e7.Offboard模式介绍及控制实验/Readme.pdf new file mode 100644 index 0000000..61651a8 Binary files /dev/null and b/基础编程/e7.Offboard模式介绍及控制实验/Readme.pdf differ diff --git a/基础编程/e7.Offboard模式介绍及控制实验/code/OffboardCircle.py b/基础编程/e7.Offboard模式介绍及控制实验/code/OffboardCircle.py new file mode 100644 index 0000000..10d33ce --- /dev/null +++ b/基础编程/e7.Offboard模式介绍及控制实验/code/OffboardCircle.py @@ -0,0 +1,89 @@ + +# import required libraries +# pip3 install pymavlink pyserial + +import cv2 +import numpy as np +import time +import VisionCaptureApi +import PX4MavCtrlV4 as PX4MavCtrl +import math +import ReqCopterSim + +req = ReqCopterSim.ReqCopterSim() # 获取局域网内所有CopterSim程序的电脑IP列表 +StartCopterID = 1 # 初始飞机的ID号 +TargetIP = req.getSimIpID(StartCopterID) # 获取CopterSim的1号程序所在电脑的IP,作为目标IP +# 注意:如果是本电脑运行的话,那TargetIP是127.0.0.1的本机地址;如果是远程访问,则是192打头的局域网地址。 +# 因此本程序能同时在本机运行,也能在其他电脑运行。 + +VehilceNum = 1 +MavList=[] +# Create MAV instance +for i in range(VehilceNum): + CopterID=StartCopterID+i # 当前配置的飞机序号 + TargetIP = req.getSimIpID(CopterID) # 获取对应的电脑IP + req.sendReSimIP(CopterID) # 请求回传数据到本电脑 + time.sleep(1) + MavList = MavList+[PX4MavCtrl.PX4MavCtrler(CopterID,TargetIP)] # 初始化并建立i号飞机的MAVLink通信连接 + +time.sleep(2) +# Start MAV loop with UDP mode: MAVLINK_FULL +for i in range(VehilceNum): + MavList[i].InitMavLoop() + +# Enter Offboard mode to start vehicle control +time.sleep(2) +for i in range(VehilceNum): + MavList[i].initOffboard() + +# Get the takeoff position of each vehicle to the UE4 Map +# this can be adopted to obtain the global position of a vehicle in swarm simulation +time.sleep(2) +Error2UE4Map=[] +for i in range(VehilceNum): + mav=MavList[i] + Error2UE4Map = Error2UE4Map+[-np.array([mav.uavGlobalPos[0]-mav.uavPosNED[0],mav.uavGlobalPos[1]-mav.uavPosNED[1],mav.uavGlobalPos[2]-mav.uavPosNED[2]])] + +# fly to 10m high above its takeoff position +for i in range(VehilceNum): + MavList[i].SendPosNED(0, 0, -10, 0) +time.sleep(10) + + +lastTime = time.time() +startTime = time.time() +timeInterval = 1/30.0 #here is 0.0333s (30Hz) +while True: + lastTime = lastTime + timeInterval + sleepTime = lastTime - time.time() + if sleepTime > 0: + time.sleep(sleepTime) # sleep until the desired clock + else: + lastTime = time.time() + # The following code will be executed 30Hz (0.0333s) + + t=time.time()-startTime + for j in range(VehilceNum): + mav=MavList[j] + + # target position in UE4 map global frame + if t<10: + targetPosE=np.array([-0,0,-15]) # fly to 15 meters high in 0 to 10s + else: #fly circle after 10s + targetPosE=np.array([10*math.sin(t/2+math.pi/2)-10,10*math.sin(t/2.0),-15]) + + # target position in vehilce takeoff frame + targetPosE=targetPosE+Error2UE4Map[j] + mav.SendPosNED(targetPosE[0],targetPosE[1],targetPosE[2],0) + + if t>200: # end simulation when 200s + break + + +for i in range(VehilceNum): + MavList[i].endOffboard() + +time.sleep(1) +for i in range(VehilceNum): + MavList[i].stopRun() + diff --git a/基础编程/e7.Offboard模式介绍及控制实验/code/Python38Run.bat b/基础编程/e7.Offboard模式介绍及控制实验/code/Python38Run.bat new file mode 100644 index 0000000..ad265a4 --- /dev/null +++ b/基础编程/e7.Offboard模式介绍及控制实验/code/Python38Run.bat @@ -0,0 +1,5 @@ +if not defined PSP_PATH ( + SET PSP_PATH=C:\PX4PSP + SET PSP_PATH_LINUX=/mnt/c/PX4PSP +) +start cmd.exe /k "echo Python3.8 environment has been set with openCV+pymavlink+numpy+pyulog etc. && echo You can use pip or pip3 command to install other libraries && echo Put Python38Run.bat into your code folder && echo Use the command: 'python XXX.py' to run the script with Python && SET PATH=%PSP_PATH%\Python38;%PSP_PATH%\Python38\Scripts;%CD%;%PATH%" diff --git a/基础编程/e7.Offboard模式介绍及控制实验/code/SITLRun.bat b/基础编程/e7.Offboard模式介绍及控制实验/code/SITLRun.bat new file mode 100644 index 0000000..fa8fcf7 --- /dev/null +++ b/基础编程/e7.Offboard模式介绍及控制实验/code/SITLRun.bat @@ -0,0 +1,171 @@ +@ECHO OFF + +REM Run script as administrator +%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c ""%~s0"" ::","","runas",1)(window.close)&&exit + + +REM The text start with 'REM' is annotation, the following options are corresponding to Options on CopterSim + +REM Set the path of the RflySim tools +if not defined PSP_PATH ( + SET PSP_PATH=E:\PX4PSP + SET PSP_PATH_LINUX=/mnt/e/PX4PSP +) + +REM Start index of vehicle number (should larger than 0) +REM This option is useful for simulation with multi-computers +SET /a START_INDEX=1 + +REM Total vehicle Number to auto arrange position +REM SET /a TOTOAL_COPTER=8 + +REM Set the vehicleType/ClassID of vehicle 3D display in RflySim3D +SET /a CLASS_3D_ID=-1 + +REM Set use DLL model name or not, use number index or name string +REM This option is useful for simulation with other types of vehicles instead of multicopters +set DLLModel=0 + +REM Check if DLLModel is a name string, if yes, copy the DLL file to CopterSim folder +SET /A DLLModelVal=DLLModel +if %DLLModelVal% NEQ %DLLModel% ( + REM Copy the latest dll file to CopterSim folder + copy /Y "%~dp0"\%DLLModel%.dll %PSP_PATH%\CopterSim\external\model\%DLLModel%.dll +) + +REM Set the simulation mode on CopterSim, use number index or name string +REM e.g., SimMode=2 equals to SimMode=PX4_SITL_RFLY +set SimMode=2 + +REM Set the vehicle-model (airframe) of PX4 SITL simulation, the default airframe is a quadcopter: iris +REM Check folder Firmware\ROMFS\px4fmu_common\init.d-posix for supported airframes (Note: You can also create your airframe file here) +REM E.g., fixed-wing aircraft: PX4SitlFrame=plane; small cars: PX4SitlFrame=rover +set PX4SitlFrame=iris + + +REM Set the map, use index or name of the map on CopterSim +REM e.g., UE4_MAP=1 equals to UE4_MAP=Grasslands +SET UE4_MAP=Grasslands + +REM Set the origin x,y position (m) and yaw angle (degree) at the map +SET /a ORIGIN_POS_X=0 +SET /a ORIGIN_POS_Y=0 +SET /a ORIGIN_YAW=0 + +REM Set the interval between two vehicle, unit:m +SET /a VEHICLE_INTERVAL=2 + + +REM Set broadcast to other computer; IS_BROADCAST=0: only this computer, IS_BROADCAST=1: broadcast; +REM or use IP address to increase speed, e.g., IS_BROADCAST=192.168.3.1 +REM Note: in IP mode, IS_BROADCAST=0 equals to IS_BROADCAST=127.0.0.1, IS_BROADCAST=1 equals to IS_BROADCAST=255.255.255.255 +REM You can also use a IP list with seperator "," or ";" to specify IPs to send, e.g., 127.0.0.1,192.168.1.4,192.168.1.5 +SET IS_BROADCAST=0 + +REM Set UDP data mode; 0: UDP_FULL, 1:UDP_Simple, 2: Mavlink_Full, 3: Mavlink_simple. input number or string +REM 4:Mavlink_NoSend, 5:Mavlink_NoGPS, 6:Mavlink_Vision (NoGPS and set PX4 EKF) +SET UDPSIMMODE=Mavlink_Full + + +:Top +ECHO. +ECHO --------------------------------------- +REM Max vehicle number 50 +SET /a MAX_VEHICLE=50 +SET /P VehicleNum=Please input UAV swarm number: +SET /A Evaluated=VehicleNum +if %Evaluated% EQU %VehicleNum% ( + IF %VehicleNum% GTR 0 ( + IF %VehicleNum% GTR %MAX_VEHICLE% ( + ECHO The vehicle number is too large, which may cause a crash + pause + ) + GOTO StartSim + ) + ECHO Not a positive integer + GOTO Top +) ELSE ( + ECHO Not a integer + GOTO Top +) +:StartSim + +SET /A VehicleTotalNum=%VehicleNum% + %START_INDEX% - 1 +if not defined TOTOAL_COPTER ( + SET /A TOTOAL_COPTER=%VehicleTotalNum% +) + +set /a sqrtNum=1 +set /a squareNum=1 +:loopSqrt +set /a squareNum=%sqrtNum% * %sqrtNum% +if %squareNum% EQU %TOTOAL_COPTER% ( + goto loopSqrtEnd +) +if %squareNum% GTR %TOTOAL_COPTER% ( + goto loopSqrtEnd +) +set /a sqrtNum=%sqrtNum%+1 +goto loopSqrt +:loopSqrtEnd + + +REM QGCPath +tasklist|find /i "QGroundControl.exe" || start %PSP_PATH%\QGroundControl\QGroundControl.exe -noComPix +ECHO Start QGroundControl + +REM UE4Path +cd /d %PSP_PATH%\RflySim3D +tasklist|find /i "RflySim3D.exe" || start %PSP_PATH%\RflySim3D\RflySim3D.exe +choice /t 5 /d y /n >nul + + +tasklist|find /i "CopterSim.exe" && taskkill /im "CopterSim.exe" +ECHO Kill all CopterSims + + +REM CptSmPath +cd /d %PSP_PATH%\CopterSim + + +set /a cntr=%START_INDEX% +set /a endNum=%VehicleTotalNum%+1 + +:loopBegin +set /a PosXX=((%cntr%-1) / %sqrtNum%)*%VEHICLE_INTERVAL% + %ORIGIN_POS_X% +set /a PosYY=((%cntr%-1) %% %sqrtNum%)*%VEHICLE_INTERVAL% + %ORIGIN_POS_Y% +start /realtime CopterSim.exe 1 %cntr% %CLASS_3D_ID% %DLLModel% %SimMode% %UE4_MAP% %IS_BROADCAST% %PosXX% %PosYY% %ORIGIN_YAW% 1 %UDPSIMMODE% +choice /t 1 /d y /n >nul +set /a cntr=%cntr%+1 + +if %cntr% EQU %endNum% goto loopEnd +goto loopBegin +:loopEnd + +REM Set ToolChainType 1:Win10WSL 3:Cygwin +SET /a ToolChainType=1 + +if "%IS_BROADCAST%" == "0" ( + SET IS_BROADCAST=0 +) else ( + SET IS_BROADCAST=1 +) + +SET WINDOWSPATH=%PATH% +if %ToolChainType% EQU 1 ( + wsl -d RflySim-20.04 echo Starting PX4 Build; cd %PSP_PATH_LINUX%/Firmware; ./BkFile/EnvOri.sh; export PATH=$HOME/ninja:$HOME/gcc-arm-none-eabi-7-2017-q4-major/bin:$PATH;make px4_sitl_default; ./Tools/sitl_multiple_run_rfly.sh %VehicleNum% %START_INDEX% %PX4SitlFrame%;echo Press any key to exit; read -n 1 +) else ( + REM CYGPath + cd /d %PSP_PATH%\CygwinToolchain + CALL setPX4Env.bat + bash -l -i -c 'echo Starting SITL SIMULATION; cd %PSP_PATH_LINUX%/Firmware; ./BkFile/EnvOri.sh; pwd; make px4_sitl_default; ./Tools/sitl_multiple_run_rfly.sh %VehicleNum% %START_INDEX% %PX4SitlFrame%;echo Press any key to exit; read -n 1; pkill -x px4 || true;' +) +SET PATH=%WINDOWSPATH% + + +REM kill all applications when press a key +tasklist|find /i "CopterSim.exe" && taskkill /im "CopterSim.exe" +tasklist|find /i "QGroundControl.exe" && taskkill /f /im "QGroundControl.exe" +tasklist|find /i "RflySim3D.exe" && taskkill /f /im "RflySim3D.exe" + +ECHO Start End.