通过android传感器控制ROV云台转动

代码写的很扯

最初是想把手机放在vr眼睛中,转头的时候,调用手机的方向传感器,计算出角度,向电脑发送指令,电脑再向下位机发送指令,demo如下。

手机和电脑进行socket通信。比较蛋疼的是不知道怎么写手机和下位机通信,只能采取这种方式。然后发现socket通信手机需要连接电脑wifi,但是手机要获取视频又要连接下位机的wifi...僵硬了。有没有大佬有解决方案。

pc端

写个服务端

class Server
    {
        private Server.onReceiveListener listener = null;

        public interface onReceiveListener
        {
            void onReceive(string order);
        }

        public void OrderTimeEvent(object source, ElapsedEventArgs e)
        {
            listener.onReceive("停止指令");
        }

        //ip地址
        private string ip = "ip地址";

        //端口
        private int port = 端口号;

        //负责监听客户端请求的线程
        Thread threadWatch = null;

        //负责监听服务端的套接字
        Socket socketWatch = null;

        //保存了服务器端所有和客户端通信的套接字
        Dictionary<string, Socket> dict = new Dictionary<string, Socket>();

        //保存了服务器端所有负责调用通信套接字的Receive方法的线程
        Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>();

        public Server(Server.onReceiveListener listener)
        {
            this.listener = listener;
        }

        //开启服务
        public void start()
        {
            //创建负责监听的套接字,参数使用IPv4寻址协议,使用流式连接,使用TCP协议传输数据
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //获取IP地址对象
            IPAddress address = IPAddress.Parse(ip);
            //创建包含IP和port的网络节点对象
            IPEndPoint endPoint = new IPEndPoint(address, port);
            //将负责监听的套接字绑定到唯一的IP和端口上
            try
            {
                socketWatch.Bind(endPoint);
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.ToString());
                return;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return;
            }

            //设置监听队列的长度
            socketWatch.Listen(10);

            //创建负责监听的线程,并传入监听方法
            threadWatch = new Thread(WatchConnection);
            //设置为后台线程
            threadWatch.IsBackground = true;
            //开启线程
            threadWatch.Start();

            Console.WriteLine("服务器启动监听成功");
        }

        public void WatchConnection()
        {
            //持续不断的监听客户端的新的连接请求
            while (true)
            {
                Socket socketConnection = null;
                try
                {
                    //开始监听请求,返回一个新的负责连接的套接字,负责和该客户端通信
                    //Accept方法会阻断当前线程
                    socketConnection = socketWatch.Accept();
                }
                catch (SocketException ex)
                {
                    Console.WriteLine("服务端连接时发生异常:" + ex.Message);
                    break;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("服务端连接时发生异常:" + ex.Message);
                    break;
                }

                //将每个新产生的套接字存起来,装到键值对Dict集合中,以客户端IP:端口作为key
                dict.Add(socketConnection.RemoteEndPoint.ToString(), socketConnection);

                //为每个服务端通信套接字创建一个单独的通信线程,负责调用通信套接字的Receive方法,监听客户端发来的数据
                //创建通信线程
                Thread threadCommunicate = new Thread(ReceiveOrder);
                threadCommunicate.IsBackground = true;
                threadCommunicate.Start(socketConnection);

                dictThread.Add(socketConnection.RemoteEndPoint.ToString(), threadCommunicate);
                string info = socketConnection.RemoteEndPoint.ToString() + " 上线了";
                Console.WriteLine(info);
            }
        }

        public void ReceiveOrder(object socketClientPara)
        {
            Socket socketClient = socketClientPara as Socket;
            while (true)
            {
                //定义一个接收消息用的字节数组缓冲区(2M大小)
                byte[] arrMsgRev = new byte[1024 * 1024 * 2];
                //将接收到的数据存入arrMsgRev,并返回真正接收到数据的长度
                int length = -1;
                try
                {
                    length = socketClient.Receive(arrMsgRev);
                    Console.WriteLine("length:"+length);
                }
                catch (SocketException ex)
                {
                    Console.WriteLine("异常:" + ex.Message + ", RemoteEndPoint: " + socketClient.RemoteEndPoint.ToString());
                    //从通信套接字结合中删除被中断连接的通信套接字
                    dict.Remove(socketClient.RemoteEndPoint.ToString());
                    //从通信线程集合中删除被中断连接的通信线程对象
                    dictThread.Remove(socketClient.RemoteEndPoint.ToString());
                    break;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("异常:" + ex.Message);
                    break;
                }
                //此时是将数组的所有元素(每个字节)都转成字符串,而真正接收到只有服务端发来的几个字符
                string strMsgReceive = Encoding.UTF8.GetString(arrMsgRev, 0, length - 1);
                string strMsg = string.Format("{0} 说:{1}", socketClient.RemoteEndPoint.ToString(), strMsgReceive);
                Console.WriteLine(strMsg);

                string direction = strMsgReceive.Substring(0, strMsgReceive.IndexOf(":"));
                string str_angle = (strMsgReceive.Substring(strMsgReceive.IndexOf(":") + 1));
                int angle = int.Parse(str_angle);
                double runTime = angle * 25 / 360.0;
                Console.WriteLine("runtime:" + runTime);
                switch (direction)
                {
                    case "upleft":
                        listener.onReceive("指令1");

                        break;
                    case "upright":
                        listener.onReceive("指令2");
                        break;
                }

                System.Timers.Timer t = new System.Timers.Timer(runTime * 1000);//实例化Timer类,设置间隔时间为runTime毫秒;
                t.Elapsed += new System.Timers.ElapsedEventHandler(OrderTimeEvent);//到达时间的时候执行事件发出停止指令;
                t.AutoReset = false;//设置是执行一次(false)还是一直执行(true);
                t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
            }
        }
    }

