본문 바로가기
공부이야기/아두파일럿

아두파일럿 개발 #2

by 헝탱 2017. 12. 29.
반응형

해당 게시글에 적는 모든 내용이 진실이 아닐 수 있으며 틀린 내용도 엄청 많을 수도 있습니다. 개발 과정을 기록해 개인적인 개발 기록을 남기기 위해 글을 적는다.


아두파일럿 준비물

저번 내용 http://yourpresence.tistory.com/198 에서 이미 적었지만 필수 내용이 있고 그 외 기타 필요 물품이 있으며 개발에 있어서 필요한 IDE도 있으니 이번 글에서 사용하는 부품들의 목록을 알려드리겠습니다.


1. Pixhawk2.1 

2. Silicon Labs CP210x USB to UART Bridge -> 다른 제품 대체가능

3. 비주얼 스튜디오 C#

4. mavlink.net 라이브러리


이렇게 4가지를 준비하시면 완전 기본적인 데이터를 받고 정의하는 부분이 사용 가능합니다. 



아두파일럿 MAVLINK

아두파일럿은 내부 내장 소스인 아두파일럿이 있고 원격으로 미션 내용을 전달하거나 명령을 보낼 때 사용하는 mavlink가 있습니다. mavlink는 프로콜로 아두파일럿이 인식 할 수 있는 신호를 패킷을 재정의 해주는 프로그램이라고 볼 수 있습니다. C++을 사용하실줄 아시거나 잘하시는 분들은 아두파일럿에서 지원하는 걸 가져다 쓰시면 됩니다. 가장 메인에 있는 mavlink는 c++를 중심으로 만들어졌고 인터페이스도 C++로 잘 만들어졌기 때문에 공식 지원하시는걸 쓰시면 됩니다.


그리고 저는 c#을 준비하라고 했는데요. c#은 깃허브에 "dsuarezv"라는 분이 인터페이스를 만들어서 줬습니다. https://github.com/dsuarezv/mavlink.net 로 들어가서 받으시면 되는데 최신버전을 받아서 빌드하면 DLL이 만들어지고 DLL을 가지고 사용하시면 됩니다. (최신버전 SendMessage 부분 인터페이스 오류가 있지만 우선은 최신버전을 가져와서 사용해 봅시다.)



1. Mavlink.net은 인터페이스가 정의된 프로젝트로 여기서 DLL이 만들어 집니다.

2. 아두파일럿에서 제공하는 XML파일을 c#의 형식으로 변경을 해주는 프로젝트로 빌드하고 난뒤에 나온 파일을 사용함


우선 전부 빌드를 하신 다음에 최신버전의 XML을 원하신다면 ""에서 v1.0안에 있는 파일들을 자신이 원하는 공간에 넣어 두시면 됩니다.

그리고  CMD(명령 프롬프트)를 실행 하셔서 아래의 형식에 맞게 입력하시면 됩니다.


mavlinkgen --output="앞 경로 입력\mavlink.net\GeneratedMessages.cs" "XML이 있는 파일 경로 입력\v1.0\ardupilotmega.xml"

이렇게 입력하시면 mavlink.net에 GeneratedMessages.cs 파일이 새로 생성됩니다. 그리고 mavlink.net 프로젝트를 빌드하면 빌드 위치에 mavlink.net.DLL이 생성됩니다.

생성된 DLL을 참고해서 사용하시면 됩니다.



아두파일럿 MAVLINK 사용법 (신호 받기)

mavlink는 아두파일럿과 통신하는 프로토콜입니다. 이걸 쉽게 사용하기 위해서 위의 DLL을 사용하는 겁니다. UDP를 사용하시는 분들은 UDP인터페이스를 쓰시면 되고 저와 같은 기계를 구매하신 분들은 시리얼 포트를 이용해서 사용하시게 됩니다. 


(1) using MavLinkNet;

- using을 이용해서 사용할 DLL를 선언해주셔도 되고 안해도 상관없지만 클래스에서 많이 사용하신다면 선언해주세요.


