zoukankan      html  css  js  c++  java
  • 通过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) {
    
        }
    }
  • 相关阅读:
    20172311《程序设计与数据结构》第六周学习总结
    20172311 2018-2019-1 《程序设计与数据结构》课堂测试修改报告
    20172323 2018-2019-1《程序设计与数据结构》课程总结
    20172323 2018-2019-1 《程序设计与数据结构》课堂测试报告
    20172323 2018-2019-1 《程序设计与数据结构》实验三报告
    20172323 2018-2019-1 《程序设计与数据结构》第九周学习总结
    20172323 2018-2019-1 《程序设计与数据结构》实验二报告
    20172323 2018-2019-1 《程序设计与数据结构》第八周学习总结
    20172323 2018-2019-1 《程序设计与数据结构》第七周学习总结
    20172323 2018-2019-1 《程序设计与数据结构》第六周学习总结
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/7258508.html
Copyright © 2011-2022 走看看