Upload files to "/"

Simulation works 4/17/2024
This commit is contained in:
jcd8858 2024-04-17 17:05:25 -04:00
parent ce2f0082d2
commit b847e76e97
5 changed files with 1919 additions and 0 deletions

123
CameraTest.m Normal file
View file

@ -0,0 +1,123 @@
%Camera to position
clc;
clear all;
%close all;
%constants
RGB = 1;
TOP_CAM_H=13;
SIDE_CAM_H = 0;
SIDE_CAM_Y = 9.5;
thresholdNum = 50;
NA = 0;
Data = [0, 0, 0, 0, 0, 0];
%Include source files in path
addpath(genpath('../src'))
%Initialization Parameters
server_ip = '127.0.0.1'; %IP address of the Unity Server
server_port = 55001; %Server Port of the Unity Sever
client = tcpclient(server_ip,server_port);
fprintf(1,"Connected to server\n");
%--------------------------------------------------------------------------------------
% x,y,z,yaw[z],pitch[y],roll[x]
pose = [0,44,0,90,-90,3]; % move TennisBall out of the way
unityLink(client,pose);
%TopCamera Baseline
pose = [NA,NA,NA,NA,NA,0]; % move camera Top
unityLink(client,pose);
unityImage = unityLink(client,pose);
baselineTop = unityImage;
imwrite(baselineTop,"baselineTop.png");
%SideCamera Baseline
pose = [NA,NA,NA,NA,NA,1]; % move camera Side
unityLink(client,pose);
unityImage = unityLink(client,pose);
baselineSide = unityImage;
imwrite(baselineSide,"baselineSide.png");
%import serve data
filename = 'serve4.dat';
M = readmatrix(filename);
%Enter Loop
for i = 1:10:(length(M)) % [m]
%Pull position from serve data
heightZ = M(i,2);
widthY = M(i,3);
lengthX = M(i,1);
pose = [lengthX,heightZ,widthY,90,-90,3]; % move TennisBall
unityLink(client,pose);
%----------------------------------------------------------------------------------------------------------
%Camera position Top
pose = [NA,NA,NA,NA,NA,0]; % move camera Top position
unityImage = unityLink(client,pose);
TenisBallOnly = imsubtract(unityImage, baselineTop);
% use RGB values here instead grey Scales a problem
[row,col] = find(TenisBallOnly(:,:,RGB) > thresholdNum);%find tennis ball indexes
xTop = mean(col);
yTop = mean(row);
centers = [xTop yTop];
%----------------------------------------------------------------------------------------------------------
%Camera Position Side
pose = [NA,NA,NA,NA,NA,1]; % move camera Side position
unityImage = unityLink(client,pose);
TenisBallOnly = imsubtract(unityImage, baselineSide); %imsubtract
% use RGB values here instead grey Scales a problem
[row,col] = find(TenisBallOnly(:,:,RGB) > thresholdNum);%find tennis ball indexes
xSide = mean(col);
ySide = mean(row);
%------------------------------------------------------------------------------------------------------------
%Calculate 3D position
[X,Y,Z] = find3DOrthogonal(xTop, yTop, ySide);
%error calculations if wanted
%errorX = ((((X))-widthY)/widthY)*100;
%errorY = ((((Y))-lengthX)/lengthX)*100;
%errorZ = (((Z)-heightZ)/heightZ)*100;
%Xsub = (X)-widthY;
%Ysub = (Y)-lengthX;
%Zsub = (Z)-heightZ;
Data(end+1,:) = [lengthX, widthY, heightZ, X, Y, Z];
end
figure
scatter3(0,0,TOP_CAM_H);
hold on
scatter3(SIDE_CAM_Y,0,SIDE_CAM_H);
scatter3(Data(:,1),Data(:,2),Data(:,3),'*')
scatter3(0,0,13);
scatter3(Data(:,4),Data(:,5),Data(:,6),'*','blue')
patch([5.02 -5.02 -5.02 5.02], [11.88 11.88 -11.88 -11.88], [0 0 0 0],'Green')
scatter3([15 15 -15 -15 15 15 -15 -15],[15 -15 15 -15 15 -15 15 -15],[-1 -1 -1 -1 TOP_CAM_H TOP_CAM_H TOP_CAM_H TOP_CAM_H],'x');
hold off
%--------------------------------------------------------------------------------------
%Close Gracefully
fprintf(1,"Disconnected from server\n");

298
Server.cs Normal file
View file

