5.14.1 基本功能介绍
精准定位(positioning)功能在M300上也是PSDK端口的功能,通常用于负载端获取特定事件发生时的飞机精确定位位置。
飞机的精准定位需要开启RTK并使得RTK fix,负载设备端与飞机端的消息联动便可以指定获取飞机记录的特定位置信息。这个消息就是定位事件,负载端的定位事件可以自定义,可以是拍照,人为触发或者其他任何可以标定本地时间的事件。飞机端的定位事件只有一个就是飞机系统时间,所以精准定位必须使用时间同步功能。使用时间同步将本地事件触发的时间对标到飞机无人机系统时间,然后请求该时间下的飞机定位位置。
5.14.2 主要代码文件
positioning/
├── test_positioning.c
PSDK lib头文件
dji_positioning.h
5.14.3 sample代码实现
精准定位功能因为必须依赖于时间同步功能,所以此sample也是基于STM32 FreeRTOS提供。Linux也可以支持此功能,主要将时间同步功能中的PPS适配,然后定位功能API的使用不需要特殊适配。具体可以参考5.16时间同步功能。
功能入口函数
if (DjiTest_PositioningStartService() != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("psdk positioning init error");
}
初始化
/**
* @brief Initialise positioning module in blocking mode. User should call this function before all other positioning
* operations, just like setting task index, register callback function and requesting positions.
* @note Max execution time of this function is slightly larger than 500ms.
* @note This function has to be called in user task, rather than main() function, and after scheduler being started.
* @return Execution result.
*/
T_DjiReturnCode DjiPositioning_Init(void);
API说明
-
初始化精准定位模块功能,在使用精准定位功能API前必须先调用。与时间同步一样,不要在主线程(任务)中初始化此模块。
-
此接口与时间同步功能的初始化没有关系,需各自分别初始化。
设置任务ID
精准定位功能是通过单个事件的时间来获取位置信息,可以将多个的事件组成任务,通过任务的记录就可以很方便的查看到任务中的事件信息。但是M300之后不再支持通过MARK文件查看定位信息,此任务ID的标记作用就比较有限了。但是本地记录时,依旧可以通过此ID来标记任务。
/**
* @brief Set task index, specifying a sequence number of operations, using to write to mark the file for some post-process
* flows.
* @details One operation may be a precise surveying and mapping task or ten exposures of camera. The default task index
* is 0.
* @param index: task index.
*/
void DjiPositioning_SetTaskIndex(uint8_t index);
API简介
-
用于设定任务ID,默认设置为0就好。
开启精准定位任务
时间同步完成之后,通过简单的初始化,就可以指定事件来获取对应事件发生时的位置信息了。sample通过开启一个线程,直接指定事件时间,并1HZ的频率持续获取飞机在指定事件的精准定位位置信息。
if (osalHandler->TaskCreate("user_positioning_task", DjiTest_PositioningTask,
POSITIONING_TASK_STACK_SIZE, NULL, &s_userPositioningThread) !=
DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("user positioning task create error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
将本地时间转换成飞机时间请参考时间同步功能相关接口(DjiTimeSync_TransferToAircraftTime)说明。
精准定位功能中最重要的一个API:DjiPositioning_GetPositionInformationSync
/**
* @brief The interface is used to get the position of target points and other information (refer to
* ::T_DjiPositioningPositionInfo) based on the timestamp in aircraft time system when some events (positioning events) are
* triggered. The function uses blocking mode.
* @details Users can request positions for multiple events (event set) conveniently, such as sync exposure of
* multiple cameras. User must register callback function used to get the newest PPS triggered timestamp (refer to
* DjiPositioning_RegGetNewestPpsTriggerTimeCallback()) before requesting position. When users have set structure
* parameters of payload and interest points (the points whose position user hope to get, e.g. center point of the camera
* image sensor), the target points are interest points, otherwise the target points are main gimbal interface center.
* Users can use position information of gimbal interface center, position offset between gimbal interface center and
* RTK main antenna, UAV attitude, gimbal structure parameters ,and gimbal attitude to calculate the position of interest
* points in the payload.
* @note Max execution time of this function is slightly larger than 600ms.
* @note All requested timestamp have to be between the time point 2 seconds earlier than the newest synchronized
* timestamp and the time point 1 seconds earlier than the newest synchronized timestamp.
* @param eventCount: count of positioning event set specified by eventInfo parameter. Please ensure the count is less
* than 5.
* @param eventInfo: pointer to positioning event information array.
* @param positionInfo: the position of target points. In Matrice 210 RTK V2 and Matrice 300 RTK aircraft system, it is
* the position of the main gimbal interface always.
* @return Execution result.
*/
T_DjiReturnCode DjiPositioning_GetPositionInformationSync(uint8_t eventCount, T_DjiPositioningEventInfo *eventInfo,
T_DjiPositioningPositionInfo *positionInfo);
API说明
-
通过指定的事件信息来获取飞机的定位记录,最主要的时间信息是无人机系统时间。可以支持同时获取多个事件的定位信息,获取事件的时间要在最新PPS时间点的前2s内,否则将无法获取到飞机上的定位数据。
参数说明
-
eventCount,此时需要获取的事件个数
-
eventInfo,事件信息列表,与需获取事件个数的对应。
typedef struct {
/*! Index of event set in which positioning event is located. The item will be written to mark file in aircraft for
* some post-precess work. If not needed, fill in 0. */
uint16_t eventSetIndex;
/*! Index of target point in payload whose position user is requesting. The item will be written to mark file in
* aircraft for some post-precess work. If not needed, fill in 0. */
uint8_t targetPointIndex;
/*! Timestamp in aircraft time system when the positioning event occur. Users should transfer time in local time
* system to time in aircraft time system by DjiTimeSync_TransferToAircraftTime() interface in time
* synchronization module. */
T_DjiTimeSyncAircraftTime eventTime;
} T_DjiPositioningEventInfo;时间信息都将被记录到Mark file中,但是M300不支持Mark查看后,似乎最重要的就是转换出来的无人机系统时间eventTime了。
-
positionInfo,获取到的位置信息列表,与需获取事件个数对应。
typedef struct {
E_DjiFcSubscriptionPositionSolutionProperty positionSolutionProperty; /*!< Property of position solution. */
T_DjiAttitude3d uavAttitude; /*!< Specifies UAV attitude, unit: degree. */
T_DjiVector3d offsetBetweenMainAntennaAndTargetPoint; /*!< Specifies position offset from RTK main antenna to target points in NED coordinate system, unit: mm. */
T_DjiPositioningPosition targetPointPosition; /*!< Specifies position of target points in GROUND coordinate system. */
T_DjiPositioningPositionStandardDeviation targetPointPositionStandardDeviation; /*!< Specifies position standard deviation of target points. */
} T_DjiPositioningPositionInfo;-
positionSolutionProperty,RTK的位置解属性,通常50 表固定fix解。
-
uavAttitude,无人机的姿态角
-
offsetBetweenMainAntennaAndTargetPoint,RTK主天线位置(M300 4号机臂RTK蘑菇头中心点)到目标点的位置偏移,NED坐标系
-
targetPointPositionStandardDeviation,指定目标点的标准差。
-
事件生成
重点说明一下事件信息生成的逻辑。通过前面的逻辑,我们理清了其实事件点与PPS信号时间没有直接关系,但是在咱们的sample中事件是依赖于PPS最新时间的。sample的实现自然有其应用道理,依托与PPS最新时间点的重点就在于通过API:DjiPositioning_GetPositionInformationSync获取事件时间点需要在最新PPS时间点的前2s。附上官网说明:
说明: 定位事件发生时的无人机时间(无人机系统的时间)应早于最新的PPS 信号上升沿时间,且时间间隔须在1~2s内,如 图2.获取精准定位 所示。
理解:
-
通过时间同步功能,无人机发送PPS信号时会将此PPS脉冲的无人机时间一起发送至PSDK设备端,也就是PPS脉冲的本地时间对应着一个无人机的系统时间。
-
PSDK端请求的事件时间点必须是最新PPS时间之前2s内,换个角度理解这个合理性,无人机那边需要将定位数据包发送到PSDK端,在保证精度的要求下,实际上起到了缓冲作用。PPS脉冲到来在精准定位功能中起到了一个通知角色,也就是通知PSDK设备端飞机端已经准备好了前2s的数据,可以去读取了。
-
获取前2s是缓冲,实时取并不会导致数据丢失,除非间隔2s没有读取数据,缓冲溢出了这个是可能导致数据丢失,PSDK端无法获取的情况。
理解API的使用,再看sample代码。这里使用PPS脉冲获取本地时间并非必须,只是用PPS的本地时间做一个时间标志,再转换成无人机时间时先减去1s,表示事件在最新PPS脉冲时间之前1s。sample是两个事件,再在合法的时间区间内模拟创建两个事件同时获取定位数据。
...
djiStat = DjiTest_TimeSyncGetNewestPpsTriggerLocalTimeUs(&ppsNewestTriggerTimeUs);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("get newest pps trigger time error: 0x%08llX.", djiStat);
continue;
}
for (i = 0; i < DJI_TEST_POSITIONING_EVENT_COUNT; ++i) {
eventInfo[i].eventSetIndex = s_eventIndex;
eventInfo[i].targetPointIndex = i;
djiStat = DjiTimeSync_TransferToAircraftTime(
ppsNewestTriggerTimeUs - 1000000 - i * DJI_TEST_TIME_INTERVAL_AMONG_EVENTS_US, &aircraftTime);
if (djiStat != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("transfer to aircraft time error: 0x%08llX.", djiStat);
continue;
}
eventInfo[i].eventTime = aircraftTime;
}
...
综上
当我们自己的开发,通常不是直接通过PPS时间来转换事件时间。但同样需要实时获取最新的PPS本地时间,只需要判断一下事件发生在PPS时间之前2S内即可。超过2s,可能就获取不到了。时间发生在PPS脉冲时间之后,待PPS通知之后再去获取就好。
5.14.4 开发注意事项
-
精准定位必须启用时间同步功能。
-
精准定位功能的API与时间同步的API本身没有耦合,但一定会使用到时间同步中的API,主要是转换事件时间到无人机系统时间。
-
精准定位功能需要使用RTK,主要是提高精确定位位置,时间同步可以不需要RTK。
-
注意事件时间需要合法,即PPS最新时间的前2s内。
-
精准定位的目标点是单云台云台接口的中心,若需要其他指定点,需要结合获取到的位置信息、姿态信息以及无人机本身的结构位置来计算。
-
评论
0 条评论
请登录写评论。