天天看點

大疆 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);
}