@ -0,0 +1,298 @@
using System;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using System.Net;
using System.IO;
public class Server : MonoBehaviour {
//General Init
private List<ServerClient> clients;
private List<int> disconnectIndex;
//Camera Variables
private GameObject MainCam;
RenderTexture CameraRender;
byte[] EncodedPng;
int Height;
int Width;
bool ScreenshotDone;
/////////////////////////////////////////////////////////////////////////////
// main GUI components that appear for the user.
/////////////////////////////////////////////////////////////////////////////
[Header("Server Settings")]
public int Port = 55001;
private TcpListener server;
private bool serverStarted;
[Header("Game Object Settings")]
public string ObjectName = "";
//public Vector2 Resolution = new Vector2();
/////////////////////////////////////////////////////////////////////////////
// Use this for initialization
void Start () {
clients = new List<ServerClient>();
disconnectIndex = new List<int>();
try {
server = new TcpListener(IPAddress.Any, Port);
server.Start();
Startlistening();
serverStarted = true;
Debug.Log("Server has started on port:" + Port.ToString());
}
catch (Exception e) {
Debug.Log("Socket Error " + e.Message);
}
InvokeRepeating("UpdateLoop", 0f, 0.003f);
}
private void UpdateLoop(){
if(this.MainCam == null)
this.MainCam = GameObject.Find("cameraTop");
if (!serverStarted)
return;
if(clients.Count == 0)
return;
for(int c = 0; c < clients.Count; c++ ) {
//Check if clients are connected
if(!isConnected(clients[c].tcp)) {
clients[c].tcp.Close();
disconnectIndex.Add(c);
Debug.Log(clients[c].clientName + " has disconnected from the server");
continue;
}
// Check for data from client
else {
float[] myFloat = new float[8];
NetworkStream s = clients[c].tcp.GetStream();
if (s.DataAvailable) {
byte[] RecievedString = new byte[sizeof(float)*8];
if (RecievedString != null){
s.Read(RecievedString, 0, sizeof(float)*8);
myFloat = ConvertBytes2Float(RecievedString);
moveCamera(myFloat);
StartCoroutine(SendCamCapture(clients[c], MainCam.GetComponent<Camera>(), myFloat[0].ToString(), myFloat[1].ToString()));
}
s.Flush();
}
}
}
//Clean up Disconnected Clients
for(int i = 0; i < disconnectIndex.Count; i++) {
clients.RemoveAt(disconnectIndex[i]);
}
disconnectIndex.Clear();
}
private byte[] ConvertFloat2Bytes(float[] FloatArray){
var byteArray = new byte[FloatArray.Length * sizeof(float)];
Buffer.BlockCopy(FloatArray, 0, byteArray, 0, byteArray.Length);
return byteArray;
}
private float[] ConvertBytes2Float(byte[] byteArray){
var floatArray = new float[byteArray.Length / sizeof(float)];
Buffer.BlockCopy(byteArray, 0, floatArray, 0, byteArray.Length);
return floatArray;
}
//Checks if client is connected
private bool isConnected(TcpClient c){
try {
if(c != null && c.Client != null && c.Client.Connected){ //Makes sure the client is connected
if(c.Client.Poll(0, SelectMode.SelectRead)){ //Polls the Client for activity
return !(c.Client.Receive(new byte[1], SocketFlags.Peek) == 0); //Checks for response
}
return true;
}
else
return false;
}
catch {
return false;
}
}
//Begins connection with client
private void AcceptServerClient(IAsyncResult ar){
TcpListener listener = (TcpListener)ar.AsyncState;
ServerClient NewClient = new ServerClient(listener.EndAcceptTcpClient(ar), null);
Debug.Log("Someone has connected");
clients.Add(NewClient);
Startlistening();
}
//Starts listening on server socket
private void Startlistening(){
server.BeginAcceptTcpClient(AcceptServerClient, server);
}
//Try to close all the connections gracefully
void OnApplicationQuit(){
for (int i = 0; i < clients.Count; i++){
try{
clients[i].tcp.GetStream().Close();
clients[i].tcp.Close();
}
catch { }
}
Debug.Log("Connections Closed");
}
//Sends out data
public void OutgoingData(ServerClient c, byte[] data){
NetworkStream ClientStream = c.tcp.GetStream();
try{
ClientStream.Write(data, 0, data.Length);
}
catch (Exception e) {
Debug.LogError("Could not write to client.\n Error:" + e);
}
}
// Matlab used NED right-handed coordinate system
// +x forward [optical axis]
// +y right
// +z down
// Unity uses a wild left-handed coordinate system
// +x right
// +y up
// +z forward [optical axis]
// matlab unity
// forward x z
// right y x
// down z -y
private void moveCamera(float[] pose){
float x_rot = pose[7];
if(x_rot == 0)
{
ObjectName = "cameraTop";
this.MainCam = GameObject.Find("cameraTop");
}
else if(x_rot == 1)
{
ObjectName = "cameraSide";
this.MainCam = GameObject.Find("cameraSide");
}
else
{
ObjectName = "TennisBall";
}
GameObject ClientObj = GameObject.Find(ObjectName);
// x,y,z,yaw[z],pitch[y],roll[x]
float x_trans = pose[2];
float y_trans = pose[3];
float z_trans = pose[4];
float z_rot = pose[5];
float y_rot = pose[6];
Debug.Log("hello:" + x_trans);
//Vector3 matlabTranslate = new Vector3(y_trans, -z_trans, x_trans);
//Vector3 matlabTranslate = new Vector3(x_trans, y_trans, z_trans);
// perform translation
//ClientObj.transform.position = transform.TransformVector(matlabTranslate);
//ClientObj.transform.position = ClientObj.transform.position + new Vector3(x_trans, y_trans, z_trans);
if(ObjectName == "TennisBall")
{
ClientObj.transform.position = new Vector3(x_trans, y_trans, z_trans);
// perform rotation in yaw, pitch, roll order while converting to left hand coordinate system.
ClientObj.transform.rotation = Quaternion.AngleAxis(z_rot, Vector3.up) * // yaw [z]
Quaternion.AngleAxis(-y_rot, Vector3.right)* // pitch [y]
Quaternion.AngleAxis(0, Vector3.forward); // roll [x]
}
}
//Organizes and Sends Picture
IEnumerator SendCamCapture(ServerClient c, Camera CameraSelect, string Width, string Height){
CaptureImage(CameraSelect, int.Parse(Width), int.Parse(Height));
while (!this.CaptureDone()){
yield return null;
}
OutgoingData(c, this.ReturnCaptureBytes());
Debug.Log("Captured Image");
}
IEnumerator GetRender(Camera cam){
this.CameraRender = new RenderTexture(this.Width, this.Height, 16);
cam.enabled = true;
cam.targetTexture = CameraRender;
Texture2D tempTex = new Texture2D(CameraRender.width, CameraRender.height, TextureFormat.RGB24, false);
cam.Render();
RenderTexture.active = CameraRender;//Sets the Render
tempTex.ReadPixels(new Rect(0, 0, CameraRender.width, CameraRender.height), 0, 0);
tempTex.Apply();
EncodedPng = tempTex.GetRawTextureData();
Destroy(tempTex);
yield return null;
CameraRender.Release();
cam.targetTexture = null;
ScreenshotDone = true;
}
public void CaptureImage(Camera SelectedCamera, int UsrWidth, int UsrHeight){
ScreenshotDone = false;
this.Width = UsrWidth;
this.Height = UsrHeight;
if (SelectedCamera != null){
StartCoroutine(GetRender(SelectedCamera));
}
}
public int GetWidth(){
return this.Width;
}
public int GetHeight(){
return this.Height;
}
public bool CaptureDone(){
return ScreenshotDone;
}
public byte[] ReturnCaptureBytes(){
return EncodedPng;
}
IEnumerator SerializeCapture(ServerClient c, byte[] PixelData, int Width, int Length){
OutgoingData(c, PixelData);
yield return null;
}
}
public class ServerClient {
public TcpClient tcp;
public string clientName;
public List<GameObject> ClientObj;
public ServerClient(TcpClient clientSocket, string Name) {
clientName = Name;
tcp = clientSocket;
ClientObj = new List<GameObject>();
}
}