(2) private MavLinkSerialPortTransport serialPort = new MavLinkSerialPortTransport();

- 시리얼 포트를 클래스 안에 적어서 객체 할당을 합니다.


(3). 함수에 객체의 정보 입력

1
2
3
4
5
6
7
8
9
public void main(){
 
    this.serialPort.SerialPortName = ComPort;
 
    this.serialPort.BaudRate = BaudRate;
 
    this.serialPort.HeartBeatUpdateRateMs = HeartBeatUpdateRateMs;
 
}
cs

- 가장 기본적으로 입력되는 3가지 정보입니다. 첫번째는 컴포트 이름으로 앞의 글에서 봤던 컴포트를 string형으로 입력해주시면 됩니다. 두번째는 신호 범위인데 이건 57600으로 정해져있는것 같습니다. 만약 다른 텔레메트리를 사용하시면 다른 범위대가 사용될거로 예상됩니다. 세번째는 주기적으로 신호를 보내고 받아오는 기능의 반복 신호 주기인데요. 나중에 mavlink.net에서 이 부분을 다른 내용으로 수정하고 주기를 좀 늦추거나 빠르게 하고 싶을 때 유동적으로 설정이 가능합니다. 설정을 하지 않으면 자동으로 1초로 설정이 됩니다.


(4).  dronCategory.SerialPort.OnPacketReceived += SerialPort_OnPacketReceived;

- 시리얼포트로부터 넘어오는 신호들을 받는 부분입니다. 델리게이트로 구성되어 있어서 이렇게하고 하단에 이것을 받아서 처리하는 함수 부분도 적어서 사용합니다.

1
2
3
4
5
6
7
8
9
//아두파일럿 신호를 받는 곳

private void SerialPort_OnPacketReceived(object sender, MavLinkNet.MavLinkPacket packet)
 
{
 
    [신호를 처리하는 곳]
 
}
cs

여기서 넘어오는 packet은 전부 uasmessage형식으로 넘어오게 됩니다. 인터페이스로 묶여있어서 언패킹을 해야지 자신이 원하는 객체로 변경해서 사용할 수 있습니다. 정확한 명칭은 잘 몰라서 우선 바로 사용방법을 알려드리면 "((UasHeartbeat)packet.Message)" 이런식으로 사용하게 되면 UasHeartbeat를 사용할 수 있도록 언패킹이 됩니다. 이것을 MessageId로 구분해서 사용하면 특정 신호만 구분해서 잡을 수 있습니다.


(5). dronCategory.SerialPort.Initialize();

- 시리얼 포트를 Initialize하는 부분으로 초기화를 하고 시리얼포트 통신을 연결해 시작을 하는 부분입니다.


(6). dronCategory.SerialPort.BeginHeartBeatLoop();

- 위에서 설정한 주기적으로 신호를 보내고 받는 것을 시작하는 함수를 불러옵니다.


위의 6가지를 초기에 설정하게 되면 기본적으로 신호를 받는 부분은 구현이 되었으며 신호를 보낼 준비도 완료된겁니다.



아두파일럿 MAVLINK 사용법 (신호 보내기)

mavlink에서 신호를 보내는 방법은 초기에 할당한 serialPort 에서 SerialPort.SendMessage를 이용해 보내면 됩니다. 보내는 프로토콜의 규칙은 https://mavlink.io/kr/ 에서 확인 할 수 있으며 미션을 입력하는 부분에 대해서 간단하게 예를 들면 아래와 같습니다.


(1). uasMissionCount를 보냄

SendMessage를 통해서 uasMissionCount를 보내면 되는데 자신이 설정한 미션을 리스트나 딕셔너리나 배열에 저장한 다음에 그 안에 있는 카운트 수 만큼 보내야 다음에 아두파일럿에서 첫번째 미션부터 마지막 미션의 번호까지 요청을 보내옵니다. 사용 방법은 아래의 코드와 같습니다.

