天天看点

大疆 DJI PSDK1.5.1 实现时间同步以及精准定位功能

1.时间同步

对于M210 RTK来说:

PPS信号是1HZ 的脉冲信号(一秒一次)同时一个PPS信号包含一个UTC数据

UTC数据包里包含含以下信息:

typedef struct {
    int32_t year;          /*!< Specifies year. */
    int32_t month;         /*!< Specifies month. */
    int32_t day;           /*!< Specifies day. */
    int32_t hour;          /*!< Specifies hour. */
    int32_t minute;        /*!< Specifies minute. */
    int32_t second;        /*!< Specifies second. */
    int32_t nanosecond;    /*!< Specifies nanosecond. */
} T_UtcTsMsg;
           

该结构体可在psdk_cmdset_msg_push.h文件中查看

由于UTC数据来自卫星则可以看作是精准时间,而用户的板载系统需要与这个时间进行同步。UTC数据推送频率与PPS脉冲信号频率一致,如此可以同步飞控系统以及STM32的时间,同步方法如下:

  1. PPS信号的上升沿作为起始信号,STM32端接收到PPS上升沿信号时记录下自己的系统的时间T1
  2. 而该上升沿信号的发送时间为UTC(整秒),所以可以计算出两个系统的时间差为T1-UTC
  3. 由该时间差我们可以同步两个系统的时间,知道任何一个系统的时间都能可以计算出另一个系统的时间
大疆 DJI PSDK1.5.1 实现时间同步以及精准定位功能

注:可参考OSDK的讲解进行理解:https://developer.dji.com/onboard-sdk/documentation/guides/component-guide-hardware-sync.html#principles-of-operation

2.如何精准的请求照片的信息

目前我们所能提供的UTC时间精度为微妙(us)级别,如果使用我们的sample,用get到的UTC时间去请求位置,只能获取到秒的时间,因为sample中 UTC时间是对齐到整秒的。那么如何得到微妙级别的精度呢?举例如下:

Step 1:相机触发拍照时,记录下曝光时间为Te

Step 2:随后检测下一个PPS上升沿到来的时间为Tp,记录该上升沿获取的UTC时间

Step 3:根据上面的时间同步原理,可以计算出相机曝光的准确时间为UTC-(Tp-Te)

Step 4:将曝光时间分离成year、month、day、hour、minute、second、nanosecond

Step 5:定义结构体:T_UtcTsMsg  test_time;并把曝光时间值赋给test_time

注:T_UtcTsMsg格式sample中已提供:

typedef struct {
    int32_t year;          /*!< Specifies year. */
    int32_t month;         /*!< Specifies month. */
    int32_t day;           /*!< Specifies day. */
    int32_t hour;          /*!< Specifies hour. */
    int32_t minute;        /*!< Specifies minute. */
    int32_t second;        /*!< Specifies second. */
    int32_t nanosecond;    /*!< Specifies nanosecond. */
} T_UtcTsMsg;
           

Step 6:将test_time值赋给posAcqReq准备请求位置信息

memcpy(&posAcqReq.year, &test_time, sizeof(T_UtcTsMsg));

posAcqReq的格式sample已提供:

T_PsdkPcePosMultiCamPosReq posAcqReq = {0};

typedef struct {
    uint8_t    camNum;                /*!< Specifies camera number. */
    uint8_t    taskId;                    /*!< Specifies task index. */
    int32_t year; /*!< Specifies year. */
    int32_t month; /*!< Specifies month. */
    int32_t day; /*!< Specifies day. */
    int32_t hour; /*!< Specifies hour. */
    int32_t minute; /*!< Specifies minute. */
    int32_t second; /*!< Specifies second. */
    int32_t reserved; /*!< Specifies nanosecond. */
    T_PsdkPcePosExpoDetlInfo expoDetlInfo[PCEPOS_MAX_PIC_NUM_ONE_POS_REQ];  /*!< Specifies exposure time offset of picture. */

} T_PsdkPcePosMultiCamPosReq;
           

请注意,这个结构体内的纳秒变成了保留位,所以这里的赋值只是到秒级别,那么曝光时间分离出的纳秒在Step 7里面将会用到

Step 7:完善请求信息:

posAcqReq.camNum = 1;              //相机数,最高为5个
posAcqReq.taskId = 1;                 //任务ID
posAcqReq.expoDetlInfo[0].picId = 1;     //请求照片的ID
posAcqReq.expoDetlInfo[0].camId = 1;    //请求相机的ID
posAcqReq.expoDetlInfo[0].timeOfsNs = ;  //照片曝光时间的nanosecond
           

所以曝光时间分离出的纳秒需要赋值给posAcqReq.expoDetlInfo[0].timeOfsN,因为可能会出现同一秒内,用户使用多个相机,拍摄了多张照片的情况。我们把纳秒提出来是为了在一次请求中把所有的照片信息都请求完,而不是分多次请求。我们以一秒内,用户使用一个相机拍摄了两张照片为例:

memcpy(&posAcqReq.year, &test_time, sizeof(T_UtcTsMsg)); //
posAcqReq.camNum = 1;              //相机数,最高为5个
posAcqReq.taskId = 1;                 //任务ID
posAcqReq.expoDetlInfo[0].picId = 1;     //请求照片的ID
posAcqReq.expoDetlInfo[0].camId = 1;    //请求相机的ID
posAcqReq.expoDetlInfo[0].timeOfsNs = ;  //照片1曝光时间的nanosecond
           
posAcqReq.expoDetlInfo[1].picId = 2;     //请求照片的ID
posAcqReq.expoDetlInfo[1].camId = 1;    //请求相机的ID
posAcqReq.expoDetlInfo[1].timeOfsNs = ;  //照片2曝光时间的nanosecond
           

Step 8:调用请求接口,打印位置信息

if (PsdkPcePos_MutilCamPosAcq(&s_psdkUpperHandle, &posAcqReq, &posAcqAck) == PSDK_STAT_OK&& posAcqAck.ackCode == PSDK_CMD_ACK_CODE_OK)
{
PSDK_LOG_DEBUG("Get precise position success.");
PSDK_LOG_DEBUG("pos: %f %f %f", posAcqAck.posDetlInfo[0].mainAntPos.longitude,posAcqAck.posDetlInfo[0].mainAntPos.latitude, posAcqAck.posDetlInfo[0].mainAntPos.height);
}
           

请求所获得的位置信息为一号云台口中心点的位置信息,如果您想获取您相机的中心点位置,可以根据飞机姿态,以及您相机的云台的姿态,进行几何运算。

3.Mark文件

Mark文件简介:https://blog.csdn.net/qq_35781447/article/details/107186832

如何触发飞控记录Mark文件

当PSDK向飞控请求位置信息时,飞控便会返回位置信息给PSDK,并且记录在Mark文件中。请求接口以及返回值判断如下:

if (PsdkPcePos_MutilCamPosAcq(&s_psdkUpperHandle, &posAcqReq, &posAcqAck) == PSDK_STAT_OK&& posAcqAck.ackCode == PSDK_CMD_ACK_CODE_OK)
{
 PSDK_LOG_DEBUG("Get precise position success.");
 PSDK_LOG_DEBUG("pos: %f %f %f", posAcqAck.posDetlInfo[0].mainAntPos.longitude,
 posAcqAck.posDetlInfo[0].mainAntPos.latitude, posAcqAck.posDetlInfo[0].mainAntPos.height);
}