Util
Drone HITL 환경 구축
Limetime
2025. 1. 20. 23:26
반응형
우분투 개발 환경 | PX4 Guide (main)
docs.px4.io
This include : Gazebo, Gazebo Classic, jMAVSim, Pixhawk and other NuttX-based hardware
Simulation and NuttX (Pixhawk) Targets
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
bash ./PX4-Autopilot/Tools/setup/ubuntu.sh
- 최초 빌드 (jMAVSim 시뮬레이션 활용)
cd PX4-Autopilot
make px4_sitl jmavsim
- gazebo-classic
make px4_sitl gazebo-classic
HITL
px4 autopilot 설치하고 QGC도 설치하고..
$ sudo usermod -a -G dialout $USER
$ sudo apt-get remove modemmanager -y
$ sudo apt-get install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y
$ sudo apt-get install libfuse2 -y
$ sudo apt-get install libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor0 -y
wget "https://d176tv9ibo4jno.cloudfront.net/latest/QGroundControl.AppImage"
$ chmod +x ./QGroundControl.AppImage
(or) $ chmod 777 ./QGroundControl.AppImage
$ ./QGroundControl.AppImage (or Double Click)
QGC
Hardware in the Loop Simulation (HITL) | PX4 Guide (main)
docs.px4.io
cd PX4-Autopilot/
DONT_RUN=1 make px4_sitl_default gazebo
- Gazebo로 할 때
source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
gazebo Tools/simulation/gazebo-classic/sitl_gazebo-classic/worlds/hitl_iris.world
- jmavsim으로 할 때
./Tools/simulation/jmavsim/jmavsim_run.sh -q -s -d /dev/ttyACM0 -b 921600 -r 250
- test.py
#!/usr/bin/env python3
import asyncio
from mavsdk import System
async def run():
#드론 객체 정의
drone = System()
#드론 연결
#await drone.connect(system_address="udp://:14540")
await drone.connect(system_address="serial:///dev/ttyACM0:57600")
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...")
async for health in drone.telemetry.health():
if health.is_global_position_ok and health.is_home_position_ok:
print("-- Global position estimate OK")
break
#드론을 사용하기 위한 Arm 수행
print("-- Arming")
await drone.action.arm()
#드론 이륙
print("-- Taking off")
await drone.action.takeoff()
#이륙 후 잠시 대기
await asyncio.sleep(20)
#드론 착륙
print("-- Landing")
await drone.action.land()
if __name__ == "__main__":
# Run the asyncio loop
asyncio.run(run())
- test2.py
from mavsdk import System
import asyncio
async def run():
drone = System()
await drone.connect(system_address="serial:///dev/ttyACM0:921600") # 실제 하드웨어 포트로 수정
print("Waiting for drone to connect...")
async for state in drone.core.connection_state():
if state.is_connected:
print(f"Drone discovered with UUID: {state.uuid}")
break
print("-- Arming")
await drone.action.arm()
# 추가: 드론 상태 확인 및 초기화
async for health in drone.telemetry.health():
if health.is_global_position_ok and health.is_home_position_ok:
print("Drone health checks passed")
break
print("Waiting for health checks to pass...")
await asyncio.sleep(1)
print("-- Taking off")
try:
await drone.action.takeoff()
except Exception as e:
print(f"Takeoff failed: {e}")
await asyncio.sleep(10)
print("-- Landing")
await drone.action.land()
if __name__ == "__main__":
asyncio.run(run())
드론 위치 이동 문제 해결
안되는 이유 : Failsafe mode가 작동 중이어서…
뭔 소린가?
우린 드론과 jmavsim 단 둘이 통신하기 때문에 조종기가 없다.
그런데, RC(Remote Controller??)가 없을 때, Failsafe가 enable되고 Return mode라는 액션을 취해서 걍 자기 혼자 집으로 돌아가버리는 것.
그럼 어케 해야되느냐
RC를 쓰지말고 오직 조이스틱으로 설정을 바꿔주게 되면 ‘Radio’항목의 빨간색도 안뜨고 잘된다.
그럼 이제 드론은 집에 안간다.
근데,, 문제는 QGC를 켰을 땐, joystick이 작동해서 코드가 잘 작동하지만
QGC를 켜지 않았을 경우 Failsafe enabled: No manual control stick input 에러가 뜨기 때문에 코드가 작동하지 않음..
히히.. 해결책을 갖고 돌아왔다구
해결책
Parameter Reference | PX4 Guide (main)
docs.px4.io
- QGC를 켠다
- COM_RC_IN_MODE 파라미터를 다시 원상복구 한다. (사실 RC Transmit만 되면 된다.)
- RC Transmit only
- RC or joystic
- 근데 사실.. 별로 중요하지 않은 것 같다.
- 이제 당연히 RC 조종기가 없으니 Radio 항목에는 빨간색이 들어오고 failsafe trigger가 작동할거다.
- 하지만 우리에겐 해결책이 있지..
- COM_RCL_EXCEPT 파라미터의 값을 0으로 강제로 바꿔준다.
- Advanced settings → Manual Entry를 체크하고 4를 입력한다.
- 그러고 save
- 잘될거다.
- failsafe는 동작하지만, RC Loss에 대한 failsafe action은 none으로 작동하지 않는다. (무시)
그렇다. failsafe action이 문제였던 것이다.
- test3.py
import asyncio
from mavsdk import System
from mavsdk.offboard import OffboardError, PositionNedYaw
async def run():
drone = System()
await drone.connect(system_address="udp://:14540")
print("Waiting for drone to connect...")
async for state in drone.core.connection_state():
if state.is_connected:
print("Drone discovered!")
break
print("-- Arming")
await drone.action.arm()
print("-- Taking off")
await drone.action.takeoff()
await asyncio.sleep(5) # 드론이 이륙하는 시간을 충분히 대기
print("-- Setting initial setpoint")
await drone.offboard.set_position_ned(PositionNedYaw(0.0, 0.0, -2.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
await asyncio.sleep(2) # Offboard 모드 전환 전에 일정 시간 대기
print("-- Go 10m North, 10m East, 5m Down within local coordinate system")
# 이동 명령을 지속적으로 보내는 task를 생성합니다.
async def send_move_setpoint():
while True:
await drone.offboard.set_position_ned(PositionNedYaw(10.0, 10.0, -7.0, 0.0))
await asyncio.sleep(0.1)
move_setpoint_task = asyncio.create_task(send_move_setpoint())
await asyncio.sleep(10) # 드론이 목표 위치로 이동할 시간을 충분히 대기
# Move setpoint task를 종료합니다.
move_setpoint_task.cancel()
try:
await move_setpoint_task
except asyncio.CancelledError:
pass
print("-- Stopping offboard")
try:
await drone.offboard.stop()
except OffboardError as error:
print(f"Stopping offboard mode failed with error code: {error._result.result}")
print("-- Landing")
await drone.action.land()
# 드론이 착륙할 때까지 대기
print("Waiting for drone to land...")
async for in_air in drone.telemetry.in_air():
if not in_air:
print("Drone has landed")
break
print("-- Disarming")
try:
await drone.action.disarm()
except Exception as e:
print(f"Disarming failed: {e}")
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
내용 정리
QGC없이 jmavsim이랑 연결해서 진행되어야 함.
단, 펌웨어 설치 및 파라미터를 건드려야 하므로 QGC 개입이 필수다.
- QGC에 가면 Firmware를 설치할 수 있다. (PX4 Pro를 설치하면 된다.)
- 단, PX4 Pro 1.4.3은 Landoff detect 후 아무일도 일어나지 않는 이슈가 있다.
- 그래서 1.3.3으로 다운받아야 한다. (orange_cube버전으로)
- QGC에서 HITL을 설정하고 air frame도 simulation의 quadroater?로 설정한다.
- offboard 관련 명령어 특히, ned 좌표 이동 관련 함수가 작동하지 않는 이슈가 있었다.
- 이유는 RC(Remote Controller?)의 부재로 인한 failsafe action 작동이다.
- 이 경우 RC Loss로 인한 failsafe action을 무시하는 파라미터를 설정하면 된다.
- QGC→ parameters → COM_RCL_EXCEPT=4
- 끝.
반응형