地理参考区域目标

 

地理参考区域目标,以获取其相对于WGS 84地理坐标系的原点和旋转角度的地理位置。我们在下面描述了实现这一点的三种不同选项。

使用下列方法之一对区域目标进行地理参考,可以将设备的地理位置用作区域目标的外部优先权基于体验,尤其是在大空间中。一旦确定了区域目标原点的纬度和经度,以及其方向相对于北方向的CCW(逆时针)旋转角度,就可以按照优先使用设备地理位置构建应用程序的指南。

方法1:对区域目标的原始扫描进行几何布局

一些扫描解决方案为地理注册和扫描对齐提供了便利。如果此数据可用,则区域目标生成将考虑输入扫描数据的来源。

  1. 使用扫描提供商的软件注册扫描源。
  2. 如果需要将资源与此坐标系对齐,或者如果需要处理其他偏移,请保留原点的地理位置作为应用程序的信息。具有扫描数据原点的纬度和经度,以及相对于北向的CCW旋转角方向,以备开发。

注释:区域目标是用一个向上的Y轴定义的,因此如果扫描的输入数据使用不同的约定,可能需要执行额外的旋转以使所有内容Y向上。

供应商特定信息:

  • 使用NavVis扫描时,扫描是在IVION中创建的,可以在数据导入期间进行地理参考。在将原始扫描数据处理成E57伪影的过程中,将保留该参考。有关更多信息,请参阅NavVis文档.
  • Leica REGISTER 360可以在导入过程中使用内置的Geo Image对齐支持或使用地理参考控制点列表对齐扫描,您可以将其应用于已注册的捆绑包。使用RTC360,您还可以利用车载GPS传感器的测量进行自动对准。请咨询徕卡旋风注册器360快速入门指南或工具的内置文档。

使用检索到的纬度和经度以及旋转,您可以开始优先使用设备地理位置.

方法2:使用卫星图像手动对齐创作模型

使用带有成对卫星图像的区域目标创作模型的自上而下视图,在Unity Editor中手动估计路线。这种方法的准确性取决于将扫描位置与卫星图像上可见的信息进行视觉对齐的容易程度。除了Unity Editor之外,您还需要一个用于对齐的图像编辑器。

遵循以下步骤:

  1. 查找扫描位置使用任何显示足够细节以对齐区域目标的地图服务,这也允许您读取精确的坐标。在本例中,我们将使用谷歌地图查找“区域目标样本”目标,其中显示了我们位于马萨诸塞州波士顿海港总部的客户体验中心。

    注释:我们正在使用地图视图,而不是全球视野模式。这可能会在某些地方的高层建筑上产生一些错误,但以下一些步骤不适用全球视野.

  1. 标记已知距离在地图中使用标尺工具,以帮助稍后在Unity中进行缩放。

  2. 拍摄卫星图像标有刻度。为了帮助Unity中的对齐,请在图像编辑工具中将图像裁剪为方形。

  1. 导入区域目标到Unity Editor中,如统一区域目标
  2. 验证原点您在Unity中的AT为(0,0,0)。确保选择枢轴模式,以查看本地坐标系的真实原点位置(而不是游戏对象的中心)。 
    注释:由于原始扫描处理或本例中ATG中的Space-3DT裁剪,扫描原点可能位于区域目标覆盖的实际区域之外。

  3. 通过单击中间的立方体和绿色圆锥体,在自上而下的视图中切换到Unity的“场景视图”到正交模式。

    选择区域目标将使用轴gizmo显示其原点。
  1. 导入捕获的图像在Unity Editor中创建一个新的平面GameObject,并将图像作为其纹理应用。默认情况下,平面为正方形。在前一步中裁剪图像有助于保持纵横比正确,否则此时需要进行纠正。切换此游戏对象的变换全球的本地.
  2. 缩放平面统一,这样统治者的比例尺与Unity的网格相一致–在下面的示例中,20米位于距原点的第二条网格线附近。如果你做得正确,区域目标和卫星图像应该是相同的比例和大小。记住,在统一编辑器中,一切都以米为单位。由此产生的比例因子(此处为9.332943)是任意的,因为它取决于地图中的缩放因子。
  3. 平移和旋转平面对区域目标进行地理参考。平面游戏对象的局部坐标系将移动和旋转。最初,平面的蓝色Z轴与北方向对齐。为了与区域目标对齐,我们必须旋转卫星图像以提供相对于北向角的CCW旋转=95度.
  1. 在卫星图像中查找区域目标的原点位置通过选择“区域目标”并在“场景视图”中放大(0,0)。由于区域目标仍然位于原点(选中以使用枢轴!) 我们将地图移到下面,地图上区域目标(0,0)原点下的点将成为我们的参考点——区域目标原点的地理位置。
  2. 查找原点的地理位置在地图服务上(在谷歌地图上右键单击源位置)。通过单击上下文菜单中的坐标,选择

    (纬度、经度)=(42.35072572772756, -71.04457501396098).

