Skip to content

位置输入

功能介绍

位置输入负责将 原始 GNSS 定位数据DR(航位推算)融合后的车辆位置数据 送入 SDK 定位引擎(Position Engine)。应用侧通过实现 LocationProvider,在获取新的车辆位置后调用 updateLocation,由 SDK 完成后续地图匹配与导航处理。

典型数据来源包括:

来源 说明
原始 GNSS 由系统 LocationManager 或车载 GNSS 模块输出的经纬度、航向、速度等
DR 融合定位 惯导、轮速计等与 GNSS 融合后的位置;建议同时提供 cumDistcumAltelapsedTime 等 DR 生产的数据
隧道 / GNSS丢失 无有效GNSS坐标时,可仅更新 speedsatelliteNumber 等字段(见下文说明)

数据职责边界: HMI 或车机定位模块负责采集与封装传感器数据;SDK 不负责 GNSS/DR 采集,仅通过 LocationProvider 接收封装后的 VehicleLocation 数据。

DR 融合定位: 在 DR 模块中融合 GNSS/IMU/车身信号,持续输入融合后 coordinate,并同步更新 speedbearingelapsedTimecumDistcumAlt,再通过 updateLocation(...) 输入到 SDK。

接入流程

位置输入接入流程

  1. 在 SDK 完成 initialize 后,创建并注入自定义 LocationProvider
  2. onStart() 中启动 GNSS/DR 数据订阅;在 onStop() 中取消订阅。
  3. 每次获取到新的位置数据时,构建VehicleLocation并调用 updateLocation(...) 输入引擎。
  4. 通过 NavigationService.eventHub 注册 PositionEventListener,接收地图匹配后的车辆位置(见 地图匹配输出)。

LocationProvider

LocationProvider 是向定位引擎提供车辆位置数据的抽象接口。构造时需传入 providerName,用于标识数据来源(如 "vehicle-gnss""vehicle-dr")。

生命周期

方法 说明
onStart() 当 SDK 开始使用该 Provider 时调用。在此可启动 GNSS / DR 数据订阅或注册系统定位监听
onStop() 当 SDK 停止使用该 Provider 时调用。在此释放资源并取消相关监听

说明:

  • 注入 Provider 后,SDK 会自动调用 onStart()
  • 切换或移除 Provider 时,SDK 会先调用 onStop(),再完成切换或移除。

状态与位置更新

方法 说明
updateStatus(status) 上报 Provider 当前工作状态。Status.NORMAL 表示正常;Status.OUT_OF_SERVICE 表示暂时不可用(如 GNSS 丢失)
updateLocation(vehicleLocation) 向 SDK 输入一帧车辆位置数据,见下文 VehicleLocation

Status

枚举值 说明
Status.NORMAL Provider 工作正常
Status.OUT_OF_SERVICE Provider 暂时不可用(如 GNSS 关闭、隧道长时间无信号)

注入 Provider

通过 SDK.getInstance().injectLocationProvider(...) 注册自定义 LocationProvider

参数 说明
nullLocationProvider 使用自定义定位源,优先级高于系统 LocationManager;输入频率支持 1~15 Hz
null 或未注入 使用 SDK 默认系统定位 LocationManager,更新频率为 4 Hz
1
2
// SDK initialize 成功后调用
SDK.getInstance().injectLocationProvider(gnssLocationProvider)

VehicleLocation

使用 VehicleLocation.Builder 构建每一帧输入数据。坐标系为 WGS84

