C# 现实的GPS传感器作为一个统一的游戏对象

C# 现实的GPS传感器作为一个统一的游戏对象,c#,unity3d,gps,sensors,C#,Unity3d,Gps,Sensors,我正在尝试构建一个全球定位系统传感器脚本(不是使用现实生活中的全球定位系统传感器的脚本),并将其用作游戏对象。我正试图在一个自动驾驶汽车项目中实现这个传感器。我试着写我自己的脚本,把x,y,z坐标转换成经度和纬度,我想理解的是,就像建立一个雷达传感器,光探测和测距传感器,惯性测量单元传感器,我如何建立一个全球定位系统传感器,它为我们提供坐标,精确测量场景(世界)中一个游戏对象相对于另一个游戏对象的位置 这是我试图构建的脚本 using System.Collections; using Syst

我正在尝试构建一个全球定位系统传感器脚本(不是使用现实生活中的全球定位系统传感器的脚本),并将其用作游戏对象。我正试图在一个自动驾驶汽车项目中实现这个传感器。我试着写我自己的脚本,把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;
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用制度;
//运用系统数学;
//使用系统诊断;
公共类GPS02:单一行为{
公共浮动纬度;
公共浮标经度;
公共双地球半径;
公共双车道;
公共浮动lat;
公众浮标;
公共静态双enu2ecefx;
公共静态双精度;
公共静态双enu2ecefz;
公共静态浮动finalX;
最终实现公共静态浮动;
公共静态浮动终局;
常数双a=6378137f;//WGS-84地球半长轴(m)
常数双b=6356752f;//导出的地球半短轴(m)
常数双f=(a-b)/a;//椭球平面度
常数双f_inv=1.0f/f;
常数双a_sq=a*a;
常数双b_sq=b*b;
常数双e_sq=f*(2f-f);
公共游戏对象carvar;
公共汽车;
公共双E;
公共双N;
公共双U;
//用于初始化
无效开始(){
othervar=carvar.GetComponent();
E=其他变量东;
N=其他变量北;
U=其他变量向上;
transform.position=Quaternion.AngleAxis(经度,-Vector3.up)*Quaternion.AngleAxis(纬度,-Vector3.right)*新矢量3(0,0,1);//----不确定
Log(“X ECEF”+transform.position.z);
Log(“Y ECEF”+transform.position.x);
Log(“Z ECEF”+transform.position.y);
EnuToEcef(E,N,U,纬度,经度,地球半径,out enu2ecefx,out enu2ecefy,out enu2ecefz);
finalX=transform.position.z+(float)enu2ecefx;
finalY=transform.position.x+(float)enu2ecefy;
finalZ=transform.position.y+(float)enu2ecefz;
调试日志(“最终X”+finalX);
调试日志(“最终Y”+最终);
Debug.Log(“最终Z”+finalZ);
lat=(浮动)数学Acos(最终/地球半径);
lon=(浮点)数学Atan(最终X/地球半径);
调试日志(“latitude”+lat);
Log(“latitude”+lon);
}
//每帧调用一次更新
无效更新(){
}
公共静态无效值(双E、双N、双U、,
双纬度,双经度,双地球半径,
out double enu2ecefx,out double enu2ecefy,out double enu2ecefz)
{
//按与图纸一致的符号转换为弧度:
var lambda=度弧度(纬度);
var phi=度弧度(经度);
var s=数学Sin(λ);
var n=a/Math.Sqrt(1-e_sq*s*s);
var sin_lambda=Math.sin(lambda);
var cos_lambda=数学cos(lambda);
var cos_phi=数学cos(phi);
var sin_phi=数学sin(phi);
双x0=(接地半径+n)*cos_lambda*cos_phi;
双y0=(接地半径+n)*cos_lambda*sin_phi;
双z0=(接地半径+(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;
双zd=cos_λ*N+sin_λ*U;
enu2ecefx=xd+x0;
enu2ecefy=yd+y0;
enu2ecefz=zd+z0;
调试日志(“car_x ECEF”+enu2ecefx);
调试日志(“car_y ECEF”+enu2ecefy);
调试日志(“car_z ECEF”+enu2ecefz);
}
公共静态双度弧度(双纬度)
{
返回(3.14f/180f)*横向;
}
}

我认为您想要的是将笛卡尔坐标(x,y,z)转换为几何坐标(半径,纬度,经度)

几何坐标几乎类似于球面坐标(半径、极坐标、方位坐标)

这显示了不同之处。纬度角几乎与球坐标(90极坐标)中的角相似。经度是方位角

这为我们提供了以下公式:

笛卡尔坐标到几何坐标

  • radius=sqrt(x^2+y^2+z^2)

  • latitude=arcin(z/半径)

  • 经度=atan2(y,x)

如果其他人需要它:

笛卡尔坐标到球面坐标

  • radius=sqrt(x^2+y^2+z^2)

  • polar=arccos(z/半径)

  • azimuthal=atan2(y,x)

球形到几何坐标

  • 纬度=极地-90°

  • 经度=方位角


我认为您想要的是将笛卡尔坐标(x,y,z)转换为几何坐标(半径,纬度,经度)

几何坐标几乎类似于球面坐标(半径、极坐标、方位坐标)

这显示了不同之处。纬度角几乎为l