38
find3DOrthogonal.m Normal file
View file

@ -0,0 +1,38 @@
function [y_comp,x_comp,h_ball] = find3DOrthogonal(top_ball_x_px, top_ball_y_px, side_ball_y_px)
% constants
TOP_CAM_FOV_H = 90;
TOP_CAM_FOV_V = 58.72538;
TOP_CAM_IMG_W = 3840;
TOP_CAM_IMG_H = 2160;
TOP_CAM_H = 13;
SIDE_CAM_FOV_V = 120;
SIDE_CAM_IMG_H = 2160;
SIDE_CAM_H = 0;
SIDE_CAM_Y = 9.5;
%Calculations
% x position
theta_x = (top_ball_x_px - (TOP_CAM_IMG_W / 2)) * (TOP_CAM_FOV_H / TOP_CAM_IMG_W);
x_ball = TOP_CAM_H * tand(theta_x);
% y position
theta_y = (top_ball_y_px - (TOP_CAM_IMG_H / 2)) * (TOP_CAM_FOV_V / TOP_CAM_IMG_H);
y_ball = TOP_CAM_H * tand(theta_y);
% height
theta_h = ((SIDE_CAM_IMG_H / 2) - side_ball_y_px) * (SIDE_CAM_FOV_V / SIDE_CAM_IMG_H);
h_ball = (SIDE_CAM_H + (tand(theta_h) * (SIDE_CAM_Y - y_ball))) / (1 - (tand(theta_h) / TOP_CAM_H));
% x & y positions compensated based on height
x_comp = x_ball * (1 - (h_ball / TOP_CAM_H));
y_comp = y_ball * (1 - (h_ball / TOP_CAM_H));
end
%TODO
% 1) take out rgb2grey and find circle with rgb image
% 2) figure out how are calculated based on camera as refences

1439
serve4.dat Normal file

File diff suppressed because it is too large Load diff

21
unityLink.m Normal file
View file

@ -0,0 +1,21 @@
function image = unityLink(TCP_Handle,pose)
% x,y,z,yaw[z],pitch[y],roll[x]
width = 3840; %480
height = 2160; %752
x = pose(1);
y = pose(2);
z = pose(3);
yaw = pose(4);
pitch = pose(5);
roll = pose(6);
%Set Position
write(TCP_Handle,single([width,height,x,y,z,yaw,pitch,roll]));
%Get image data
data = read(TCP_Handle,width*height*3);
temp = reshape(data,[3,width*height]);
image = imrotate(reshape(temp',[width,height,3]),90);