代码写的很扯
最初是想把手机放在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) { } }