使用检索到的纬度和经度,以及北向的CCW旋转角度,您可以开始优先使用设备地理位置.

方法3:使用测量区域目标和GPS设备姿势对齐

如果其他描述的地理参考方法不可行,或者如果您希望验证其他方法之一的结果,则此方法可能很方便。它使用一个Python脚本和一个包含测量值的输入文件,将区域目标姿势与区域目标原点的地理位置对齐。结果的准确性取决于提供的测量数据的质量。

方法1:在桌面上离线收集样本位置数据

通过明确定义,可以获得最佳结果样本位置在目标(建筑角落、屋顶窗、空调单元或道路标记)中,可以从卫星图像相对准确地查找其地理位置,并使用区域目标的创作模型进行识别。

 

区域目标坐标系

WGS 84中的地理位置
(“GPS位置”)

X(X)

Y(Y)

Z轴

纬度

经度

海拔

样品位置1

-10.0

1

0

-65.814396

125.076176

2.94844144

样品位置2

10

1

0

-65.814554

125.076076

2.08687038

要在统一编辑器中测量区域目标内的位置,请创建一个空的游戏对象,并将其命名为“示例位置1”。选择游戏对象以显示其原点枢轴已选择。现在可以移动和旋转gizmo,使其与场景中的采样位置对齐。

在卫星图像中找到相同的位置,并匹配它们的地理位置,如上表所示。

这种方法适用于这样的情况,即可以识别捕获位置中的对象或环境片段,并且可以从上方看到它们,例如可以在卫星图像中看到它们。

方法2:使用移动设备和自定义应用程序现场收集示例位置数据

或者,也可以通过使用简单的定制应用程序测量和记录成对数据来收集上表的数据。此应用程序应读取环境中不同采样位置的Vuforia区域目标姿势和GPS位置。

这个GPS位置提供商.cs使用设备地理位置作为先前页面中的脚本显示了如何读取GPS位置。

要在运行时捕获设备在区域目标坐标系中的位置,必须使用以下代码段转换设备位置。

类DevicePoseConverter:MonoBehaviour{区域目标行为区域目标;设备姿势行为设备姿势;无效DPPoseToATLocalSpace(){DevicePose.transform(设备姿势转换)。SetParent(AreaTarget.transform);var设备位置InAreaTarget=设备位置.transform.localPosition;DevicePose.transform(设备姿势转换)。SetParent(空);}}

由于建筑物内或周围的实时GPS测量可能存在几米的误差,因此这种方法可能给出的结果不太准确。在这种情况下,最好的措施是在GPS精度尽可能好的位置围绕目标进行几次大间距测量。 

准备路线数据文件

获得足够高质量的测量取决于GPS信号的强度和精度。当数据被认为准确时,我们建议至少获取几个采样点,采样点之间的距离超过一米,如果GPS测量被认为不准确,则最多获取十几个采样点。

下一节中的对齐Python脚本需要一个输入文件,其中包含区域目标和地理位置中的成对设备位置。一个例子对齐输入.txt文件显示预期格式:

#设备在区域目标(x y z)中的位置,设备在GPS中的位置(纬度-高度)-10.0 1.0 0.0 -65.81439611 125.07617591 0.9484414410.0 1.0 0.0 -65.8145536 125.076076 -0.08687038350.0 1.0 -10.0 -65.81440561 125.07592207 2.98062477

将区域目标姿势与GPS坐标对齐

