我正在尝试构建全球定位系统传感器脚本(不是使用真实全球定位系统传感器的脚本),并将其用作游戏对象。我正试图在自驾车项目中实施这种传感器。我已经尝试编写自己的脚本,将x,y,z坐标转换为经度和纬度。我想了解的就像构建雷达传感器和光探测和测距传感器以及惯性测量单元传感器,我该如何构建一个全球定位系统传感器,它为我们提供坐标,准确测量一个游戏对象相对于另一个游戏对象与场景(世界)的位置。
这是我试图构建的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//using System.Math;
//using System.Diagnostics;
public class GPS02 : MonoBehaviour {
public float latitude;
public float longitude;
public double earthradius;
public double Lat_lon;
public float lat;
public float lon;
public static double enu2ecefx;
public static double enu2ecefy;
public static double enu2ecefz;
public static float finalX;
public static float finalY;
public static float finalZ;
const double a = 6378137f; // WGS-84 Earth semimajor axis (m)
const double b = 6356752f; // Derived Earth semiminor axis (m)
const double f = (a - b) / a; // Ellipsoid Flatness
const double f_inv = 1.0f / f;
const double a_sq = a * a;
const double b_sq = b * b;
const double e_sq = f * (2f - f);
public GameObject carvar;
public Car othervar;
public double E;
public double N;
public double U;
// Use this for initialization
void Start () {
othervar = carvar.GetComponent<Car>();
E = othervar.east;
N = othervar.north;
U = othervar.up;
transform.position = Quaternion.AngleAxis(longitude, -Vector3.up) * Quaternion.AngleAxis(latitude, -Vector3.right) * new Vector3(0,0,1); // ----not sure
Debug.Log("X ECEF "+transform.position.z);
Debug.Log("Y ECEF "+transform.position.x);
Debug.Log("Z ECEF "+transform.position.y);
EnuToEcef(E,N,U,latitude,longitude,earthradius,out enu2ecefx,out enu2ecefy,out enu2ecefz);
finalX = transform.position.z + (float)enu2ecefx;
finalY = transform.position.x + (float)enu2ecefy;
finalZ = transform.position.y + (float)enu2ecefz;
Debug.Log("final X "+finalX);
Debug.Log("final Y "+finalY);
Debug.Log("final Z "+finalZ);
lat = (float)Math.Acos( finalY / earthradius);
lon = (float)Math.Atan(finalX/ earthradius);
Debug.Log("lattitude "+lat);
Debug.Log("lattitude "+lon);
}
// Update is called once per frame
void Update () {
}
public static void EnuToEcef(double E, double N, double U,
double latitude, double longitude, double earthradius,
out double enu2ecefx, out double enu2ecefy, out double enu2ecefz)
{
// Convert to radians in notation consistent with the paper:
var lambda = DegreeToRadians(latitude);
var phi = DegreeToRadians(longitude);
var s = Math.Sin(lambda);
var n = a / Math.Sqrt(1 - e_sq * s * s);
var sin_lambda = Math.Sin(lambda);
var cos_lambda = Math.Cos(lambda);
var cos_phi = Math.Cos(phi);
var sin_phi = Math.Sin(phi);
double x0 =(earthradius + n) * cos_lambda * cos_phi;
double y0 = (earthradius + n) * cos_lambda * sin_phi;
double z0 = (earthradius + (1 - e_sq) * n) * sin_lambda;
double xd = -sin_phi * E - cos_phi * sin_lambda * N+ cos_lambda * cos_phi * U;
double yd = cos_phi * E - sin_lambda * sin_phi * N + cos_lambda * sin_phi * U;
double zd = cos_lambda * N + sin_lambda * U;
enu2ecefx = xd + x0;
enu2ecefy = yd + y0;
enu2ecefz = zd + z0;
Debug.Log("car_x ECEF "+enu2ecefx);
Debug.Log("car_y ECEF "+enu2ecefy);
Debug.Log("car_z ECEF "+enu2ecefz);
}
public static double DegreeToRadians(double Lat_lon)
{
return (3.14f/180f)*Lat_lon;
}
}
答案 0 :(得分:3)
我认为您想要的是将笛卡尔坐标(x,y,z)转换为几何坐标坐标(半径,纬度,经度)。
几何坐标几乎类似于球面坐标(半径,极坐标,方位角)。
此link显示了差异。 纬度角度几乎与球形坐标(90°极坐标)中的极角度相似。 经度是方位角角度。
这给了我们以下公式:
笛卡尔与几何坐标
radius = sqrt(x^2 + y^2 + z^2)
latitude = arcsin(z/radius)
longitude = atan2(y, x)
万一其他人需要它:
笛卡尔坐标到球面坐标
radius = sqrt(x^2 + y^2 + z^2)
polar = arccos(z/radius)
azimuthal = atan2(y, x)
球形到几何坐标
latitude = polar - 90°
longitude = azimuthal