123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Text;
- using UnityEngine;
- using UnityEngine.Networking;
- using System.Net;
- using System.Threading;
- namespace Seengene.XDKUnityPluginCloud {
- public delegate void AuthorizationResponseHandler(AuthorizationResponse response);
- public delegate void RelocationResponseHandler(RelocationResponse response);
- public class XDKCloudInterface : MonoBehaviour {
- private const string k_DefaultAuthorizationAPIAddress = "http://124.70.37.47:80/requestMap";
- private const string k_DefaultRelocationAPIAddress = "http://124.70.37.47:80/relocalize";
- [SerializeField] private string m_AuthorizationAPIAddress = k_DefaultAuthorizationAPIAddress;
- [SerializeField] private string m_RelocationAPIAddress = k_DefaultRelocationAPIAddress;
- [SerializeField] private string m_MapId = "";
- string k_FieldNameServerFlag = "ServerFlag";
- int m_ServerFlag = 0;
- public event AuthorizationResponseHandler OnAuthorized;
- public event RelocationResponseHandler OnRelocated;
- bool m_IsUploadingImage = false;
- Thread m_ThreadUploadImage = null;
- List<RelocUploadImageItem> m_UploadImageList = new List<RelocUploadImageItem>();
- private void Awake() {
- m_ServerFlag = UnityEngine.Random.Range(1, 1000);
- if (string.IsNullOrEmpty(XDKConfigs.AuthorizationAPIAddress)) {
- XDKConfigs.AuthorizationAPIAddress = m_AuthorizationAPIAddress;
- }
- if (string.IsNullOrEmpty(XDKConfigs.RelocationAPIAddress)) {
- XDKConfigs.RelocationAPIAddress = m_RelocationAPIAddress;
- }
- if (string.IsNullOrEmpty(XDKConfigs.MapId)) {
- XDKConfigs.MapId = m_MapId;
- }
- }
- private void Start() {
- try {
- m_IsUploadingImage = true;
- m_ThreadUploadImage = new Thread(RelocUploadImageThread);
- m_ThreadUploadImage.IsBackground = true;
- m_ThreadUploadImage.Start();
- Debug.Log("开始线程 RelocUploadingImageThread 成功");
- } catch (Exception e) {
- Debug.LogErrorFormat("开始线程 RelocUploadingImageThread 失败: {0}", e.Message);
- }
- }
- private void OnDestroy() {
- try {
- m_IsUploadingImage = false;
- if (m_ThreadUploadImage != null)
- m_ThreadUploadImage.Abort();
- Debug.Log("结束线程 RelocUploadingImageThread 成功");
- } catch (Exception e) {
- Debug.LogErrorFormat("结束线程 RelocUploadingImageThread 失败:{0}", e.Message);
- }
- XDKConfigs.SetDefault();
- }
- public void Authorize() {
- StartCoroutine(AuthorizeAsync(XDKConfigs.MapId));
- }
- public void Relocate(string sessionID, Int32 seq, Matrix4x4 cameraPose, CameraCalibration cameraCalibration, byte[] imageBytes) {
- RelocUploadImageItem item = new RelocUploadImageItem(sessionID, seq, cameraPose, cameraCalibration, imageBytes);
- m_UploadImageList.Add(item);
- }
- IEnumerator AuthorizeAsync(string mapId) {
- byte[] myData;
- using (MemoryStream mMemStream = new MemoryStream()) {
- using (BinaryWriter mBinaryWriter = new BinaryWriter(mMemStream, Encoding.ASCII)) {
- mBinaryWriter.Write(RequestMapKeys.RequestType_MapId);
- byte[] bytesMapId = System.Text.Encoding.ASCII.GetBytes(mapId);
- mBinaryWriter.Write(bytesMapId.Length);
- mBinaryWriter.Write(bytesMapId);
- myData = mMemStream.ToArray();
- }
- }
- UnityWebRequest webRequest = new UnityWebRequest(XDKConfigs.AuthorizationAPIAddress, UnityWebRequest.kHttpVerbPOST);
- webRequest.SetRequestHeader(k_FieldNameServerFlag, m_ServerFlag.ToString());
- UploadHandler uploader = new UploadHandlerRaw(myData);
- DownloadHandler downloadHandler = new DownloadHandlerBuffer();
- webRequest.downloadHandler = downloadHandler;
- webRequest.uploadHandler = uploader;
- webRequest.uploadHandler.contentType = "application/json";
- webRequest.timeout = 30;
- long startTicks = DateTime.Now.Ticks / 10000;
- if (XDKConfigs.IfLogOn) {
- Debug.LogFormat("Start To Authorize(RequestSessionID) ... MapID:{0}; {1}:{2};startTime:{3},{4}ms",
- mapId, k_FieldNameServerFlag, webRequest.GetRequestHeader(k_FieldNameServerFlag), DateTime.Now, startTicks);
- }
- yield return webRequest.SendWebRequest();
- if (webRequest.isNetworkError || webRequest.isHttpError) {
- Debug.LogErrorFormat("{0}, {1}", webRequest.error, webRequest.url);
- } else {
- long endTicks = DateTime.Now.Ticks / 10000;
- string msgInfo = "";
- switch (webRequest.responseCode) {
- case 200:
- msgInfo = "获取SessionID成功";
- break;
- case 400:
- msgInfo = "参数错误";
- break;
- case 404:
- msgInfo = "地图不存在";
- break;
- case 500:
- msgInfo = "内部服务器错误";
- break;
- case 503:
- msgInfo = "服务器忙,请稍后再试";
- break;
- default:
- msgInfo = "其它错误";
- break;
- }
- if (webRequest.responseCode == 200) {
- if (XDKConfigs.IfLogOn) {
- Debug.LogFormat("Request SessionID: {0}, code:{1}; endTime:{2},{3}ms; delay:{4}ms",
- msgInfo, webRequest.responseCode, DateTime.Now, endTicks, endTicks - startTicks);
- }
- ParseAuthorizationResponse(webRequest.downloadHandler.data);
- } else {
- if (XDKConfigs.IfLogOn) {
- Debug.LogErrorFormat("Request SessionID: {0}, code:{1}; endTime:{2},{3}ms; delay:{4}ms",
- msgInfo, webRequest.responseCode, DateTime.Now, endTicks, endTicks - startTicks);
- }
- }
- }
- }
- private void ParseAuthorizationResponse(byte[] buffer) {
- Int32 status = 0;
- string sessionID = string.Empty;
- double scale = 0;
- using (MemoryStream mMemStream = new MemoryStream(buffer)) {
- using (BinaryReader mBinaryReader = new BinaryReader(mMemStream, Encoding.ASCII)) {
- while (mBinaryReader.BaseStream.Position < buffer.Length) {
- byte type = mBinaryReader.ReadByte();
- int len = mBinaryReader.ReadInt32();
- switch (type) {
- case RequestMapKeys.ResponseType_SessionId:
- byte[] bytes = mBinaryReader.ReadBytes(len);
- System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
- sessionID = encoding.GetString(bytes);
- break;
- case RequestMapKeys.ResponseType_Status:
- status = mBinaryReader.ReadInt32();
- break;
- case RequestMapKeys.ResponseType_Scale:
- scale = mBinaryReader.ReadDouble();
- break;
- default:
- break;
- }
- }
- }
- }
- if (XDKConfigs.IfLogOn) {
- Debug.LogFormat("ParseAuthorizationResponse Success, status:{0}; scale:{1}; sessionID:{2}", status, scale, sessionID);
- }
- AuthorizationResponse response = new AuthorizationResponse(status, scale, sessionID);
- OnAuthorized?.Invoke(response);
- }
- private void ParseRelocationResponse(byte[] buffer, Matrix4x4 cameraPos, CameraCalibration cameraCalibration, string sessionID) {
- Int32 status = 0;
- Int32 seq = 0;
- List<Vector2> point2d_vec = new List<Vector2>();
- List<Vector3> point3d_vec = new List<Vector3>();
- List<double> transform_ltg = new List<double>();
- string extra_msg = string.Empty;
- using (MemoryStream mMemStream = new MemoryStream(buffer)) {
- using (BinaryReader mBinaryReader = new BinaryReader(mMemStream, Encoding.ASCII)) {
- while (mBinaryReader.BaseStream.Position < buffer.Length) {
- byte type = mBinaryReader.ReadByte();
- int length = mBinaryReader.ReadInt32();
- switch (type) {
- case RelocalizeKeys.ResponseType_Status:
- status = mBinaryReader.ReadInt32();
- break;
- case RelocalizeKeys.RequestType_Seq:
- seq = mBinaryReader.ReadInt32();
- break;
- case RelocalizeKeys.ResponseType_Point2dVec:
- int countV2 = length / 8;
- for (int i = 0; i < countV2; i++) {
- float x = mBinaryReader.ReadSingle();
- float y = mBinaryReader.ReadSingle();
- Vector2 v2 = new Vector2(x, y);
- point2d_vec.Add(v2);
- }
- break;
- case RelocalizeKeys.ResponseType_Point3dVec:
- int countV3 = length / 12;
- for (int i = 0; i < countV3; i++) {
- float x = mBinaryReader.ReadSingle();
- float y = mBinaryReader.ReadSingle();
- float z = mBinaryReader.ReadSingle();
- Vector3 v3 = new Vector3(x, y, z);
- point3d_vec.Add(v3);
- }
- break;
- case RelocalizeKeys.ResponseType_TransformLtg:
- for (int i = 0; i < 16; i++) {
- double item = mBinaryReader.ReadDouble();
- transform_ltg.Add(item);
- }
- break;
- case RelocalizeKeys.ResponseType_ExtraMsg:
- byte[] bytes = mBinaryReader.ReadBytes(length);
- System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
- extra_msg = encoding.GetString(bytes);
- break;
- default:
- break;
- }
- }
- }
- }
- if (XDKConfigs.IfLogOn) {
- string strLog = string.Format("ParseRelocationResponse Success:\nstatus: {0} \n\n seq: {1} \n\n point2d_vec: \n{2} \n\n point3d_vec: \n{3} \n\n transform_ltg: \n{4} \n\n extra_msg: \n{5}",
- status, seq, XDKTools.ListVectro2ToString(point2d_vec), XDKTools.ListVector3ToString(point3d_vec), XDKTools.ListDoubleToString(transform_ltg), extra_msg);
- Debug.LogFormat(strLog);
- }
- RelocationResponse response = new RelocationResponse(status, seq, point2d_vec, point3d_vec, transform_ltg, extra_msg, cameraPos, cameraCalibration, sessionID);
- Loom.QueueOnMainThread(() => {
- OnRelocated?.Invoke(response);
- });
- }
- /// <summary>
- /// 同步更新图片给云定位
- /// U3D端使用单独线程,为了减少主线程UI界面卡顿
- /// </summary>
- private void RelocUploadImageThread() {
- while (m_IsUploadingImage) {
- if (m_UploadImageList.Count > 0) {
- try {
- RelocUploadImageItem item = m_UploadImageList[0];
- PostValue(item);
- m_UploadImageList.RemoveAt(0);
- } catch (Exception ex) {
- // 一旦出错, 做相应的处理,进入下一次循环
- Debug.LogError(ex.Message);
- m_UploadImageList.RemoveAt(0);
- continue;
- }
- }
- Thread.Sleep(10);
- }
- }
- private void PostValue(RelocUploadImageItem uploadImageItem) {
- try {
- byte[] postBytes;
- using (MemoryStream mMemStream = new MemoryStream()) {
- using (BinaryWriter mBinaryWriter = new BinaryWriter(mMemStream, Encoding.ASCII)) {
- // write sessionID
- mBinaryWriter.Write(RelocalizeKeys.RequestType_SessionId);
- byte[] bytesSessionID = System.Text.Encoding.ASCII.GetBytes(uploadImageItem.sessionID);
- mBinaryWriter.Write(bytesSessionID.Length);
- mBinaryWriter.Write(bytesSessionID);
- // write seq
- mBinaryWriter.Write(RelocalizeKeys.RequestType_Seq);
- mBinaryWriter.Write(4);
- mBinaryWriter.Write(uploadImageItem.seq);
- // write pose
- mBinaryWriter.Write(RelocalizeKeys.RequestType_Pose);
- mBinaryWriter.Write(4 * 16);
- for (int x = 0; x < 4; x++) {
- for (int y = 0; y < 4; y++) {
- mBinaryWriter.Write(uploadImageItem.cameraPose[x, y]);
- }
- }
- // write intrinsics
- mBinaryWriter.Write(RelocalizeKeys.RequestType_Intrinsics);
- mBinaryWriter.Write(4 * 9);
- float intrinsic_00 = uploadImageItem.cameraCalibration.focal_length.x;
- float intrinsic_01 = 0;
- float intrinsic_02 = uploadImageItem.cameraCalibration.principal_point.x;
- float intrinsic_10 = 0;
- float intrinsic_11 = uploadImageItem.cameraCalibration.focal_length.y;
- float intrinsic_12 = uploadImageItem.cameraCalibration.principal_point.y;
- float intrinsic_20 = 0;
- float intrinsic_21 = 0;
- float intrinsic_22 = 1;
- mBinaryWriter.Write(intrinsic_00);
- mBinaryWriter.Write(intrinsic_01);
- mBinaryWriter.Write(intrinsic_02);
- mBinaryWriter.Write(intrinsic_10);
- mBinaryWriter.Write(intrinsic_11);
- mBinaryWriter.Write(intrinsic_12);
- mBinaryWriter.Write(intrinsic_20);
- mBinaryWriter.Write(intrinsic_21);
- mBinaryWriter.Write(intrinsic_22);
- // write image
- mBinaryWriter.Write(RelocalizeKeys.RequestType_Image);
- mBinaryWriter.Write(uploadImageItem.imageBytes.Length);
- mBinaryWriter.Write(uploadImageItem.imageBytes);
- // write camera model 相机模型 是否为鱼眼图
- mBinaryWriter.Write(RelocalizeKeys.RequestType_CameraModel);
- mBinaryWriter.Write(4);
- if (uploadImageItem.cameraCalibration.fish_eye == true) {
- mBinaryWriter.Write(2);
- } else {
- mBinaryWriter.Write(1);
- }
- // write ditortion para:相机畸变参数
- mBinaryWriter.Write(RelocalizeKeys.RequestType_DitortionPara);
- mBinaryWriter.Write(4 * 8);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[0]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[1]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[2]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[3]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[4]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[5]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[6]);
- mBinaryWriter.Write(uploadImageItem.cameraCalibration.radial_distortion_8[7]);
- postBytes = mMemStream.ToArray();
- }
- }
- long startTicks = DateTime.Now.Ticks / 10000;
- HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(XDKConfigs.RelocationAPIAddress);
- req.Headers.Add(k_FieldNameServerFlag, m_ServerFlag.ToString());
- req.Method = "POST";
- req.ContentType = "application/json";
- req.ContentLength = postBytes.Length;
- if (XDKConfigs.IfLogOn)
- Debug.LogFormat("Start to relocalize web request ... seq:{0}; {1}:{2};startTime:{3},{4}ms;imageBytesLength:{5}",
- uploadImageItem.seq, k_FieldNameServerFlag, req.Headers.Get(k_FieldNameServerFlag), DateTime.Now, startTicks, uploadImageItem.imageBytes.Length);
- using (Stream reqStream = req.GetRequestStream()) {
- reqStream.Write(postBytes, 0, postBytes.Length);
- }
- using (HttpWebResponse myHttpWebResponse = (HttpWebResponse)req.GetResponse()) {
- long endTicks = DateTime.Now.Ticks / 10000;
- string msgInfo = "";
- switch ((int)myHttpWebResponse.StatusCode) {
- case 200:
- msgInfo = "请求成功";
- break;
- case 400:
- msgInfo = "参数错误";
- break;
- case 404:
- msgInfo = "地图不存在";
- break;
- case 500:
- msgInfo = "内部服务器错误";
- break;
- case 503:
- msgInfo = "服务器忙,请稍后再试";
- break;
- default:
- msgInfo = "其它错误";
- break;
- }
- if (myHttpWebResponse.StatusCode == HttpStatusCode.OK) {
- if (XDKConfigs.IfLogOn) {
- Debug.LogFormat("Relocalize WebRequest: {0}, code:{1}; seq:{2}; endTime:{3},{4}ms; delay:{5}ms",
- msgInfo,
- myHttpWebResponse.StatusCode,
- uploadImageItem.seq,
- DateTime.Now,
- endTicks,
- endTicks - startTicks
- );
- }
- Stream responseStream = myHttpWebResponse.GetResponseStream();
- ParseRelocationResponse(HttpResponseStreamToBytes(responseStream), uploadImageItem.cameraPose, uploadImageItem.cameraCalibration, uploadImageItem.sessionID);
- } else {
- if (XDKConfigs.IfLogOn) {
- Debug.LogErrorFormat("Relocalize WebRequest: {0}, code:{1}; seq:{2}; endTime:{3},{4}ms; delay:{5}ms",
- msgInfo,
- myHttpWebResponse.StatusCode,
- uploadImageItem.seq,
- DateTime.Now,
- endTicks,
- endTicks - startTicks
- );
- }
- Debug.LogErrorFormat("{0}, {1}", myHttpWebResponse.StatusDescription, req.Address);
- }
- }
- } catch (Exception ex) {
- Debug.LogError(ex.ToString());
- throw ex;
- }
- }
- /// 将 Stream 转成 byte[]
- private byte[] HttpResponseStreamToBytes(Stream responseStream) {
- using (StreamReader reader = new StreamReader(responseStream)) {
- MemoryStream stmMemory = new MemoryStream();
- byte[] buffer = new byte[64 * 1024];
- int i;
- while ((i = responseStream.Read(buffer, 0, buffer.Length)) > 0) {
- stmMemory.Write(buffer, 0, i);
- }
- byte[] arraryByte = stmMemory.ToArray();
- stmMemory.Close();
- return arraryByte;
- }
- }
- }
- }
|