1
2
3
4
5
6
7
8
//미션 정보 저장을 날림
MavLinkNet.UasMissionCount uasMissionCount = new MavLinkNet.UasMissionCount()
{
    TargetSystem = (byte)1,
    TargetComponent = (byte)1,
    Count = (ushort)arduMissionItems.Count
};
SerialPort.SendMessage(uasMissionCount);
cs

카운트에는 자신의 미션의 개수를 넣으면 신호를 받는 곳에 seq가 0부터 자신의 미션개수 만큼 넘어옵니다. 그리고 일정 시간안에 리퀘스트를 받아서 신호를 보내지 않으면 일정 횟수만큼 다시 재요청을 하게 됩니다. 


(2). uasMissionResquest를 받고 미션을 보내기

- 아래의 코드는 SerialPort_OnPacketReceived에서 오는 신호를 받는 부분입니다.

1
2
3
4
5
6
//uasMissionResquest
else if (packet.Message.MessageId == uasMissionRequest.MessageId)
{
    arduMissionItems[((UasMissionRequest)packet.Message).Seq].Seq = ((UasMissionRequest)packet.Message).Seq;
    SerialPort.SendMessage(dronCategory.arduMissionItems[((UasMissionRequest)packet.Message).Seq]);
}
cs

신호를 받고 언팩킹을 하면 seq이라는 속성값이 나옵니다. 해당 속성 값은 0부터 시작해서 마지막 카운트까지 넘어오게 되며 배열이나 리스트에 저장된 미션이 있다면 미션의 순서대로 불러와서 SendMessageUasMissionItems의 구성된 요소를 보내면 됩니다. UasMissionItems은 아래와 같은 구조를 가지고 있으며 이러한 구조들을 구성해놓은 사이트는 "http://mavlink.org/messages/common"와 "http://ardupilot.org/dev/docs/mavlink-commands.html" 여기에서 확인 할 수 있습니다.

내용을 확인 해보면 seq의 속성은 리퀘스트에서 받은 seq를 받아서 넣으며 됩니다. 기본적으로 적어야하는 속성 값은 아래의 6가지만 넣으면 기본적인 미션의 구성은 가지게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
//미션 포인트 설정 (직선형 미션 진행)
uasMissionItem = new MavLinkNet.UasMissionItem()
{
    TargetSystem = (byte)1,
    TargetComponent = (byte)1,
    Command = MavLinkNet.MavCmd.NavWaypoint,
    X = (float)mission.Waypoints[i].lat,
    Y = (float)mission.Waypoints[i].lon,
    Z = (float)mission.Waypoints[i].alt
};
dronCategory.arduMissionItems.Add(uasMissionItem);
cs

여기서 사용하는 MavCmdenum의 목록은 위의 사이트에서 확인 할 수 있습니다. 이렇게 모든 카운트의 미션을 보내고 나면 UasMissionACK의 값이 넘어와 결과에 대해서 알려주게 됩니다. 이런 방식으로 아두파일럿을 mavlink를 연결해서 신호를 주고 받을 수 있습니다. 여러가지 기능들에 대한 자세한 설명은 다음 편에서 적도록 하겠습니다. 위의 방법은 예를들어서 적은 사용 방법입니다.


마치면서 주의 사항

맨 위에서 CMD로 GeneratedMessages파일을 업데이트 받는 부분을 한게 있는데 이것을 사용해서 업데이트를 하고 DLL을 만들게 되면 사용시 아두파일럿과 통신이 안되는 현상이 있습니다. 이러한 작업을 하지마시고 그냥 내부만 수정해서 사용하시면 정상적으로 이용이 가능할 것 같습니다. 필요한 부분이 있다면 직접 추가해서 사용하시면 될것 같습니다.

반응형

'공부이야기 > 아두파일럿' 카테고리의 다른 글

아두파일럿 개발 #1  (0) 2017.12.12

댓글