# 이륙하기(MAV\_CMD\_NAV\_TAKEOFF)

이번 시간에는 COMMAND\_LONG 메시지를 이용하여 드론을 이륙하는 MAV\_CMD 명령에 대해 알아 보겠습니다.

드론을 이륙시키기 위해서는 MAV\_CMD\_NAV\_TAKEOFF ([22](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_TAKEOFF) ) 명령을 사용 합니다.

## MAV\_CMD\_NAV\_TAKEOFF 전문

| 파라메터         | 설명                                                                                                                                                                     | 단위  |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- |
| 1: Pitch     | Minimum pitch (if airspeed sensor present), desired pitch without sensor                                                                                               | deg |
| 2            | Empty                                                                                                                                                                  |     |
| 3            | Empty                                                                                                                                                                  |     |
| 4: Yaw       | Yaw angle (if magnetometer present), ignored without magnetometer. NaN to use the current system yaw heading mode (e.g. yaw towards next waypoint, yaw to home, etc.). | deg |
| 5: Latitude  | Latitude                                                                                                                                                               |     |
| 6: Longitude | Longitude                                                                                                                                                              |     |
| 7: Altitude  | Altitude                                                                                                                                                               | m   |

## 비행 모드 변경

이륙에 앞서 비행모드를 수동 모드가 아닌 GUIDED 모드로 변경 하여야 합니다.

비행 모드 변경 역시 [MAV\_CMD의 MAV\_CMD\_DO\_SET\_MODE (176 )](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE) 명령을 사용하여 변경 합니다.

[FLTMODE1: Flight Mode 1](https://ardupilot.org/copter/docs/parameters.html#fltmode1)의 값을 4(GUIDED)로 주어야 합니다.

```python
# change MODE to GUIDED into COMMAND_LONG
the_connection.mav.command_long_send(the_connection.target_system, the_connection.target_component, 
                                     mavutil.mavlink.MAV_CMD_DO_SET_MODE, 0, 1, 
                                     4, 0, 0, 0, 0, 0)
```

### 이륙 명령

```python
# Takeoff COMMAND_LONG
the_connection.mav.command_long_send(the_connection.target_system, the_connection.target_component, 
                                     mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, 10)
```

이전 시간에 작성한 arm.py 프로그램에 위의 코드를 추가하고 takeoff.py 이름으로 저장한후 실행해 보겠습니다.

```python
from pymavlink import mavutil
import time

# Start a connection listening on a UDP port
# UDP 14550 for primary GSC
#the_connection = mavutil.mavlink_connection('udpin:localhost:14550')
#for ArduPilot
#the_connection = mavutil.mavlink_connection('tcp:localhost:5763')
#for PX4-SITL
the_connection = mavutil.mavlink_connection('udp:localhost:14540')

# Wait for the first heartbeat 
#   This sets the system and component ID of remote system for the link
the_connection.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (the_connection.target_system, the_connection.target_component))

# change MODE to GUIDED into COMMAND_LONG
the_connection.mav.command_long_send(the_connection.target_system, the_connection.target_component, 
                                     mavutil.mavlink.MAV_CMD_DO_SET_MODE, 0, 1, 
                                     4, 0, 0, 0, 0, 0)

# check response COMMAND_ACK
msg = the_connection.recv_match(type='COMMAND_ACK', blocking=True)
print(msg)

# Arming COMMAND_LONG
the_connection.mav.command_long_send(the_connection.target_system, the_connection.target_component, 
                                     mavutil.mavlink.MAV_CMD_COMPONENT_ARM_DISARM, 0, 1, 0, 0, 0, 0, 0, 0)
# check response COMMAND_ACK
msg = the_connection.recv_match(type='COMMAND_ACK', blocking=True)
print(msg)

time.sleep(3)

target_altitude = 10

# Takeoff COMMAND_LONG
the_connection.mav.command_long_send(the_connection.target_system, the_connection.target_component, 
                                     mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 0, 0, 0, 0, 0, 0, target_altitude)

# check response COMMAND_ACK
msg = the_connection.recv_match(type='COMMAND_ACK', blocking=True)
print(msg)
```

실행결과는 다음과 같습니다.

```
$ python3 takeoff.py 
Heartbeat from system (system 1 component 0)
COMMAND_ACK {command : 176, result : 0, progress : 0, result_param2 : 0, target_system : 255, target_component : 0}
COMMAND_ACK {command : 400, result : 0, progress : 0, result_param2 : 0, target_system : 255, target_component : 0}
COMMAND_ACK {command : 22, result : 0, progress : 0, result_param2 : 0, target_system : 255, target_component : 0}
```

<figure><img src="https://content.gitbook.com/content/yrhT8fUTtAhJoq98NeDs/blobs/9Xg8g3idJvp0iEY9uq3A/image.png" alt=""><figcaption></figcaption></figure>

드론의 비행 모드가 GUIDED 모드로 변경후 정상적으로 10m 고도로이륙한 것을 볼 수 있습니다.

### \[참고]PX4 플라이트 모드 종류 및 설정

상수값 참고

```
Manual: base_mode:217, main_mode:1, sub_mode:0
Stabilized: base_mode:209, main_mode:7, sub_mode:0
Acro: base_mode:209, main_mode:5, sub_mode:0
Rattitude: base_mode:193, main_mode:8, sub_mode:0
Altitude: base_mode:193, main_mode:2, sub_mode:0
Offboard: base_mode:209, main_mode:6, sub_mode:0
Position: base_mode:209, main_mode:3, sub_mode:0
Hold: base_mode:217, main_mode:4, sub_mode:3
Missition: base_mode:157, main_mode:4, sub_mode:4
Return: base_mode:157, main_mode:4, sub_mode:5
Follow me: base_mode:157, main_mode:4, sub_mode:8
```

아래는기체가 일정 고도에 도달했는지 확인하는 방법 입니다.

```python
# 기체의 최대 고도(meter)
target_altitude = 10

# 최대 고도에 도달할 때까지 반복
while True:
    # MSG_ID_GLOBAL_POSITION_INT (33)로부터 GPS 고도 정보 수신
    msg = master.recv_match(type='GLOBAL_POSITION_INT', blocking=True)

    # GPS_AP보다 GLOBAL_POSITION_INT를 이용하는 것을 추천
    # msg = master.recv_match(type='ALTITUDE', blocking=True)

    if not msg:
        continue

    # 기체의 현재 고도(meter)
    current_altitude = msg.relative_alt / 1000.0 # 1cm 단위이므로 1000으로 나누어 meter로 변환

    # 현재 고도 출력
    print(f"Altitude: {current_altitude:.2f}m")

    # 최대 고도 도달 확인
    if current_altitude >= target_altitude:
        print(f"Reached target altitude of {target_altitude}m")
        break

    time.sleep(1)
```

### \[참고] PX4 Offboard 플라이트 모드 설정

```bash
param1: VEHICLE_MODE_FLAG_CUSTOM_MODE_ENABLED (1, see commander/commander.cpp)
param2: PX4_CUSTOM_MAIN_MODE_OFFBOARD (6, see commander/px4_custom_mode.h)
```
