MAVLINK 메시지 주고받기

저작권: 쿼드(QUAD) 드론연구소 https://www.youtube.com/@quad-robotics

메시지 보내기

MAVLink주요 프로토콜 처리 클래스입니다. 각 다이알렉트 모듈에서 정의되며 <message_name>_send()의 형식으로 메시지 정의 에 있는 모든 메시지에 대한 메소드를 포함합니다 .

메시지 필드 값은 함수에 대한 인수로 전달됩니다. 모든 메시지에 대해 동일한 필드는 클래스(예: 소스 시스템, 소스 구성 요소)에서 정의됩니다. 각 메시지는 자동으로 생성된 경우에도 다이알렉트 소스 코드에 문서화됩니다 .

예를 들어 system_time_send() 이 함수는 아래와 같이 SYSTEM_TIME 메시지를 보내는 데 사용됩니다 .

def system_time_send(self, time_unix_usec, time_boot_ms, force_mavlink1=False):
    '''
    The system time is the time of the master clock, typically the
    computer clock of the main onboard computer.

    time_unix_usec    : Timestamp (UNIX epoch time). (uint64_t)
    time_boot_ms      : Timestamp (time since system boot). (uint32_t)
    '''

링크 관리에 mavutil을 사용하는 경우 mav속성은 메시지 전송에 사용할 수 있는 구성된 클래스 개체에 대한 액세스를 제공합니다. 예를 들어 the_connection 이라는 MAVLink링크를 사용하여 SYSTEM_TIME메시지를 보내려면 다음과 같이 하십시오 .

the_connection.mav.system_time_send(time_unix_usec, time_boot_ms)

mavutil을 사용하지 않는 경우 MAVLink속성으로 표시되는 메시지 전송에 사용해야 하는 채널에 대해 알 수 있도록 개체를 직접 만들고 설정해야 합니다.

메시지 수신하기

수신된 특정 유형의 마지막 메시지에 동기식으로 액세스하고 수신된 경우 mavutil.messages 속성을사용하여 액세스할 수 있습니다. 예를 들어 the_connection 이라는 mavutil 링크를 사용하는 경우 다음을 수행할 수 있습니다.

try: 
    altitude = the_connection.messages['GPS_RAW_INT'].alt  # Note, you can access message fields as attributes!
    timestamp = the_connection.time_since('GPS_RAW_INT')
    print("Current Alt is %dm" % (altitude/1000))
except:
    print('No GPS_RAW_INT message received')

또는 mavutil recv_match() 메서드를 사용하여 메시지가 도착할 때까지 기다렸다가 가로챌 수 있습니다.

def recv_match(self, condition=None, type=None, blocking=False, timeout=None):
    '''Receive the next MAVLink message that matches the given type and condition
    type:        Message name(s) as a string or list of strings - e.g. 'SYS_STATUS'
    condition:   Condition based on message values - e.g. 'SYS_STATUS.mode==2 and SYS_STATUS.nav_mode==4'
    blocking:    Set to wait until message arrives before method completes. 
    timeout:     ? <!-- timeout for blocking message when the system will return. Is this just a time? -->
    '''

예를 들어 다음과 같이 메시지를 기다릴 수 있습니다 . (blocking=False는 기다리지 않음)

msg = the_connection.recv_match(blocking=True)

대신 특정 속성 값(SYS_STATUS)이 있는 특정 메시지를 얻으려면 대신 다음을 수행할 수 있습니다.

# Wait for a 'SYS_STATUS' message with the specified values.
msg = the_connection.recv_match(type='SYS_STATUS', blocking=True)

또한 메시지를 사용하기 전에 메시지가 유효한지 확인해야 합니다.

msg = the_connection.recv_match(type='SYS_STATUS',blocking=True)

if msg.get_type() == "BAD_DATA":
    if mavutil.all_printable(msg.data):
        sys.stdout.write(msg.data)
        sys.stdout.flush()
else:
    #Message is valid
    # Use the attribute
    print('Status: %s' % msg.battery_remaining)

MAVLink_message반환된 개체는 특정 메시지에 대한 하위 클래스입니다. 위의 코드 단편에서 모드에 대해 표시된 것처럼 클래스 속성으로 메시지 필드에 액세스할 수 있습니다. 필요한 경우 MAVLink_message서명, CRC 및 기타 헤더 정보에 대한 정보를 쿼리할 수 있습니다.

특정 메시지 요청

원격 시스템은 일반적으로 연결된 GCS, 카메라 또는 기타 시스템에 기본 메시지 집합을 스트리밍합니다. 이 기본 세트는 하드 코딩될 수 있으며 채널의 트래픽을 줄이기 위해 필연적으로 제한됩니다.

일반적으로 시스템은 필요한 스트림( MAV_DATA_STREAM ) 및 속도를 지정하는 REQUEST_DATA_STREAM 메시지를 전송하여 추가 정보를 제공하도록 요청할 수도 있습니다.

메시지는 다음을 사용하여 전송됩니다 request_data_stream_send()(아래 arg.rate는 원하는 전송 속도 Hz 임).

# Request all data streams
the_connection.mav.request_data_stream_send(the_connection.target_system, the_connection.target_component,
                                        mavutil.mavlink.MAV_DATA_STREAM_ALL, args.rate, 1)