最后,您可以在下面找到区域目标地理位置估计器Python脚本,该脚本将区域目标姿势与格式化输入文件中收集和提供的GPS坐标对齐。

注释:此脚本仅适用于区域目标的二维对齐。

注释:要运行此脚本,您的Python安装必须具有依赖项; argparse(参数解析)随机的,随机的numpy公司、和撇油.

使用输入文件运行下面的脚本将生成区域目标的地理参考信息。使用Python命令python脚本.py-i路径to_input.txt以运行脚本。

使用检索到的纬度和经度以及与北向逆时针旋转的角度,您可以开始优先使用设备地理位置.

#===============================================================================#版权所有(c)2022 PTC Inc.保留所有权利。#Vuforia是PTC Inc.在美国和其他国家注册的商标#国家。#===============================================================================“”区域目标地理位置估计器此脚本估计区域目标的地理位置和方向区域目标和GPS设备位置对。它需要一个.txt输入文件,其中包含包含成对设备位置的行格式为(x y z lat lon alt),其中(x,y,z)是设备在区域目标坐标系和(lat,lon,alt)是相应的GPS纬度和经度以度表示,高度以米表示的位置。GPS坐标转换为笛卡尔东-北-上(ENU)坐标与区域目标坐标系对齐的系统。打印区域目标原点的估计(lat、lon、alt)坐标至控制台,以及从北方以度为单位的逆时针角度区域目标Z轴的方向。请注意,从GPS到ENU和vice-versa的转换使用了一个近似值方法。对于彼此相距100m以内的点,应提供结果足够好,可以开始了。对于较大的区域目标,请考虑使用Python大地测量库中更精确的方法进行替换。"""导入argparse随机输入将numpy导入为np从撇脂进口转变def get_earth_radius(纬度):“”“计算给定纬度(度)下的本地地球半径(米)半径是通过在赤道半径之间插值来近似的以及北极的半径。"""EARTH_RADIUS_METERS_EQUATOR=6378137。接地半径_米_北_极=6356752.314245θ=np.deg2rad(纬度)rst=EARTH_RADIUS_METERS_EQUATOR*np.sin(θ)rct=EARTH_RADIUS_METERS_NORTH_POLE*np.cos(θ)半径=EARTH_radius_METERS_EQUATOR*EARTH_SADIUS_NETERS_NORTH_POLE/np.sqrt(rst*rst+rct*rct)回程半径定义gps_to_enu(gps_position,gps_origin):“”“将纬度、经度、高度转换为东、北、上(简体中文)坐标请注意,这是一种近似方法。各100m范围内分布的点另一方面,它应该提供足够好的结果来开始。对于较大的区域目标,考虑使用Python大地测量库中更精确的方法进行替换。参数----------gps_position:numpy数组数组包含要转换的位置(lat、lon、alt),其中纬度和经度以度为单位,海拔以米为单位gps_origin:numpy数组包含ENU坐标系局部原点(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意原点的定义应尽可能靠近其他GPS位置。退换商品-------numpy数组包含相对于提供的原产地"""local_earth_radius=获取地球半径(gps_origin[0])latitude_deeres_to_meters=本地地球半径*np.pi/180。longitude_radius=本地地球半径*np.cos(np.deg2rad(gps_origin[0]))longitude_deeres_to_meters=经度半径*np.pi/180。相对位置=gps_position-gps_origin东=相对位置[1]*经度_度_米北=相对位置[0]*纬度_度_米up=相对位置[2]return np.array([east,north,up])定义enu_to_area_target(enu_position,gps_orientation_angle):“”“将东、北、上(ENU)坐标转换为区域目标坐标参数----------enu_position:numpy数组包含要转换的(东、北、上)位置(以米为单位)的数组gps_orientation_angle:浮动从北向到区域的逆时针角度(度)目标Z轴退换商品-------numpy数组包含(x,y,z)区域目标坐标(以米为单位)的数组,其中y轴指向上"""gps_orientation_angle_rad=np.deg2rad(gps_方位角)x=enu_position[0]*np.cos(gps_orientation_angle_rad)-enu_pposition[1] *np.sin(gps_orientation_angle_rad)y=enu位置[2]z=enu_position[0]*np.sin(gps_orientation_angle_rad)+enu_pposition[1] *np.cos(gps_orientation_angle_rad)返回np.array([x,y,z])定义gps_to_area_target(gps_position、gps_origin、gps _ orientation_angle):“”“将纬度、经度、高度转换为区域目标坐标参数----------gps_position:numpy数组数组包含要转换的位置(lat、lon、alt),其中纬度和经度以度为单位,海拔以米为单位gps_origin:numpy数组包含ENU坐标系局部原点(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意原点的定义应尽可能靠近其他GPS位置。gps_orientation_angle:浮动从北向到区域目标的逆时针角度(度)Z轴退换商品-------numpy数组包含(x,y,z)区域目标坐标(以米为单位)的数组,其中y轴指向上"""enu_position=gps_to_enu(gps_position,gps_origin)返回enu_to_area_target(enu_position,gps_orientation_angle)定义区域目标到菜单(区域目标位置,gps方向角度):“”“将区域目标坐标转换为东、北、上(简体中文)坐标参数----------区域目标位置:numpy数组包含要转换的(x,y,z)位置(以米为单位)的数组,其中y轴指向上gps_orientation_angle:浮动从北向到区域的逆时针角度(度)目标Z轴退换商品-------numpy数组包含(东、北、上)坐标的数组,单位为米"""gps_orientation_angle_rad=np.deg2rad(gps_方位角)e=区域目标位置[0]*np.cos(gps_方向_角度_拉德)+区域_目标_位置[2]*np.sin(gps_方向_角度_拉德)n=区域目标位置[2]*np.cos(gps_方向_角度_拉德)-区域_目标_位置[0]*np.sin(gps_方向_角度_拉德)u=区域目标位置[1]返回np.数组([e,n,u])定义enu_to_gps(enu_position,gps_origin):“”“将东、北、上(ENU)坐标转换为纬度、经度、海拔请注意,这是一种近似方法。各100m范围内分布的点另一方面,它应该提供足够好的结果来开始。对于较大的区域目标,考虑使用Python大地测量库中更精确的方法进行替换。参数----------enu_position:numpy数组数组包含要转换的位置(lat、lon、alt),其中纬度和经度以度为单位,海拔以米为单位gps_origin:numpy数组包含ENU坐标系局部原点(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意原点的定义应尽可能靠近其他GPS位置。退换商品-------numpy数组数组包含(lat、lon、alt),其中纬度和经度以度为单位海拔以米为单位"""local_earth_radius=获取地球半径(gps_origin[0])latitude_deeres_to_meters=本地地球半径*np.pi/180。longitude_radius=本地地球半径*np.cos(np.deg2rad(gps_origin[0]))longitude_deeres_to_meters=经度半径*np.pi/180。relative_longitude_degrees=enu_position[0]/longitude_dees_to_metersrelative_latitude_dees=enu_position[1]/纬度_度_to_metersrelative_altitude_mers=enu_position[2]纬度=相对纬度+gps_origin[0]经度=relative_longitude_degrees+gps_origin[1]海拔=相对高度米+gps_origin[2]return np.array([纬度、经度、海拔])定义区域目标到全球定位系统(区域目标位置,全球定位系统原点,gps_orientation_angle):“”“将区域目标坐标转换为纬度、经度、高度参数----------区域目标位置:numpy数组包含要转换的(x,y,z)区域目标位置(以米为单位)的数组,其中y轴指向上gps_origin:numpy数组包含ENU坐标系局部原点(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意原点的定义应尽可能靠近其他GPS位置。gps_orientation_angle:浮动从北向到区域目标的逆时针角度(度)Z轴退换商品-------numpy数组数组包含(lat、lon、alt),其中纬度和经度以度为单位海拔以米为单位"""enu_position=区域目标到菜单(区域目标位置,gps_方向_角度)返回enu_to_gps(enu_position,gps_origin)def estimate_offset(区域目标位置,gps位置):“”“估算区域目标的地理位置和方向参数----------区域目标位置:numpy数组以米为单位的(x,y,z)区域目标位置数组,其中y轴指向上gps_positions:numpy数组与区域目标相对应的(lat,lon,alt)GPS坐标数组位置,其中纬度和经度以度为单位,海拔以度为单位米。退换商品-------numpy数组包含区域目标组织的估计值(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意,只有纬度和经度实际上是估计的,所以海拔总是返回零。浮动从北向到区域的估计逆时针角度(度)目标Z轴"""#使用平均GPS位置作为本地坐标原点转换为ENUgps_origin=np.mean(gps_位置,轴=0)转换的gps_positions=[gps_positions中pos的gps_to_enu(pos,gps_origin)]enu_positions=np.array(已转换gps_positions)#估计从区域目标XZ到东西方向的二维变换en_positions=enu_positions[:,0:2]区域目标位置=np.take(区域目标位置,[0,2],轴=1)tform_xz_to_en=transform.estimate_transform(‘核素’,区域目标位置,en_位置)区域目标_xz_origin=np.array([0.,0.])区域目标en_origin=变换矩阵变换(区域目标xz_origin,tform_xz_to_en.params)区域目标enu_origin=np.阵列([area_target_en_origin[0][0],area_target_en_origin[0][1],0.])区域目标gps_origin=enu_to_gps(区域目标enu_origin,gps_oigin)#方向角应从北向区域目标z轴旋转orientation_angle_rad=np.arctan2(tform_xz_to_en.params[0][1],tform_xz_to_en.params[0][0])方位角=np.rad2deg(方位角拉德)返回np.array([区域目标gps_origin[0],区域目标gps _origin[1],0.]),方位角定义generate_random_gps_origin_and_orientation_angle():“”“生成随机GPS原点和方向角退换商品-------numpy数组包含区域目标组织的估计值(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意,只有纬度和经度实际上是估计的,所以海拔总是返回零。浮动从北向到区域的估计逆时针角度(度)目标Z轴"""randR=随机统一返回np.array([randR(-90.,90.),randR(-180.,180.),0.]),randR(-180.,180.)定义generate_random_area_target_position():“”“生成随机区域目标位置退换商品-------numpy数组包含(x,y,z)区域目标坐标(以米为单位)的数组,其中y轴指向上"""randR=随机统一返回np.array([randR(-20.,20.),randR定义generate_noisy_gps_position(区域目标位置,gps_origin,gps_orientation_angle、gps_noise、alt_noise):“”“使用区域目标位置的人工噪声生成GPS位置参数----------区域目标位置:numpy数组包含要转换的(x,y,z)区域目标位置(以米为单位)的数组,其中y轴指向上gps_origin:numpy数组包含ENU坐标系局部原点(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意原点应定义为尽可能靠近其他GPS位置。gps_orientation_angle:浮动从北方向到区域目标Z轴的逆时针角度(度)gps_noise:浮点加入经纬度坐标的噪声标准偏差(米)alt_noise:浮动添加到高度坐标的米噪声标准偏差退换商品-------numpy数组数组包含(lat、lon、alt),其中纬度和经度以度为单位海拔以米为单位"""randR=随机.gausnoisy_area_target_position=np.阵列([randR(区域目标位置[0],gps_noise),randR(区域目标位置[1],alt_noise),randR(区域目标位置[2],gps_noise)])noisy_enu_position=区域目标位置,gps_方向_角度)noisy_gps_position=enu_to_gps(noisy_ enu_position,gps_origin)返回噪音gps_position定义运行源人工数据(区域目标位置,gps_origin,gps_orientation_angle、gps_noise、alt_noise):“”“测试从人工数据估算区域目标地理位置和方向输入的区域目标位置用于计算人工噪声GPS测量值基于所提供的GPS原点和方位角。地理位置和方向然后根据区域目标位置和噪声GPS估计区域目标测量值。将结果与原始GPS原点和方向进行比较角度和误差被打印出来。参数----------区域目标位置:numpy数组以米为单位的(x,y,z)区域目标位置数组,其中y轴指向上gps_origin:numpy数组包含ENU坐标系局部原点(lat、lon、alt)的数组,其中纬度和经度以度为单位,海拔以米为单位。请注意原点的定义应尽可能靠近其他GPS位置。gps_orientation_angle:浮动从北方向到区域目标Z轴的逆时针角度(度)gps_noise:浮点加入经纬度坐标的噪声标准偏差(米)alt_noise:浮点噪声的标准偏差(以米为单位)添加到海拔坐标"""gps_positions=np.array([生成噪音gps位置(位置、gps原点、gps方位角,gps_noise、alt_noise)对于区域目标位置中的位置])estimated_gps_origin,estimated_gps_orientation_angle=估计偏移(区域_目标_位置,gps _位置)estimated_enu_origin=gps_to_enu(估计的gps_origin,gps_oigin)打印(“估计GPS原点误差(度):”)打印(估计的gps_origin[0:2]-gps_原始[0:2])打印(“估计ENU原点误差(米):”)打印(估计的原始值)打印(“估计方位角误差(度):”)打印(估计的gps方位角-gps方位角度)定义test_random_points(num_positions,gps_origin,gps_porientation_angle,gps_noise、alt_noise):“”“从一组随机点测试区域目标地理位置和方向的估计”“”打印(“-----------------------------------”)打印(“从随机点测试偏移计算”)区域目标位置=np.阵列([范围内__的generate_random_area_target_position()(num_positions)])运行来自人工数据(区域目标位置,gps_origin,gps_orientation_angle、gps_noise、alt_noise)定义测试_形状(gps_origin、gps_方位角、gps_noise、alt_noise):“”“从一组3个点测试区域目标地理位置和方向的估计”“”打印(“-----------------------------------”)打印(“从T形的3个位置测试偏移计算”)区域目标位置=np.数组([[-10.,1.,0.],[10.,1.,0],[0., 1., -10.]])运行来自人工数据(区域目标位置,gps_origin,gps_orientation_angle、gps_noise、alt_noise)定义运行测试(种子):“”“使用人工数据运行集合测试”“”随机种子gps_noise=5。alt_noise=1。random_gps_origin,random_gps_orientation_angle=生成random_gs_origin_and_orientation角度()打印(“-----------------------------------”)打印(“GPS原点纬度、经度(度)、海拔(米):”)打印(随机gps_origin)打印(“GPS方位角(度):”)打印(随机gps方向角度)打印(“GPS噪音大小(米):”)打印(gps_noise)打印(“海拔噪声幅度(米):”)打印(alt_noise)测试随机点(5,随机gps_origin,随机gps定向角度,gps_noise、alt_noise)测试_形状(random_gps_origin、random_gps_orientation_angle、gps_noise、,alt_noise)定义运行文件(输入文件路径):“”“根据从文件加载的数据估计区域目标地理位置和方向需要一个.txt输入文件,其中包含包含设备位置对的行格式为(x y z lat lon alt),其中(x,y,z)是设备在区域目标坐标系和(lat,lon,alt)是相应的GPS纬度和经度以度表示,高度以米表示的位置。打印区域目标原点的估计(lat、lon、alt)坐标至控制台,以及从北方以度为单位的逆时针角度区域目标Z轴的方向。参数----------输入文件路径:str包含指定格式的输入数据的文件的路径"""f=打开(输入文件路径,'r')区域目标位置=np.loadtxt(f,usecols=(0,1,2))f.关闭()f=打开(输入文件路径,'r')gps_positions=np.loadtxt(f,usecols=(3,4,5))f.关闭()estimated_gps_origin,estimated_ gps_方位角=estimate_offset(区域_目标_位置,gps _位置)打印(区域目标原点的估计GPS位置(纬度、经度(度)、高度(米)):)打印(估计gps_origin)打印(“估计从北方到区域目标z轴的逆时针角度(度):”)打印(估计的gps方向角度)定义main():parser=argparse。参数分析器()分析器.add_argument(“-i”,“--输入”,帮助=“包含区域目标和GPS坐标系中设备坐标对的输入文件的路径”)分析器.add_argument(“-t”,“--测试”,action=“store_true”,help=“使用随机生成的输入数据,而不是输入文件”)分析器.add_argument(“-s”,“--种子”,默认值=1,类型=int,帮助=“使用随机生成的输入数据运行测试时要使用的随机种子”)args=解析器.parse_args()如果args.input:运行源文件(args.input)elif参数测试:运行测试(args.seed)其他:解析器.print_help()如果__name__=='__main__':main()