async def print_z_velocity(drone):
async for odom in drone.telemetry.position_velocity_ned():
print(f"{odom.velocity.north_m_s} {odom.velocity.down_m_s}")
asyncio.ensure_future(print_z_velocity(drone))
asyncio는 저사양 PC에서는 에러가 발생할 수 있습니다.
10m 고도로 이륙
print("-- Go 0m North, 0m East, -10m Down within local coordinate system")
await drone.offboard.set_position_velocity_ned(
PositionNedYaw(0.0, 0.0, -10.0, 0.0),
VelocityNedYaw(0.0, 0.0, -1.0, 0.0))
위에서와 같이 PositionNedYaw, VelocityNedYaw를 이용해 방향과 거리, 속도(Feed-Forward)를 동시에 줄 수 있습니다.
Feed-Forward:
PX4 포지션 컨트롤러에서의 '피드-포워드(feed-forward)'는 제어 시스템에서 목표값을 더 빠르고 정확하게 달성하기 위해 사용되는 기법입니다. 이 방법은 예상되는 시스템의 동작이나 외부에서 주어지는 명령을 미리 고려하여 제어 신호에 반영하는 것을 말합니다. 즉, 현재의 오차값만을 기반으로 한다면 '피드백' 제어인 반면, 피드-포워드는 미래의 목표 상태나 외부 조건 변화를 미리 반영하여 제어 효율을 개선하는 방식입니다.
PX4에서는 드론의 위치 제어에 있어서 피드-포워드를 사용하여 명령된 속도나 가속도를 직접 제어 신호에 더함으로써, 목표 위치에 더 정확하고 빠르게 도달할 수 있도록 합니다. 예를 들어, 드론이 특정 방향으로 가속해야 할 때, 피드-포워드 값을 사용하면 드론은 명령에 따른 가속도를 미리 고려하여 더 부드럽고 신속하게 목표 속도에 도달할 수 있습니다.
피드-포워드 제어는 특히 동적 환경에서의 성능을 개선하는데 유용합니다. 예를 들어, 앞으로 나아가기 위해 가속해야 하는 경우, 피드-포워드 제어는 필요한 가속도를 제어 신호에 미리 반영함으로써, 드론이 보다 정확하게 원하는 위치와 속도에 도달하게 합니다. 이는 피드백 제어만 사용할 때보다 더 빠른 응답과 높은 정밀도를 가능하게 합니다.
단, 피드-포워드 제어를 효과적으로 사용하기 위해서는 시스템의 동적 특성을 잘 이해하고, 적절한 피드-포워드 값을 설정하는 것이 중요합니다. 잘못된 값을 사용하면 오히려 성능 저하를 초래할 수 있습니다. 따라서, 피드-포워드 값을 적용할 때는 시스템의 동적 모델을 바탕으로 신중하게 조정해야 합니다.
전체 코드
offboard_position_velocity_ned.py
#!/usr/bin/env python3
import asyncio
from mavsdk import System
from mavsdk.offboard import (PositionNedYaw, VelocityNedYaw, OffboardError)
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(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
print("-- Arming")
await drone.action.arm()
print("-- Setting initial setpoint")
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
async def print_z_velocity(drone):
async for odom in drone.telemetry.position_velocity_ned():
print(f"{odom.velocity.north_m_s} {odom.velocity.down_m_s}")
asyncio.ensure_future(print_z_velocity(drone))
print("-- Go 0m North, 0m East, -10m Down within local coordinate system")
await drone.offboard.set_position_velocity_ned(
PositionNedYaw(0.0, 0.0, -10.0, 0.0),
VelocityNedYaw(0.0, 0.0, -1.0, 0.0))
await asyncio.sleep(10)
print("-- Go 10m North, 0m East, 0m Down within local coordinate system")
await drone.offboard.set_position_velocity_ned(
PositionNedYaw(50.0, 0.0, -10.0, 0.0),
VelocityNedYaw(1.0, 0.0, 0.0, 0.0))
await asyncio.sleep(20)
await drone.action.land()
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())