mavlink的Java语言之探索实现

1.mavlink是什么,贴上官方的原话:大家自己脑补一下英文。

      MAVLink is a very lightweight, header-only message marshalling library for micro air vehicles.

    It can pack C-structs over serial channels with high effiency and send these packets to the ground control station. It is extensively tested on the PX4, PIXHAWK, APM and Parrot AR.Drone platforms and serves there as communication backbone for the MCU/IMU communication as well as for Linux interprocess and ground link communication.


     mavlink支持多种语言,常见的有C/C++,Java,C#,JavaScript,Python等等。在开源无人机中,APM,pixhawk,pix4及其相关的地面站都使用了mavlink通信协议。正如官方所说,要想在项目中使用mavlink,得有头文件。头文件是自动生成的,自动生成的软件采用Python编写,可在点击打开链接

下载到。好了,本文打算使用Java语言在eclipse上探索实现,所有我们先生成相关的.java文件吧。下载自动生成软件后,它包含如图所示的文件目录:

                        


        打开命令行:进入这个文件的目录,输入 python  mav(按table键自动补全) 如图:

        

       

       按下enter键,弹出一个界面,如图:

                  


      我们选择Language项,这里选择Java,如图:

                  

    然后在XML项加载刚刚下载的文件,即\mavlink-master\message_definitions\v1.0,选择common.xml,如图:

                        

      然后选择你的输出文件,新建一个文件夹一个,我这里在桌面新建mavlink文件夹C:\Users\John\Desktop\mavlink,如图:

                  

       最后一步,点击Generate即可,会提示你是否要覆盖改文件夹下的内容,一般选择“确定”,如图:

                 


               如果生成成功,会弹出一个对话框,如图:

               


             查看是否生成了文件,我的是:

             

                    到这一步,就OK了,将这个文件夹的所有文件导入eclipse工程中,并建立相应的包(4个)。我的是这样的:

                    

注意:将common文件中文件导进来时有错误,这应该是疏忽吧,common文件夹的文件在开始处的包是这样子的:

                   package com.MAVLink.mavlink\common;

            应该把\改成点(.),我这里修改成这样:package com.MAVLink.mavlink.common;

              中间两个包文件,我就不展开了。然后我们使用socket模拟网络通信。


2.  前面废话挺多的,不好意思,下面开始写代码,首先是客户端,使用的socket,这里我默认大家都知道什么写了,我就不详细介绍,直接上代码:




客户端:

package com.client.tcp;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import com.MAVLink.MAVLinkPacket;
import com.MAVLink.mavlink.common.msg_altitude;
import com.test.Test;
public class Client {

	public static void main(String[] args) {
		new ClientThread().start();	
	}

}

class ClientThread extends Thread {
	private   MAVLinkPacket packet = null;
	private   boolean flag = true;
	private   msg_altitude msgAltt = new msg_altitude();
	private Socket socket = null;
	@Override
	public void run()
	{
		try {
			socket = new Socket();
			InetSocketAddress isa = new InetSocketAddress("127.0.0.1",40000);
			socket.connect(isa);

			ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
	
			msgAltt.altitude_amsl = 34.5f;
			msgAltt.altitude_local = 34.87f;
			msgAltt.altitude_monotonic = 76.54f;
			msgAltt.altitude_relative = 100.09f;
			msgAltt.altitude_terrain = 23.5f;
			msgAltt.bottom_clearance = 567.76f;
			packet = msgAltt.pack();

			oos.writeObject(packet);
			oos.flush();
			oos.close();
//			socket.shutdownOutput();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}finally
		{
			if(null != socket)
				try {
					socket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		

	}
}


服务端:




package com.server.tcp;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.MAVLink.MAVLinkPacket;
import com.MAVLink.Messages.MAVLinkPayload;
import com.MAVLink.mavlink.common.msg_altitude;
import com.test.Test;
public class Server {
	
	public static void main(String[] args) {
		ServerThread st = new ServerThread();
		st.start();
	}
}

class ServerThread extends Thread {
	private ServerSocket server = null;
	private Socket s = null;
	private boolean flag = true;
	private byte[] result = new byte[1024];
	@Override
	public void run() {
		try {
			server = new ServerSocket(40000);
			System.out.println("Server is running....");
			while(flag)
			{
				 s = server.accept();
				 s.setSoTimeout(15000);
				
				ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
				try {

					msg_altitude msgAltt = new msg_altitude();
					MAVLinkPacket packet = (MAVLinkPacket)ois.readObject();
					msgAltt.unpack(packet.payload);
					
					msgAltt = (msg_altitude)ois.readObject();
					
					System.out.println("time_usec=" + msgAltt.time_usec +
			                           "\naltitude_monotonic=" +   msgAltt.altitude_monotonic +
			                           "\naltitude_amsl=" + msgAltt.altitude_amsl +
					                   "\naltitude_local=" + msgAltt.altitude_local +
					                   "\naltitude_relative=" + msgAltt.altitude_relative + 
					                   "\naltitude_terrain=" + msgAltt.altitude_terrain +
					                   "\nbottom_clearance=" + msgAltt.bottom_clearance);                   
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}	
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally
		{
				try {
					if(null != s)s.close();
					if(null != server)
					   server.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
		}
		
	}
	
}

         客户端和服务端都是使用序列化发送和接收数据,这里要发送的类 msg_altitude 的实例,这个类是自动生成的。在APM中它表示无人机的高度。我们启动服务器:

             


然后启动客户端,出现如下错误:

           

   错误消息有点长,截图看不清,我粘贴在这里:

      java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: com.MAVLink.Messages.MAVLinkPayload

错误很明显, com.MAVLink.Messages.MAVLinkPayload这个类没有序列化,好我们让它实现java.io.Serializable接口,如图:

               

      注意:官方说,自动生成的类不应该,如图:

                   

       但是为了能够运行,我们先改了再说。然后运行客户端,然后又出现错误,如图:

            


具体是:java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.nio.HeapByteBuffer。很明显,又是没有实现java.io.Serializable接口。这个该什么办???在这个MAVLinkPayload.java文件中,有定义:

                       

     其中ByteBuffer是在java.nio.ByteBuffer定义的。没法让它序列化。我目前也没想到什么好方法去修改这个错误。这里抛砖引玉,希望有大神能够解决这个问题。谢谢。该博文还会继续,当我想到好法子之后。

   












你可能感兴趣的:(Java,mavlink通信协议,无人机,硬件-嵌入式开发)