字段 类型 必填 精度要求 说明
coordinate LatLon 通常必填 建议至少保留小数点后 6 位(约 0.11 m 量级) 经纬度。合法范围:纬度 [-85, 85],经度 [-180, 180];隧道等无有效 GNSS 坐标时可置为 VehicleLocation.INVALID_COORDINATE
utcTime Long 强烈建议 UTC 时间戳(Unix epoch 起,单位:毫秒) 用于计算位置时间间隔
elapsedTime Long DR 强烈建议 自系统启动后的累计时间(单位:毫秒) 用于 DR 时间基准对齐
bearing Int 强烈建议 1 度(整型) 航向角(度),北为 0,顺时针 [0, 360)
speed Float 强烈建议 建议至少 0.1 m/s 分辨率 速度(m/s);负值视为无效
satelliteNumber Int 隧道、城市峡谷等场景建议 1 颗卫星(整型) 当前 GNSS 卫星数,可用于弱 GNSS / 隧道场景判定
cumDist Float DR 可选 建议至少 0.1 m 分辨率 自启动累计行驶距离(米)
cumAlt Float DR 可选 建议至少 0.1 m 分辨率 自启动累计高度变化(米)

更新频率

通过 LocationProvider.updateLocation 输入数据时:

  • 支持频率:1~15 Hz
  • 由应用侧根据 GNSS / DR 实际输出控制
  • SDK 不强制推荐固定频率

未调用 injectLocationProvider 或传入 null 时,SDK 使用默认系统 LocationProvider,其更新频率为 4 Hz

隧道GNSS丢失场景

enableSelfPropellingUponWeakGPS 需在创建 NavigationService 时预先确定,不支持在运行中临时切换。接入阶段应先评估以下条件:

  • 是否接入外部 DR
  • 是否存在隧道等 GNSS 丢失场景

未接入外部 DR存在隧道等弱 GNSS 场景,建议在初始化时开启该能力。 运行中进入隧道并发生 GNSS 丢失时,可按以下方式输入数据:

  • coordinate 设为 VehicleLocation.INVALID_COORDINATE(90.0, 180.0)
  • 持续更新 speedsatelliteNumber 等辅助字段,用于增强隧道内轨迹推算效果

说明:

  • 隧道内触发自推算后,定位引擎默认以固定 4 Hz 频率进行推算;该频率不等同于上文 LocationProvider.updateLocation 的输入频率(1~15 Hz)。
  • 若已接入外部 DR,通常不建议开启该能力,以避免与外部推算逻辑产生冲突。

示例代码

以下以 GNSS 为例说明 LocationProvider 的实现方式。

实现 GNSS LocationProvider

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class GnssLocationProvider(
    private val context: Context
) : LocationProvider("vehicle-gnss") {

    private val locationManager =
        context.getSystemService(Context.LOCATION_SERVICE) as LocationManager

    private val listener = object : LocationListener {

        override fun onLocationChanged(location: Location) {

            val vehicleLocation = VehicleLocation.Builder()
                .coordinate(location.latitude, location.longitude)
                .utcTime(location.time)
                .bearing(location.bearing.toInt())
                .speed(
                    if (location.hasSpeed())
                        location.speed
                    else
                        VehicleLocation.INVALID_SPEED
                )
                .build()

            updateLocation(vehicleLocation)
        }

        override fun onProviderDisabled(provider: String) {
            updateStatus(Status.OUT_OF_SERVICE)
        }

        override fun onProviderEnabled(provider: String) {
            updateStatus(Status.NORMAL)
        }
    }

    @SuppressLint("MissingPermission")
    override fun onStart() {
        locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            250L,   // 示例值:请按车端实际 GNSS 输出频率配置(建议 1~15 Hz)
            2f,
            listener
        )

        updateStatus(Status.NORMAL)
    }

    override fun onStop() {
        locationManager.removeUpdates(listener)
        updateStatus(Status.OUT_OF_SERVICE)
    }
}

注意事项

  • 线程建议(建议): updateLocation 建议在 GNSS / DR 数据回调线程 中调用,避免在主线程执行复杂数据处理或阻塞操作,以保证定位数据实时性。
  • 输入频率(建议): updateLocation 推荐输入频率为 1~15 Hz;输入频率过低可能导致车位更新不顺滑,过高频率可能增加 CPU 开销,影响整体性能表现。
  • 数据合法性(必须): 经纬度超出合法范围(纬度 [-85, 85],经度 [-180, 180])的定位数据可能不会被导航服务接受。