这里比较蛋疼,头转过几度,云台就转几度,但是旋转的时候不是在理想状态下旋转,所以只是随便处理了一下。

向下位机发送旋转指令,到达转动时间后发送停止指令。(Timer)

这里是用了一个简单的事件监听

主窗体实现接口

开启服务

android端

package com.example.android.sensortest;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private SensorManager mSensorManager;
    EditText etOrientation;
    Button btnTemp;
    Socket socket = null;
    int previousAngle = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etOrientation = (EditText) findViewById(R.id.etOrientation);
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        btnTemp = (Button) findViewById(R.id.btnTemp);
        btnTemp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            InetAddress serverAddr = InetAddress.getByName("ip地址");
                            Log.d("TCP", "Connecting..........");
                            //连接pc端服务器
                            socket = new Socket(serverAddr, 20000);
                        } catch (UnknownHostException e) {
                            Log.e("error", "ip地址 is unknown server!");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }.start();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        //为系统的方向传感器注册监听器
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_UI);
    }

    @Override
    protected void onStop() {
        mSensorManager.unregisterListener(this);
        super.onStop();
    }

    @Override
    protected void onPause() {
        mSensorManager.unregisterListener(this);
        super.onPause();
    }

    String toServer;

    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        float[] values = sensorEvent.values;
        int sensorType = sensorEvent.sensor.getType();
        StringBuilder sb = null;
        switch (sensorType) {
            case Sensor.TYPE_ORIENTATION:
                sb = new StringBuilder();
                sb.append("绕z轴转过的角度:");
                sb.append(values[0]);
                sb.append("
绕x轴转过的角度:");
                sb.append(values[1]);
                sb.append("
绕y轴转过的角度:");
                sb.append(values[2]);
                etOrientation.setText(sb.toString());
                if (previousAngle == -1) {
                    previousAngle = (int) values[0];
                } else {
                    int inteval = (int) values[0] - previousAngle;
                    if (Math.abs(inteval) > 30) {

                        previousAngle = (int) values[0];
                        if (inteval > 180) inteval -= 360;
                        if (inteval < -180) inteval += 360;
                        if (inteval < 0) {
                            toServer = "upleft:" + Math.abs(inteval);
                        } else {
                            toServer = "upright:" + inteval;
                        }

                        new Thread() {
                            @Override
                            public void run() {
                                try {
                                    PrintWriter out = new PrintWriter(new BufferedWriter(
                                            new OutputStreamWriter(socket.getOutputStream())),
                                            true);

                                    Log.d("info", "To server:'" + toServer + "'");
                                    out.println(toServer);
                                    out.flush();

                                } catch (UnknownHostException e) {
                                    Log.e("error", "ip地址 is unknown server!");
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {

                                }
                            }
                        }.start();
                    }
                }
                break;
        }
    }

    //当传感器精度改变时回调该方法
    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }
}
原文地址:https://www.cnblogs.com/wangkaipeng/p/7258508.html