OSDK 3.3
Esse commit está contido em:
@@ -0,0 +1,9 @@
|
|||||||
|
BasedOnStyle: Mozilla
|
||||||
|
Standard: Cpp03
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: true
|
||||||
|
AlignConsecutiveDeclarations: true
|
||||||
|
AllowShortFunctionsOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
*.o
|
||||||
|
*~
|
||||||
|
osdk-core/cmake-modules/DJIOSDKConfig.cmake
|
||||||
|
osdk-core/cmake-modules/DJIOSDKConfigVersion.cmake
|
||||||
|
lib/build-DJI_onboardSDK-Desktop_Qt_5_4_2_MinGW_32bit-Debug/
|
||||||
|
Onboard_SDK_Lib/build-DJI_onboardSDK-Desktop_Qt_5_4_2_MinGW_32bit-Debug/
|
||||||
|
sample/STM32/MDK/Objects/
|
||||||
|
sample/STM32/MDK/Listings/
|
||||||
|
sample/Windows/Windows12/DJIonboardSDK/DJIonboardSDK/Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt_5_4_2_MinGW_32bit-Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt_5_4_2_MinGW_32bit-Release/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt5_5_1_MSVC12_64bit-Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt5_5_1_MSVC12_64bit-Release/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt_5_5_1_MSVC2013_64bit-Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt_5_5_1_MSVC2013_64bit-Release/
|
||||||
|
sample/PureQT/build-onboardSDK-Desktop_Qt_5_5_1_MSVC2012_32bit-Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-5_5_1Mingw-Release/
|
||||||
|
sample/PureQT/build-onboardSDK-msvc2013-Release/
|
||||||
|
sample/PureQT/build-onboardSDK-5_5_1Mingw-Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-msvc2013-Debug/
|
||||||
|
sample/PureQT/build-onboardSDK-*
|
||||||
|
sample/PureQT/onboardSDK/onboardSDK.pro.user
|
||||||
|
|
||||||
|
sample/commandline/build-conboardSDK-5_5_1Mingw-Debug/
|
||||||
|
sample/commandline/build-conboardSDK-5_5_1Mingw-Release/
|
||||||
|
sample/commandline/build-conboardSDK-msvc2013-Release/
|
||||||
|
sample/commandline/build-conboardSDK-msvc2013-Debug/
|
||||||
|
|
||||||
|
sample/Linux/bin
|
||||||
|
sample/commandline/Linux/bin/onboardSDK
|
||||||
|
sample/commandline/build-conboardSDK-Desktop_Qt_5_4_2_MinGW_32bit-Debug/
|
||||||
|
|
||||||
|
sample/STM32/OnBoardSDK_STM32/Project/Objects/
|
||||||
|
sample/STM32/OnBoardSDK_STM32/Project/OnBoardSDK_STM32.uvguix.*
|
||||||
|
sample/STM32/OnBoardSDK_STM32/Project/Listings
|
||||||
|
sample/STM32/OnBoardSDK_STM32/Project/DebugConfig
|
||||||
|
|
||||||
|
sample/Linux/bin/onboardSDK
|
||||||
|
|
||||||
|
*.sw*
|
||||||
|
tags
|
||||||
|
/.cproject
|
||||||
|
/.project
|
||||||
|
|
||||||
|
.vagrant/
|
||||||
|
.idea/
|
||||||
|
bin/
|
||||||
|
build/
|
||||||
|
CMakeFiles/
|
||||||
|
CMakeCache.txt
|
||||||
|
cmake_install.cmake
|
||||||
|
Makefile
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(onboardsdk)
|
||||||
|
|
||||||
|
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||||
|
|
||||||
|
set(DJIOSDK 0)
|
||||||
|
set(DJIOSDK_MINOR_VERSION 1)
|
||||||
|
set(DJIOSDK_PATCH_VERSION 0)
|
||||||
|
set(DJIOSDK_VERSION
|
||||||
|
${DJIOSDK_MAJOR_VERSION}.${DJIOSDK_MINOR_VERSION}.${DJIOSDK_PATCH_VERSION})
|
||||||
|
|
||||||
|
if (${CMAKE_SYSTEM_NAME} MATCHES Linux)
|
||||||
|
add_subdirectory(sample/linux)
|
||||||
|
endif()
|
||||||
+2303
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+20
@@ -0,0 +1,20 @@
|
|||||||
|
# DJI Onboard SDK (OSDK) 3.3
|
||||||
|
|
||||||
|
[](https://gitter.im/dji-sdk/Onboard-SDK?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
|
## What is the DJI Onboard SDK?
|
||||||
|
|
||||||
|
DJI's Onboard SDK allows you to connect your own Onboard Computer to a [supported](https://developer.dji.com/onboard-sdk/documentation/introduction/osdk-hardware-introduction.html#supported-products) DJI vehicle or flight controller using a serial port (TTL UART). For full documentation, please visit the [DJI Developer Site](https://developer.dji.com/onboard-sdk/documentation/). Documentation regarding the code can be found in the [OSDK API Reference](https://developer.dji.com/onboard-api-reference/index.html) section of the developer website.
|
||||||
|
|
||||||
|
## New Major Release
|
||||||
|
|
||||||
|
A new major version of DJI Onboard SDK (v3.3) was released on 15 Jun 2017. This is a full re-write of the DJI OSDK, so be sure to read the [release notes](https://developer.dji.com/onboard-sdk/documentation/appendix/releaseNotes.html).
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
You can get support from DJI and the community with the following methods:
|
||||||
|
|
||||||
|
- Github Issues or [gitter.im](https://gitter.im/dji-sdk/Onboard-SDK)
|
||||||
|
- Send email to dev@dji.com describing your problem and a clear description of your setup
|
||||||
|
- Post questions on [**Stackoverflow**](http://stackoverflow.com) using [**dji-sdk**](http://stackoverflow.com/questions/tagged/dji-sdk) tag
|
||||||
|
- [**DJI Forum**](http://forum.dev.dji.com/en)
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(djiosdk-core)
|
||||||
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING
|
||||||
|
"Choose the type of build Debug/Release/Coverage:"
|
||||||
|
FORCE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Add module path for <name>.cmake conf files
|
||||||
|
set(CURRENT_CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules)
|
||||||
|
|
||||||
|
## Set compiler flags accordingly to the build type
|
||||||
|
if (MSVC)
|
||||||
|
include_directories(${Qt5Widgets_INCLUDES})
|
||||||
|
add_definitions(${Qt5Widgets_DEFINITIONS})
|
||||||
|
set(COMMON_CXX_FLAGS "-std=c++11 ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||||
|
endif (MSVC)
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||||
|
set(COMMON_CXX_FLAGS "-std=c++11 -pthread")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES Darwin)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -g -O0")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 ${COMMON_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (COVERAGE)
|
||||||
|
SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage -fPIC")
|
||||||
|
SET(GCC_COVERAGE_LINK_FLAGS "-lgcov")
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${GCC_COVERAGE_COMPILE_FLAGS}")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE MATCHES "Release")
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${COMMON_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
|
###########
|
||||||
|
## Build ##
|
||||||
|
###########
|
||||||
|
|
||||||
|
## Specify additional locations of header files
|
||||||
|
## Your package locations should be listed before other locations
|
||||||
|
include_directories(
|
||||||
|
api/inc
|
||||||
|
protocol/inc
|
||||||
|
hal/inc
|
||||||
|
utility/inc
|
||||||
|
platform/default/inc
|
||||||
|
)
|
||||||
|
|
||||||
|
# Use this if more platform is supported
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||||
|
include_directories(
|
||||||
|
platform/linux/inc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
## Declare a C++ library
|
||||||
|
FILE(GLOB OSDK_LIB_SRCS
|
||||||
|
api/inc/*.hpp
|
||||||
|
api/src/*.cpp
|
||||||
|
protocol/src/*.cpp
|
||||||
|
hal/src/*.cpp
|
||||||
|
utility/src/*.cpp
|
||||||
|
platform/default/src/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Use this if more platform is supported
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||||
|
FILE(GLOB OSDK_LIB_SRCS ${OSDK_LIB_SRCS} platform/linux/src/*.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME}
|
||||||
|
STATIC
|
||||||
|
${OSDK_LIB_SRCS})
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} pthread)
|
||||||
|
|
||||||
|
################
|
||||||
|
# Installation #
|
||||||
|
################
|
||||||
|
|
||||||
|
set(INSTALL_LIB_DIR lib)
|
||||||
|
set(INSTALL_BIN_DIR bin)
|
||||||
|
set(INSTALL_INCLUDE_DIR include/djiosdk)
|
||||||
|
set(DEF_INSTALL_CMAKE_DIR lib/cmake/djiosdk)
|
||||||
|
set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR})
|
||||||
|
foreach(p LIB BIN INCLUDE CMAKE)
|
||||||
|
set(var INSTALL_${p}_DIR)
|
||||||
|
if(NOT IS_ABSOLUTE "${${var}}")
|
||||||
|
set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Add all targets to the build-tree export set
|
||||||
|
export(TARGETS djiosdk-core
|
||||||
|
FILE "${PROJECT_BINARY_DIR}/djiosdkTargets.cmake")
|
||||||
|
|
||||||
|
# Export the package for use from the build-tree
|
||||||
|
# (this registers the build-tree with a global CMake-registry)
|
||||||
|
export(PACKAGE djiosdk)
|
||||||
|
|
||||||
|
# Create the DJIOSDKConfig.cmake and DJIOSDKConfigVersion files
|
||||||
|
file(RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}"
|
||||||
|
"${INSTALL_INCLUDE_DIR}")
|
||||||
|
# ... for the build tree
|
||||||
|
set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}")
|
||||||
|
configure_file(${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfig.cmake.in
|
||||||
|
"${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfig.cmake" @ONLY)
|
||||||
|
|
||||||
|
# ... for the install tree
|
||||||
|
set(CONF_INCLUDE_DIRS "\${DJIOSDK_CMAKE_DIR}/${REL_INCLUDE_DIR}")
|
||||||
|
|
||||||
|
configure_file(${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfig.cmake.in
|
||||||
|
"${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfig.cmake" @ONLY)
|
||||||
|
|
||||||
|
# ... for both
|
||||||
|
configure_file(${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfigVersion.cmake.in
|
||||||
|
"${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfigVersion.cmake" @ONLY)
|
||||||
|
|
||||||
|
# Install the DJIOSDKConfig.cmake and DJIOSDKConfigVersion.cmake
|
||||||
|
install(FILES
|
||||||
|
"${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfig.cmake"
|
||||||
|
"${CURRENT_CMAKE_MODULE_PATH}/DJIOSDKConfigVersion.cmake"
|
||||||
|
DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
|
||||||
|
|
||||||
|
# Install the export set for use with the install-tree
|
||||||
|
install(EXPORT djiosdkTargets DESTINATION
|
||||||
|
"${INSTALL_CMAKE_DIR}" COMPONENT dev)
|
||||||
|
|
||||||
|
FILE(GLOB OSDK_LIB_HEADERS
|
||||||
|
api/inc/*.h*
|
||||||
|
protocol/inc/*.h*
|
||||||
|
hal/inc/*.h*
|
||||||
|
utility/inc/*.h*
|
||||||
|
default/inc/*.h*
|
||||||
|
platform/linux/inc/*.h*
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
PUBLIC_HEADER "${OSDK_LIB_HEADERS}")
|
||||||
|
|
||||||
|
if(NOT INSTALL_LIB_DIR)
|
||||||
|
message(STATUS, "Install to build folder" )
|
||||||
|
set(INSTALL_LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/lib")
|
||||||
|
set(INSTALL_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS ${PROJECT_NAME}
|
||||||
|
# IMPORTANT: Add the osdk-core library to the "export-set"
|
||||||
|
EXPORT djiosdkTargets
|
||||||
|
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT shlib
|
||||||
|
PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev)
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
/** @file dji_ack.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief All DJI OSDK ACK parsing
|
||||||
|
* @brief ACK error API getError and getErrorCodeMessage
|
||||||
|
* to decode received ACK(s).
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_ACK_HPP
|
||||||
|
#define DJI_ACK_HPP
|
||||||
|
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
#include "dji_mission_type.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
#include "dji_version.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
/*! @brief Class for handling acknowledgements from the aircraft
|
||||||
|
* @details The constructs in this class are used to extract data and metadata
|
||||||
|
* from the incoming packets,
|
||||||
|
* and pack this data into usable return types for blocking API calls.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct Entry
|
||||||
|
{
|
||||||
|
uint8_t cmd_set;
|
||||||
|
uint8_t cmd_id;
|
||||||
|
uint16_t len;
|
||||||
|
uint8_t* buf;
|
||||||
|
uint8_t seqNumber;
|
||||||
|
Version::FirmWare version;
|
||||||
|
} Entry; // pack(1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACK structures not exposed to user
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct HotPointStartInternal
|
||||||
|
{
|
||||||
|
uint8_t ack;
|
||||||
|
float32_t maxRadius;
|
||||||
|
} HotPointStartInternal; // pack(1)
|
||||||
|
|
||||||
|
typedef struct HotPointReadInternal
|
||||||
|
{
|
||||||
|
uint8_t ack;
|
||||||
|
HotPointSettings data;
|
||||||
|
} HotPointReadInternal; // pack(1)
|
||||||
|
|
||||||
|
typedef struct WayPointDataInternal
|
||||||
|
{
|
||||||
|
uint8_t ack;
|
||||||
|
uint8_t index;
|
||||||
|
} WayPointDataInternal; // pack(1)
|
||||||
|
|
||||||
|
typedef struct WayPointVelocityInternal
|
||||||
|
{
|
||||||
|
uint8_t ack;
|
||||||
|
float32_t idleVelocity;
|
||||||
|
} WayPointVelocityInternal; // pack(1)
|
||||||
|
|
||||||
|
typedef struct WayPointInitInternal
|
||||||
|
{
|
||||||
|
uint8_t ack;
|
||||||
|
WayPointInitSettings data;
|
||||||
|
} WayPointInitInternal; // pack(1)
|
||||||
|
|
||||||
|
typedef struct MFIOGetInternal
|
||||||
|
{
|
||||||
|
uint8_t result;
|
||||||
|
uint32_t value;
|
||||||
|
} MFIOGetInternal; // pack(1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACK structures exposed to user
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! @brief This struct is returned from all blocking calls, except certain
|
||||||
|
* mission calls that have explicit types defined later in this file
|
||||||
|
* @note NOT TO BE CONFUSED with class \ref DJI::OSDK::ErrorCode "ErrorCode"
|
||||||
|
* that contains parsing for acknowledgements
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct ErrorCode
|
||||||
|
{
|
||||||
|
Entry info;
|
||||||
|
uint32_t data;
|
||||||
|
} ErrorCode; // pack(1)
|
||||||
|
|
||||||
|
typedef struct MFIOGet
|
||||||
|
{
|
||||||
|
ErrorCode ack;
|
||||||
|
uint32_t value;
|
||||||
|
} MFIOGet; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief This struct is returned from the DJI::OSDK::HotpointMission::start
|
||||||
|
* blocking API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct HotPointStart
|
||||||
|
{
|
||||||
|
ErrorCode ack;
|
||||||
|
float32_t maxRadius;
|
||||||
|
} HotPointStart; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief This struct is returned from the DJI::OSDK::HotpointMission::read
|
||||||
|
* blocking API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct HotPointRead
|
||||||
|
{
|
||||||
|
ErrorCode ack;
|
||||||
|
HotPointSettings data;
|
||||||
|
} HotPointRead; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief This struct is returned from the
|
||||||
|
* DJI::OSDK::WaypointMission::uploadIndexData blocking API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct WayPointIndex
|
||||||
|
{
|
||||||
|
ErrorCode ack;
|
||||||
|
uint8_t index;
|
||||||
|
} WayPointIndex; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief This struct is returned from the
|
||||||
|
* DJI::OSDK::WaypointMission::updateIdleVelocity blocking API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct WayPointVelocity
|
||||||
|
{
|
||||||
|
ErrorCode ack;
|
||||||
|
float32_t idleVelocity;
|
||||||
|
} WayPointVelocity; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief This struct is used in the readInitData non-blocking API callback
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct WayPointInit
|
||||||
|
{
|
||||||
|
ErrorCode ack;
|
||||||
|
WayPointInitSettings data;
|
||||||
|
} WaypointInit; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief This struct is returned from the
|
||||||
|
* DJI::OSDK::Vehicle::getDroneVersion blocking API
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct DroneVersion
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
Version::VersionData data;
|
||||||
|
} DroneVersion; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief This struct captures PushData while ground-station is enabled on
|
||||||
|
* Assistant's SDK Page
|
||||||
|
*/
|
||||||
|
typedef struct WayPointReachedData
|
||||||
|
{
|
||||||
|
uint8_t incident_type; /*! see WayPointIncidentType */
|
||||||
|
uint8_t waypoint_index; /*! the index of current waypt mission */
|
||||||
|
uint8_t current_status; /*! 4 - pre-action, 6 - post-action */
|
||||||
|
uint8_t reserved_1;
|
||||||
|
uint8_t reserved_2;
|
||||||
|
} WayPointReachedData; // pack(1)
|
||||||
|
|
||||||
|
typedef union TypeUnion {
|
||||||
|
uint8_t raw_ack_array[MAX_INCOMING_DATA_SIZE];
|
||||||
|
uint8_t versionACK[MAX_ACK_SIZE];
|
||||||
|
uint16_t ack;
|
||||||
|
uint8_t commandACK;
|
||||||
|
uint8_t missionACK;
|
||||||
|
uint8_t subscribeACK;
|
||||||
|
uint8_t mfioACK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACK(s) containing ACK data plus extra payload
|
||||||
|
*/
|
||||||
|
HotPointStartInternal hpStartACK;
|
||||||
|
HotPointReadInternal hpReadACK;
|
||||||
|
WayPointInitInternal wpInitACK;
|
||||||
|
WayPointDataInternal wpDataACK;
|
||||||
|
WayPointVelocityInternal wpVelocityACK;
|
||||||
|
MFIOGetInternal mfioGetACK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Push Data in ground-station mode
|
||||||
|
*/
|
||||||
|
WayPointReachedData wayPointReachedData;
|
||||||
|
|
||||||
|
} TypeUnion; // pack(1)
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! @brief ACK::getError return type when blocking call is successful
|
||||||
|
static const bool SUCCESS;
|
||||||
|
//! @brief ACK::getError return type when blocking call is unsuccessful
|
||||||
|
static const bool FAIL;
|
||||||
|
|
||||||
|
// Since control authority is a single command, we keep track of state in the
|
||||||
|
// ack-handling
|
||||||
|
// to unify next steps on receiving a control authority ack.
|
||||||
|
static const uint8_t OBTAIN_CONTROL = 1;
|
||||||
|
static const uint8_t RELEASE_CONTROL = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*! @brief Call this function with an ACK::ErrorCode returned from a blocking
|
||||||
|
* call
|
||||||
|
* to find out if the call succeeded or not.
|
||||||
|
* @details If the call did not succeed, recommended workflow is to call
|
||||||
|
* getErrorCodeMessage(ack) to parse the failure ack.
|
||||||
|
* @param ack ACK::ErrorCode returned from a blocking call
|
||||||
|
* @return bool that is SUCCESS if the call was successful, FAIL if the call
|
||||||
|
* was not.
|
||||||
|
*/
|
||||||
|
static bool getError(ErrorCode ack);
|
||||||
|
|
||||||
|
/*! @brief Call this function to get a human-readable message that tells you
|
||||||
|
* the
|
||||||
|
* meaning of the ACK. Most useful when your getError(ack) call
|
||||||
|
* returns FAIL.
|
||||||
|
*
|
||||||
|
* @param ack ACK::ErrorCode returned from a blocking call.
|
||||||
|
* @param func char array for receiving the error message string;
|
||||||
|
* @warning param func is not supported in this release, please pass
|
||||||
|
* \__func\__ as the value for this argument.
|
||||||
|
*/
|
||||||
|
static void getErrorCodeMessage(ErrorCode ack, const char* func);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void getCMDSetActivationMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCommonErrorCodeMessage(ACK::ErrorCode ack);
|
||||||
|
static void getCMDSetSubscribeMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDSetControlMSG(ACK::ErrorCode ack);
|
||||||
|
static void getMotorErrorMessage(ACK::ErrorCode ack);
|
||||||
|
static void getCMDIDSetControlMSG(uint8_t ack, Version::FirmWare version);
|
||||||
|
static void getCMDIDControlMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDIDTaskMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDIDSetArmMSG(ACK::ErrorCode ack);
|
||||||
|
static void getSetBroadcastMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDSetMissionMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDSetSyncMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDSetVirtualRCMSG(ACK::ErrorCode ack);
|
||||||
|
static void getCMDSetMFIOMSG(ACK::ErrorCode ack);
|
||||||
|
|
||||||
|
static const std::map<const uint32_t, const char*> createCommonErrorCodeMap();
|
||||||
|
static const std::map<const uint32_t, const char*>
|
||||||
|
createActivateErrorCodeMap();
|
||||||
|
static const std::map<const uint32_t, const char*>
|
||||||
|
createSubscribeErrorCodeMap();
|
||||||
|
static const std::map<const uint32_t, const char*>
|
||||||
|
createSetControlErrorCodeMap();
|
||||||
|
static const std::map<const uint32_t, const char*> createTaskErrorCodeMap();
|
||||||
|
static const std::map<const uint32_t, const char*>
|
||||||
|
createMissionErrorCodeMap();
|
||||||
|
static const std::map<const uint32_t, const char*> createMFIOErrorCodeMap();
|
||||||
|
}; // class ACK
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
#endif // DJI_ACK_HPP
|
||||||
@@ -0,0 +1,343 @@
|
|||||||
|
/** @file dji_broadcast.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Broadcast Telemetry API for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJIBROADCAST_H
|
||||||
|
#define DJIBROADCAST_H
|
||||||
|
|
||||||
|
#include "dji_telemetry.hpp"
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief Telemetry API through asynchronous "Broadcast"-style messages
|
||||||
|
*
|
||||||
|
* @details Broadcast telemetry is sent by the FC as push data - whenever an
|
||||||
|
* OES connects to the API port on FC, broadcast telemetry starts pushing data
|
||||||
|
* to the OES.
|
||||||
|
*
|
||||||
|
* Frequencies can be set through DJI Assistant 2 or through these APIs.
|
||||||
|
*
|
||||||
|
* @note Broadcast-style telemetry is an old feature, and will not see many
|
||||||
|
* updates.
|
||||||
|
*/
|
||||||
|
class DataBroadcast
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Frequency values
|
||||||
|
*/
|
||||||
|
enum FREQ
|
||||||
|
{
|
||||||
|
FREQ_0HZ = 0,
|
||||||
|
FREQ_1HZ = 1,
|
||||||
|
FREQ_10HZ = 2,
|
||||||
|
FREQ_50HZ = 3,
|
||||||
|
FREQ_100HZ = 4,
|
||||||
|
FREQ_200HZ = 6,
|
||||||
|
FREQ_400HZ = 7,
|
||||||
|
FREQ_HOLD = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @note this enable flag helps you clarify what data
|
||||||
|
* is coming in from data broadcast
|
||||||
|
* If the user specify GPS @50Hz and gyro @10Hz
|
||||||
|
* The whole data packet from broadcast will come
|
||||||
|
* in @50 Hz but gyro will only come in every 5
|
||||||
|
* data packets.
|
||||||
|
* Use this enum with the passFlag then you can
|
||||||
|
* check what data is available
|
||||||
|
* EX:
|
||||||
|
* if (passFlag & DataBroadcast::DATA_ENABLE_FLAG::HAS_W){
|
||||||
|
* // you get gyro data
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
enum DATA_ENABLE_FLAG
|
||||||
|
{
|
||||||
|
HAS_TIME = 0x0001,
|
||||||
|
HAS_Q = 0x0002,
|
||||||
|
HAS_A = 0x0004,
|
||||||
|
HAS_V = 0x0008,
|
||||||
|
HAS_W = 0x0010,
|
||||||
|
HAS_POS = 0x0020,
|
||||||
|
// below flags are for M100
|
||||||
|
HAS_MAG = 0x0040,
|
||||||
|
HAS_RC = 0x0080,
|
||||||
|
HAS_GIMBAL = 0x0100,
|
||||||
|
HAS_STATUS = 0x0200,
|
||||||
|
HAS_BATTERY = 0x0400,
|
||||||
|
HAS_DEVICE = 0x0800,
|
||||||
|
// below flags are for A3
|
||||||
|
A3_HAS_GPS = 0x0040,
|
||||||
|
A3_HAS_RTK = 0x0080,
|
||||||
|
A3_HAS_MAG = 0x0100,
|
||||||
|
A3_HAS_RC = 0x0200,
|
||||||
|
A3_HAS_GIMBAL = 0x0400,
|
||||||
|
A3_HAS_STATUS = 0x0800,
|
||||||
|
A3_HAS_BATTERY = 0x1000,
|
||||||
|
A3_HAS_DEVICE = 0x2000
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
DataBroadcast(Vehicle* vehicle = 0);
|
||||||
|
~DataBroadcast();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Non-Blocking local-cache API
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
/*! Get timestamp from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @return Telemetry::TimeStamp data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::TimeStamp getTimeStamp() const;
|
||||||
|
|
||||||
|
/*! Get software sync timestamp from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details Note that this is unrelated to the hardware sync subscription.
|
||||||
|
* @return Telemetry::SyncStamp data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::SyncStamp getSyncStamp() const;
|
||||||
|
|
||||||
|
/*! Get quaternion data from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
*
|
||||||
|
* @return Quaternion data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Quaternion getQuaternion() const;
|
||||||
|
|
||||||
|
/*! Get acceleration from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details The acceleration may be in body or ground frame, fused or raw,
|
||||||
|
* based on settings on DJI Assistant 2's SDK page.
|
||||||
|
* @return Telemetry::Vector3f data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Vector3f getAcceleration() const;
|
||||||
|
|
||||||
|
/*! Get velocity from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details The velocity may be in body or ground frame
|
||||||
|
* based on settings on DJI Assistant 2's SDK page.
|
||||||
|
* @return Telemetry::Vector3f data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Vector3f getVelocity() const;
|
||||||
|
|
||||||
|
/*! Get Angular Rates from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details The angular rates may be in body or ground frame, fused or raw,
|
||||||
|
* based on settings on DJI Assistant 2's SDK page.
|
||||||
|
* @return Telemetry::Vector3f data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Vector3f getAngularRate() const;
|
||||||
|
|
||||||
|
/*! Get Velocity Info (health) from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details This data is received along with velocity.
|
||||||
|
* @return Telemetry::VelocityInfo data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::VelocityInfo getVelocityInfo() const;
|
||||||
|
|
||||||
|
/*! Get Globalc Position (LLA and metadata) from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details The returned Lat/Lon values are in rad.
|
||||||
|
* @return Telemetry::GlobalPosition data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::GlobalPosition getGlobalPosition() const;
|
||||||
|
|
||||||
|
/*! Get Obstacle info around the vehicle from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details The returned value is relative to your home location.
|
||||||
|
* @return Telemetry::RelativePosition data strucutre with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::RelativePosition getRelativePosition() const;
|
||||||
|
|
||||||
|
/*! Get GPS Info from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details This feature provides detailed GPS info. Available on A3/N3/M600.
|
||||||
|
* You need to enable it separately on DJI Assistant 2's SDK page.
|
||||||
|
* @return Telemetry::GPSInfo data structure with the newest value.
|
||||||
|
*/
|
||||||
|
Telemetry::GPSInfo getGPSInfo() const;
|
||||||
|
|
||||||
|
/*! Get RTK data from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details This feature provides detailed RTK info. Available on A3/M600.
|
||||||
|
* You need to enable it separately on DJI Assistant 2's SDK page.
|
||||||
|
* @return Telemetry::RTK data structure with the newest value.
|
||||||
|
*/
|
||||||
|
Telemetry::RTK getRTKInfo() const;
|
||||||
|
|
||||||
|
/*! Get Magnetometer data from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @details The returned value is calibrated mag data,
|
||||||
|
* 1000 < |mag| < 2000 for normal operation
|
||||||
|
* @return Telemetry::Mag data structure with the newest value.
|
||||||
|
*/
|
||||||
|
Telemetry::Mag getMag() const;
|
||||||
|
|
||||||
|
/*! Get RC channel data from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
* @return Telemetry::RC data structure with the newest value.
|
||||||
|
*/
|
||||||
|
Telemetry::RC getRC() const;
|
||||||
|
|
||||||
|
/*! Get Gimbal data from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
*
|
||||||
|
* @return Telemetry::Gimbal data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Gimbal getGimbal() const;
|
||||||
|
|
||||||
|
/*! Get Status (flight status, mode, gear and error) from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
*
|
||||||
|
* @return Telemetry::Status data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Status getStatus() const;
|
||||||
|
|
||||||
|
/*! Get Battery Info from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
*
|
||||||
|
* @return Telemetry::Battery data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::Battery getBatteryInfo() const;
|
||||||
|
|
||||||
|
/*! Get SDK Control Mode/Authority info from local cache
|
||||||
|
* @note This getter function is only available with Broadcast, not with Subscribe telemetry
|
||||||
|
*
|
||||||
|
* @return Telemetry::SDKInfo data structure with the newest value
|
||||||
|
*/
|
||||||
|
Telemetry::SDKInfo getSDKInfo() const;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*! Non-blocking call for Frequency setting
|
||||||
|
*
|
||||||
|
* @param dataLenIs16 Array of length 16 that has frequency values for each
|
||||||
|
* topic
|
||||||
|
* @param callback Callback function you want called upon ACK
|
||||||
|
* @param userData Additional data you want the callback function to have
|
||||||
|
* access to
|
||||||
|
*/
|
||||||
|
void setBroadcastFreq(uint8_t* dataLenIs16, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! Blocking call for Frequency setting
|
||||||
|
*
|
||||||
|
* @param dataLenIs16 Array of length 16 that has frequency values for each
|
||||||
|
* topic
|
||||||
|
* @param wait_timeout Time(in s) you want the function to wait for an ACK
|
||||||
|
* @return ACK::ErrorCode struct containing the ACK and metadata
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode setBroadcastFreq(uint8_t* dataLenIs16, int wait_timeout);
|
||||||
|
|
||||||
|
/*! Non-Blocking call for setting default frequencies
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setBroadcastFreqDefaults();
|
||||||
|
|
||||||
|
/*! Blocking call for setting default frequencies
|
||||||
|
*
|
||||||
|
* @param wait_timeout Time(in s) you want the function to wait for an ACK
|
||||||
|
* @return ACK::ErrorCode struct containing the ACK and metadata
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode setBroadcastFreqDefaults(int timeout);
|
||||||
|
|
||||||
|
/*! Non-Blocking call for setting all frequencies to zero
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setBroadcastFreqToZero();
|
||||||
|
|
||||||
|
/*! getter function for passFlag
|
||||||
|
*
|
||||||
|
* @return uint16_t passFlag
|
||||||
|
*/
|
||||||
|
uint16_t getPassFlag();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vehicle* getVehicle() const;
|
||||||
|
void setVehicle(Vehicle* vehiclePtr);
|
||||||
|
/*
|
||||||
|
* @note Distinguish between different FW versions
|
||||||
|
*/
|
||||||
|
void setVersionDefaults(uint8_t* frequencyBuffer);
|
||||||
|
void setFreqDefaultsM100_31(uint8_t* frequencyBuffer);
|
||||||
|
void setFreqDefaults(uint8_t* frequencyBuffer);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setUserBroadcastCallback(VehicleCallBack callback, UserData userData);
|
||||||
|
VehicleCallBackHandler unpackHandler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void unpackCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
static void setFrequencyCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// clang-format off
|
||||||
|
typedef enum FLAG {
|
||||||
|
FLAG_TIME = 0X0001,
|
||||||
|
FLAG_QUATERNION = 0X0002,
|
||||||
|
FLAG_ACCELERATION = 0X0004,
|
||||||
|
FLAG_VELOCITY = 0X0008,
|
||||||
|
FLAG_ANGULAR_RATE = 0X0010,
|
||||||
|
FLAG_POSITION = 0X0020,
|
||||||
|
FLAG_GPSINFO = 0X0040,
|
||||||
|
FLAG_RTKINFO = 0X0080,
|
||||||
|
FLAG_MAG = 0X0100,
|
||||||
|
FLAG_RC = 0X0200,
|
||||||
|
FLAG_GIMBAL = 0X0400,
|
||||||
|
FLAG_STATUS = 0X0800,
|
||||||
|
FLAG_BATTERY = 0X1000,
|
||||||
|
FLAG_DEVICE = 0X2000,
|
||||||
|
FLAG_END = 0X4000
|
||||||
|
} FLAG;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
private:
|
||||||
|
void unpackData(RecvContainer* recvFrame);
|
||||||
|
|
||||||
|
inline void unpackOne(FLAG flag, void* data, uint8_t*& buf, size_t size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// clang-format off
|
||||||
|
Telemetry::TimeStamp timeStamp ;
|
||||||
|
Telemetry::SyncStamp syncStamp ;
|
||||||
|
Telemetry::Quaternion q ;
|
||||||
|
Telemetry::Vector3f a ;
|
||||||
|
Telemetry::Vector3f v ;
|
||||||
|
Telemetry::Vector3f w ;
|
||||||
|
Telemetry::VelocityInfo vi ;
|
||||||
|
Telemetry::GlobalPosition gp ;
|
||||||
|
Telemetry::RelativePosition rp ;
|
||||||
|
Telemetry::GPSInfo gps ;
|
||||||
|
Telemetry::RTK rtk ;
|
||||||
|
Telemetry::Mag mag ;
|
||||||
|
Telemetry::RC rc ;
|
||||||
|
Telemetry::Gimbal gimbal ;
|
||||||
|
Telemetry::Status status ;
|
||||||
|
Telemetry::Battery battery ;
|
||||||
|
Telemetry::SDKInfo info ;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
uint16_t passFlag;
|
||||||
|
|
||||||
|
VehicleCallBackHandler userCbHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
#endif // DJIBROADCAST_H
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/** @file dji_camera.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Camera/Gimbal API for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_CAMERA_H
|
||||||
|
#define DJI_CAMERA_H
|
||||||
|
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declaration
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief Camera class for controlling camera-related functions
|
||||||
|
* available through open protocol
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Camera(Vehicle* vehicle);
|
||||||
|
~Camera();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Non-Blocking API
|
||||||
|
/*! take a photo, check DJI Go app or SD card for photo */
|
||||||
|
void shootPhoto();
|
||||||
|
/*! start recording video, check DJI Go app or SD card for video */
|
||||||
|
void videoStart();
|
||||||
|
/*! stop recording video, check DJI Go app or SD card for video */
|
||||||
|
void videoStop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*! @brief Function for commanding: Take Picture, Start Video, Stop Video
|
||||||
|
* @note The camera function does not return an acknowledgment.
|
||||||
|
* @param cmd array representing camera command
|
||||||
|
* Available camera commands:
|
||||||
|
* OpenProtocol::CMDSet::Control::cameraShot
|
||||||
|
* OpenProtocol::CMDSet::Control::cameraVideoStart
|
||||||
|
* OpenProtocol::CMDSet::Control::cameraVideoStop
|
||||||
|
*/
|
||||||
|
void action(const uint8_t cmd[]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
}; // class camera
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // DJI_CAMERA_H
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/** @file dji_command.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief All DJI OSDK OpenProtocol Command IDs
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_COMMAND_H
|
||||||
|
#define DJI_COMMAND_H
|
||||||
|
|
||||||
|
#include "dji_error.hpp"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
class OpenProtocol : public ErrorCode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const static int MAX_CMD_ARRAY_SIZE = 2;
|
||||||
|
|
||||||
|
class CMDSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef struct Activation
|
||||||
|
{
|
||||||
|
const static uint8_t getVersion[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t activate[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t frequency[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t toMobile[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} Activation;
|
||||||
|
|
||||||
|
typedef struct Broadcast
|
||||||
|
{
|
||||||
|
const static uint8_t broadcast[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t fromMobile[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t lostCTRL[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t mission[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t subscribe[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t test[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypoint[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} Broadcast;
|
||||||
|
|
||||||
|
typedef struct Control
|
||||||
|
{
|
||||||
|
const static uint8_t setControl[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t task[MAX_CMD_ARRAY_SIZE];
|
||||||
|
// CMD_ID_STATUS Not used at all
|
||||||
|
const static uint8_t status[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t control[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t gimbalSpeed[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t gimbalAngle[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t cameraShot[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t cameraVideoStart[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t cameraVideoStop[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} Control;
|
||||||
|
|
||||||
|
typedef struct Mission
|
||||||
|
{
|
||||||
|
// Waypoint mission commands
|
||||||
|
const static uint8_t waypointInit[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointAddPoint[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointSetStart[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointSetPause[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointDownload[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointIndex[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointSetVelocity[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t waypointGetVelocity[MAX_CMD_ARRAY_SIZE];
|
||||||
|
// Hotpint mission commands
|
||||||
|
const static uint8_t hotpointStart[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t hotpointStop[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t hotpointSetPause[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t hotpointYawRate[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t hotpointRadius[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t hotpointSetYaw[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t hotpointDownload[MAX_CMD_ARRAY_SIZE];
|
||||||
|
// Follow mission commands
|
||||||
|
const static uint8_t followStart[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t followStop[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t followSetPause[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t followTarget[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} Mission;
|
||||||
|
|
||||||
|
typedef struct HardwareSync
|
||||||
|
{
|
||||||
|
const static uint8_t broadcast[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} HardwareSync;
|
||||||
|
|
||||||
|
typedef struct VirtualRC
|
||||||
|
{
|
||||||
|
const static uint8_t settings[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t data[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} VirtualRC;
|
||||||
|
|
||||||
|
typedef struct MFIO
|
||||||
|
{
|
||||||
|
const static uint8_t init[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t get[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t set[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} MFIO;
|
||||||
|
|
||||||
|
typedef struct Subscribe
|
||||||
|
{
|
||||||
|
const static uint8_t versionMatch[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t addPackage[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t reset[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t removePackage[MAX_CMD_ARRAY_SIZE];
|
||||||
|
// TODO implement API call
|
||||||
|
const static uint8_t updatePackageFreq[MAX_CMD_ARRAY_SIZE];
|
||||||
|
const static uint8_t pauseResume[MAX_CMD_ARRAY_SIZE];
|
||||||
|
// TODO implement API call
|
||||||
|
const static uint8_t getConfig[MAX_CMD_ARRAY_SIZE];
|
||||||
|
} Subscribe;
|
||||||
|
|
||||||
|
//! CMD SET definitions
|
||||||
|
const static uint8_t activation = 0x00;
|
||||||
|
const static uint8_t control = 0x01;
|
||||||
|
const static uint8_t broadcast = 0x02;
|
||||||
|
const static uint8_t mission = 0x03;
|
||||||
|
const static uint8_t hardwareSync = 0x04;
|
||||||
|
const static uint8_t virtualRC = 0x05;
|
||||||
|
const static uint8_t mfio = 0x09;
|
||||||
|
const static uint8_t subscribe = 0x0B;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif /* DJI_COMMAND_H */
|
||||||
@@ -0,0 +1,421 @@
|
|||||||
|
/** @file dji_control.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Control API for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_CONTROL_H
|
||||||
|
#define DJI_CONTROL_H
|
||||||
|
|
||||||
|
#include "dji_ack.hpp"
|
||||||
|
#include "dji_open_protocol.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief Flight control API: high-level actions and low-level control modes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Control
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*! @brief Flight control commands
|
||||||
|
*/
|
||||||
|
class FlightCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* @note Deprecated in OSDK release 3.3
|
||||||
|
*/
|
||||||
|
const static int TASK_GOHOME = 1;
|
||||||
|
const static int TASK_TAKEOFF = 4;
|
||||||
|
const static int TASK_LANDING = 6;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @note OSDK release 3.3
|
||||||
|
*/
|
||||||
|
const static int takeOff = 1; /*!< vehicle takeoff*/
|
||||||
|
const static int landing = 2; /*!< vehicle landing*/
|
||||||
|
//! @note independent mode courseLock,
|
||||||
|
//! cannot be controlled through SDK
|
||||||
|
const static int courseLock = 5;
|
||||||
|
const static int goHome = 6; /*!< vehicle return home position*/
|
||||||
|
const static int startMotor = 7;
|
||||||
|
const static int stopMotor = 8;
|
||||||
|
const static int calibrateCompass = 9;
|
||||||
|
const static int exitGoHome = 12;
|
||||||
|
const static int exitTakeOff = 13;
|
||||||
|
const static int exitLanding = 14;
|
||||||
|
const static int exitCalibrateCompass = 21;
|
||||||
|
const static int landingGearDown = 28;
|
||||||
|
const static int landingGearUp = 29;
|
||||||
|
};
|
||||||
|
// clang-format off
|
||||||
|
/*! @brief bit 5:4 of the 8-bit (7:0) CtrlData.flag
|
||||||
|
*
|
||||||
|
* We suggest developers do not use VERTICAL_POSITION control mode indoor
|
||||||
|
* when your UAV
|
||||||
|
* flight height is larger than 3 meters.
|
||||||
|
* This is because in indoor environments, barometer can be inaccurate, and
|
||||||
|
* the
|
||||||
|
* vertical controller may fail to keep the height of the UAV.
|
||||||
|
*/
|
||||||
|
enum VerticalLogic
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control the vertical
|
||||||
|
speed of UAV, upward is positive
|
||||||
|
- Limit: -5 to 5 m/s
|
||||||
|
*/
|
||||||
|
VERTICAL_VELOCITY = 0x00,
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control the height of UAV
|
||||||
|
- Limit: 0 to 120 m
|
||||||
|
*/
|
||||||
|
VERTICAL_POSITION = 0x10,
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to directly control the thrust
|
||||||
|
- Range: 0% to 100%
|
||||||
|
*/
|
||||||
|
VERTICAL_THRUST = 0x20,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! @brief bit 7:6 of the 8-bit (7:0) CtrlData.flag
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* - Only when the GPS signal is good (health_flag >=3),horizontal
|
||||||
|
* position control (HORIZONTAL_POSITION) related control modes can be used.
|
||||||
|
* - Only when GPS signal is good (health_flag >=3),or when Guidance
|
||||||
|
* system is working properly with Autopilot,
|
||||||
|
* horizontal velocity control(HORIZONTAL_VELOCITY)related control
|
||||||
|
* modes can be used.
|
||||||
|
*/
|
||||||
|
enum HorizontalLogic
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control pitch & roll
|
||||||
|
angle of the vehicle.
|
||||||
|
- Need to be referenced to either the ground or
|
||||||
|
body frame by HorizontalCoordinate setting.
|
||||||
|
- Limit: 35 degree
|
||||||
|
*/
|
||||||
|
HORIZONTAL_ANGLE = 0x00,
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control horizontal
|
||||||
|
vehicle velocities.
|
||||||
|
- Need to be referenced to either the ground
|
||||||
|
or body frame by HorizontalCoordinate setting.
|
||||||
|
- Limit: 30 m/s
|
||||||
|
*/
|
||||||
|
HORIZONTAL_VELOCITY = 0x40,
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control position
|
||||||
|
offsets of pitch & roll directions
|
||||||
|
- Need to be referenced to either the ground
|
||||||
|
or body frame by HorizontalCoordinate setting.
|
||||||
|
- Limit: N/A
|
||||||
|
*/
|
||||||
|
HORIZONTAL_POSITION = 0x80,
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control rate of
|
||||||
|
change of the vehicle's attitude
|
||||||
|
- Need to be referenced to either the ground
|
||||||
|
or body frame by HorizontalCoordinate setting.
|
||||||
|
- Limit: 150.0 deg/s
|
||||||
|
*/
|
||||||
|
HORIZONTAL_ANGULAR_RATE = 0xC0
|
||||||
|
};
|
||||||
|
/*! @brief bit 3 of the 8-bit (7:0) CtrlData.flag
|
||||||
|
*/
|
||||||
|
enum YawLogic
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control yaw angle.
|
||||||
|
- Yaw angle is referenced to the ground frame.
|
||||||
|
- In this control mode, Ground frame is enforeced in Autopilot.
|
||||||
|
*/
|
||||||
|
YAW_ANGLE = 0x00,
|
||||||
|
/*!
|
||||||
|
- Set the control-mode to control yaw angular velocity.
|
||||||
|
- Same reference frame as YAW_ANGLE.
|
||||||
|
- Limite: 150 deg/s
|
||||||
|
*/
|
||||||
|
YAW_RATE = 0x08
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! @brief bit 2:1 of the 8-bit (7:0) CtrlData.flag
|
||||||
|
*/
|
||||||
|
enum HorizontalCoordinate
|
||||||
|
{
|
||||||
|
/*! Set the x-y of ground frame as the horizontal frame (NEU) */
|
||||||
|
HORIZONTAL_GROUND = 0x00,
|
||||||
|
/*! Set the x-y of body frame as the horizontal frame (FRU) */
|
||||||
|
HORIZONTAL_BODY = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief bit 0 of the 8-bit (7:0) CtrlData.flag.
|
||||||
|
*
|
||||||
|
* Drone will try to hold at current position if enable
|
||||||
|
*/
|
||||||
|
enum StableMode
|
||||||
|
{
|
||||||
|
STABLE_DISABLE = 0x00, /*!< Disable the stable mode */
|
||||||
|
STABLE_ENABLE = 0x01 /*!< Enable the stable mode */
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
/*! The struct for CtrlData
|
||||||
|
|
||||||
|
*/
|
||||||
|
#pragma pack(1)
|
||||||
|
/*! @brief CtrlData used for flight control.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct CtrlData
|
||||||
|
{
|
||||||
|
uint8_t flag; /*!< control data flag consists of 8 bits.
|
||||||
|
|
||||||
|
- CtrlData.flag = ( DJI::OSDK::Control::HorizontalLogic |
|
||||||
|
DJI::OSDK::Control::VerticalLogic |
|
||||||
|
DJI::OSDK::Control::YawLogic |
|
||||||
|
DJI::OSDK::Control::HorizontalCoordinate |
|
||||||
|
DJI::OSDK::Control::StableMode)
|
||||||
|
*/
|
||||||
|
float32_t x; /*!< Control with respect to the x axis of the
|
||||||
|
DJI::OSDK::Control::HorizontalCoordinate.*/
|
||||||
|
float32_t y; /*!< Control with respect to the y axis of the
|
||||||
|
DJI::OSDK::Control::HorizontalCoordinate.*/
|
||||||
|
float32_t z; /*!< Control with respect to the z axis, up is positive. */
|
||||||
|
float32_t yaw; /*!< Yaw position/velocity control w.r.t. the ground frame.*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief CtrlData initialize the CtrlData variable.
|
||||||
|
* \param in_flag See CtrlData.flag
|
||||||
|
* \param in_x See CtrlData.x
|
||||||
|
* \param in_y See CtrlData.y
|
||||||
|
* \param in_z See CtrlData.z
|
||||||
|
* \param in_yaw See CtrlData.yaw
|
||||||
|
*/
|
||||||
|
CtrlData(uint8_t in_flag, float32_t in_x, float32_t in_y, float32_t in_z,
|
||||||
|
float32_t in_yaw);
|
||||||
|
} CtrlData; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief AdvancedCtrlData
|
||||||
|
*
|
||||||
|
* @note for flag, x, y, z, yaw definition see CtrlData.
|
||||||
|
*/
|
||||||
|
typedef struct AdvancedCtrlData
|
||||||
|
{
|
||||||
|
uint8_t flag;
|
||||||
|
uint8_t advFlag;
|
||||||
|
float32_t x;
|
||||||
|
float32_t y;
|
||||||
|
float32_t z;
|
||||||
|
float32_t yaw;
|
||||||
|
float32_t xFeedforward;
|
||||||
|
float32_t yFeedforward;
|
||||||
|
|
||||||
|
AdvancedCtrlData(uint8_t in_flag, float32_t in_x, float32_t in_y,
|
||||||
|
float32_t in_z, float32_t in_yaw, float32_t x_forw,
|
||||||
|
float32_t y_forw);
|
||||||
|
} AdvancedCtrlData; // pack(1)
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
/*! @note
|
||||||
|
*
|
||||||
|
* Basically control class provide two functions:
|
||||||
|
* 1. action() which implements CMD_ID_TASK
|
||||||
|
* 2. modeCtrl() which implements CMD_ID_CONTROL
|
||||||
|
*
|
||||||
|
* The rest of the functions are just wrapper functions
|
||||||
|
* that provide commonly used control functions
|
||||||
|
* EX: takeoff, landing, and position control mode
|
||||||
|
*/
|
||||||
|
private:
|
||||||
|
const int wait_timeout;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Control(Vehicle* vehicle = 0);
|
||||||
|
~Control();
|
||||||
|
|
||||||
|
Vehicle* vehicle;
|
||||||
|
|
||||||
|
/*! @brief Basic action command for the vehicle, see FlightCommand for cmd
|
||||||
|
* choices
|
||||||
|
*
|
||||||
|
* @param cmd action command from FlightCommand
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void action(const int cmd, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief Control the vehicle using user-specified mode, see FlightCommand
|
||||||
|
* for cmd choices
|
||||||
|
*
|
||||||
|
* @param cmd action command from FlightCommand
|
||||||
|
* @param timeout timeout to wait for ACK
|
||||||
|
* @return ErrorCode
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode action(const int cmd, int timeout);
|
||||||
|
|
||||||
|
/*! @brief Wrapper function for arming the motors
|
||||||
|
*
|
||||||
|
* @return ACK::ErrorCode struct with the acknowledgement from the FC
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode armMotors(int wait_timeout);
|
||||||
|
/*! @brief Wrapper function for arming the motors
|
||||||
|
*
|
||||||
|
* @note If user does not provide his/her own callback, default callback
|
||||||
|
* will be executed
|
||||||
|
*/
|
||||||
|
void armMotors(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
/*! @brief Wrapper function for disarming the motors
|
||||||
|
*
|
||||||
|
* @return ACK::ErrorCode struct with the acknowledgement from the FC
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode disArmMotors(int wait_timeout);
|
||||||
|
/*! @brief Wrapper function for disarming the motors
|
||||||
|
*
|
||||||
|
* @note If user does not provide his/her own callback, default callback
|
||||||
|
* will be executed
|
||||||
|
*/
|
||||||
|
void disArmMotors(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
/*! @brief Wrapper function for take off
|
||||||
|
*
|
||||||
|
* @return ACK::ErrorCode struct with the acknowledgement from the FC
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode takeoff(int wait_timeout);
|
||||||
|
/*! @brief Wrapper function for take off
|
||||||
|
*
|
||||||
|
* @note If user does not provide his/her own callback, default callback
|
||||||
|
* will be executed
|
||||||
|
*/
|
||||||
|
void takeoff(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
/*! @brief Wrapper function for go Home
|
||||||
|
*
|
||||||
|
* @return ACK::ErrorCode struct with the acknowledgement from the FC
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode goHome(int wait_timeout);
|
||||||
|
/*! @brief Wrapper function for go Home
|
||||||
|
*
|
||||||
|
* @note If user does not provide his/her own callback, default callback
|
||||||
|
* will be executed
|
||||||
|
*/
|
||||||
|
void goHome(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
/*! @brief Wrapper function for landing
|
||||||
|
*
|
||||||
|
* @return ACK::ErrorCode struct with the acknowledgement from the FC
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode land(int wait_timeout);
|
||||||
|
/*! @brief Wrapper function for landing
|
||||||
|
*
|
||||||
|
* @note If user does not provide his/her own callback, default callback
|
||||||
|
* will be executed
|
||||||
|
*/
|
||||||
|
void land(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
/*! @brief Control the vehicle using user-specified mode
|
||||||
|
*
|
||||||
|
* @param data control set-points and flags
|
||||||
|
*/
|
||||||
|
void flightCtrl(CtrlData data);
|
||||||
|
|
||||||
|
/*! @brief Control the vehicle using user-specified mode (overloaded)
|
||||||
|
*
|
||||||
|
* @note this mode only works in HORIZONTAL_VELOCITY and the unit of
|
||||||
|
* feedforward term is m/s^2
|
||||||
|
*
|
||||||
|
* @param data control set-points and flags
|
||||||
|
*/
|
||||||
|
void flightCtrl(AdvancedCtrlData data);
|
||||||
|
|
||||||
|
/*! @brief Control the position and yaw angle of the vehicle.
|
||||||
|
* The reference frame is the DJI::OSDK::Control::HORIZONTAL_GROUND (NEU).
|
||||||
|
*
|
||||||
|
* @param x position set-point in x axis of ground frame (m)
|
||||||
|
* @param y position set-point in y axis of ground frame (m)
|
||||||
|
* @param z position set-point in z axis of ground frame (m), input limit see
|
||||||
|
* DJI::OSDK::Control::VERTICAL_POSITION
|
||||||
|
* @param yaw yaw set-point (deg)
|
||||||
|
*/
|
||||||
|
void positionAndYawCtrl(float32_t x, float32_t y, float32_t z, float32_t yaw);
|
||||||
|
|
||||||
|
/*! @brief Control the velocity and yaw rate of the vehicle.
|
||||||
|
* The reference frame is the DJI::OSDK::Control::HORIZONTAL_GROUND (NEU).
|
||||||
|
*
|
||||||
|
* @param Vx velocity set-point in x axis of ground frame (m/s), input limit
|
||||||
|
* see DJI::OSDK::Control::HORIZONTAL_VELOCITY
|
||||||
|
* @param Vy velocity set-point in y axis of ground frame (m/s), input limit
|
||||||
|
* see DJI::OSDK::Control::HORIZONTAL_VELOCITY
|
||||||
|
* @param Vz velocity set-point in z axis of ground frame (m/s), input limit
|
||||||
|
* see DJI::OSDK::Control::VERTICAL_VELOCITY
|
||||||
|
* @param yawRate yawRate set-point (deg/s)
|
||||||
|
*/
|
||||||
|
void velocityAndYawRateCtrl(float32_t Vx, float32_t Vy, float32_t Vz,
|
||||||
|
float32_t yawRate);
|
||||||
|
|
||||||
|
/*! @brief Control the attitude and vertical position of the vehicle
|
||||||
|
*
|
||||||
|
* @param roll attitude set-point in x axis of body frame (FRU) (deg),
|
||||||
|
* input limit see DJI::OSDK::Control::HORIZONTAL_ANGLE
|
||||||
|
* @param pitch attitude set-point in y axis of body frame (FRU) (deg),
|
||||||
|
* input limit see DJI::OSDK::Control::HORIZONTAL_ANGLE
|
||||||
|
* @param z z position set-point in z axis of ground frame (NED) (m),
|
||||||
|
* input limit see DJI::OSDK::Control::VERTICAL_POSITION
|
||||||
|
* @param yaw attitude set-point in z axis of ground frame (NED) (deg)
|
||||||
|
*/
|
||||||
|
void attitudeAndVertPosCtrl(float32_t roll, float32_t pitch, float32_t yaw,
|
||||||
|
float32_t z);
|
||||||
|
|
||||||
|
/*! @brief Control the attitude rate and vertical position of the vehicle
|
||||||
|
*
|
||||||
|
* @param rollRate attitude rate set-point in x axis of body frame (FRU)
|
||||||
|
* (deg/s)
|
||||||
|
* @param pitchRate attitude rate set-point in y axis of body frame (FRU)
|
||||||
|
* (deg/s)
|
||||||
|
* @param yawRate attitude rate set-point in z axis of body frame (FRU)
|
||||||
|
* (deg/s), input limit see DJI::OSDK::Control::YAW_RATE
|
||||||
|
* @param z z position set-point in z axis of ground frame (NED)
|
||||||
|
* (m), input limit see DJI::OSDK::Control::VERTICAL_POSITION
|
||||||
|
*/
|
||||||
|
void angularRateAndVertPosCtrl(float32_t rollRate, float32_t pitchRate,
|
||||||
|
float32_t yawRate, float32_t z);
|
||||||
|
|
||||||
|
/*! @brief Stop the vehicle in horiz velocity, vert velocity, yaw rate mode
|
||||||
|
* (body frame)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void emergencyBrake();
|
||||||
|
/*! @brief A callback function for action non-blocking calls
|
||||||
|
*
|
||||||
|
* @param recvFrame the data comes with the callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void actionCallback(Vehicle* vehiclePtr, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
}; // class Control
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // DJI_CONTROL_H
|
||||||
@@ -0,0 +1,553 @@
|
|||||||
|
/** @file dji_error.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief All DJI OSDK OpenProtocol ACK Error Codes
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_ERROR_H
|
||||||
|
#define DJI_ERROR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @class ErrorCode contains all the acknowledgments sent by the aircraft
|
||||||
|
* @details Each component of the SDK has its own subclass defined within the
|
||||||
|
* ErrorCode class.
|
||||||
|
*/
|
||||||
|
class ErrorCode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* @brief Common ACK Error Codes
|
||||||
|
*/
|
||||||
|
class CommonACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const static uint16_t SUCCESS;
|
||||||
|
const static uint16_t KEY_ERROR;
|
||||||
|
const static uint16_t NO_AUTHORIZATION_ERROR;
|
||||||
|
const static uint16_t NO_RIGHTS_ERROR;
|
||||||
|
const static uint16_t NO_RESPONSE_ERROR;
|
||||||
|
|
||||||
|
// These error codes would return either from
|
||||||
|
// CMDSet Control::Task or from Missions
|
||||||
|
const static uint8_t MOTOR_FAIL_NONE;
|
||||||
|
/*! The compass being used appears as follows: <br>
|
||||||
|
* (1) The compass data has too much noise. <br>
|
||||||
|
* (2) The compass data is stuck. <br>
|
||||||
|
* (3) The compass is disconnected. <br>
|
||||||
|
* (4) Compass user compilation error. <br>
|
||||||
|
* For the flight control of N3, A3 and M600, there are
|
||||||
|
* more situations: <br>
|
||||||
|
* (5) The compass is disturbed. <br>
|
||||||
|
* (6) Multiple compasses point different directions. <br>
|
||||||
|
* (7) Compass calibration failed. <br>
|
||||||
|
* (8) The compass is not calibrated. */
|
||||||
|
const static uint8_t MOTOR_FAIL_COMPASS_ABNORMAL;
|
||||||
|
/*! The aircraft is connected to the software for debugging parameters via
|
||||||
|
the
|
||||||
|
USB cable. */
|
||||||
|
const static uint8_t MOTOR_FAIL_ASSISTANT_PROTECTED;
|
||||||
|
/*! The structure of the parameter list has changed after the FW upgrade.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_DEVICE_LOCKED;
|
||||||
|
/*! The IMU being used appears as follows: <br>
|
||||||
|
* (1) The accelerometer output exceeds its range. <br>
|
||||||
|
* (2) The accelerometer is stuck. <br>
|
||||||
|
* (3) The accelerometer data has too much noise. <br>
|
||||||
|
* (4) The accelerometer outputs illegal floating numbers. <br>
|
||||||
|
* (5) The factory data of IMU has exception. <br>
|
||||||
|
* (6) Multiple accelerometers output differently. <br>
|
||||||
|
* (7) The temperature of the IMU is too high. <br>
|
||||||
|
* (8) The temperature of the IMU is very high. <br>
|
||||||
|
* (9) The gyro output exceeds its range. <br>
|
||||||
|
* (10) The gyro is stuck. <br>
|
||||||
|
* (11) The gyro data has too much noise. <br>
|
||||||
|
* (12) The gyro outputs illegal floating numbers. <br>
|
||||||
|
* (13) Multiple accelerometers output differently. <br>
|
||||||
|
* (14) The temperature control of gyro is abnormal. <br>
|
||||||
|
* For the flight control of Inspire 2, there are more situations: <br>
|
||||||
|
* (15)The default IMU exception causes the switch to backup IMU.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_NEED_ADV_CALIBRATION;
|
||||||
|
/*! The SN status is wrong. */
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_SN_ERROR;
|
||||||
|
/*! The IMU being used is preheated and current temperature is not wihin the
|
||||||
|
calibration range. */
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_PREHEATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_COMPASS_CALIBRATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_NO_ATTITUDE;
|
||||||
|
/*! The aircraft is in Novice Mode without gps. */
|
||||||
|
const static uint8_t MOTOR_FAIL_NO_GPS_IN_NOVICE_MODE;
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_CELL_ERROR;
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_COMMUNICATION_ERROR;
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_VOLTAGE_TOO_LOW;
|
||||||
|
/*! The volume (%) is below the second-level power set by user. */
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_USER_LOW_LAND;
|
||||||
|
/*! The voltage is below the second-level power set by user. */
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_MAIN_VOL_LOW;
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_TEMP_VOL_LOW;
|
||||||
|
/*! Flight contol calculates that current power is only adequate to land.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_SMART_LOW_LAND;
|
||||||
|
/*! This error occurs whin 7s after power up.
|
||||||
|
* Also, it occurs if the battery certification hasn't passed yet.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_NOT_READY;
|
||||||
|
const static uint8_t MOTOR_FAIL_RUNNING_SIMULATOR;
|
||||||
|
/*! The aircraft (Inspire series) is setting itself to packing config.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_PACK_MODE;
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_ATTI_LIMIT;
|
||||||
|
const static uint8_t MOTOR_FAIL_NOT_ACTIVATED;
|
||||||
|
const static uint8_t MOTOR_FAIL_IN_FLYLIMIT_AREA;
|
||||||
|
/*! The IMU is too biased if the gyro's bias is over 0.03rad/s
|
||||||
|
* or the accelerometer's bias is over 50 mg when first started up.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_BIAS_LIMIT;
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_ERROR;
|
||||||
|
/*! The IMU is initializing.The attitude data of the current
|
||||||
|
* navigation system has not converged yet and the height
|
||||||
|
* data of the current navigation system is not ready.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_INITING;
|
||||||
|
const static uint8_t MOTOR_FAIL_UPGRADING;
|
||||||
|
/*! The simulator has already been run.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_HAVE_RUN_SIM;
|
||||||
|
/*! The IMU is in calibration or the aircraft should reset after IMU
|
||||||
|
calibration.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_CALIBRATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_TAKEOFF_TILT_TOO_LARGE;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_31;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_32;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_33;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_34;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_35;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_36;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_37;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_38;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_39;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_40;
|
||||||
|
/*! invalid serial number */
|
||||||
|
const static uint8_t MOTOR_FAIL_INVALID_SN;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_42;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_43;
|
||||||
|
/*! accessing flash data, MCU is blocked */
|
||||||
|
const static uint8_t MOTOR_FAIL_FLASH_OPERATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_GPS_DISCONNECT;
|
||||||
|
const static uint8_t MOTOR_FAIL_INTERNAL_46;
|
||||||
|
/*! SD card has an exception. Please repair SD card if repeats after
|
||||||
|
* reset.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_RECORDER_ERROR;
|
||||||
|
/*! The firmware is unmatched with configured type.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_INVALID_PRODUCT;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_49;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_50;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_51;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_52;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_53;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_54;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_55;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_56;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_57;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_58;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_59;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_60;
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_DISCONNECTED;
|
||||||
|
const static uint8_t MOTOR_FAIL_RC_CALIBRATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_RC_CALI_DATA_OUT_RANGE;
|
||||||
|
const static uint8_t MOTOR_FAIL_RC_QUIT_CALI;
|
||||||
|
const static uint8_t MOTOR_FAIL_RC_CENTER_OUT_RANGE;
|
||||||
|
const static uint8_t MOTOR_FAIL_RC_MAP_ERROR;
|
||||||
|
/*! The aircraft type in flash is unmatched with the type in firmware. <br>
|
||||||
|
* Please check the aircraft type.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_WRONG_AIRCRAFT_TYPE;
|
||||||
|
const static uint8_t MOTOR_FAIL_SOME_MODULE_NOT_CONFIGURED;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_69;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_70;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_71;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_72;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_73;
|
||||||
|
/*! navigation system abnormal */
|
||||||
|
const static uint8_t MOTOR_FAIL_NS_ABNORMAL;
|
||||||
|
/*! Each craft has a set of devices to register. <br>
|
||||||
|
* It won't take off if a class of device is missing. Please reset and check
|
||||||
|
* the connection.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_TOPOLOGY_ABNORMAL;
|
||||||
|
const static uint8_t MOTOR_FAIL_RC_NEED_CALI;
|
||||||
|
/*! invalid data, system will block motor spinning */
|
||||||
|
const static uint8_t MOTOR_FAIL_INVALID_FLOAT;
|
||||||
|
const static uint8_t MOTOR_FAIL_M600_BAT_TOO_FEW;
|
||||||
|
const static uint8_t MOTOR_FAIL_M600_BAT_AUTH_ERR;
|
||||||
|
const static uint8_t MOTOR_FAIL_M600_BAT_COMM_ERR;
|
||||||
|
/*! Battery voltage difference is too large. Please check the battery
|
||||||
|
status.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_M600_BAT_DIF_VOLT_LARGE_1;
|
||||||
|
const static uint8_t MOTOR_FAIL_BATTERY_BOLTAHGE_DIFF_82;
|
||||||
|
const static uint8_t MOTOR_FAIL_INVALID_VERSION;
|
||||||
|
/*! There is an gimbal attitude error which happens only in M600.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_GYRO_ABNORMAL;
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_ESC_PITCH_NO_DATA;
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_ESC_ROLL_NO_DATA;
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_ESC_YAW_NO_DATA;
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_FIRM_IS_UPDATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_OUT_OF_CONTROL;
|
||||||
|
/*! The gimbal has self-oscillation in the pitch direction. <br>
|
||||||
|
* Please lock the camera or reduce the gimbal sensitivity.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_PITCH_SHOCK;
|
||||||
|
/*! The gimbal has self-oscillation in the roll direction. <br>
|
||||||
|
* Please lock the camera or reduce the gimbal sensitivity.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_ROLL_SHOCK;
|
||||||
|
/*! The gimbal has self-oscillation in the yaw direction. <br>
|
||||||
|
* Please lock the camera or reduce the gimbal sensitivity.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_YAW_SHOCK;
|
||||||
|
/*! IMU calibration finished. Please reset aircraft.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_IMU_CALI_SUCCESS;
|
||||||
|
const static uint8_t MOTOR_FAIL_TAKEOFF_EXCEPTION;
|
||||||
|
/*! The motor is locked. Please check the status of the motors and blades.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_STALL_NEAR_GOUND;
|
||||||
|
/*! The feedback speed of motor is different with the input command.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_UNBALANCE_ON_GRD;
|
||||||
|
/*! There are some no-load motors. Please check the status of the motors and
|
||||||
|
blades.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_PART_EMPTY_ON_GRD;
|
||||||
|
/*! During starting, the speed of any motor is less than the minimum
|
||||||
|
* starting
|
||||||
|
* speed. <br>
|
||||||
|
* For N3 and A3, the minimum starting speed is 100rpm. <br>
|
||||||
|
* For M600, the minimum starting speed is 700rpm. <br>
|
||||||
|
* For other aircrafts, the minimum starting speed is 1100rpm.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_ENGINE_START_FAILED;
|
||||||
|
const static uint8_t MOTOR_FAIL_AUTO_TAKEOFF_LAUNCH_FAILED;
|
||||||
|
const static uint8_t MOTOR_FAIL_ROLL_OVER_ON_GRD;
|
||||||
|
const static uint8_t MOTOR_FAIL_BAT_VERSION_ERR;
|
||||||
|
const static uint8_t MOTOR_FAIL_RTK_INITING;
|
||||||
|
/*! rtk yaw and magnetometer yaw misaligned */
|
||||||
|
const static uint8_t MOTOR_FAIL_RTK_FAIL_TO_INIT;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_104;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_105;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_106;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_107;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_108;
|
||||||
|
const static uint8_t MOTOR_FAIL_RESERVED_109;
|
||||||
|
/*! The motor status shows the motor has been started.*/
|
||||||
|
const static uint8_t START_MOTOR_FAIL_MOTOR_STARTED;
|
||||||
|
const static uint8_t MOTOR_FAIL_INTERNAL_111;
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_CALIBRATING;
|
||||||
|
const static uint8_t MOTOR_FAIL_GPS_SIGNATURE_INVALID;
|
||||||
|
const static uint8_t MOTOR_FAIL_GIMBAL_CALIBRATING;
|
||||||
|
/*! The aircraft is force locked by APP.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_FORCE_DISABLE;
|
||||||
|
/*! The height of the takeoff is abnormal. <br>
|
||||||
|
* This error happens when the takeoff height relative to ground is up to
|
||||||
|
* 100m.*/
|
||||||
|
const static uint8_t TAKEOFF_HEIGHT_EXCEPTION;
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_NEED_UPGRADE;
|
||||||
|
/*! IMU direction is misaligned.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_GYRO_DATA_NOT_MATCH;
|
||||||
|
/*! APP stops the takeoff.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_APP_NOT_ALLOW;
|
||||||
|
const static uint8_t MOTOR_FAIL_COMPASS_IMU_MISALIGN;
|
||||||
|
const static uint8_t MOTOR_FAIL_FLASH_UNLOCK;
|
||||||
|
/*! The ESC is in the buzzing mode.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_SCREAMING;
|
||||||
|
const static uint8_t MOTOR_FAIL_ESC_TEMP_HIGH;
|
||||||
|
/*! The battery is not in place. */
|
||||||
|
const static uint8_t MOTOR_FAIL_BAT_ERR;
|
||||||
|
/*! The aircraft detects an impact if the measured value of
|
||||||
|
* accelerometer exceeds 8g near ground.*/
|
||||||
|
const static uint8_t IMPACT_IS_DETECTED;
|
||||||
|
/*! Under the P stall, the aircraft mode degenerates to the Attitude mode.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_MODE_FAILURE;
|
||||||
|
/*! The aircraft recently had an error of NO. 125.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_CRAFT_FAIL_LATELY;
|
||||||
|
/*! The code logic is illegal.*/
|
||||||
|
const static uint8_t MOTOR_FAIL_MOTOR_CODE_ERROR;
|
||||||
|
|
||||||
|
/*! @brief Flight Status enum
|
||||||
|
* @note this is not just an acknowledgement,
|
||||||
|
* it is also a DataBroadcast/DataSubscription telemetry message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct FlightStatus
|
||||||
|
{
|
||||||
|
const static uint8_t STOPED;
|
||||||
|
const static uint8_t ON_GROUND;
|
||||||
|
const static uint8_t IN_AIR;
|
||||||
|
} FlightStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief CMDSet: Activation ACK Error Codes
|
||||||
|
*/
|
||||||
|
class ActivationACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const static uint16_t SUCCESS;
|
||||||
|
const static uint16_t PARAMETER_ERROR;
|
||||||
|
const static uint16_t ENCODE_ERROR;
|
||||||
|
const static uint16_t NEW_DEVICE_ERROR;
|
||||||
|
const static uint16_t DJIGO_APP_NOT_CONNECTED;
|
||||||
|
const static uint16_t NETWORK_ERROR;
|
||||||
|
const static uint16_t SERVER_ACCESS_REFUSED;
|
||||||
|
const static uint16_t ACCESS_LEVEL_ERROR;
|
||||||
|
const static uint16_t OSDK_VERSION_ERROR;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief CMDSet: Control ACK Error Codes
|
||||||
|
*/
|
||||||
|
class ControlACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* @brief CMDID: SetControl
|
||||||
|
*/
|
||||||
|
typedef struct SetControl
|
||||||
|
{
|
||||||
|
const static uint16_t RC_MODE_ERROR;
|
||||||
|
const static uint16_t RELEASE_CONTROL_SUCCESS;
|
||||||
|
const static uint16_t OBTAIN_CONTROL_SUCCESS;
|
||||||
|
const static uint16_t OBTAIN_CONTROL_IN_PROGRESS;
|
||||||
|
const static uint16_t RELEASE_CONTROL_IN_PROGRESS;
|
||||||
|
const static uint16_t RC_NEED_MODE_F;
|
||||||
|
const static uint16_t RC_NEED_MODE_P;
|
||||||
|
const static uint16_t IOC_OBTAIN_CONTROL_ERROR;
|
||||||
|
} SetControl;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @note New 3.3 release
|
||||||
|
*
|
||||||
|
* @brief CMDID: Task
|
||||||
|
*/
|
||||||
|
typedef struct Task
|
||||||
|
{
|
||||||
|
const static uint16_t SUCCESS;
|
||||||
|
const static uint16_t MOTOR_ON;
|
||||||
|
const static uint16_t MOTOR_OFF;
|
||||||
|
const static uint16_t IN_AIR;
|
||||||
|
const static uint16_t NOT_IN_AIR;
|
||||||
|
const static uint16_t NO_HOMEPOINT;
|
||||||
|
const static uint16_t BAD_GPS;
|
||||||
|
// Do not consider as error?
|
||||||
|
const static uint16_t IN_SIMULATOR_MODE;
|
||||||
|
const static uint16_t ALREADY_RUNNING;
|
||||||
|
const static uint16_t NOT_RUNNING;
|
||||||
|
const static uint16_t INVAILD_COMMAND;
|
||||||
|
const static uint16_t NO_LANDING_GEAR;
|
||||||
|
// Do not consider as error?
|
||||||
|
const static uint16_t GIMBAL_MOUNTED;
|
||||||
|
const static uint16_t BAD_SENSOR;
|
||||||
|
const static uint16_t ALREADY_PACKED;
|
||||||
|
const static uint16_t NO_PACKED;
|
||||||
|
const static uint16_t PACKED_MODE_NOT_SUPPORTED;
|
||||||
|
} Task;
|
||||||
|
|
||||||
|
}; // Control class
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @note New in 3.3 release
|
||||||
|
*
|
||||||
|
* @brief CMDSet: Subscribe
|
||||||
|
*/
|
||||||
|
class SubscribeACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const static uint8_t SUCCESS;
|
||||||
|
const static uint8_t ILLEGAL_INPUT;
|
||||||
|
const static uint8_t VERSION_DOES_NOT_MATCH;
|
||||||
|
const static uint8_t PACKAGE_OUT_OF_RANGE;
|
||||||
|
const static uint8_t PACKAGE_ALREADY_EXISTS;
|
||||||
|
const static uint8_t PACKAGE_DOES_NOT_EXIST;
|
||||||
|
const static uint8_t ILLEGAL_FREQUENCY;
|
||||||
|
const static uint8_t PACKAGE_TOO_LARGE;
|
||||||
|
const static uint8_t PIPELINE_OVERFLOW;
|
||||||
|
const static uint8_t INTERNAL_ERROR_0X09;
|
||||||
|
const static uint8_t PACKAGE_EMPTY;
|
||||||
|
const static uint8_t INPUT_SEGMENTATION_FAULT;
|
||||||
|
const static uint8_t ILLEGAL_UID;
|
||||||
|
const static uint8_t PERMISSION_DENY;
|
||||||
|
const static uint8_t MULTIPLE_SUBSCRIBE;
|
||||||
|
const static uint8_t SOUCE_DEVICE_OFFLINE;
|
||||||
|
const static uint8_t PAUSED;
|
||||||
|
const static uint8_t RESUMED;
|
||||||
|
const static uint8_t INTERNAL_ERROR_0X4A;
|
||||||
|
const static uint8_t INTERNAL_ERROR_0X50;
|
||||||
|
const static uint8_t VERSION_VERSION_TOO_FAR;
|
||||||
|
const static uint8_t VERSION_UNKNOWN_ERROR;
|
||||||
|
const static uint8_t INTERNAL_ERROR_0XFF;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Mission ACK Error Codes
|
||||||
|
*/
|
||||||
|
class MissionACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! @brief Common Mission ACK codes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct Common
|
||||||
|
{
|
||||||
|
const static uint8_t SUCCESS;
|
||||||
|
const static uint8_t WRONG_WAYPOINT_INDEX;
|
||||||
|
const static uint8_t RC_NOT_IN_MODE_F;
|
||||||
|
const static uint8_t OBTAIN_CONTROL_REQUIRED;
|
||||||
|
const static uint8_t CLOSE_IOC_REQUIRED;
|
||||||
|
const static uint8_t NOT_INITIALIZED;
|
||||||
|
const static uint8_t NOT_RUNNING;
|
||||||
|
const static uint8_t IN_PROGRESS;
|
||||||
|
/*!Estimated time needed to perform a task is greater
|
||||||
|
* than the flight time left*/
|
||||||
|
const static uint8_t TASK_TIMEOUT;
|
||||||
|
const static uint8_t OTHER_MISSION_RUNNING;
|
||||||
|
/*!GPS signal GPS_LEVEL < 3*/
|
||||||
|
const static uint8_t BAD_GPS;
|
||||||
|
const static uint8_t RTK_NOT_READY;
|
||||||
|
/*!Battery beyond first-stage voltage for non-smart battery
|
||||||
|
* OR first-stage volume for smart battery*/
|
||||||
|
const static uint8_t LOW_BATTERY;
|
||||||
|
const static uint8_t VEHICLE_DID_NOT_TAKE_OFF;
|
||||||
|
const static uint8_t INVALID_PARAMETER;
|
||||||
|
/*!Execution condition is not satisfied
|
||||||
|
* @note Aircraft not in one of the following modes:
|
||||||
|
* Assist Takeoff
|
||||||
|
* Auto Takeoff
|
||||||
|
* Auto Landing
|
||||||
|
* Go Home
|
||||||
|
*/
|
||||||
|
const static uint8_t CONDITIONS_NOT_SATISFIED;
|
||||||
|
const static uint8_t CROSSING_NO_FLY_ZONE;
|
||||||
|
/*!HomePoint not recorded*/
|
||||||
|
const static uint8_t UNRECORDED_HOME;
|
||||||
|
const static uint8_t AT_NO_FLY_ZONE;
|
||||||
|
/*!Height is too high (higher than MAX flying height
|
||||||
|
* set by user (default: 120m))*/
|
||||||
|
const static uint8_t TOO_HIGH;
|
||||||
|
/*!Height is too low (lower than 5m)*/
|
||||||
|
const static uint8_t TOO_LOW;
|
||||||
|
const static uint8_t TOO_FAR_FROM_HOME;
|
||||||
|
/*!Mission not supported*/
|
||||||
|
const static uint8_t NOT_SUPPORTED;
|
||||||
|
/*!Current position of aircraft is too far from the HotPoint
|
||||||
|
* or first point*/
|
||||||
|
const static uint8_t TOO_FAR_FROM_CURRENT_POSITION;
|
||||||
|
const static uint8_t BEGGINER_MODE_NOT_SUPPORTED;
|
||||||
|
const static uint8_t TAKE_OFF_IN_PROGRESS;
|
||||||
|
const static uint8_t LANDING_IN_PROGRESS;
|
||||||
|
const static uint8_t RRETURN_HOME_IN_PROGRESS;
|
||||||
|
const static uint8_t START_MOTORS_IN_PROGRESS;
|
||||||
|
const static uint8_t INVALID_COMMAND;
|
||||||
|
const static uint8_t UNKNOWN_ERROR;
|
||||||
|
} Common;
|
||||||
|
|
||||||
|
//! @brief Follow Mission ACK Error Code
|
||||||
|
typedef struct Follow
|
||||||
|
{
|
||||||
|
const static uint8_t TOO_FAR_FROM_YOUR_POSITION_LACK_OF_RADIO_CONNECTION;
|
||||||
|
const static uint8_t CUTOFF_TIME_OVERFLOW;
|
||||||
|
const static uint8_t GIMBAL_PITCH_ANGLE_OVERFLOW;
|
||||||
|
} Follow;
|
||||||
|
|
||||||
|
//! @brief HotPoint Mission ACK Error Code
|
||||||
|
typedef struct HotPoint
|
||||||
|
{
|
||||||
|
const static uint8_t INVALID_RADIUS;
|
||||||
|
const static uint8_t YAW_RATE_OVERFLOW;
|
||||||
|
/*
|
||||||
|
* Start point given by user during HotPoint mission initialization is
|
||||||
|
* invalid.
|
||||||
|
* Available options are :
|
||||||
|
* 0 - North to the HP
|
||||||
|
* 1 - South
|
||||||
|
* 2 - West
|
||||||
|
* 3 - East
|
||||||
|
* 4 - Nearest Point
|
||||||
|
*/
|
||||||
|
const static uint8_t INVALID_START_POINT;
|
||||||
|
const static uint8_t INVALID_YAW_MODE;
|
||||||
|
const static uint8_t TOO_FAR_FROM_HOTPOINT;
|
||||||
|
const static uint8_t INVALID_PAREMETER;
|
||||||
|
const static uint8_t INVALID_LATITUDE_OR_LONGITUTE;
|
||||||
|
const static uint8_t INVALID_DIRECTION;
|
||||||
|
const static uint8_t IN_PAUSED_MODE;
|
||||||
|
const static uint8_t FAILED_TO_PAUSE;
|
||||||
|
} HotPoint;
|
||||||
|
|
||||||
|
//! @brief WayPoint Mission ACK Error Code
|
||||||
|
typedef struct WayPoint
|
||||||
|
{
|
||||||
|
const static uint8_t INVALID_DATA;
|
||||||
|
const static uint8_t INVALID_POINT_DATA;
|
||||||
|
const static uint8_t DISTANCE_OVERFLOW;
|
||||||
|
const static uint8_t TIMEOUT;
|
||||||
|
const static uint8_t POINT_OVERFLOW;
|
||||||
|
const static uint8_t POINTS_TOO_CLOSE;
|
||||||
|
const static uint8_t POINTS_TOO_FAR;
|
||||||
|
const static uint8_t CHECK_FAILED;
|
||||||
|
const static uint8_t INVALID_ACTION;
|
||||||
|
const static uint8_t POINT_DATA_NOT_ENOUGH;
|
||||||
|
const static uint8_t DATA_NOT_ENOUGH;
|
||||||
|
const static uint8_t POINTS_NOT_ENOUGH;
|
||||||
|
const static uint8_t IN_PROGRESS;
|
||||||
|
const static uint8_t NOT_IN_PROGRESS;
|
||||||
|
const static uint8_t INVALID_VELOCITY;
|
||||||
|
} WayPoint;
|
||||||
|
|
||||||
|
//! @brief IOC ACK Mission Error Code
|
||||||
|
typedef struct IOC
|
||||||
|
{
|
||||||
|
const static uint8_t TOO_CLOSE_TO_HOME;
|
||||||
|
const static uint8_t UNKNOWN_TYPE;
|
||||||
|
} IOC;
|
||||||
|
|
||||||
|
}; // Class Mission
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief CMDSet: MFIO
|
||||||
|
* @note New in 3.3 release
|
||||||
|
*/
|
||||||
|
class MFIOACK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* @brief CMDID: init
|
||||||
|
*/
|
||||||
|
typedef struct init
|
||||||
|
{
|
||||||
|
const static uint8_t SUCCESS;
|
||||||
|
const static uint8_t UNKNOWN_ERROR;
|
||||||
|
const static uint8_t PORT_NUMBER_ERROR;
|
||||||
|
const static uint8_t PORT_MODE_ERROR;
|
||||||
|
const static uint8_t PORT_DATA_ERROR;
|
||||||
|
} init;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief CMDID: set
|
||||||
|
*/
|
||||||
|
typedef struct set
|
||||||
|
{
|
||||||
|
const static uint8_t SUCCESS;
|
||||||
|
/*!Port not exit or not an output configuration*/
|
||||||
|
const static uint8_t CHANNEL_ERROR;
|
||||||
|
/*! Port not map to f channel*/
|
||||||
|
const static uint8_t PORT_NOT_MAPPED_ERROR;
|
||||||
|
} set;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief CMDID: get
|
||||||
|
*/
|
||||||
|
typedef struct get
|
||||||
|
{
|
||||||
|
const static uint8_t SUCCESS; //! @note Anything else is failure
|
||||||
|
} get;
|
||||||
|
|
||||||
|
}; // Class MFIO
|
||||||
|
|
||||||
|
}; // Class ErrorCode
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif /* DJI_ERROR_H */
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/** @file dji_gimbal.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Gimbal API for OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GIMBAL_H
|
||||||
|
#define GIMBAL_H
|
||||||
|
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declaration
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The Gimbal class for controlling gimbal-related functions
|
||||||
|
*/
|
||||||
|
class Gimbal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#pragma pack(1)
|
||||||
|
/*! @brief The Angle Data struct for gimbal control.
|
||||||
|
|
||||||
|
The relationship bewteen the angle reference in absolute control mode and
|
||||||
|
gimbal mode configuration in DJI Go App
|
||||||
|
Gimbal Mode | Roll | Pitch | Yaw | Gimbal Follow UAV's Head
|
||||||
|
---------- |--------- |--------- |----- |------------------
|
||||||
|
Follow | Ground | Ground |Body | Y
|
||||||
|
FPV | N/A | Ground | N/A | Y
|
||||||
|
Free | Ground | Ground | Ground| N
|
||||||
|
@note
|
||||||
|
- Rotating 90 degree in pitch direction will cause gimbal lock
|
||||||
|
problem, in which the value of roll and yaw are not reliable.
|
||||||
|
- M600 with A3 only supports Ronin-MX/Zenmuse X5 Series/Zenmuse
|
||||||
|
X3/Zenmuse XT when operating gimbal control in angle.
|
||||||
|
|
||||||
|
*/
|
||||||
|
typedef struct AngleData
|
||||||
|
{
|
||||||
|
int16_t yaw; /*!< Yaw angle, unit 0.1 degree , input range [-3200,3200] */
|
||||||
|
int16_t roll; /*!< Roll angle, unit 0.1 degree, input range [-350,350] */
|
||||||
|
int16_t pitch; /*!< Pitch angle, unit 0.1 degree, input range [-900,300] */
|
||||||
|
uint8_t mode;
|
||||||
|
// clang-format off
|
||||||
|
/*!< Mode is 1 byte size:
|
||||||
|
Bit #: | Set to 0: | Set to 1:
|
||||||
|
------------- | ------------- | -------------
|
||||||
|
bit 0 | Incremental control, the angle reference is the current Gimbal location | Absolute control, the angle reference is related to configuration in DJI Go App
|
||||||
|
bit 1 | Gimbal will follow the command in Yaw | Gimbal will maintain position in Yaw
|
||||||
|
bit 2 | Roll invalid bit, the same as bit[1] | Roll invalid bit, the same as bit[1]|
|
||||||
|
bit 3 |Pitch invalid bit, the same as bit[1] | Pitch invalid bit, the same as bit[1]
|
||||||
|
bit [4:7] | bit [4:7]: reserved, set to be 0| |
|
||||||
|
*/
|
||||||
|
// clang-format on
|
||||||
|
uint8_t duration; /*!< Command completion time.
|
||||||
|
- Unit 0.1s, for example 20 means gimbal will reach
|
||||||
|
the commended postition in 2 seconds.
|
||||||
|
- Rotate rate beyond 400º/s is not recommand */
|
||||||
|
} AngleData; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief The Speed Data struct for gimbal control
|
||||||
|
*
|
||||||
|
* The angle reference frame is same in AngleData free mode.
|
||||||
|
*/
|
||||||
|
typedef struct SpeedData
|
||||||
|
{
|
||||||
|
int16_t yaw; /*!< Yaw in rate, unit 0.1 deg/s, input range[-1800,1800] */
|
||||||
|
int16_t roll; /*!< Roll in rate, unit 0.1 deg/s, input range[-1800,1800] */
|
||||||
|
int16_t
|
||||||
|
pitch; /*!< Pitch in rate, unit 0.1 deg/s, input range[-1800,1800] */
|
||||||
|
uint8_t reserved; /*!< @note always 0x80 */
|
||||||
|
} SpeedData; // pack(1)
|
||||||
|
#pragma pack()
|
||||||
|
public:
|
||||||
|
Gimbal(Vehicle* vehicle);
|
||||||
|
~Gimbal();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*! @brief Function for setting Gimbal Angle
|
||||||
|
*
|
||||||
|
* Define the mode and the angles for the gimbal angle control in the
|
||||||
|
* AngleData struct and pass it to setAngle().
|
||||||
|
*
|
||||||
|
* @param data AngleData struct containing all the angle values, mode
|
||||||
|
* and duration
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void setAngle(Gimbal::AngleData* data);
|
||||||
|
|
||||||
|
/*! @brief Function for setting Gimbal Speed
|
||||||
|
*
|
||||||
|
* Define the rate of change for the gimbal angle in SpeedData struct and
|
||||||
|
* pass it to setSpeed();
|
||||||
|
*
|
||||||
|
* @param data SpeedData struct containing the roll, pitch and yaw
|
||||||
|
* rates
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void setSpeed(Gimbal::SpeedData* data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // GIMBAL_H
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/** @file dji_hardware_sync.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Hardware Sync API for DJI OSDK
|
||||||
|
* @details Use with Subscription UID_HARD_SYNC.
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HARDSYNC_H
|
||||||
|
#define HARDSYNC_H
|
||||||
|
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief APIs for controlling Hardware Sync
|
||||||
|
*
|
||||||
|
* @details These APIs enable you to output a pulse/pulse train along with
|
||||||
|
* a software packet with synchronized timestamps and sensor data.
|
||||||
|
*
|
||||||
|
* @note You must use this in conjunction with TOPIC_HARD_SYNC subscription.
|
||||||
|
* @note You need to set a F-channel to Sync through DJI Assistant 2.
|
||||||
|
*/
|
||||||
|
class HardwareSync
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
typedef struct SyncSettings
|
||||||
|
{
|
||||||
|
uint32_t freq;
|
||||||
|
uint16_t tag;
|
||||||
|
} SyncSettings;
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
HardwareSync(Vehicle* vehiclePtr = 0);
|
||||||
|
|
||||||
|
/*! @brief Call this API to start sending a hardware pulse and
|
||||||
|
* set up a software packet to accompany it
|
||||||
|
* @details You need to select a pin on DJI Assistant 2 that will output this
|
||||||
|
* hardware pulse.
|
||||||
|
* To receive the software packet that accompanies this pulse,
|
||||||
|
* you will need to subscribe to TOPIC_HARD_SYNC.
|
||||||
|
*
|
||||||
|
* @param freqInHz The frequency at which you want this pulse to be output.
|
||||||
|
* @param tag Identification to match pulse with the corresponding software
|
||||||
|
* packet
|
||||||
|
*/
|
||||||
|
void setSyncFreq(uint32_t freqInHz, uint16_t tag = 0);
|
||||||
|
|
||||||
|
/*! @brief Internal setter function that is called by setSyncFreq function
|
||||||
|
* @details Use setSyncFreq instead of this direct interface.
|
||||||
|
*
|
||||||
|
* @param data Struct of type SyncCmdData.
|
||||||
|
*/
|
||||||
|
void startSync(SyncSettings& data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
};
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // HARDSYNC_H
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
/** @file dji_hotpoint.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Implementation of HotPoint (Point of Interest) Missions for DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_HOTPOINT_H
|
||||||
|
#define DJI_HOTPOINT_H
|
||||||
|
|
||||||
|
#include "dji_mission_base.hpp"
|
||||||
|
#include "dji_telemetry.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief APIs for Hotpoint (Point of Interest) Missions
|
||||||
|
*
|
||||||
|
* @details This class inherits from MissionBase and can be used with
|
||||||
|
* MissionManager.
|
||||||
|
*/
|
||||||
|
class HotpointMission : public MissionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct YawRate
|
||||||
|
{
|
||||||
|
uint8_t clockwise;
|
||||||
|
float32_t yawRate;
|
||||||
|
} YawRate;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
enum View
|
||||||
|
{
|
||||||
|
VIEW_NORTH = 0,
|
||||||
|
VIEW_SOUTH = 1,
|
||||||
|
VIEW_WEST = 2,
|
||||||
|
VIEW_EAST = 3,
|
||||||
|
VIEW_NEARBY = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
enum YawMode
|
||||||
|
{
|
||||||
|
YAW_AUTO = 0,
|
||||||
|
YAW_INSIDE = 1,
|
||||||
|
YAW_OUTSIDE = 2,
|
||||||
|
YAW_CUSTOM = 3,
|
||||||
|
YAW_STATIC = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! @note API functions
|
||||||
|
* @attention difference between set and update <br>
|
||||||
|
* Set functions only change the HotPoint data in this class,
|
||||||
|
* Update functions will change the Mission status.
|
||||||
|
* In other words: drone will response update functions immediately.
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
HotpointMission(Vehicle* vehicle = 0);
|
||||||
|
~HotpointMission();
|
||||||
|
|
||||||
|
VehicleCallBackHandler hotPointCallback;
|
||||||
|
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init hotpoint default data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void initData();
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* getting hotpoint data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
HotPointSettings getData() const;
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* start the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void start(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* start the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode start(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* stop the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void stop(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* stop the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode stop(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* pause the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void pause(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* pause the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode pause(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* resume the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void resume(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* resume the hotpoint mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode resume(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* update yaw rate and orientation of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param Data specified yaw rate and orientation
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void updateYawRate(YawRate& Data, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* update yaw rate and orientation of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param Data specified yaw rate and orientation
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode updateYawRate(YawRate& Data, int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* update yaw rate and orientation of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param yawRate specified yaw rate
|
||||||
|
* @param isClockwise specified orientation
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
void updateYawRate(float32_t yawRate, bool isClockwise,
|
||||||
|
VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* update radius of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param meter radius
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void updateRadius(float32_t meter, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* update radius of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param meter radius
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode updateRadius(float32_t meter, int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* reset yaw of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void resetYaw(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* reset yaw of hotpoint mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode resetYaw(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* read hotpt mission info from flight controller
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void readData(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* read hotpt mission info from flight controller
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode readData(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* A callback function for start non-blocking calls
|
||||||
|
*
|
||||||
|
* @param recvFrame the data comes with the callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
static void startCallback(RecvContainer recvFrame, UserData userData);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* A callback function for read non-blocking calls
|
||||||
|
*
|
||||||
|
* @param recvFrame the data comes with the callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
static void readCallback(RecvContainer recvFrame, UserData userData);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint callback
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
void setHotpointCallback(VehicleCallBack callback, UserData userData);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param data HotPointSettings
|
||||||
|
*/
|
||||||
|
void setData(HotPointSettings* data);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param longitude longitude
|
||||||
|
* @param latitude latitude
|
||||||
|
* @param altitude altitude
|
||||||
|
*/
|
||||||
|
void setHotPoint(float64_t longitude, float64_t latitude, float64_t altitude);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param gps gps
|
||||||
|
*/
|
||||||
|
void setHotPoint(Telemetry::GlobalPosition gps);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param meter radius in meter
|
||||||
|
*/
|
||||||
|
void setRadius(float64_t meter);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param degree yawrate in degree/sec
|
||||||
|
*/
|
||||||
|
void setYawRate(float32_t degree);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param isClockwise isClockwise
|
||||||
|
*/
|
||||||
|
void setClockwise(bool isClockwise);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param view check View struct
|
||||||
|
*/
|
||||||
|
void setCameraView(View view);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set hotpoint data for initialization purpose
|
||||||
|
*
|
||||||
|
* @param mode check YawMode struct
|
||||||
|
*/
|
||||||
|
void setYawMode(YawMode mode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HotPointSettings hotPointData;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // DJI_HOTPOINT_H
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/** @file dji_mfio.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* MFIO API for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_MFIO_H
|
||||||
|
#define DJI_MFIO_H
|
||||||
|
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief APIs for Multi-Function Input-Output functionality
|
||||||
|
*
|
||||||
|
* @details This class offers control over the F-channel pins on DJI products.
|
||||||
|
* Five modes are available through the F-channels:
|
||||||
|
* 1. PWM Input (not supported yet)
|
||||||
|
* 2. PWM Output
|
||||||
|
* 3. Digital Input (GPI)
|
||||||
|
* 4. Digital Output (GPO)
|
||||||
|
* 5. Analog-Digital Conversion (ADC) Input
|
||||||
|
*
|
||||||
|
* @note You must map F-channels to SDK channels through DJI Assistant 2 to use
|
||||||
|
* MFIO functionality.
|
||||||
|
*/
|
||||||
|
class MFIO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef enum MODE {
|
||||||
|
MODE_PWM_OUT = 0,
|
||||||
|
MODE_PWM_IN = 1,
|
||||||
|
MODE_GPIO_OUT = 2,
|
||||||
|
MODE_GPIO_IN = 3,
|
||||||
|
MODE_ADC = 4
|
||||||
|
} MODE;
|
||||||
|
|
||||||
|
typedef enum CHANNEL {
|
||||||
|
CHANNEL_0 = 0,
|
||||||
|
CHANNEL_1 = 1,
|
||||||
|
CHANNEL_2 = 2,
|
||||||
|
CHANNEL_3 = 3,
|
||||||
|
CHANNEL_4 = 4,
|
||||||
|
CHANNEL_5 = 5,
|
||||||
|
CHANNEL_6 = 6,
|
||||||
|
CHANNEL_7 = 7,
|
||||||
|
} CHANNEL;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MFIO(Vehicle* vehicle);
|
||||||
|
~MFIO();
|
||||||
|
|
||||||
|
// Non-blocking API
|
||||||
|
|
||||||
|
/*! @brief Non-blocking call for initializing an MFIO channel
|
||||||
|
*
|
||||||
|
* @param mode The mode (PWM, GPIO, ADC) to initialize to
|
||||||
|
* @param channel The channel (0-7) to initialize
|
||||||
|
* @param defaultValue The starting value [for output]
|
||||||
|
* @param freq The frequency
|
||||||
|
* @param fn Callback function you want called upon ACK
|
||||||
|
* @param userData Additional data you want the callback function to have
|
||||||
|
* access to
|
||||||
|
*/
|
||||||
|
void config(MODE mode, CHANNEL channel, uint32_t defaultValue, uint16_t freq,
|
||||||
|
VehicleCallBack fn = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
/*! @brief Non-blocking call for setting an MFIO value to a channel
|
||||||
|
*
|
||||||
|
* @param channel The channel (0-7) to set the value to
|
||||||
|
* @param value The value you want to set
|
||||||
|
* @param fn Callback function you want called upon ACK
|
||||||
|
* @param data Additional data you want the callback function to have access
|
||||||
|
* to
|
||||||
|
*/
|
||||||
|
void setValue(CHANNEL channel, uint32_t value, VehicleCallBack fn = 0,
|
||||||
|
UserData data = 0);
|
||||||
|
|
||||||
|
/*! @brief Non-blocking call for getting data from an MFIO channel
|
||||||
|
*
|
||||||
|
* @param channel The channel (0-7) to get the value from
|
||||||
|
* @param fn Callback function you want called upon ACK
|
||||||
|
* @param data Additional data you want the callback function to have access
|
||||||
|
* to
|
||||||
|
*/
|
||||||
|
void getValue(CHANNEL channel, VehicleCallBack fn = 0, UserData data = 0);
|
||||||
|
|
||||||
|
// Blocking API
|
||||||
|
|
||||||
|
/*! @brief Blocking call for initializing an MFIO channel
|
||||||
|
*
|
||||||
|
* @param mode The mode (PWM, GPIO, ADC) to initialize to
|
||||||
|
* @param channel The channel (0-7) to initialize
|
||||||
|
* @param defaultValue The starting value [for output]
|
||||||
|
* @param freq The frequency
|
||||||
|
* @param wait_timeout Time(in s) you want the function to wait for an ACK
|
||||||
|
* @return ACK::ErrorCode struct containing the ACK and metadata
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode config(MODE mode, CHANNEL channel, uint32_t defaultValue,
|
||||||
|
uint16_t freq, int wait_timeout);
|
||||||
|
|
||||||
|
/*! Blocking call for setting an MFIO value to a channel
|
||||||
|
*
|
||||||
|
* @param channel The channel (0-7) to set the value to
|
||||||
|
* @param value The value you want to set
|
||||||
|
* @param wait_timeout Time(in s) you want the function to wait for an ACK
|
||||||
|
* @return ACK::ErrorCode struct containing the ACK and metadata
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode setValue(CHANNEL channel, uint32_t value, int wait_timeout);
|
||||||
|
|
||||||
|
/*! Blocking call for getting data from an MFIO channel
|
||||||
|
*
|
||||||
|
* @param channel The channel (0-7) to get the value from
|
||||||
|
* @param wait_timeout Time(in s) you want the function to wait for an ACK
|
||||||
|
* @return ACK::ErrorCode struct containing the ACK and metadata
|
||||||
|
*/
|
||||||
|
ACK::MFIOGet getValue(CHANNEL channel, int wait_timeout);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void initCallback(RecvContainer recvFrame, UserData data);
|
||||||
|
static void setValueCallback(RecvContainer recvFrame, UserData data);
|
||||||
|
static void getValueCallback(RecvContainer recvFrame, UserData data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
|
||||||
|
uint8_t channelUsage;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct InitData
|
||||||
|
{
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t mode;
|
||||||
|
uint32_t value;
|
||||||
|
uint16_t freq;
|
||||||
|
} InitData; // pack(1)
|
||||||
|
|
||||||
|
typedef struct SetData
|
||||||
|
{
|
||||||
|
uint8_t channel;
|
||||||
|
uint32_t value;
|
||||||
|
} SetData; // pack(1)
|
||||||
|
|
||||||
|
typedef uint32_t GetData;
|
||||||
|
|
||||||
|
typedef struct GetResult
|
||||||
|
{
|
||||||
|
uint8_t reserved;
|
||||||
|
uint32_t value;
|
||||||
|
} GetResult; // pack(1)
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
}; // class MFIO
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // DJI_MFIO_H
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/** @file dji_mission_base.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Mission-Base abstract class for DJI OSDK library
|
||||||
|
* @details This is a low-level abstraction for having
|
||||||
|
* commonality between all missions.
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_DJI_MISSIONBASE_H
|
||||||
|
#define ONBOARDSDK_DJI_MISSIONBASE_H
|
||||||
|
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef enum MissionType {
|
||||||
|
MISSION_MODE_A,
|
||||||
|
MISSION_WAYPOINT,
|
||||||
|
MISSION_HOTPOINT,
|
||||||
|
MISSION_FOLLOW,
|
||||||
|
MISSION_IOC
|
||||||
|
} MissionType;
|
||||||
|
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief Mission Base class for commonality between SDK Missions.
|
||||||
|
*
|
||||||
|
* @details You can inherit from this class if making a custom mission.
|
||||||
|
*/
|
||||||
|
class MissionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MissionBase(Vehicle* vehicle = 0)
|
||||||
|
: vehicle(vehicle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~MissionBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void start(VehicleCallBack callback = 0, UserData userData = 0) = 0;
|
||||||
|
virtual ACK::ErrorCode start(int timer) = 0;
|
||||||
|
|
||||||
|
virtual void stop(VehicleCallBack callback = 0, UserData userData = 0) = 0;
|
||||||
|
virtual ACK::ErrorCode stop(int timer) = 0;
|
||||||
|
|
||||||
|
virtual void pause(VehicleCallBack callback = 0, UserData userData = 0) = 0;
|
||||||
|
virtual ACK::ErrorCode pause(int timer) = 0;
|
||||||
|
|
||||||
|
virtual void resume(VehicleCallBack callback = 0, UserData userData = 0) = 0;
|
||||||
|
virtual ACK::ErrorCode resume(int timer) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
}; // class MissionBase
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // ONBOARDSDK_DJI_MISSIONBASE_H
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/** @file dji_mission_manager.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Mission-Manager API for DJI OSDK library
|
||||||
|
* @details This is a high-level abstraction for handling/chaining missions
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_DJI_MISSIONMANAGER_H
|
||||||
|
#define ONBOARDSDK_DJI_MISSIONMANAGER_H
|
||||||
|
|
||||||
|
#include "dji_hotpoint.hpp"
|
||||||
|
#include "dji_waypoint.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
enum DJI_MISSION_TYPE
|
||||||
|
{
|
||||||
|
WAYPOINT = 0,
|
||||||
|
HOTPOINT = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MISSION_ACTION
|
||||||
|
{
|
||||||
|
START = 0,
|
||||||
|
STOP = 1,
|
||||||
|
PAUSE = 2,
|
||||||
|
RESUME = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaypointMission;
|
||||||
|
class HotpointMission;
|
||||||
|
|
||||||
|
/*! @brief MissionManager class for chaining/managing missions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class MissionManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MissionManager(Vehicle* vehiclePtr = 0);
|
||||||
|
~MissionManager();
|
||||||
|
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init missions, could be hotpt or waypt, blocking calls
|
||||||
|
*
|
||||||
|
* @param type mission type enum
|
||||||
|
* @param timeout timeout
|
||||||
|
* @param missionData initData for the mission (void ptr)
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode init(DJI_MISSION_TYPE type, int timeout,
|
||||||
|
UserData missionData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init missions, could be hotpt or waypt, non-blocking calls
|
||||||
|
*
|
||||||
|
* @param type mission type enum
|
||||||
|
* @param callback user specified callback
|
||||||
|
* @param missionData initData for the mission (void ptr)
|
||||||
|
*/
|
||||||
|
void init(DJI_MISSION_TYPE type, VehicleCallBack callback = 0,
|
||||||
|
UserData missionData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* a callback function for waypoint non-blocking calls
|
||||||
|
*
|
||||||
|
* @param recvFrame RecvContainer populated by the protocolLayer
|
||||||
|
* @param userData void ptr for user usage
|
||||||
|
*/
|
||||||
|
static void missionCallback(Vehicle* vehiclePtr, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init waypt mission, blocking calls
|
||||||
|
*
|
||||||
|
* @param timeout timeout
|
||||||
|
* @param wayptData initData for the waypt (void ptr)
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode initWayptMission(int timeout = 10, UserData wayptData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init waypt mission, non-blocking calls
|
||||||
|
*
|
||||||
|
* @param timeout timeout
|
||||||
|
* @param wayptData initData for the waypt (void ptr)
|
||||||
|
*/
|
||||||
|
void initWayptMission(VehicleCallBack callback = 0, UserData wayptData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init hot pt mission, blocking calls
|
||||||
|
*
|
||||||
|
* @param timeout timeout
|
||||||
|
* @param wayptData initData for hotpt (void ptr)
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode initHotptMission(int timeout = 10, UserData wayptData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init hot pt mission, non-blocking calls
|
||||||
|
*
|
||||||
|
* @param timeout timeout
|
||||||
|
* @param wayptData initData for hotpt (void ptr)
|
||||||
|
*/
|
||||||
|
void initHotptMission(VehicleCallBack callback = 0, UserData wayptData = 0);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* get waypt ptr from waypt container
|
||||||
|
*
|
||||||
|
* @param index index of waypt container
|
||||||
|
*/
|
||||||
|
WaypointMission* getWaypt(int index);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* get hotpt ptr from hotpt container
|
||||||
|
*
|
||||||
|
* @param index index of hotpt container
|
||||||
|
*/
|
||||||
|
HotpointMission* getHotpt(int index);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* print the status of the mission manager
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void printInfo();
|
||||||
|
|
||||||
|
Vehicle* vehicle;
|
||||||
|
WaypointMission* wpMission;
|
||||||
|
HotpointMission* hpMission;
|
||||||
|
|
||||||
|
//! counter to keep track of the amount of mission (protection mechanism in
|
||||||
|
//! get_Pt())
|
||||||
|
int wayptCounter;
|
||||||
|
int hotptCounter;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! @note no dynamic container, so fix the size of the mission container
|
||||||
|
static const int MAX_MISSION_SIZE = 5;
|
||||||
|
|
||||||
|
WaypointMission* wpMissionArray[MAX_MISSION_SIZE];
|
||||||
|
HotpointMission* hpMissionArray[MAX_MISSION_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // ONBOARDSDK_DJI_MISSIONMANAGER_H
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/** @file dji_mission_type.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Mission related data struct for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_DJI_MISSION_TYPE_H
|
||||||
|
#define ONBOARDSDK_DJI_MISSION_TYPE_H
|
||||||
|
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
/**********Mission structs/Enums***********/
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HotPoint Mission Initialization settings
|
||||||
|
* @details This is one of the few structs in the OSDK codebase that
|
||||||
|
* is used in both a sending and a receiving API.
|
||||||
|
*/
|
||||||
|
typedef struct HotPointSettings
|
||||||
|
{
|
||||||
|
uint8_t version; /*!< Reserved, kept as 0 */
|
||||||
|
float64_t latitude; /*!< Latitude (radian) */
|
||||||
|
float64_t longitude; /*!< Longitude (radian) */
|
||||||
|
float64_t height; /*!< Altitude (relative altitude from takeoff point */
|
||||||
|
float64_t radius; /*!< Radius (5m~500m) */
|
||||||
|
float32_t yawRate; /*!< Angle rate (0~30°/s) */
|
||||||
|
uint8_t clockwise; /*!< 0->fly in counter-clockwise direction, 1->clockwise direction */
|
||||||
|
uint8_t startPoint; /*!< Start point position <br>*/
|
||||||
|
/*!< 0: north to the hot point <br>*/
|
||||||
|
/*!< 1: south to the hot point <br>*/
|
||||||
|
/*!< 2: west to the hot point <br>*/
|
||||||
|
/*!< 3: east to the hot point <br>*/
|
||||||
|
/*!< 4: from current position to nearest point on the hot point */
|
||||||
|
uint8_t yawMode; /*!< Yaw mode <br>*/
|
||||||
|
/*!< 0: point to velocity direction <br>*/
|
||||||
|
/*!< 1: face inside <br>*/
|
||||||
|
/*!< 2: face ouside <br>*/
|
||||||
|
/*!< 3: controlled by RC <br>*/
|
||||||
|
/*!< 4: same as the starting yaw<br> */
|
||||||
|
uint8_t reserved[11]; /*!< Reserved */
|
||||||
|
} HotPointSettings; // pack(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waypoint Mission Initialization settings
|
||||||
|
* @details This is one of the few structs in the OSDK codebase that
|
||||||
|
* is used in both a sending and a receiving API.
|
||||||
|
*/
|
||||||
|
typedef struct WayPointInitSettings
|
||||||
|
{
|
||||||
|
uint8_t indexNumber; /*!< Total number of waypoints <br>*/
|
||||||
|
float32_t maxVelocity; /*!< Maximum speed joystick input(2~15m) <br>*/
|
||||||
|
float32_t idleVelocity; /*!< Cruising Speed */
|
||||||
|
/*!< (without joystick input, no more than vel_cmd_range) */
|
||||||
|
uint8_t finishAction; /*!< Action on finish <br>*/
|
||||||
|
/*!< 0: no action <br>*/
|
||||||
|
/*!< 1: return to home <br>*/
|
||||||
|
/*!< 2: auto landing <br>*/
|
||||||
|
/*!< 3: return to point 0 <br>*/
|
||||||
|
/*!< 4: infinite mode, no exit <br>*/
|
||||||
|
uint8_t executiveTimes; /*!< Function execution times <br>*/
|
||||||
|
/*!< 1: once <br>*/
|
||||||
|
/*!< 2: twice <br>*/
|
||||||
|
uint8_t yawMode; /*!< Yaw mode <br>*/
|
||||||
|
/*!< 0: auto mode(point to next waypoint) <br>*/
|
||||||
|
/*!< 1: lock as an initial value <br>*/
|
||||||
|
/*!< 2: controlled by RC <br>*/
|
||||||
|
/*!< 3: use waypoint's yaw(tgt_yaw) */
|
||||||
|
uint8_t traceMode; /*!< Trace mode <br>*/
|
||||||
|
/*!< 0: point to point, after reaching the target waypoint hover,
|
||||||
|
* complete waypoints action (if any),
|
||||||
|
* then fly to the next waypoint <br>
|
||||||
|
* 1: Coordinated turn mode, smooth transition between waypoints,
|
||||||
|
* no waypoints task <br>
|
||||||
|
*/
|
||||||
|
uint8_t RCLostAction; /*!< Action on rc lost <br>*/
|
||||||
|
/*!< 0: exit waypoint and failsafe <br>*/
|
||||||
|
/*!< 1: continue the waypoint <br>*/
|
||||||
|
uint8_t gimbalPitch; /*!< Gimbal pitch mode <br>*/
|
||||||
|
/*!< 0: free mode, no control on gimbal <br>*/
|
||||||
|
/*!< 1: auto mode, Smooth transition between waypoints <br>*/
|
||||||
|
float64_t latitude; /*!< Focus latitude (radian) */
|
||||||
|
float64_t longitude; /*!< Focus longitude (radian) */
|
||||||
|
float32_t altitude; /*!< Focus altitude (relative takeoff point height) */
|
||||||
|
uint8_t reserved[16]; /*!< Reserved, must be set to 0 */
|
||||||
|
|
||||||
|
} WayPointInitSettings; // pack(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waypoint settings for individual waypoints being added to the mission
|
||||||
|
* @details This is one of the few structs in the OSDK codebase that
|
||||||
|
* is used in both a sending and a receiving API.
|
||||||
|
*/
|
||||||
|
typedef struct WayPointSettings
|
||||||
|
{
|
||||||
|
uint8_t index; /*!< Index to be uploaded */
|
||||||
|
float64_t latitude; /*!< Latitude (radian) */
|
||||||
|
float64_t longitude; /*!< Longitude (radian) */
|
||||||
|
float32_t altitude; /*!< Altitude (relative altitude from takeoff point) */
|
||||||
|
float32_t damping; /*!< Bend length (effective coordinated turn mode only) */
|
||||||
|
int16_t yaw; /*!< Yaw (degree) */
|
||||||
|
int16_t gimbalPitch; /*!< Gimbal pitch */
|
||||||
|
uint8_t turnMode; /*!< Turn mode <br> */
|
||||||
|
/*!< 0: clockwise <br>*/
|
||||||
|
/*!< 1: counter-clockwise <br>*/
|
||||||
|
uint8_t reserved[8]; /*!< Reserved */
|
||||||
|
uint8_t hasAction; /*!< Action flag <br>*/
|
||||||
|
/*!< 0: no action <br>*/
|
||||||
|
/*!< 1: has action <br>*/
|
||||||
|
uint16_t actionTimeLimit; /*!< Action time limit */
|
||||||
|
uint8_t actionNumber : 4; /*!< Total number of actions */
|
||||||
|
uint8_t actionRepeat : 4; /*!< Total running times */
|
||||||
|
uint8_t commandList[16]; /*!< Command list */
|
||||||
|
uint16_t commandParameter[16]; /*!< Command parameters */
|
||||||
|
} WayPointSettings; // pack(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief WayPoint Push Data Incident Type enumerator
|
||||||
|
*/
|
||||||
|
//! @note can be separated by the first bytes of data
|
||||||
|
typedef enum WayPointIncidentType {
|
||||||
|
NAVI_UPLOAD_FINISH,
|
||||||
|
NAVI_MISSION_FINISH,
|
||||||
|
NAVI_MISSION_WP_REACH_POINT
|
||||||
|
} WayPointIncidentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Waypoint Mission Finish Event Push Data
|
||||||
|
*/
|
||||||
|
typedef struct WayPointFinishData
|
||||||
|
{
|
||||||
|
uint8_t incident_type; /*! see WayPointIncidentType */
|
||||||
|
uint8_t repeat;
|
||||||
|
uint16_t reserved_1;
|
||||||
|
uint16_t reserved_2;
|
||||||
|
} WayPointFinishData; // pack(1)
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
// clang-format on
|
||||||
|
} // OSDK
|
||||||
|
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // ONBOARDSDK_DJI_MISSION_TYPE_H
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/** @file dji_mobile_communication.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Implementation of DJI Mobile-Onboard SDK Communication (MOC)
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MOC_H
|
||||||
|
#define MOC_H
|
||||||
|
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief APIs for Mobile-Onboard SDK Communication
|
||||||
|
*
|
||||||
|
* @details This class implements the Onboard SDK side of
|
||||||
|
* Data Transparent Transmission functionality. You must implement APIs
|
||||||
|
* available
|
||||||
|
* in the Mobile SDK to have full functionality on both directions of the
|
||||||
|
* pipeline.
|
||||||
|
*/
|
||||||
|
class MobileCommunication
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MobileCommunication(Vehicle* vehicle = 0);
|
||||||
|
~MobileCommunication();
|
||||||
|
|
||||||
|
Vehicle* getVehicle() const;
|
||||||
|
void setVehicle(Vehicle* value);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* @brief sending data from OSDK to MSDK
|
||||||
|
*
|
||||||
|
* @param data sent data
|
||||||
|
* @param len length of data
|
||||||
|
*/
|
||||||
|
void sendDataToMSDK(uint8_t* data, uint8_t len);
|
||||||
|
static void getDataFromMSDKCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
public:
|
||||||
|
VehicleCallBackHandler fromMSDKHandler;
|
||||||
|
void setFromMSDKCallback(VehicleCallBack callback, UserData userData = 0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
|
||||||
|
#endif // MOC_H
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/** @file dji_status.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date June 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* Status information for DJI Vehicle
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_STATUS_H
|
||||||
|
#define DJI_STATUS_H
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* @brief info about vehicle
|
||||||
|
*/
|
||||||
|
namespace VehicleStatus
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* @brief status of vehicle
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/*! This mode requires the user to manually
|
||||||
|
* control the aircraft to remain stable in air. */
|
||||||
|
MODE_MANUAL_CTRL = 0,
|
||||||
|
/*! In this mode, the aircraft can keep
|
||||||
|
* attitude stabilization and only use the
|
||||||
|
* barometer for positioning to control the altitude. <br>
|
||||||
|
* The aircraft can not autonomously locate and hover stably.*/
|
||||||
|
MODE_ATTITUDE = 1,
|
||||||
|
MODE_RESERVED_2 = 2,
|
||||||
|
MODE_RESERVED_3 = 3,
|
||||||
|
MODE_RESERVED_4 = 4,
|
||||||
|
MODE_RESERVED_5 = 5,
|
||||||
|
/*! The aircraft is in normal GPS mode. <br>
|
||||||
|
* In normal GPS mode, the aircraft can
|
||||||
|
* autonomously locate and hover stably. <br>
|
||||||
|
* The sensitivity of the aircraft to the
|
||||||
|
* command response is moderate.
|
||||||
|
*/
|
||||||
|
MODE_P_GPS = 6,
|
||||||
|
MODE_RESERVED_7 = 7,
|
||||||
|
MODE_RESERVED_8 = 8,
|
||||||
|
/*! In hotpoint mode */
|
||||||
|
MODE_HOTPOINT_MODE = 9,
|
||||||
|
/*! In this mode, user can push the throttle
|
||||||
|
* stick to complete stable take-off. */
|
||||||
|
MODE_ASSISTED_TAKEOFF = 10,
|
||||||
|
/*! In this mode, the aircraft will autonomously
|
||||||
|
* start motor, ascend and finally hover. */
|
||||||
|
MODE_AUTO_TAKEOFF = 11,
|
||||||
|
/*! In this mode, the aircraft can land autonomously. */
|
||||||
|
MODE_AUTO_LANDING = 12,
|
||||||
|
MODE_RESERVED_13 = 13,
|
||||||
|
MODE_RESERVED_14 = 14,
|
||||||
|
/*! In this mode, the aircraft can antonomously return the
|
||||||
|
* last recorded Home Point. <br>
|
||||||
|
* There are three types of this mode: Smart RTH(Return-to-Home),
|
||||||
|
* Low Batterry RTH, and Failsafe RTTH. */
|
||||||
|
MODE_NAVI_GO_HOME = 15,
|
||||||
|
MODE_RESERVED_16 = 16,
|
||||||
|
/*! In this mode, the aircraft is controled by SDK API. <br>
|
||||||
|
* User can directly define the control mode of horizon
|
||||||
|
* and vertical directions and send control datas to aircraft. */
|
||||||
|
MODE_NAVI_SDK_CTRL = 17,
|
||||||
|
MODE_RESERVED_18 = 18,
|
||||||
|
MODE_RESERVED_19 = 19,
|
||||||
|
MODE_RESERVED_20 = 20,
|
||||||
|
MODE_RESERVED_21 = 21,
|
||||||
|
MODE_RESERVED_22 = 22,
|
||||||
|
MODE_RESERVED_23 = 23,
|
||||||
|
MODE_RESERVED_24 = 24,
|
||||||
|
MODE_RESERVED_25 = 25,
|
||||||
|
MODE_RESERVED_26 = 26,
|
||||||
|
MODE_RESERVED_27 = 27,
|
||||||
|
MODE_RESERVED_28 = 28,
|
||||||
|
MODE_RESERVED_29 = 29,
|
||||||
|
MODE_RESERVED_30 = 30,
|
||||||
|
MODE_RESERVED_31 = 31,
|
||||||
|
MODE_RESERVED_32 = 32,
|
||||||
|
/*! drone is forced to land, might due to low battery */
|
||||||
|
MODE_FORCE_AUTO_LANDING = 33,
|
||||||
|
MODE_RESERVED_34 = 34,
|
||||||
|
MODE_RESERVED_35 = 35,
|
||||||
|
MODE_RESERVED_36 = 36,
|
||||||
|
MODE_RESERVED_37 = 37,
|
||||||
|
MODE_RESERVED_38 = 38,
|
||||||
|
MODE_RESERVED_39 = 39,
|
||||||
|
/*! drone will search for the last position where the rc is not lost */
|
||||||
|
MODE_SEARCH_MODE = 40,
|
||||||
|
/*! Mode for motor starting. <br>
|
||||||
|
* Every time user unlock the motor, this will be the first mode. */
|
||||||
|
MODE_ENGINE_START = 41,
|
||||||
|
MODE_RESERVED_42 = 42,
|
||||||
|
MODE_RESERVED_43 = 42,
|
||||||
|
|
||||||
|
LANDING_GEAR_UNDEFINED = 0,
|
||||||
|
LANDING_GEAR_DOWN = 1,
|
||||||
|
LANDING_GEAR_UP_TO_DOWN = 2,
|
||||||
|
LANDING_GEAR_UP = 3,
|
||||||
|
LANDING_GEAR_DOWN_TO_UP = 4,
|
||||||
|
LANDING_GEAR_HOLD = 5,
|
||||||
|
LANDING_GEAR_PACKED = 6,
|
||||||
|
LANDING_GEAR_PACKING_IN_PROGRESS = 7,
|
||||||
|
LANDING_GEAR_UNPACKING_IN_PROGRESS = 8,
|
||||||
|
|
||||||
|
CTRL_MODE_ATTI_STOP = 0,
|
||||||
|
CTRL_MODE_HORIZ_ANG_VERT_VEL_YAW_ANG = 1,
|
||||||
|
CTRL_MODE_HORIZ_ANG_VERT_VEL_YAW_RATE = 2,
|
||||||
|
CTRL_MODE_HORIZ_VEL_VERT_VEL_YAW_ANG = 3,
|
||||||
|
CTRL_MODE_HORIZ_VEL_VERT_VEL_YAW_RATE = 4,
|
||||||
|
CTRL_MODE_HORIZ_POS_VERT_VEL_YAW_ANG = 5,
|
||||||
|
CTRL_MODE_HORIZ_POS_VERT_VEL_YAW_RATE = 6,
|
||||||
|
CTRL_MODE_HORIZ_ANG_VERT_POS_YAW_ANG = 7,
|
||||||
|
CTRL_MODE_HORIZ_ANG_VERT_POS_YAW_RATE = 8,
|
||||||
|
CTRL_MODE_HORIZ_VEL_VERT_POS_YAW_ANG = 9,
|
||||||
|
CTRL_MODE_HORIZ_VEL_VERT_POS_YAW_RATE = 10,
|
||||||
|
CTRL_MODE_HORIZ_POS_VERT_POS_YAW_ANG = 11,
|
||||||
|
CTRL_MODE_HORIZ_POS_VERT_POS_YAW_RATE = 12,
|
||||||
|
CTRL_MODE_HORIZ_ANG_VERT_THR_YAW_ANG = 13,
|
||||||
|
CTRL_MODE_HORIZ_ANG_VERT_THR_YAW_RATE = 14,
|
||||||
|
CTRL_MODE_HORIZ_VEL_VERT_THR_YAW_ANG = 15,
|
||||||
|
CTRL_MODE_HORIZ_VEL_VERT_THR_YAW_RATE = 16,
|
||||||
|
CTRL_MODE_HORIZ_POS_VERT_THR_YAW_ANG = 17,
|
||||||
|
CTRL_MODE_HORIZ_POS_VERT_THR_YAW_RATE = 18,
|
||||||
|
CTRL_MODE_HORIZ_PAL_VERT_VEL_YAW_RATE = 19,
|
||||||
|
CTRL_MODE_HORIZ_PAL_VERT_POS_YAW_RAT = 20,
|
||||||
|
CTRL_MODE_HORIZ_PAL_VERT_THR_YAW_RATE = 21,
|
||||||
|
CTRL_MODE_GPS_ATII_CTRL_CL_YAW_RATE = 97, //!< @note unused
|
||||||
|
CTRL_MODE_GPS_ATTI_CTRL_YAW_RATE = 98, //!< @note unused
|
||||||
|
CTRL_MODE_ATTI_CTRL_YAW_RATE = 99, //!< @note unused
|
||||||
|
CTRL_MODE_ATTI_CTRL_STOP = 100,
|
||||||
|
CTRL_MODE_MODE_NOT_SUPPORTED = 0xFF //!< @note unused
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace VehicleStatus
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
#endif /* DJI_STATUS_H */
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/** @file dji_subscription.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Telemetry Subscription API for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_DATASUBSCRIPTION_H
|
||||||
|
#define DJI_DATASUBSCRIPTION_H
|
||||||
|
|
||||||
|
#include "dji_open_protocol.hpp"
|
||||||
|
#include "dji_telemetry.hpp"
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
/*! @brief Package class to support Subscribe-style telemetry
|
||||||
|
*
|
||||||
|
* @details Use the DJI_DataSubscription class to access telemetry.
|
||||||
|
*
|
||||||
|
* @note This class is internal and does not need to be used by applications
|
||||||
|
* directly.
|
||||||
|
*/
|
||||||
|
class SubscriptionPackage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct PackageInfo
|
||||||
|
{
|
||||||
|
uint8_t packageID;
|
||||||
|
uint16_t freq;
|
||||||
|
uint8_t config;
|
||||||
|
uint8_t numberOfTopics;
|
||||||
|
} PackageInfo;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubscriptionPackage();
|
||||||
|
~SubscriptionPackage();
|
||||||
|
|
||||||
|
void setPackageID(uint8_t id);
|
||||||
|
void setConfig(uint8_t config);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Fill in necessary information for ADD_PACKAGE call
|
||||||
|
* @param topics: List of TopicName
|
||||||
|
* @param numberOfTopics: Number of topics to subscribe for this package
|
||||||
|
* @param freq: Frequency of this package
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool setTopicList(Telemetry::TopicName* topics, int numberOfTopics,
|
||||||
|
uint16_t freq);
|
||||||
|
void allocateDataBuffer();
|
||||||
|
void clearDataBuffer();
|
||||||
|
|
||||||
|
void cleanUpPackage();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Serialize the info and uidList to a buffer to send to FC
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
int serializePackageInfo(uint8_t* buffer);
|
||||||
|
|
||||||
|
void setUserUnpackCallback(VehicleCallBack userFunctionAfterPackageExtraction,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
bool isOccupied();
|
||||||
|
|
||||||
|
void setOccupied(bool status);
|
||||||
|
|
||||||
|
// Accessors to private variables:
|
||||||
|
PackageInfo getInfo();
|
||||||
|
uint32_t* getUidList(); // explicitly show it's a pointer
|
||||||
|
Telemetry::TopicName* getTopicList();
|
||||||
|
uint32_t* getOffsetList();
|
||||||
|
uint8_t* getDataBuffer();
|
||||||
|
uint32_t getBufferSize();
|
||||||
|
VehicleCallBackHandler getUnpackHandler();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Helper function to do post processing when adding package is
|
||||||
|
* successful.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void packageAddSuccessHandler();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Helper function to do post processing when removing package is
|
||||||
|
* successful.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void packageRemoveSuccessHandler();
|
||||||
|
|
||||||
|
private: // Private variables
|
||||||
|
bool occupied;
|
||||||
|
PackageInfo info;
|
||||||
|
|
||||||
|
// We have only 30 topics and 5 packages.
|
||||||
|
// So let's not bother with dynamic memory for now.
|
||||||
|
// The UID
|
||||||
|
uint32_t uidList[Telemetry::TOTAL_TOPIC_NUMBER];
|
||||||
|
// The Name enum, used as index in the DataBase
|
||||||
|
Telemetry::TopicName topicList[Telemetry::TOTAL_TOPIC_NUMBER];
|
||||||
|
// The offset of each topic in the data flow
|
||||||
|
uint32_t offsetList[Telemetry::TOTAL_TOPIC_NUMBER];
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The total size of all the actual topics in the package,
|
||||||
|
* not the size of the uidlist or namelist
|
||||||
|
*/
|
||||||
|
uint32_t packageDataSize;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The buffer to hold data from FC
|
||||||
|
*/
|
||||||
|
uint8_t* incomingDataBuffer;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Advanced users can optionally register a callback function
|
||||||
|
* (for each package) to run after every package is received.
|
||||||
|
* This function is called in the end of decodeCallback function.
|
||||||
|
*/
|
||||||
|
VehicleCallBackHandler userUnpackHandler;
|
||||||
|
}; // class SubscriptionPackage
|
||||||
|
|
||||||
|
/*! @brief Telemetry API through asynchronous "Subscribe"-style messages
|
||||||
|
*
|
||||||
|
* @details The subscribe API allows fine-grained control over requesting
|
||||||
|
* various topics at various frequencies.
|
||||||
|
*
|
||||||
|
* All topics at a certain frequency should be put into a single "package".
|
||||||
|
*
|
||||||
|
* @note Subscribe-style telemetry is a new feature, available since OSDK 3.3
|
||||||
|
*/
|
||||||
|
class DataSubscription
|
||||||
|
{
|
||||||
|
public: // public methods
|
||||||
|
DataSubscription(Vehicle* vehicle);
|
||||||
|
~DataSubscription();
|
||||||
|
|
||||||
|
Vehicle* getVehicle();
|
||||||
|
/*!
|
||||||
|
* @brief This is the interface for the end user to generate a package for
|
||||||
|
* subscription.
|
||||||
|
*
|
||||||
|
* @param packageID: The ID of package it'll generate
|
||||||
|
* @param numberOfTopics:
|
||||||
|
* @param topicList: List of Topic Names to subscribe in the package
|
||||||
|
* @param sendTimeStamp
|
||||||
|
* @param freq
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool initPackageFromTopicList(int packageID, int numberOfTopics,
|
||||||
|
Telemetry::TopicName* topicList,
|
||||||
|
bool sendTimeStamp, uint16_t freq);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Non-blocking call for version match
|
||||||
|
*/
|
||||||
|
void verify();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Blocking call for version match.
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode verify(int timeout); // blocking call
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Non-blocking call for starting a package
|
||||||
|
* @param packageID
|
||||||
|
*/
|
||||||
|
void startPackage(int packageID);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Blocking call for start package
|
||||||
|
* @param packageID
|
||||||
|
* @param timeout
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode startPackage(int packageID, int timeout); // blocking call
|
||||||
|
|
||||||
|
void removePackage(int packageID);
|
||||||
|
ACK::ErrorCode removePackage(int packageID, int timeout); // blocking call
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Register a callback function after package[packageID] is received
|
||||||
|
* @param packageID
|
||||||
|
* @param userFunctionAfterPackageExtraction
|
||||||
|
*/
|
||||||
|
void registerUserPackageUnpackCallback(
|
||||||
|
int packageID, VehicleCallBack userFunctionAfterPackageExtraction,
|
||||||
|
UserData userData = NULL);
|
||||||
|
|
||||||
|
// Not implemented yet
|
||||||
|
bool pausePackage(int packageID);
|
||||||
|
bool resumePackage(int packageID);
|
||||||
|
// bool changePackageFrequency(int packageID, uint16_t newFreq);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Callback function for non-blocking verify()
|
||||||
|
*
|
||||||
|
* @param API
|
||||||
|
* @param header
|
||||||
|
* @param userData
|
||||||
|
*/
|
||||||
|
static void verifyCallback(Vehicle* vehiclePtr, RecvContainer rcvContainer,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
static void addPackageCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer rcvContainer,
|
||||||
|
UserData pkgHandle);
|
||||||
|
|
||||||
|
static void removePackageCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer rcvContainer,
|
||||||
|
UserData pkgHandle);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief This callback function is called by recvReqData, case
|
||||||
|
* CMD_ID_SUBSCRIBE.
|
||||||
|
* @param API
|
||||||
|
* @param header
|
||||||
|
* @param subHandle: The pointer to the subscription object.
|
||||||
|
*/
|
||||||
|
static void decodeCallback(Vehicle* vehiclePtr, RecvContainer rcvContainer,
|
||||||
|
UserData subscriptionPtr);
|
||||||
|
|
||||||
|
template <Telemetry::TopicName topic>
|
||||||
|
typename Telemetry::TypeMap<topic>::type getValue()
|
||||||
|
{
|
||||||
|
typename Telemetry::TypeMap<topic>::type ans;
|
||||||
|
|
||||||
|
void* p = Telemetry::TopicDataBase[topic].latest;
|
||||||
|
|
||||||
|
protocol->getThreadHandle()->lockMSG();
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
ans = *reinterpret_cast<typename Telemetry::TypeMap<topic>::type*>(p);
|
||||||
|
protocol->getThreadHandle()->freeMSG();
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("Topic 0x%X value memory not initialized, return default", topic);
|
||||||
|
}
|
||||||
|
protocol->getThreadHandle()->freeMSG();
|
||||||
|
|
||||||
|
memset(&ans, 0xFF, sizeof(ans));
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
public: // public variables
|
||||||
|
const static uint8_t MAX_NUMBER_OF_PACKAGE = 5;
|
||||||
|
VehicleCallBackHandler subscriptionDataDecodeHandler;
|
||||||
|
|
||||||
|
private: // private variables
|
||||||
|
Vehicle* vehicle;
|
||||||
|
Protocol* protocol;
|
||||||
|
SubscriptionPackage package[MAX_NUMBER_OF_PACKAGE];
|
||||||
|
|
||||||
|
private: // private methods
|
||||||
|
void extractOnePackage(RecvContainer* pRcvContainer,
|
||||||
|
SubscriptionPackage* pkg);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DJI_DATASUBSCRIPTION_H
|
||||||
@@ -0,0 +1,554 @@
|
|||||||
|
/** @file dji_telemetry.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Enumeration of all telemetry data types, structures and maps.
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_DJI_Telemetry_H
|
||||||
|
#define ONBOARDSDK_DJI_Telemetry_H
|
||||||
|
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Top-level namespace
|
||||||
|
*/
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* Onboard SDK related commands
|
||||||
|
*/
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
/*! @brief This namespace encapsulates all available telemetry topics through
|
||||||
|
* either
|
||||||
|
* Broadcast or Subscribe
|
||||||
|
*/
|
||||||
|
namespace Telemetry
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
* @brief enum TopicName is the interface for user to create packages and access
|
||||||
|
* data
|
||||||
|
* It is also used as index for TopicDataBase
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// clang-format off
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TOPIC_QUATERNION, /*!< quaternion @200Hz*/
|
||||||
|
TOPIC_ACCELERATION_GROUND, /*!< acceleration in ground frame @200Hz */
|
||||||
|
TOPIC_ACCELERATION_BODY, /*!< acceleration in body frame @200Hz*/
|
||||||
|
TOPIC_ACCELERATION_RAW, /*!< raw acceleration @400Hz */
|
||||||
|
TOPIC_VELOCITY, /*!< velocity @200Hz */
|
||||||
|
TOPIC_ANGULAR_RATE_FUSIONED, /*!< attitude rate @200Hz */
|
||||||
|
TOPIC_ANGULAR_RATE_RAW, /*!< raw attitude rate @400Hz */
|
||||||
|
TOPIC_ALTITUDE_FUSIONED, /*!< fused altitude @200Hz */
|
||||||
|
TOPIC_ALTITUDE_BAROMETER, /*!< barometer @200Hz */
|
||||||
|
TOPIC_HEIGHT_HOMEPOOINT, /*!< home point height @1Hz */
|
||||||
|
TOPIC_HEIGHT_FUSION, /*!< fused height @100Hz */
|
||||||
|
TOPIC_GPS_FUSED, /*!< fused position @50Hz */
|
||||||
|
TOPIC_GPS_DATE, /*!< GPS date @50Hz */
|
||||||
|
TOPIC_GPS_TIME, /*!< GPS time @50Hz */
|
||||||
|
TOPIC_GPS_POSITION, /*!< GPS position data type: (uint32)deg*10^7 @50Hz */
|
||||||
|
TOPIC_GPS_VELOCITY, /*!< GPS velocity @50Hz */
|
||||||
|
TOPIC_GPS_DETAILS, /*!< GPS status @50Hz */
|
||||||
|
TOPIC_RTK_POSITION, /*!< RTK position @50Hz */
|
||||||
|
TOPIC_RTK_VELOCITY, /*!< RTK velocity @50Hz */
|
||||||
|
TOPIC_RTK_YAW, /*!< RTK yaw @50Hz */
|
||||||
|
TOPIC_RTK_POSITION_INFO, /*!< RTK status @50Hz */
|
||||||
|
TOPIC_RTK_YAW_INFO, /*!< RTK yaw status @50Hz */
|
||||||
|
TOPIC_COMPASS, /*!< magnetometer @100Hz */
|
||||||
|
TOPIC_RC, /*!< 6-channel RC @50Hz */
|
||||||
|
TOPIC_GIMBAL_ANGLES, /*!< gimbal angle @50Hz */
|
||||||
|
TOPIC_GIMBAL_STATUS, /*!< gimbal status @50Hz */
|
||||||
|
TOPIC_STATUS_FLIGHT, /*!< flight status @50Hz */
|
||||||
|
TOPIC_STATUS_DISPLAYMODE, /*!< display mode @50Hz */
|
||||||
|
TOPIC_STATUS_LANDINGGEAR, /*!< landing gear status @50Hz */
|
||||||
|
TOPIC_STATUS_MOTOR_START_ERROR, /*!< motor start error @50Hz */
|
||||||
|
TOPIC_BATTERY_INFO, /*!< battery info @50Hz */
|
||||||
|
TOPIC_CONTROL_DEVICE, /*!< SDK control device info @50Hz */
|
||||||
|
TOPIC_HARD_SYNC, /*!< hardware sync @400Hz */
|
||||||
|
TOPIC_GPS_SIGNAL_LEVEL, /*!< GPS Signal Level @50Hz */
|
||||||
|
TOPIC_GPS_CONTROL_LEVEL, /*!< GPS Control Level @50Hz */
|
||||||
|
TOTAL_TOPIC_NUMBER // Always put this line in the end
|
||||||
|
} TopicName;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* enum TOPIC_UID is the UID that is accepted by the FC
|
||||||
|
*/
|
||||||
|
// clang-format off
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
UID_QUATERNION = 0xa493281f,
|
||||||
|
UID_ACCELERATION_GROUND = 0x8696c85b,
|
||||||
|
UID_ACCELERATION_BODY = 0xbb17d5fe,
|
||||||
|
UID_ACCELERATION_RAW = 0xc3503a6e,
|
||||||
|
UID_VELOCITY = 0x18fb271d,
|
||||||
|
UID_ANGULAR_RATE_FUSIONED = 0x3599c4be,
|
||||||
|
UID_ANGULAR_RATE_RAW = 0x700389ee,
|
||||||
|
UID_ALTITUDE_FUSIONED = 0x11e9c81a,
|
||||||
|
UID_ALTITUDE_BAROMETER = 0x27396a39,
|
||||||
|
UID_HEIGHT_HOMEPOOINT = 0x252c164b,
|
||||||
|
UID_HEIGHT_FUSION = 0x87cf419d,
|
||||||
|
UID_GPS_FUSED = 0x4b19a8c7,
|
||||||
|
UID_GPS_DATE = 0x598f79bc,
|
||||||
|
UID_GPS_TIME = 0xd48912c9,
|
||||||
|
UID_GPS_POSITION = 0x0c949e94,
|
||||||
|
UID_GPS_VELOCITY = 0x7ac7eb80,
|
||||||
|
UID_GPS_DETAILS = 0x81fed54e,
|
||||||
|
UID_RTK_POSITION = 0x1df9a6b6,
|
||||||
|
UID_RTK_VELOCITY = 0x763d13c3,
|
||||||
|
UID_RTK_YAW = 0xf45d73fd,
|
||||||
|
UID_RTK_POSITION_INFO = 0xda4a57b5,
|
||||||
|
UID_RTK_YAW_INFO = 0xcb72b9e3,
|
||||||
|
UID_COMPASS = 0xdf3d72b7,
|
||||||
|
UID_RC = 0x739f7fe4,
|
||||||
|
UID_GIMBAL_ANGLES = 0x01f71678,
|
||||||
|
UID_GIMBAL_STATUS = 0x8b6cd45c,
|
||||||
|
UID_STATUS_FLIGHT = 0x20cfb02a,
|
||||||
|
UID_STATUS_DISPLAYMODE = 0x1a67d6a1,
|
||||||
|
UID_STATUS_LANDINGGEAR = 0x772d6e22,
|
||||||
|
UID_STATUS_MOTOR_START_ERROR = 0x3a41e909,
|
||||||
|
UID_BATTERY_INFO = 0x69779dd9,
|
||||||
|
UID_CONTROL_DEVICE = 0x667ba86a,
|
||||||
|
UID_HARD_SYNC = 0xecbef06d,
|
||||||
|
UID_GPS_SIGNAL_LEVEL = 0xa6a0395f,
|
||||||
|
UID_GPS_CONTROL_LEVEL = 0xe30b17b0
|
||||||
|
} TOPIC_UID;
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const TopicName name;
|
||||||
|
const uint32_t uid;
|
||||||
|
const size_t size; /* The size of actual data for the topic */
|
||||||
|
const uint16_t maxFreq; /* max freq in Hz for the topic provided by FC */
|
||||||
|
uint16_t freq; /* Frequency at which the topic is subscribed */
|
||||||
|
uint8_t pkgID; /* Package ID in which the topic is subscribed */
|
||||||
|
/* Point to topic's address in the data buffer which stores the latest data */
|
||||||
|
uint8_t* latest;
|
||||||
|
} TopicInfo; // pack(1)
|
||||||
|
|
||||||
|
/*! @brief struct for TOPIC_QUATERNION
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct Quaternion
|
||||||
|
{
|
||||||
|
float32_t q0; /*!< w */
|
||||||
|
float32_t q1; /*!< x */
|
||||||
|
float32_t q2; /*!< y */
|
||||||
|
float32_t q3; /*!< z */
|
||||||
|
} Quaternion; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for multiple Topics
|
||||||
|
*/
|
||||||
|
typedef struct Vector3f
|
||||||
|
{
|
||||||
|
float32_t x;
|
||||||
|
float32_t y;
|
||||||
|
float32_t z;
|
||||||
|
} Vector3f; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for multiple Topics
|
||||||
|
*
|
||||||
|
* @note for TOPIC_GPS_POSITION, data type: (uint32)deg*10^7
|
||||||
|
*/
|
||||||
|
typedef struct Vector3d
|
||||||
|
{
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
int32_t z;
|
||||||
|
} Vector3d; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, timestamp from local cache
|
||||||
|
*
|
||||||
|
* @note not available in data subscription
|
||||||
|
*/
|
||||||
|
typedef struct TimeStamp
|
||||||
|
{
|
||||||
|
uint32_t time_ms;
|
||||||
|
uint32_t time_ns;
|
||||||
|
} TimeStamp; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, software sync timestamp from local cache
|
||||||
|
*
|
||||||
|
* @note not available in data subscription and different from Hardware sync
|
||||||
|
*/
|
||||||
|
typedef struct SyncStamp
|
||||||
|
{
|
||||||
|
uint32_t time_2p5ms; /*!< relative sync time */
|
||||||
|
uint16_t tag;
|
||||||
|
uint8_t flag;
|
||||||
|
} SyncStamp; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct indicates the signal level of GPS velocity info <br>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct VelocityInfo
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t health : 1; /*!< 1 - using GPS, 0 - not using GPS */
|
||||||
|
uint8_t reserve : 7;
|
||||||
|
} VelocityInfo; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_VELOCITY
|
||||||
|
*
|
||||||
|
* @note The velocity may be in body or ground frame
|
||||||
|
* based on settings in DJI Assistant 2's SDK page.
|
||||||
|
*/
|
||||||
|
typedef struct Velocity
|
||||||
|
{
|
||||||
|
Vector3f data;
|
||||||
|
/*! scale from 0 - 5 signifying gps signal strength <br>
|
||||||
|
* greater than 3 for strong signal
|
||||||
|
*/
|
||||||
|
VelocityInfo info;
|
||||||
|
} Velocity; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, return GPS data
|
||||||
|
*
|
||||||
|
* @note not available in data subscription
|
||||||
|
*/
|
||||||
|
typedef struct GlobalPosition
|
||||||
|
{
|
||||||
|
float64_t latitude; /*!< unit: rad */
|
||||||
|
float64_t longitude; /*!< unit: rad */
|
||||||
|
float32_t altitude; /*!< WGS 84 reference ellipsoid */
|
||||||
|
float32_t height; /*!< relative height to the ground */
|
||||||
|
uint8_t health; /*!< scale from 0 - 5 signifying gps signal strength <br>
|
||||||
|
* greater than 3 for strong signal */
|
||||||
|
} GlobalPosition; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_GPS_FUSED
|
||||||
|
*
|
||||||
|
* @note fusion data from GPS and IMU, return in gps format
|
||||||
|
*/
|
||||||
|
typedef struct GPSFused
|
||||||
|
{
|
||||||
|
float64_t longitude; /*!< unit: rad */
|
||||||
|
float64_t latitude; /*!< unit: rad */
|
||||||
|
float32_t altitude; /*!< WGS 84 reference ellipsoid */
|
||||||
|
uint16_t visibleSatelliteNumber; /*!< number of visible satellite */
|
||||||
|
} GPSFused; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, return obstacle info around the vehicle
|
||||||
|
*
|
||||||
|
* @note available in M210 (front, up, down)
|
||||||
|
*/
|
||||||
|
typedef struct RelativePosition
|
||||||
|
{
|
||||||
|
float32_t down; /*!< distance from obstacle (cm) */
|
||||||
|
float32_t front; /*!< distance from obstacle (cm) */
|
||||||
|
float32_t right; /*!< distance from obstacle (cm) */
|
||||||
|
float32_t back; /*!< distance from obstacle (cm) */
|
||||||
|
float32_t left; /*!< distance from obstacle (cm) */
|
||||||
|
float32_t up; /*!< distance from obstacle (cm) */
|
||||||
|
uint8_t downHealth : 1; /*!< 0 - not working, 1 - working */
|
||||||
|
uint8_t frontHealth : 1; /*!< 0 - not working, 1 - working */
|
||||||
|
uint8_t rightHealth : 1; /*!< 0 - not working, 1 - working */
|
||||||
|
uint8_t backHealth : 1; /*!< 0 - not working, 1 - working */
|
||||||
|
uint8_t leftHealth : 1; /*!< 0 - not working, 1 - working */
|
||||||
|
uint8_t upHealth : 1; /*!< 0 - not working, 1 - working */
|
||||||
|
uint8_t reserved : 2;
|
||||||
|
} RelativePosition; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief sub struct for GPSInfo
|
||||||
|
*/
|
||||||
|
typedef struct PositionTimeStamp
|
||||||
|
{
|
||||||
|
uint32_t date; /*!< yyyy-mm-dd */
|
||||||
|
uint32_t time; /*!< hh-mm-ss */
|
||||||
|
} PositionTimeStamp; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_RTK_POSITION and sub struct for RTK of data broadcast
|
||||||
|
*/
|
||||||
|
typedef struct PositionData
|
||||||
|
{
|
||||||
|
float64_t longitude; /*!< deg */
|
||||||
|
float64_t latitude; /*!< deg */
|
||||||
|
float32_t HFSL; /*!< height above mean sea level (m) */
|
||||||
|
} PositionData; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_GPS_DETAILS and sub struct for GPSInfo of data
|
||||||
|
* broadcast
|
||||||
|
*
|
||||||
|
* @note only work outside of simulation
|
||||||
|
*/
|
||||||
|
typedef struct GPSDetail
|
||||||
|
{
|
||||||
|
float32_t hdop; /*!< horizontal dilution of precision */
|
||||||
|
float32_t pdop; /*!< position dilution of precision */
|
||||||
|
float32_t fix; /*!< the state of GPS fix */
|
||||||
|
float32_t gnssStatus; /*!< vertical position accuracy (mm) */
|
||||||
|
float32_t hacc; /*!< horizontal position accuracy (mm) */
|
||||||
|
float32_t sacc; /*!< the speed accuracy (cm/s) */
|
||||||
|
uint32_t usedGPS; /*!< the number of GPS satellites used for pos fix */
|
||||||
|
uint32_t usedGLN; /*!< the number of GLONASS satellites used for pos fix */
|
||||||
|
uint16_t NSV; /*!< the total number of satellites used for pos fix */
|
||||||
|
uint16_t GPScounter; /*!< the accumulated times of sending GPS data */
|
||||||
|
} GPSDetail; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for GPSInfo of data broadcast
|
||||||
|
*
|
||||||
|
* @note only work outside of simulation
|
||||||
|
*/
|
||||||
|
typedef struct GPSInfo
|
||||||
|
{
|
||||||
|
PositionTimeStamp time;
|
||||||
|
int32_t longitude; /*!< 1/1.0e7deg */
|
||||||
|
int32_t latitude; /*!< 1/1.0e7deg */
|
||||||
|
int32_t HFSL; /*!< height above mean sea level (mm) */
|
||||||
|
Vector3f velocityNED; /*!< cm/s */
|
||||||
|
GPSDetail detail;
|
||||||
|
} GPSInfo; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief sub struct for RTK of data broadcast
|
||||||
|
*/
|
||||||
|
typedef struct PositionFrame
|
||||||
|
{
|
||||||
|
PositionTimeStamp time;
|
||||||
|
PositionData data;
|
||||||
|
} PositionFrame; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, return RTK info
|
||||||
|
*
|
||||||
|
* @note Available on A3/M600, need to enable it separately on DJI Assistant 2
|
||||||
|
*/
|
||||||
|
typedef struct RTK
|
||||||
|
{
|
||||||
|
PositionFrame pos;
|
||||||
|
Vector3f velocityNED;
|
||||||
|
/*! the azimuth measured by RTK */
|
||||||
|
int16_t yaw;
|
||||||
|
/*!
|
||||||
|
* 0 - no solution <br>
|
||||||
|
* 1 - Position has been fixed by the FIX POSITION command <br>
|
||||||
|
* 2 - Position has been fixed by the FIX HEIGHT/AUTO command <br>
|
||||||
|
* 8 - Velocity computed using instantaneous Doppler <br>
|
||||||
|
* 16 - Single point position <br>
|
||||||
|
* 17 - Pseudorange differential solution <br>
|
||||||
|
* 18 - Solution calculated using corrections from an SBAS <br>
|
||||||
|
* 19 - Propagated by a Kalman filter without new observations <br>
|
||||||
|
* 20 - OmniSTAR VBS position (L1 sub-metre) <br>
|
||||||
|
* 32 - Floating L1 ambiguity solution <br>
|
||||||
|
* 33 - Floating ionospheric-free ambiguity solution <br>
|
||||||
|
* 34 - Floating narrow-lane ambiguity solution <br>
|
||||||
|
* 48 - Integer L1 ambiguity solution <br>
|
||||||
|
* 49 - Integer wide-lane ambiguity solution <br>
|
||||||
|
* 50 - Integer narrow-lane ambiguity solution <br>
|
||||||
|
*/
|
||||||
|
uint8_t posHealthFlag;
|
||||||
|
uint8_t yawHealthFlag; /*!< same as posHealthFlag */
|
||||||
|
} RTK; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, return magnetometer reading
|
||||||
|
*
|
||||||
|
* @note returned value is calibrated mag data,
|
||||||
|
* 1000 < |mag| < 2000 for normal operation
|
||||||
|
*/
|
||||||
|
typedef struct Mag
|
||||||
|
{
|
||||||
|
int16_t x;
|
||||||
|
int16_t y;
|
||||||
|
int16_t z;
|
||||||
|
} Mag; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast and data subscription, return RC reading
|
||||||
|
*/
|
||||||
|
typedef struct RC
|
||||||
|
{
|
||||||
|
int16_t roll; /*!< [-10000,10000] */
|
||||||
|
int16_t pitch; /*!< [-10000,10000] */
|
||||||
|
int16_t yaw; /*!< [-10000,10000] */
|
||||||
|
int16_t throttle; /*!< [-10000,10000] */
|
||||||
|
int16_t mode; /*!< P: -8000, A: 0, F: 8000 */
|
||||||
|
int16_t gear; /*!< Up: -10000, Down: -4545 */
|
||||||
|
} RC; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_GIMBAL_STATUS
|
||||||
|
*/
|
||||||
|
typedef struct GimbalStatus
|
||||||
|
{
|
||||||
|
uint32_t mountStatus : 1;
|
||||||
|
uint32_t isBusy : 1;
|
||||||
|
uint32_t pitchLimited : 1; /*!< 1 - axis reached limit, 0 - no */
|
||||||
|
uint32_t rollLimited : 1; /*!< 1 - axis reached limit, 0 - no */
|
||||||
|
uint32_t yawLimited : 1; /*!< 1 - axis reached limit, 0 - no */
|
||||||
|
uint32_t calibrating : 1; /*!< 1 - calibrating, 0 - no */
|
||||||
|
uint32_t prevCalibrationgResult : 1; /*!< 1 - success, 0 - fail */
|
||||||
|
uint32_t installedDirection : 1; /*!< 1 - reversed for OSMO, 0 - normal */
|
||||||
|
uint32_t disabled_mvo : 1;
|
||||||
|
uint32_t gear_show_unable : 1;
|
||||||
|
uint32_t gyroFalut : 1; /*!< 1 - at fault, 0 - normal */
|
||||||
|
uint32_t escPitchFault : 1; /*!< 1 - at fault, 0 - normal */
|
||||||
|
uint32_t escRollFault : 1; /*!< 1 - at fault, 0 - normal */
|
||||||
|
uint32_t escYawFault : 1; /*!< 1 - at fault, 0 - normal */
|
||||||
|
uint32_t droneDataFault : 1; /*!< 1 - at fault, 0 - normal */
|
||||||
|
uint32_t initUnfinished : 1; /*!< 1 - complete, 0 - not complete */
|
||||||
|
uint32_t FWUpdating : 1; /*!< 1 - updating, 0 - not updating */
|
||||||
|
uint32_t reserved2 : 15;
|
||||||
|
} GimbalStatus; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, return gimbal angle
|
||||||
|
*/
|
||||||
|
typedef struct Gimbal
|
||||||
|
{
|
||||||
|
|
||||||
|
float32_t roll; /*!< degree */
|
||||||
|
float32_t pitch; /*!< degree */
|
||||||
|
float32_t yaw; /*!< degree */
|
||||||
|
uint8_t pitchLimit : 1; /*!< 1 - axis reached limit, 0 - no */
|
||||||
|
uint8_t rollLimit : 1; /*!< 1 - axis reached limit, 0 - no */
|
||||||
|
uint8_t yawLimit : 1; /*!< 1 - axis reached limit, 0 - no */
|
||||||
|
uint8_t reserved : 5;
|
||||||
|
} Gimbal; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for data broadcast, return flight status
|
||||||
|
*/
|
||||||
|
typedef struct Status
|
||||||
|
{
|
||||||
|
uint8_t flight; /*!< enum STATUS */
|
||||||
|
uint8_t mode; /*!< enum MODE */
|
||||||
|
uint8_t gear; /*!< enum LANDING_GEAR */
|
||||||
|
uint8_t error; /*!< enum DJI_ERROR_CODE */
|
||||||
|
} Status; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_BATTERY_INFO and data broadcast, return battery
|
||||||
|
* status
|
||||||
|
*/
|
||||||
|
typedef struct Battery
|
||||||
|
{
|
||||||
|
uint32_t capacity;
|
||||||
|
int32_t voltage;
|
||||||
|
int32_t current;
|
||||||
|
uint8_t percentage;
|
||||||
|
} Battery; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_CONTROL_DEVICE and data broadcast, return SDK info
|
||||||
|
*/
|
||||||
|
typedef struct SDKInfo
|
||||||
|
{
|
||||||
|
uint8_t controlMode; /*!< enum CTRL_MODE */
|
||||||
|
uint8_t deviceStatus : 3; /*!< 0->rc 1->app 2->serial*/
|
||||||
|
uint8_t flightStatus : 1; /*!< 1->opensd 0->close */
|
||||||
|
uint8_t vrcStatus : 1;
|
||||||
|
uint8_t reserved : 3;
|
||||||
|
} SDKInfo; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief sub struct for TOPIC_HARD_SYNC
|
||||||
|
*/
|
||||||
|
typedef struct SyncTimestamp
|
||||||
|
{
|
||||||
|
uint32_t time2p5ms; /*!< clock time in multiples of 2.5ms. Sync timer runs at
|
||||||
|
400Hz, this field increments in integer steps */
|
||||||
|
uint32_t time1ns; /*!< nanosecond time offset from the 2.5ms pulse */
|
||||||
|
uint32_t
|
||||||
|
resetTime2p5ms; /*!< clock time in multiple of 2.5ms elapsed since the
|
||||||
|
hardware sync started */
|
||||||
|
uint16_t index; /*!< This is the tag field you filled out when using the
|
||||||
|
setSyncFreq API above; use it to identify the packets that
|
||||||
|
have sync data. This is useful when you call the
|
||||||
|
setSyncFreq API with freqInHz = 0, so you get a single
|
||||||
|
pulse that can be uniquely identified with a tag - allowing
|
||||||
|
you to create your own pulse train with uniquely
|
||||||
|
identifiable pulses. */
|
||||||
|
uint8_t flag; /*!< This is true when the packet corresponds to a hardware
|
||||||
|
pulse and false otherwise. This is useful because you can
|
||||||
|
request the software packet to be sent at a higher frequency
|
||||||
|
that the hardware line.*/
|
||||||
|
} SyncTimestamp; // pack(1)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief struct for TOPIC_HARD_SYNC
|
||||||
|
*/
|
||||||
|
typedef struct HardSyncData
|
||||||
|
{
|
||||||
|
SyncTimestamp ts; /*!< time stamp for the incoming data */
|
||||||
|
Quaternion q; /*!< quaternion */
|
||||||
|
Vector3f a; /*!< accelerometer reading unit: g */
|
||||||
|
Vector3f w; /*!< gyro reading unit: rad/sec */
|
||||||
|
} HardSyncData; // pack(1)
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
extern TopicInfo TopicDataBase[];
|
||||||
|
|
||||||
|
/*! @brief template struct maps a topic name to the corresponding data
|
||||||
|
* type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template <TopicName T>
|
||||||
|
struct TypeMap
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
template <> struct TypeMap<TOPIC_QUATERNION > { typedef Quaternion type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ACCELERATION_GROUND > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ACCELERATION_BODY > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ACCELERATION_RAW > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_VELOCITY > { typedef Velocity type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ANGULAR_RATE_FUSIONED > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ANGULAR_RATE_RAW > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ALTITUDE_FUSIONED > { typedef float32_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_ALTITUDE_BAROMETER > { typedef float32_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_HEIGHT_HOMEPOOINT > { typedef float32_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_HEIGHT_FUSION > { typedef float32_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_FUSED > { typedef GPSFused type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_DATE > { typedef uint32_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_TIME > { typedef uint32_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_POSITION > { typedef Vector3d type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_VELOCITY > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_DETAILS > { typedef GPSDetail type;};
|
||||||
|
template <> struct TypeMap<TOPIC_RTK_POSITION > { typedef PositionData type;};
|
||||||
|
template <> struct TypeMap<TOPIC_RTK_VELOCITY > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_RTK_YAW > { typedef int16_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_RTK_POSITION_INFO > { typedef uint8_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_RTK_YAW_INFO > { typedef uint8_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_COMPASS > { typedef Mag type;};
|
||||||
|
template <> struct TypeMap<TOPIC_RC > { typedef RC type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GIMBAL_ANGLES > { typedef Vector3f type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GIMBAL_STATUS > { typedef GimbalStatus type;};
|
||||||
|
template <> struct TypeMap<TOPIC_STATUS_FLIGHT > { typedef uint8_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_STATUS_DISPLAYMODE > { typedef uint8_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_STATUS_LANDINGGEAR > { typedef uint8_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_STATUS_MOTOR_START_ERROR > { typedef uint16_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_BATTERY_INFO > { typedef Battery type;};
|
||||||
|
template <> struct TypeMap<TOPIC_CONTROL_DEVICE > { typedef SDKInfo type;};
|
||||||
|
template <> struct TypeMap<TOPIC_HARD_SYNC > { typedef HardSyncData type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_SIGNAL_LEVEL > { typedef uint8_t type;};
|
||||||
|
template <> struct TypeMap<TOPIC_GPS_CONTROL_LEVEL > { typedef uint8_t type;};
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ONBOARDSDK_DJI_Telemetry_H
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/*! @file dji_type.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Data type and Data Structure definitions for use throughout DJI OSDK
|
||||||
|
* @attention Most broadcast data definitions in this file have been
|
||||||
|
* deprecated.
|
||||||
|
* See dji_topics.hpp for updated definitions.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* Copyright 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef DJI_TYPE
|
||||||
|
#define DJI_TYPE
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//! Define the UNUSED macro to suppress compiler warnings about unused arguments
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define __UNUSED __attribute__((__unused__))
|
||||||
|
#define __DELETE(x) delete (char*)x
|
||||||
|
#else
|
||||||
|
#define __UNUSED
|
||||||
|
#define __DELETE(x) delete x
|
||||||
|
|
||||||
|
//! @todo fix warning.
|
||||||
|
#ifndef STM32
|
||||||
|
#pragma warning(disable : 4100)
|
||||||
|
#pragma warning(disable : 4800)
|
||||||
|
#pragma warning(disable : 4996)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
#pragma warning(disable : 4267)
|
||||||
|
#pragma warning(disable : 4700)
|
||||||
|
#pragma warning(disable : 4101)
|
||||||
|
#endif // STM32
|
||||||
|
#endif //__GNUC__
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define __func__ __FUNCTION__
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
//! @note for ARMCC-5.0 compiler
|
||||||
|
#ifdef ARMCC
|
||||||
|
#pragma anon_unions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STM32
|
||||||
|
typedef unsigned int size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
//! This is used as the datatype for all data arguments in callbacks.
|
||||||
|
typedef void* UserData;
|
||||||
|
|
||||||
|
typedef uint64_t time_ms;
|
||||||
|
typedef uint64_t time_us; // about 0.3 million years
|
||||||
|
|
||||||
|
typedef float float32_t;
|
||||||
|
typedef double float64_t;
|
||||||
|
|
||||||
|
extern char buffer[];
|
||||||
|
|
||||||
|
/******************Protocol Related Definitions***************************/
|
||||||
|
|
||||||
|
//! @todo move to class Vehicle as a configuration
|
||||||
|
const uint8_t encrypt = 0;
|
||||||
|
|
||||||
|
const size_t SESSION_TABLE_NUM = 32;
|
||||||
|
const size_t CALLBACK_LIST_NUM = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @note size is in Bytes
|
||||||
|
*/
|
||||||
|
const size_t MAX_INCOMING_DATA_SIZE = 300;
|
||||||
|
const size_t MAX_ACK_SIZE = 107;
|
||||||
|
|
||||||
|
//! The Header struct is meant to handle the open protocol header.
|
||||||
|
typedef struct Header
|
||||||
|
{
|
||||||
|
uint32_t sof : 8;
|
||||||
|
uint32_t length : 10;
|
||||||
|
uint32_t version : 6;
|
||||||
|
uint32_t sessionID : 5;
|
||||||
|
uint32_t isAck : 1;
|
||||||
|
uint32_t reserved0 : 2; // always 0
|
||||||
|
uint32_t padding : 5;
|
||||||
|
uint32_t enc : 3;
|
||||||
|
uint32_t reserved1 : 24;
|
||||||
|
uint32_t sequenceNumber : 16;
|
||||||
|
uint32_t crc : 16;
|
||||||
|
} Header;
|
||||||
|
|
||||||
|
typedef struct Command
|
||||||
|
{
|
||||||
|
uint16_t sessionMode : 2;
|
||||||
|
uint16_t encrypt : 1;
|
||||||
|
uint16_t retry : 13;
|
||||||
|
uint16_t timeout; // unit is ms
|
||||||
|
size_t length;
|
||||||
|
uint8_t* buf;
|
||||||
|
uint8_t cmd_set;
|
||||||
|
uint8_t cmd_id;
|
||||||
|
bool isCallback;
|
||||||
|
int callbackID;
|
||||||
|
} Command;
|
||||||
|
|
||||||
|
typedef struct MMU_Tab
|
||||||
|
{
|
||||||
|
uint32_t tabIndex : 8;
|
||||||
|
uint32_t usageFlag : 8;
|
||||||
|
uint32_t memSize : 16;
|
||||||
|
uint8_t* pmem;
|
||||||
|
} MMU_Tab;
|
||||||
|
|
||||||
|
typedef struct CMDSession
|
||||||
|
{
|
||||||
|
uint8_t cmd_set;
|
||||||
|
uint8_t cmd_id;
|
||||||
|
uint8_t* buf;
|
||||||
|
|
||||||
|
uint32_t sessionID : 5;
|
||||||
|
uint32_t usageFlag : 1;
|
||||||
|
uint32_t sent : 5;
|
||||||
|
uint32_t retry : 5;
|
||||||
|
uint32_t timeout : 16;
|
||||||
|
MMU_Tab* mmu;
|
||||||
|
bool isCallback;
|
||||||
|
int callbackID;
|
||||||
|
uint32_t preSeqNum;
|
||||||
|
time_ms preTimestamp;
|
||||||
|
} CMDSession;
|
||||||
|
|
||||||
|
typedef struct ACKSession
|
||||||
|
{
|
||||||
|
uint32_t sessionID : 5;
|
||||||
|
uint32_t sessionStatus : 2;
|
||||||
|
uint32_t res : 25;
|
||||||
|
MMU_Tab* mmu;
|
||||||
|
} ACKSession;
|
||||||
|
|
||||||
|
/*! @brief Dispatch info
|
||||||
|
* @details This struct has booleans that get populated in the protocol layer
|
||||||
|
* and help the dispatcher in the Vehicle layer decide what to do
|
||||||
|
* with the received packet.
|
||||||
|
*/
|
||||||
|
typedef struct DispatchInfo
|
||||||
|
{
|
||||||
|
bool isAck;
|
||||||
|
bool isCallback;
|
||||||
|
uint8_t callbackID;
|
||||||
|
} DispatchInfo;
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // DJI_TYPE
|
||||||
@@ -0,0 +1,360 @@
|
|||||||
|
/** @file dji_vehicle.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Vehicle API for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OSDK_CORE_INC_DJI_VEHICLE_H_
|
||||||
|
#define OSDK_CORE_INC_DJI_VEHICLE_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "dji_broadcast.hpp"
|
||||||
|
#include "dji_camera.hpp"
|
||||||
|
#include "dji_circular_buffer.hpp"
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
#include "dji_control.hpp"
|
||||||
|
#include "dji_gimbal.hpp"
|
||||||
|
#include "dji_hard_driver.hpp"
|
||||||
|
#include "dji_hardware_sync.hpp"
|
||||||
|
#include "dji_mfio.hpp"
|
||||||
|
#include "dji_mission_manager.hpp"
|
||||||
|
#include "dji_mobile_communication.hpp"
|
||||||
|
#include "dji_open_protocol.hpp"
|
||||||
|
#include "dji_status.hpp"
|
||||||
|
#include "dji_subscription.hpp"
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
#include "dji_version.hpp"
|
||||||
|
|
||||||
|
/*! Platform includes:
|
||||||
|
* This set of macros figures out which files to include based on your
|
||||||
|
* platform.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef qt
|
||||||
|
#include <QThread.h>
|
||||||
|
#elif STM32
|
||||||
|
#include <STM32F4DataGuard.h>
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include "posix_thread.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
static int callbackId;
|
||||||
|
|
||||||
|
/*! @brief A top-level encapsulation of a DJI drone/FC connected to your OES.
|
||||||
|
*
|
||||||
|
* @details This class instantiates objects for all features your drone/FC
|
||||||
|
* supports.
|
||||||
|
* Create a Vechile object in your code and you will have access to the entire
|
||||||
|
* DJI OSDK API.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Vehicle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct ActivateData
|
||||||
|
{
|
||||||
|
uint32_t ID;
|
||||||
|
uint32_t reserved;
|
||||||
|
uint32_t version;
|
||||||
|
uint8_t iosID[32]; //! @note useless
|
||||||
|
char* encKey;
|
||||||
|
} ActivateData; // pack(1)
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vehicle(const char* device, uint32_t baudRate, bool threadSupport);
|
||||||
|
Vehicle(bool threadSupport);
|
||||||
|
~Vehicle();
|
||||||
|
|
||||||
|
Protocol* protocolLayer;
|
||||||
|
DataSubscription* subscribe;
|
||||||
|
DataBroadcast* broadcast;
|
||||||
|
Control* control;
|
||||||
|
Camera* camera;
|
||||||
|
Gimbal* gimbal;
|
||||||
|
MFIO* mfio;
|
||||||
|
MobileCommunication* moc;
|
||||||
|
MissionManager* missionManager;
|
||||||
|
HardwareSync* hardSync;
|
||||||
|
|
||||||
|
////// Control authorities //////
|
||||||
|
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Obtain the control authority of the api (non-blocking call)
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void obtainCtrlAuthority(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Obtain the control authority of the api (blocking call)
|
||||||
|
*
|
||||||
|
* @param timeout time to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode obtainCtrlAuthority(int timeout);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Release the control authority of the api (non-blocking call)
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void releaseCtrlAuthority(VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Release the control authority of the api (blocking call)
|
||||||
|
*
|
||||||
|
* @param timeout time to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode releaseCtrlAuthority(int timeout);
|
||||||
|
|
||||||
|
////// Callback Handler setters //////
|
||||||
|
|
||||||
|
////////// Blocking calls ///////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @remark
|
||||||
|
* Blocks until ACK frame arrives or timeout occurs
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Send activation control to your flight controller to check if: \n a)
|
||||||
|
* your application registered in your developer
|
||||||
|
* account \n b) API Control enabled in the Assistant software\n\n
|
||||||
|
* Proceed to programming if activation successful.
|
||||||
|
*
|
||||||
|
* @return ACK from flight controller
|
||||||
|
*
|
||||||
|
* @todo
|
||||||
|
* Implement high resolution timer to catch ACK timeout
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode activate(ActivateData* data, int timeout);
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Send get version control to the vehicle.
|
||||||
|
*
|
||||||
|
* @return type ACK::DroneVersion containing:
|
||||||
|
* ACKErrorCode: data (ack value)
|
||||||
|
* VersionData: hardware version
|
||||||
|
* VersionData: firmware version
|
||||||
|
* VersionData: hardware serial number
|
||||||
|
* VersionData: CRC
|
||||||
|
* VersionData: version name
|
||||||
|
*/
|
||||||
|
ACK::DroneVersion getDroneVersion(int timeout);
|
||||||
|
|
||||||
|
////////// Callback calls //////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Send activation request to your flight controller
|
||||||
|
* to check if: \n a) your application registered in your developer
|
||||||
|
* account \n b) API Control enabled in the Assistant software\n\n
|
||||||
|
* Proceed to programming if activation successful.
|
||||||
|
*/
|
||||||
|
void activate(ActivateData* data, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
* Get aircraft version.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* You can query your flight controller prior to activation.
|
||||||
|
*/
|
||||||
|
void getDroneVersion(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
|
||||||
|
//////////// Getters/Setters //////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Activation information
|
||||||
|
*/
|
||||||
|
ActivateData getAccountData() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Activation Control
|
||||||
|
*/
|
||||||
|
void setAccountData(const ActivateData& value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set SDK version.
|
||||||
|
*/
|
||||||
|
void setVersion(const Version::FirmWare& value);
|
||||||
|
|
||||||
|
Version::FirmWare getFwVersion() const;
|
||||||
|
char* getHwVersion() const;
|
||||||
|
char* getHwSerialNum() const;
|
||||||
|
|
||||||
|
void setKey(const char* key);
|
||||||
|
void setStopCond(bool stopCond);
|
||||||
|
bool getStopCond();
|
||||||
|
CircularBuffer* circularBuffer; //! @note not used yet
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage for last received packet: accessors
|
||||||
|
*/
|
||||||
|
void setLastReceivedFrame(RecvContainer recvFrame);
|
||||||
|
RecvContainer getLastReceivedFrame();
|
||||||
|
//! @brief Wait for ACK frame to arrive
|
||||||
|
void* waitForACK(const uint8_t (&cmd)[OpenProtocol::MAX_CMD_ARRAY_SIZE],
|
||||||
|
int timeout);
|
||||||
|
|
||||||
|
///////////// Interact with Protocol ///////////
|
||||||
|
|
||||||
|
/*! @brief This function takes a frame and calls the right handlers/functions
|
||||||
|
* based
|
||||||
|
* on the nature of the frame (ack, blocking, etc.)
|
||||||
|
* @param receivedFrame: RecvContainer populated by the protocolLayer
|
||||||
|
* @return NULL
|
||||||
|
*/
|
||||||
|
void processReceivedData(RecvContainer receivedFrame);
|
||||||
|
|
||||||
|
//! User sets this to true in order to enable Callback thread with Non
|
||||||
|
//! blocking calls.
|
||||||
|
void callbackPoll();
|
||||||
|
int callbackIdIndex();
|
||||||
|
void* nbCallbackFunctions[200]; //! @todo magic number
|
||||||
|
UserData nbUserData[200]; //! @todo magic number
|
||||||
|
|
||||||
|
private:
|
||||||
|
Version::VersionData versionData;
|
||||||
|
ActivateData accountData;
|
||||||
|
|
||||||
|
//! Thread management
|
||||||
|
Thread* readThread;
|
||||||
|
Thread* callbackThread;
|
||||||
|
bool stopCond;
|
||||||
|
|
||||||
|
//! Initialization data
|
||||||
|
bool threadSupported;
|
||||||
|
const char* device;
|
||||||
|
uint32_t baudRate;
|
||||||
|
|
||||||
|
//! ACK management
|
||||||
|
|
||||||
|
// Internal space
|
||||||
|
uint8_t rawVersionACK[MAX_ACK_SIZE];
|
||||||
|
|
||||||
|
// User space ACK types
|
||||||
|
ACK::ErrorCode ackErrorCode;
|
||||||
|
ACK::DroneVersion droneVersionACK;
|
||||||
|
ACK::HotPointStart hotpointStartACK;
|
||||||
|
ACK::HotPointRead hotpointReadACK;
|
||||||
|
ACK::WayPointInit waypointInitACK;
|
||||||
|
ACK::WayPointIndex waypointDataACK;
|
||||||
|
ACK::MFIOGet mfioGetACK;
|
||||||
|
|
||||||
|
//! This array will be populated by Non blocking calls depending on
|
||||||
|
//! availability of array elements.
|
||||||
|
//! Elements may be equal to NULL if Callback function execution has been
|
||||||
|
//! completed and array element of
|
||||||
|
//! callbackFunction is available to be populated.
|
||||||
|
RecvContainer nbCallbackRecvContainer[200]; //! @todo magic number
|
||||||
|
|
||||||
|
VehicleCallBackHandler nbVehicleCallBackHandler;
|
||||||
|
|
||||||
|
//! Added for connecting protocolLayer to Vehicle
|
||||||
|
RecvContainer lastReceivedFrame;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Vehicle initialization components
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
/*! @brief Initialize all functional Vehicle components
|
||||||
|
* like, Subscription, Broadcast, Control, Gimbal, ect
|
||||||
|
*/
|
||||||
|
void functionalSetUp();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*! @brief Initialize minimal Vehicle components
|
||||||
|
*/
|
||||||
|
void mandatorySetUp();
|
||||||
|
bool initOpenProtocol();
|
||||||
|
/*! @brief Initialize the right platform-specific implementations
|
||||||
|
* @details
|
||||||
|
* @return false if error, true if success
|
||||||
|
*/
|
||||||
|
bool initPlatformSupport();
|
||||||
|
void initCallbacks();
|
||||||
|
void initCMD_SetSupportMatrix();
|
||||||
|
bool initSubscriber();
|
||||||
|
bool initBroadcast();
|
||||||
|
bool initControl();
|
||||||
|
bool initCamera();
|
||||||
|
bool initGimbal();
|
||||||
|
bool initMFIO();
|
||||||
|
bool initMOC();
|
||||||
|
bool initMissionManager();
|
||||||
|
bool initHardSync();
|
||||||
|
|
||||||
|
//* Set of callback handler for various things
|
||||||
|
VehicleCallBackHandler subscriberDecodeHandler;
|
||||||
|
|
||||||
|
/*! @brief Check if given CMD_SET supported on your flight controller
|
||||||
|
* @return false if not supported, true if supported
|
||||||
|
*/
|
||||||
|
bool isCmdSetSupported(const uint8_t cmdSet);
|
||||||
|
|
||||||
|
bool initVersion();
|
||||||
|
|
||||||
|
/*! @brief A callback function for activate non-blocking calls
|
||||||
|
* @param receivedFrame: RecvContainer populated by the protocolLayer
|
||||||
|
* @return NULL
|
||||||
|
*/
|
||||||
|
static void activateCallback(Vehicle* vehiclePtr, RecvContainer recvFrame,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief A callback function for get drone version non-blocking calls
|
||||||
|
* @param receivedFrame: RecvContainer populated by the protocolLayer
|
||||||
|
* @return NULL
|
||||||
|
*/
|
||||||
|
static void getDroneVersionCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer recvFrame,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief A callback function for control authority non-blocking calls
|
||||||
|
* @param receivedFrame: RecvContainer populated by the protocolLayer
|
||||||
|
* @return NULL
|
||||||
|
*/
|
||||||
|
static void controlAuthorityCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
void ACKHandler(void* eventData);
|
||||||
|
void PushDataHandler(void* eventData);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Used in PushData event handling
|
||||||
|
*/
|
||||||
|
bool hotPointData;
|
||||||
|
bool wayPointData;
|
||||||
|
|
||||||
|
VehicleCallBackHandler hotPointCallback;
|
||||||
|
VehicleCallBackHandler wayPointCallback;
|
||||||
|
VehicleCallBackHandler missionCallback;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool parseDroneVersionInfo(Version::VersionData& versionData,
|
||||||
|
uint8_t* ackPtr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int wait_timeout = 5;
|
||||||
|
CMD_SETSupportMatrix cmd_setSupportMatrix[9];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* OSDK_CORE_INC_DJI_VEHICLE_H_ */
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/** @file dji_vehicle_callback.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Type definition for new Vehicle-style callbacks
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_VEHICLECALLBACK_H
|
||||||
|
#define DJI_VEHICLECALLBACK_H
|
||||||
|
|
||||||
|
#include "dji_open_protocol.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
//! @todo move definition below to class Vehicle
|
||||||
|
//! so that we could remove this file
|
||||||
|
|
||||||
|
/*! @brief Function prototype for all callback functions used in the OSDK
|
||||||
|
*
|
||||||
|
* @details If you want to register a function as a callback funtion, make sure
|
||||||
|
* it matches this prototype.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void (*VehicleCallBack)(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
|
||||||
|
/*! @brief The CallBackHandler struct allows users to encapsulate callbacks and
|
||||||
|
* data in one struct
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct VehicleCallBackHandler
|
||||||
|
{
|
||||||
|
VehicleCallBack callback;
|
||||||
|
UserData userData;
|
||||||
|
} VehicleCallBackHandler;
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
#endif /* DJI_VEHICLECALLBACK_H */
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*! @file dji_version.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Drone/SDK Version definition for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @note Since OSDK 3.2.2 (Feb 2017), versioning is handled by the SDK.
|
||||||
|
* You can use the Version::FW macro to target your code towards specific
|
||||||
|
* platforms/firmware.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* Copyright 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef DJI_VERSION_H
|
||||||
|
#define DJI_VERSION_H
|
||||||
|
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
class Version
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef uint32_t FirmWare;
|
||||||
|
|
||||||
|
typedef struct VersionData
|
||||||
|
{
|
||||||
|
uint16_t version_ack;
|
||||||
|
uint32_t version_crc;
|
||||||
|
char hw_serial_num[16];
|
||||||
|
char hwVersion[12]; //! Current longest product code: pm820v3pro
|
||||||
|
FirmWare fwVersion;
|
||||||
|
|
||||||
|
//! Legacy member
|
||||||
|
char version_name[32];
|
||||||
|
} VersionData;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const FirmWare FW(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! @todo clean up
|
||||||
|
// clang-format off
|
||||||
|
static const FirmWare M100_23 = 0x02030A00;//Version::FW(2, 3, 10, 0 );
|
||||||
|
static const FirmWare M100_31 = 0x03010A00;//Version::FW(3, 1, 10, 0 );
|
||||||
|
static const FirmWare A3_31 = 0x03016400;//Version::FW(3, 1, 100, 0 );
|
||||||
|
static const FirmWare A3_32 = 0x03026400;//Version::FW(3, 2, 100, 0 );
|
||||||
|
static const FirmWare A3_3_2_20_test = 0x030214FF;//Version::FW(3, 2, 20, 255);
|
||||||
|
static const FirmWare A3_3_2_22_test = 0x03021616;//Version::FW(3, 2, 22, 22 );
|
||||||
|
static const FirmWare A3_3_2_80_test = 0x03025012;//Version::FW(3, 2, 80, 18 );
|
||||||
|
static const FirmWare A3_3_2_80_13_test = 0x0302500D;//Version::FW(3, 2, 80, 13 );
|
||||||
|
static const FirmWare A3_3_3_00_release = 0x030300FF;//Version::FW(3, 3, 00, 255);
|
||||||
|
// clang-format on
|
||||||
|
}; // class version
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Define FW version that supports "mandatory" CMD_SET
|
||||||
|
*
|
||||||
|
* @details All supported products implement predefined CMD_SET list
|
||||||
|
*
|
||||||
|
* Supported products: M100, M210, M600, A3, N3
|
||||||
|
*/
|
||||||
|
const Version::FirmWare mandatoryVersionBase = (Version::FW(3, 2, 36, 1));
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Define FW version that supports "extended" CMD_SET
|
||||||
|
*
|
||||||
|
* @details Limited products support predefined CMD_SET list
|
||||||
|
*
|
||||||
|
* Supported products: M210, A3, N3
|
||||||
|
*/
|
||||||
|
const Version::FirmWare extendedVersionBase = (Version::FW(3, 2, 36, 1));
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Define CMD_SET support matrix
|
||||||
|
*/
|
||||||
|
typedef struct CMD_SETSupportMatrix
|
||||||
|
{
|
||||||
|
uint8_t cmdSet;
|
||||||
|
Version::FirmWare fwVersion;
|
||||||
|
} CMD_SETSupportMatrix;
|
||||||
|
} // namespace DJI
|
||||||
|
} // namespace OSDK
|
||||||
|
|
||||||
|
#endif // DJI_VERSION_H
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
/** @file dji_waypoint.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Implementation of GPS Waypoint Missions for DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_WAYPOINT_H
|
||||||
|
#define DJI_WAYPOINT_H
|
||||||
|
|
||||||
|
#include "dji_mission_base.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief APIs for GPS Waypoint Missions
|
||||||
|
*
|
||||||
|
* @details This class inherits from MissionBase and can be used with
|
||||||
|
* MissionManager.
|
||||||
|
*/
|
||||||
|
class WaypointMission : public MissionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaypointMission(Vehicle* vehicle = 0);
|
||||||
|
~WaypointMission();
|
||||||
|
|
||||||
|
VehicleCallBackHandler wayPointEventCallback;
|
||||||
|
VehicleCallBackHandler wayPointCallback;
|
||||||
|
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init waypoint mission settings
|
||||||
|
*
|
||||||
|
* @param Info action command from DJI_ControllerCMD.h
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void init(WayPointInitSettings* Info = 0, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* init waypoint mission settings
|
||||||
|
*
|
||||||
|
* @param Info action command from DJI_ControllerCMD.h
|
||||||
|
* @param timeout timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode init(WayPointInitSettings* Info, int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* start the waypt mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void start(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* start the waypt mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode start(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* stop the waypt mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void stop(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* stop the waypt mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode stop(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* pause the waypt mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void pause(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* pause the waypt mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode pause(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* resume the waypt mission
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void resume(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* resume the waypt mission
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode resume(int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* setting waypt init data
|
||||||
|
*
|
||||||
|
* @param value user specified WayPointInitData
|
||||||
|
*/
|
||||||
|
void setInfo(const WayPointInitSettings& value);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* getting waypt init data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
WayPointInitSettings getInfo() const;
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* setting waypt data to the waypt container wiht specified idx
|
||||||
|
*
|
||||||
|
* @param value user specified WayPointData
|
||||||
|
* @param pos the index of the waypt
|
||||||
|
*/
|
||||||
|
void setIndex(WayPointSettings* value, size_t pos);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* getting waypt data
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
WayPointSettings* getIndex() const;
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* getting waypt data
|
||||||
|
*
|
||||||
|
* @param pos idx of the specified watpt data
|
||||||
|
*/
|
||||||
|
WayPointSettings* getIndex(size_t pos) const;
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* setting waypt init data
|
||||||
|
*
|
||||||
|
* @param value user specified WayPointInitData
|
||||||
|
*/
|
||||||
|
bool uploadIndexData(WayPointSettings* data, VehicleCallBack callback = 0,
|
||||||
|
UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* setting waypt init data
|
||||||
|
*
|
||||||
|
* @param value user specified WayPointInitData
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::WayPointIndex uploadIndexData(WayPointSettings* data, int timer);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* getting waypt idle velocity
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void readIdleVelocity(VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* getting waypt idle velocity
|
||||||
|
*
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::ErrorCode readIdleVelocity(int timeout);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* setting waypt idle velocity
|
||||||
|
*
|
||||||
|
* @param meterPreSecond specified velocity
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData user data (void ptr)
|
||||||
|
*/
|
||||||
|
void updateIdleVelocity(float32_t meterPreSecond,
|
||||||
|
VehicleCallBack callback = 0, UserData userData = 0);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* setting waypt idle velocity
|
||||||
|
*
|
||||||
|
* @param meterPreSecond specified velocity
|
||||||
|
* @param timer timeout to wait for ACK
|
||||||
|
*/
|
||||||
|
ACK::WayPointVelocity updateIdleVelocity(float32_t meterPreSecond,
|
||||||
|
int timeout);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* A callback function for setting idle velocity non-blocking calls
|
||||||
|
*
|
||||||
|
* @param recvFrame the data comes with the callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
static void idleVelocityCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* A callback function for uploading waypt index non-blocking calls
|
||||||
|
*
|
||||||
|
* @param recvFrame the data comes with the callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
static void uploadIndexDataCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set waypoint push data callback
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
void setWaypointEventCallback(VehicleCallBack callback, UserData userData);
|
||||||
|
/*! @brief
|
||||||
|
*
|
||||||
|
* Set waypoint callback
|
||||||
|
*
|
||||||
|
* @param callback callback function
|
||||||
|
* @param userData a void ptr that user can manipulate inside the callback
|
||||||
|
*/
|
||||||
|
void setWaypointCallback(VehicleCallBack callback, UserData userData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WayPointInitSettings info;
|
||||||
|
WayPointSettings* index;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // DJI_WAYPOINT_H
|
||||||
@@ -0,0 +1,747 @@
|
|||||||
|
/** @file dji_ack.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief All DJI OSDK ACK parsing
|
||||||
|
* @brief ACK error API getError and getErrorCodeMessage
|
||||||
|
* to decode received ACK(s).
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_ack.hpp"
|
||||||
|
#include "dji_log.hpp"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
const bool DJI::OSDK::ACK::SUCCESS = 0;
|
||||||
|
const bool DJI::OSDK::ACK::FAIL = 1;
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> commonData[] = {
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::NO_RESPONSE_ERROR,
|
||||||
|
(const char*)"ACK_NO_RESPONSE_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::KEY_ERROR,
|
||||||
|
(const char*)"ACK_KEY_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::NO_AUTHORIZATION_ERROR,
|
||||||
|
(const char*)"ACK_NO_AUTHORIZATION_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::NO_RIGHTS_ERROR,
|
||||||
|
(const char*)"ACK_NO_RIGHTS_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::SUCCESS,
|
||||||
|
(const char*)"ACK_SUCCESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::START_MOTOR_FAIL_MOTOR_STARTED,
|
||||||
|
(const char*)"START_MOTOR_FAIL_MOTOR_STARTED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::MOTOR_FAIL_COMPASS_ABNORMAL,
|
||||||
|
(const char*)"MOTOR_FAIL_COMPASS_ABNORMAL\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::MOTOR_FAIL_ASSISTANT_PROTECTED,
|
||||||
|
(const char*)"USB_CABLE_CONNECTED_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::MOTOR_FAIL_DEVICE_LOCKED,
|
||||||
|
(const char*)"MOTOR_FAIL_DEVICE_LOCKED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::MOTOR_FAIL_IMU_CALIBRATING,
|
||||||
|
(const char*)"MOTOR_FAIL_IMU_CALIBRATING\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::MOTOR_FAIL_M600_BAT_TOO_FEW,
|
||||||
|
(const char*)"MISSING_BATTERIES\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::CommonACK::MOTOR_FAIL_NOT_ACTIVATED,
|
||||||
|
(const char*)"NOT_ACTIVATED_ERROR\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createCommonErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
commonData, commonData + sizeof commonData / sizeof commonData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> activateData[] = {
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::SUCCESS,
|
||||||
|
(const char*)"ACTIVATE_SUCCESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::ACCESS_LEVEL_ERROR,
|
||||||
|
(const char*)"ACCESS_LEVEL_ERROR\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ActivationACK::DJIGO_APP_NOT_CONNECTED,
|
||||||
|
(const char*)"DJIGO_APP_NOT_CONNECTED_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::ENCODE_ERROR,
|
||||||
|
(const char*)"ENCODE_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::NETWORK_ERROR,
|
||||||
|
(const char*)"NETWORK_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::NEW_DEVICE_ERROR,
|
||||||
|
(const char*)"NEW_DEVICE_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::OSDK_VERSION_ERROR,
|
||||||
|
(const char*)"OSDK_VERSION_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::PARAMETER_ERROR,
|
||||||
|
(const char*)"PARAMETER_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ActivationACK::SERVER_ACCESS_REFUSED,
|
||||||
|
(const char*)"SERVER_ACCESS_REFUSED\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createActivateErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
activateData, activateData + sizeof activateData / sizeof activateData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> subscribeData[] = {
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::SUCCESS,
|
||||||
|
(const char*)"SUBSCRIBER_SUCCESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::ILLEGAL_FREQUENCY,
|
||||||
|
(const char*)"SUBSCRIBER_ILLEGAL_FREQUENCY\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::ILLEGAL_INPUT,
|
||||||
|
(const char*)"SUBSCRIBER_ILLEGAL_INPUT\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::ILLEGAL_UID,
|
||||||
|
(const char*)"SUBSCRIBER_ILLEGAL_UID\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::SubscribeACK::INPUT_SEGMENTATION_FAULT,
|
||||||
|
(const char*)"SUBSCRIBER_INPUT_SEGMENTATION_FAULT\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::INTERNAL_ERROR_0X09,
|
||||||
|
(const char*)"SUBSCRIBER_INTERNAL_ERROR_0X09\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::INTERNAL_ERROR_0X4A,
|
||||||
|
(const char*)"SUBSCRIBER_INTERNAL_ERROR_0X4A\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::INTERNAL_ERROR_0X50,
|
||||||
|
(const char*)"SUBSCRIBER_INTERNAL_ERROR_0X50\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::INTERNAL_ERROR_0XFF,
|
||||||
|
(const char*)"SUBSCRIBER_INTERNAL_ERROR_0XFF\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::MULTIPLE_SUBSCRIBE,
|
||||||
|
(const char*)"SUBSCRIBER_MULTIPLE_SUBSCRIBE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PACKAGE_ALREADY_EXISTS,
|
||||||
|
(const char*)"SUBSCRIBER_PACKAGE_ALREADY_EXISTS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PACKAGE_DOES_NOT_EXIST,
|
||||||
|
(const char*)"SUBSCRIBER_PACKAGE_DOES_NOT_EXIST\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PACKAGE_EMPTY,
|
||||||
|
(const char*)"SUBSCRIBER_PACKAGE_EMPTY\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PACKAGE_OUT_OF_RANGE,
|
||||||
|
(const char*)"SUBSCRIBER_PACKAGE_OUT_OF_RANGE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PACKAGE_TOO_LARGE,
|
||||||
|
(const char*)"SUBSCRIBER_PACKAGE_TOO_LARGE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PAUSED,
|
||||||
|
(const char*)"SUBSCRIBER_PAUSED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PERMISSION_DENY,
|
||||||
|
(const char*)"SUBSCRIBER_PERMISSION_DENY\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::PIPELINE_OVERFLOW,
|
||||||
|
(const char*)"SUBSCRIBER_PIPELINE_OVERFLOW\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::RESUMED,
|
||||||
|
(const char*)"SUBSCRIBER_RESUMED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::SOUCE_DEVICE_OFFLINE,
|
||||||
|
(const char*)"SUBSCRIBER_SOUCE_DEVICE_OFFLINE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::VERSION_DOES_NOT_MATCH,
|
||||||
|
(const char*)"SUBSCRIBER_VERSION_DOES_NOT_MATCH\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::VERSION_UNKNOWN_ERROR,
|
||||||
|
(const char*)"SUBSCRIBER_VERSION_UNKNOWN_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::SubscribeACK::VERSION_VERSION_TOO_FAR,
|
||||||
|
(const char*)"SUBSCRIBER_VERSION_VERSION_TOO_FAR\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createSubscribeErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
subscribeData,
|
||||||
|
subscribeData + sizeof subscribeData / sizeof subscribeData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> setControlData[] = {
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::IOC_OBTAIN_CONTROL_ERROR,
|
||||||
|
(const char*)"IOC_OBTAIN_CONTROL_ERROR\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::OBTAIN_CONTROL_IN_PROGRESS,
|
||||||
|
(const char*)"OBTAIN_CONTROL_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::OBTAIN_CONTROL_SUCCESS,
|
||||||
|
(const char*)"OBTAIN_CONTROL_SUCCESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::SetControl::RC_MODE_ERROR,
|
||||||
|
(const char*)"RC_MODE_ERROR\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::RC_NEED_MODE_F,
|
||||||
|
(const char*)"RC_NEED_MODE_F\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::RC_NEED_MODE_P,
|
||||||
|
(const char*)"RC_NEED_MODE_P\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::SetControl::
|
||||||
|
RELEASE_CONTROL_IN_PROGRESS,
|
||||||
|
(const char*)"RELEASE_CONTROL_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::RELEASE_CONTROL_SUCCESS,
|
||||||
|
(const char*)"RELEASE_CONTROL_SUCCESS\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createSetControlErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
setControlData,
|
||||||
|
setControlData + sizeof setControlData / sizeof setControlData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> taskData[] = {
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::SUCCESS,
|
||||||
|
(const char*)"CONTROLLER_TASK_SUCCESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::ALREADY_PACKED,
|
||||||
|
(const char*)"CONTROLLER_ALREADY_PACKED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::ALREADY_RUNNING,
|
||||||
|
(const char*)"CONTROLLER_ALREADY_RUNNING\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::BAD_GPS,
|
||||||
|
(const char*)"CONTROLLER_BAD_GPS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::BAD_SENSOR,
|
||||||
|
(const char*)"CONTROLLER_BAD_SENSOR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::GIMBAL_MOUNTED,
|
||||||
|
(const char*)"CONTROLLER_GIMBAL_MOUNTED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::INVAILD_COMMAND,
|
||||||
|
(const char*)"CONTROLLER_INVAILD_COMMAND\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::IN_AIR,
|
||||||
|
(const char*)"CONTROLLER_IN_AIR"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::IN_SIMULATOR_MODE,
|
||||||
|
(const char*)"CONTROLLER_IN_SIMULATOR_MODE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::MOTOR_OFF,
|
||||||
|
(const char*)"CONTROLLER_MOTOR_OFF\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::MOTOR_ON,
|
||||||
|
(const char*)"CONTROLLER_MOTOR_ON\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::NOT_IN_AIR,
|
||||||
|
(const char*)"CONTROLLER_NOT_IN_AIR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::NOT_RUNNING,
|
||||||
|
(const char*)"CONTROLLER_NOT_RUNNING\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::NO_HOMEPOINT,
|
||||||
|
(const char*)"CONTROLLER_NO_HOMEPOINT\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::NO_LANDING_GEAR,
|
||||||
|
(const char*)"CONTROLLER_NO_LANDING_GEAR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::ControlACK::Task::NO_PACKED,
|
||||||
|
(const char*)"CONTROLLER_NO_PACKED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::Task::PACKED_MODE_NOT_SUPPORTED,
|
||||||
|
(const char*)"CONTROLLER_PACKED_MODE_NOT_SUPPORTED\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createTaskErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
taskData, taskData + sizeof taskData / sizeof taskData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> missionData[] = {
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::AT_NO_FLY_ZONE,
|
||||||
|
(const char*)"MISSION_AT_NO_FLY_ZONE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::BAD_GPS,
|
||||||
|
(const char*)"MISSION_BAD_GPS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::BEGGINER_MODE_NOT_SUPPORTED,
|
||||||
|
(const char*)"MISSION_BEGGINER_MODE_NOT_SUPPORTED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::CLOSE_IOC_REQUIRED,
|
||||||
|
(const char*)"MISSION_CLOSE_IOC_REQUIRED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::CONDITIONS_NOT_SATISFIED,
|
||||||
|
(const char*)"MISSION_CONDITIONS_NOT_SATISFIED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::CROSSING_NO_FLY_ZONE,
|
||||||
|
(const char*)"MISSION_CROSSING_NO_FLY_ZONE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::INVALID_COMMAND,
|
||||||
|
(const char*)"MISSION_INVALID_COMMAND\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::INVALID_PARAMETER,
|
||||||
|
(const char*)"MISSION_INVALID_PARAMETER"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::IN_PROGRESS,
|
||||||
|
(const char*)"MISSION_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::LANDING_IN_PROGRESS,
|
||||||
|
(const char*)"MISSION_LANDING_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::LOW_BATTERY,
|
||||||
|
(const char*)"MISSION_LOW_BATTERY\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::NOT_INITIALIZED,
|
||||||
|
(const char*)"MISSION_NOT_INITIALIZED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::NOT_RUNNING,
|
||||||
|
(const char*)"MISSION_NOT_RUNNING\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::NOT_SUPPORTED,
|
||||||
|
(const char*)"MISSION_NOT_SUPPORTED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::OBTAIN_CONTROL_REQUIRED,
|
||||||
|
(const char*)"MISSION_OBTAIN_CONTROL_REQUIRED\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::OTHER_MISSION_RUNNING,
|
||||||
|
(const char*)"OTHER_MISSION_RUNNING\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::RC_NOT_IN_MODE_F,
|
||||||
|
(const char*)"MISSION_RC_NOT_IN_MODE_F\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::RRETURN_HOME_IN_PROGRESS,
|
||||||
|
(const char*)"MISSION_RRETURN_HOME_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::START_MOTORS_IN_PROGRESS,
|
||||||
|
(const char*)"MISSION_START_MOTORS_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::SUCCESS,
|
||||||
|
(const char*)"MISSION_SUCCESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::TAKE_OFF_IN_PROGRESS,
|
||||||
|
(const char*)"MISSION_TAKE_OFF_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::TASK_TIMEOUT,
|
||||||
|
(const char*)"MISSION_TASK_TIMEOUT\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::TOO_FAR_FROM_CURRENT_POSITION,
|
||||||
|
(const char*)"MISSION_TOO_FAR_FROM_CURRENT_POSITION\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::TOO_FAR_FROM_HOME,
|
||||||
|
(const char*)"MISSION_TOO_FAR_FROM_HOME\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::TOO_HIGH,
|
||||||
|
(const char*)"MISSION_TOO_HIGH\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::TOO_LOW,
|
||||||
|
(const char*)"MISSION_TOO_LOW\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::UNKNOWN_ERROR,
|
||||||
|
(const char*)"MISSION_UNKNOWN_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Common::UNRECORDED_HOME,
|
||||||
|
(const char*)"MISSION_UNRECORDED_HOME\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::VEHICLE_DID_NOT_TAKE_OFF,
|
||||||
|
(const char*)"MISSION_VEHICLE_DID_NOT_TAKE_OFF\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Common::WRONG_WAYPOINT_INDEX,
|
||||||
|
(const char*)"MISSION_WRONG_WAYPOINT_INDEX\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Follow::CUTOFF_TIME_OVERFLOW,
|
||||||
|
(const char*)"FOLLOW_MISSION_CUTOFF_TIME_OVERFLOW\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::Follow::GIMBAL_PITCH_ANGLE_OVERFLOW,
|
||||||
|
(const char*)"FOLLOW_MISSION_GIMBAL_PITCH_ANGLE_OVERFLOW\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::Follow::
|
||||||
|
TOO_FAR_FROM_YOUR_POSITION_LACK_OF_RADIO_CONNECTION,
|
||||||
|
(const char*)"FOLLOW_MISSION_TOO_FAR_FROM_YOUR_POSITION_LACK_"
|
||||||
|
"OF_RADIO_CONNECTION\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::HotPoint::FAILED_TO_PAUSE,
|
||||||
|
(const char*)"HOTPOINT_MISSION_FAILED_TO_PAUSE\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::INVALID_DIRECTION,
|
||||||
|
(const char*)"HOTPOINT_MISSION_INVALID_DIRECTION\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::
|
||||||
|
INVALID_LATITUDE_OR_LONGITUTE,
|
||||||
|
(const char*)"HOTPOINT_MISSION_INVALID_LATITUDE_OR_LONGITUTE\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::INVALID_PAREMETER,
|
||||||
|
(const char*)"HOTPOINT_MISSION_INVALID_PAREMETER\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::HotPoint::INVALID_RADIUS,
|
||||||
|
(const char*)"HOTPOINT_MISSION_INVALID_RADIUS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::INVALID_START_POINT,
|
||||||
|
(const char*)"HOTPOINT_MISSION_INVALID_VISION\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::INVALID_YAW_MODE,
|
||||||
|
(const char*)"HOTPOINT_MISSION_INVALID_YAW_MODE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::HotPoint::IN_PAUSED_MODE,
|
||||||
|
(const char*)"HOTPOINT_MISSION_IN_PAUSED_MODE\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::TOO_FAR_FROM_HOTPOINT,
|
||||||
|
(const char*)"HOTPOINT_MISSION_TOO_FAR_FROM_HOTPOINT\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::HotPoint::YAW_RATE_OVERFLOW,
|
||||||
|
(const char*)"HOTPOINT_MISSION_YAW_RATE_OVERFLOW\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::CHECK_FAILED,
|
||||||
|
(const char*)"WAYPOINT_MISSION_CHECK_FAILED\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::DATA_NOT_ENOUGH,
|
||||||
|
(const char*)"WAYPOINT_MISSION_DATA_NOT_ENOUGH\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::WayPoint::DISTANCE_OVERFLOW,
|
||||||
|
(const char*)"WAYPOINT_MISSION_DISTANCE_OVERFLOW\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::INVALID_ACTION,
|
||||||
|
(const char*)"WAYPOINT_MISSION_INVALID_ACTION\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::INVALID_DATA,
|
||||||
|
(const char*)"WAYPOINT_MISSION_INVALID_DATA\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::WayPoint::INVALID_POINT_DATA,
|
||||||
|
(const char*)"WAYPOINT_MISSION_INVALID_POINT_DATA\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::WayPoint::INVALID_VELOCITY,
|
||||||
|
(const char*)"WAYPOINT_MISSION_INVALID_VELOCITY\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::IN_PROGRESS,
|
||||||
|
(const char*)"MISSION_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::NOT_IN_PROGRESS,
|
||||||
|
(const char*)"WAYPOINT_MISSION_NOT_IN_PROGRESS\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::WayPoint::POINTS_NOT_ENOUGH,
|
||||||
|
(const char*)"WAYPOINT_MISSION_POINTS_NOT_ENOUGH\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::WayPoint::POINTS_TOO_CLOSE,
|
||||||
|
(const char*)"WAYPOINT_MISSION_POINTS_TOO_CLOSE\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::POINTS_TOO_FAR,
|
||||||
|
(const char*)"WAYPOINT_MISSION_POINTS_TOO_FAR\n"),
|
||||||
|
std::make_pair(
|
||||||
|
OpenProtocol::ErrorCode::MissionACK::WayPoint::POINT_DATA_NOT_ENOUGH,
|
||||||
|
(const char*)"WAYPOINT_MISSION_POINT_DATA_NOT_ENOUGH\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::POINT_OVERFLOW,
|
||||||
|
(const char*)"WAYPOINT_MISSION_POINT_OVERFLOW\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::WayPoint::TIMEOUT,
|
||||||
|
(const char*)"WAYPOINT_MISSION_TIMEOUT\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::IOC::TOO_CLOSE_TO_HOME,
|
||||||
|
(const char*)"IOC_MISSION_TOO_CLOSE_TO_HOME\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MissionACK::IOC::UNKNOWN_TYPE,
|
||||||
|
(const char*)"IOC_MISSION_UNKNOWN_TYPE\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createMissionErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
missionData, missionData + sizeof missionData / sizeof missionData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<const uint32_t, const char*> mfioData[] = {
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::init::PORT_DATA_ERROR,
|
||||||
|
(const char*)"MFIO_INIT_PORT_DATA_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::init::PORT_MODE_ERROR,
|
||||||
|
(const char*)"MFIO_INIT_PORT_MODE_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::init::PORT_NUMBER_ERROR,
|
||||||
|
(const char*)"MFIO_INIT_PORT_NUMBER_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::init::SUCCESS,
|
||||||
|
(const char*)"MFIO_INIT_SUCCESS\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::init::UNKNOWN_ERROR,
|
||||||
|
(const char*)"RC_NEED_MODE_F\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::set::CHANNEL_ERROR,
|
||||||
|
(const char*)"MFIO_SET_CHANNEL_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::set::PORT_NOT_MAPPED_ERROR,
|
||||||
|
(const char*)"MFIO_SET_PORT_NOT_MAPPED_ERROR\n"),
|
||||||
|
std::make_pair(OpenProtocol::ErrorCode::MFIOACK::set::SUCCESS,
|
||||||
|
(const char*)"MFIO_SET_SUCCESS\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<const uint32_t, const char*>
|
||||||
|
ACK::createMFIOErrorCodeMap()
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> errorCodeMap(
|
||||||
|
mfioData, mfioData + sizeof mfioData / sizeof mfioData[0]);
|
||||||
|
return errorCodeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ACK::getError(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const uint8_t cmd[] = { ack.info.cmd_set, ack.info.cmd_id };
|
||||||
|
|
||||||
|
if (ack.info.cmd_set == OpenProtocol::CMDSet::activation)
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::ActivationACK::SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
else if (ack.info.cmd_set == OpenProtocol::CMDSet::broadcast)
|
||||||
|
{
|
||||||
|
// Push Data, no ACK
|
||||||
|
}
|
||||||
|
else if (memcmp(cmd, OpenProtocol::CMDSet::Control::setControl,
|
||||||
|
sizeof(cmd)) == 0)
|
||||||
|
{
|
||||||
|
if (ack.info.buf[2] == ACK::RELEASE_CONTROL)
|
||||||
|
{ //! Data is set at buf + SET_CMD_SIZE which is buf + 2;
|
||||||
|
// Release control was called
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::ControlACK::SetControl::
|
||||||
|
RELEASE_CONTROL_SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
else if (ack.info.buf[2] == ACK::OBTAIN_CONTROL)
|
||||||
|
{
|
||||||
|
// Obtain control was called
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::ControlACK::SetControl::
|
||||||
|
OBTAIN_CONTROL_SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (memcmp(cmd, OpenProtocol::CMDSet::Control::control, sizeof(cmd)) ==
|
||||||
|
0)
|
||||||
|
{
|
||||||
|
// Does not return an ACK
|
||||||
|
}
|
||||||
|
else if (memcmp(cmd, OpenProtocol::CMDSet::Control::task, sizeof(cmd)) == 0)
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::ControlACK::Task::SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
else if (ack.info.cmd_set == OpenProtocol::CMDSet::mission)
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::MissionACK::Common::SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
else if (ack.info.cmd_set == OpenProtocol::CMDSet::hardwareSync)
|
||||||
|
{
|
||||||
|
// Verify ACK
|
||||||
|
}
|
||||||
|
else if (ack.info.cmd_set == OpenProtocol::CMDSet::virtualRC)
|
||||||
|
{
|
||||||
|
// Deprecated in 3.2.20
|
||||||
|
|
||||||
|
// TODO implement for backward compatibility
|
||||||
|
}
|
||||||
|
else if (ack.info.cmd_set == OpenProtocol::CMDSet::subscribe)
|
||||||
|
{
|
||||||
|
if (memcmp(cmd, OpenProtocol::CMDSet::Subscribe::pauseResume,
|
||||||
|
sizeof(cmd)) == 0)
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::SubscribeACK::PAUSED ||
|
||||||
|
ack.data == OpenProtocol::ErrorCode::SubscribeACK::RESUMED)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::SubscribeACK::SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ack.info.cmd_set == OpenProtocol::CMDSet::mfio)
|
||||||
|
{
|
||||||
|
if (memcmp(cmd, OpenProtocol::CMDSet::MFIO::get, sizeof(cmd)) == 0)
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::MFIOACK::get::SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (ack.data == OpenProtocol::ErrorCode::MFIOACK::init::SUCCESS)
|
||||||
|
? ACK::SUCCESS
|
||||||
|
: ACK::FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ACK::FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @note Log Error Message
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ACK::getErrorCodeMessage(ACK::ErrorCode ack, const char* func)
|
||||||
|
{
|
||||||
|
DSTATUS("%s", func);
|
||||||
|
switch (ack.info.cmd_set)
|
||||||
|
{
|
||||||
|
case OpenProtocol::CMDSet::activation:
|
||||||
|
// CMD_ID agnostic
|
||||||
|
getCMDSetActivationMSG(ack);
|
||||||
|
break;
|
||||||
|
case OpenProtocol::CMDSet::control:
|
||||||
|
// Get message by CMD_ID
|
||||||
|
getCMDSetControlMSG(ack);
|
||||||
|
case OpenProtocol::CMDSet::broadcast:
|
||||||
|
getSetBroadcastMSG(ack);
|
||||||
|
break;
|
||||||
|
case OpenProtocol::CMDSet::mission:
|
||||||
|
// CMD_ID agnostic
|
||||||
|
getCMDSetMissionMSG(ack);
|
||||||
|
break;
|
||||||
|
case OpenProtocol::CMDSet::hardwareSync:
|
||||||
|
getCMDSetSyncMSG(ack);
|
||||||
|
break;
|
||||||
|
case OpenProtocol::CMDSet::virtualRC:
|
||||||
|
getCMDSetVirtualRCMSG(ack);
|
||||||
|
break;
|
||||||
|
case OpenProtocol::CMDSet::mfio:
|
||||||
|
getCMDSetMFIOMSG(ack);
|
||||||
|
break;
|
||||||
|
case OpenProtocol::CMDSet::subscribe:
|
||||||
|
// CMD_ID agnostic
|
||||||
|
getCMDSetSubscribeMSG(ack);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DSTATUS("UNKNOWN_ACK_ERROR_CODE\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @note CMD_ID agnostic
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ACK::getCMDSetActivationMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> activateErrorCodeMap =
|
||||||
|
ACK::createActivateErrorCodeMap();
|
||||||
|
auto msg = activateErrorCodeMap.find(ack.data);
|
||||||
|
|
||||||
|
if (msg != activateErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getCommonErrorCodeMessage(ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCommonErrorCodeMessage(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> commonErrorCodeMap =
|
||||||
|
ACK::createCommonErrorCodeMap();
|
||||||
|
auto msg = commonErrorCodeMap.find(ack.data);
|
||||||
|
|
||||||
|
if (msg != commonErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("UNKNOWN_ACK_ERROR_CODE\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDSetSubscribeMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> subscribeErrorCodeMap =
|
||||||
|
ACK::createSubscribeErrorCodeMap();
|
||||||
|
auto msg = subscribeErrorCodeMap.find(ack.data);
|
||||||
|
|
||||||
|
if (msg != subscribeErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("UNKNOWN_SUBSCRIBER_ACK_ERROR_CODE_0x%X\n", ack.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDSetControlMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const uint8_t cmd[] = { ack.info.cmd_set, ack.info.cmd_id };
|
||||||
|
|
||||||
|
if (memcmp(cmd, OpenProtocol::CMDSet::Control::setControl, sizeof(cmd)) == 0)
|
||||||
|
{
|
||||||
|
getCMDIDSetControlMSG(ack.data, ack.info.version);
|
||||||
|
}
|
||||||
|
else if (memcmp(cmd, OpenProtocol::CMDSet::Control::control, sizeof(cmd)) ==
|
||||||
|
0)
|
||||||
|
{
|
||||||
|
getCMDIDControlMSG(ack);
|
||||||
|
}
|
||||||
|
else if (memcmp(cmd, OpenProtocol::CMDSet::Control::task, sizeof(cmd)) == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @note Deprecated in 3.2.20
|
||||||
|
*/
|
||||||
|
getCMDIDTaskMSG(ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDIDSetControlMSG(uint8_t ack, Version::FirmWare version)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> setControlErrorCodeMap =
|
||||||
|
ACK::createSetControlErrorCodeMap();
|
||||||
|
auto msg = setControlErrorCodeMap.find(ack);
|
||||||
|
|
||||||
|
if (msg != setControlErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
if (msg->first ==
|
||||||
|
OpenProtocol::ErrorCode::ControlACK::SetControl::RC_MODE_ERROR)
|
||||||
|
{
|
||||||
|
if (version != Version::M100_23 || version != Version::M100_31 ||
|
||||||
|
version != Version::A3_31)
|
||||||
|
{
|
||||||
|
DSTATUS("RC_NEED_MODE_P\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("RC_NEED_MODE_F\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("UNKNOWN_ACK_ERROR_CODE\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDIDControlMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDIDTaskMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> taskErrorCodeMap =
|
||||||
|
ACK::createTaskErrorCodeMap();
|
||||||
|
auto msg = taskErrorCodeMap.find(ack.data);
|
||||||
|
|
||||||
|
if (msg != taskErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getCommonErrorCodeMessage(ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getSetBroadcastMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @note CMD_ID agnostic
|
||||||
|
*
|
||||||
|
* @todo Check DJI_ERROR_CODE for comments
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ACK::getCMDSetMissionMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> missionErrorCodeMap =
|
||||||
|
ACK::createMissionErrorCodeMap();
|
||||||
|
auto msg = missionErrorCodeMap.find(ack.data);
|
||||||
|
|
||||||
|
if (msg != missionErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("UNKNOWN_MISSION_ACK_ERROR_CODE\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDSetSyncMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDSetVirtualRCMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ACK::getCMDSetMFIOMSG(ACK::ErrorCode ack)
|
||||||
|
{
|
||||||
|
const std::map<const uint32_t, const char*> mfioErrorCodeMap =
|
||||||
|
ACK::createMFIOErrorCodeMap();
|
||||||
|
auto msg = mfioErrorCodeMap.find(ack.data);
|
||||||
|
|
||||||
|
if (msg != mfioErrorCodeMap.end())
|
||||||
|
{
|
||||||
|
DSTATUS(msg->second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("MFIO_UNKNOWN_ERROR\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
@@ -0,0 +1,316 @@
|
|||||||
|
/** @file dji_broadcast.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Broadcast Telemetry API for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_broadcast.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::unpackCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData data)
|
||||||
|
{
|
||||||
|
DataBroadcast* broadcastPtr = (DataBroadcast*)data;
|
||||||
|
broadcastPtr->unpackData(&recvFrame);
|
||||||
|
if (broadcastPtr->userCbHandler.callback)
|
||||||
|
broadcastPtr->userCbHandler.callback(vehicle, recvFrame,
|
||||||
|
broadcastPtr->userCbHandler.userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBroadcast::DataBroadcast(Vehicle* vehiclePtr)
|
||||||
|
{
|
||||||
|
if (vehiclePtr)
|
||||||
|
{
|
||||||
|
setVehicle(vehiclePtr);
|
||||||
|
}
|
||||||
|
unpackHandler.callback = unpackCallback;
|
||||||
|
unpackHandler.userData = this;
|
||||||
|
|
||||||
|
userCbHandler.callback = 0;
|
||||||
|
userCbHandler.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBroadcast::~DataBroadcast()
|
||||||
|
{
|
||||||
|
this->setUserBroadcastCallback(0, NULL);
|
||||||
|
unpackHandler.callback = 0;
|
||||||
|
unpackHandler.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
Telemetry::TimeStamp DataBroadcast::getTimeStamp() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::TimeStamp ans = timeStamp; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::SyncStamp DataBroadcast::getSyncStamp() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::SyncStamp ans = syncStamp; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Quaternion DataBroadcast::getQuaternion() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Quaternion ans = q; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Vector3f DataBroadcast::getAcceleration() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Vector3f ans = a; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Vector3f DataBroadcast::getVelocity() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Vector3f ans = v; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Vector3f DataBroadcast::getAngularRate() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Vector3f ans = w; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::VelocityInfo DataBroadcast::getVelocityInfo() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::VelocityInfo ans = vi; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::GlobalPosition DataBroadcast::getGlobalPosition() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::GlobalPosition ans = gp; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::RelativePosition DataBroadcast::getRelativePosition() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::RelativePosition ans = rp; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::GPSInfo DataBroadcast::getGPSInfo() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::GPSInfo ans = gps; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::RTK DataBroadcast::getRTKInfo() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::RTK ans = rtk; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Mag DataBroadcast::getMag() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Mag ans = mag; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::RC DataBroadcast::getRC() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::RC ans = rc; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Gimbal DataBroadcast::getGimbal() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Gimbal ans = gimbal; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Status DataBroadcast::getStatus() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Status ans = status; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::Battery DataBroadcast::getBatteryInfo() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::Battery ans = battery; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
Telemetry::SDKInfo DataBroadcast::getSDKInfo() const { vehicle->protocolLayer->getThreadHandle()->lockMSG(); Telemetry::SDKInfo ans = info; vehicle->protocolLayer->getThreadHandle()->freeMSG(); return ans;}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
Vehicle*
|
||||||
|
DataBroadcast::getVehicle() const
|
||||||
|
{
|
||||||
|
return vehicle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setVehicle(Vehicle* vehiclePtr)
|
||||||
|
{
|
||||||
|
vehicle = vehiclePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setBroadcastFreq(uint8_t* dataLenIs16, VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
//! @note see also enum BROADCAST_FREQ in DJI_API.h
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
dataLenIs16[i] = (dataLenIs16[i] > 7 ? 5 : dataLenIs16[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t cmd_timeout = 100; // unit is ms
|
||||||
|
uint32_t retry_time = 1;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)setFrequencyCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, 0, OpenProtocol::CMDSet::Activation::frequency, dataLenIs16, 16,
|
||||||
|
cmd_timeout, retry_time, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
DataBroadcast::setBroadcastFreq(uint8_t* dataLenIs16, int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
dataLenIs16[i] = (dataLenIs16[i] > 7 ? 5 : dataLenIs16[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, 0,
|
||||||
|
OpenProtocol::CMDSet::Activation::frequency,
|
||||||
|
dataLenIs16, 16, 100, 1, 0, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)getVehicle()->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Activation::frequency, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::unpackData(RecvContainer* pRecvFrame)
|
||||||
|
{
|
||||||
|
uint8_t* pdata = pRecvFrame->recvData.raw_ack_array;
|
||||||
|
vehicle->protocolLayer->getThreadHandle()->lockMSG();
|
||||||
|
passFlag = *(uint16_t*)pdata;
|
||||||
|
pdata += sizeof(uint16_t);
|
||||||
|
// clang-format off
|
||||||
|
unpackOne(FLAG_TIME ,&timeStamp ,pdata,sizeof(timeStamp ));
|
||||||
|
unpackOne(FLAG_TIME ,&syncStamp ,pdata,sizeof(syncStamp ));
|
||||||
|
unpackOne(FLAG_QUATERNION ,&q ,pdata,sizeof(q ));
|
||||||
|
unpackOne(FLAG_ACCELERATION,&a ,pdata,sizeof(a ));
|
||||||
|
unpackOne(FLAG_VELOCITY ,&v ,pdata,sizeof(v ));
|
||||||
|
unpackOne(FLAG_VELOCITY ,&vi ,pdata,sizeof(vi ));
|
||||||
|
unpackOne(FLAG_ANGULAR_RATE,&w ,pdata,sizeof(w ));
|
||||||
|
unpackOne(FLAG_POSITION ,&gp ,pdata,sizeof(gp ));
|
||||||
|
unpackOne(FLAG_POSITION ,&rp ,pdata,sizeof(rp ));
|
||||||
|
unpackOne(FLAG_GPSINFO ,&gps ,pdata,sizeof(gps ));
|
||||||
|
unpackOne(FLAG_RTKINFO ,&rtk ,pdata,sizeof(rtk ));
|
||||||
|
unpackOne(FLAG_MAG ,&mag ,pdata,sizeof(mag ));
|
||||||
|
unpackOne(FLAG_RC ,&rc ,pdata,sizeof(rc ));
|
||||||
|
unpackOne(FLAG_GIMBAL ,&gimbal ,pdata,sizeof(gimbal ));
|
||||||
|
unpackOne(FLAG_STATUS ,&status ,pdata,sizeof(status ));
|
||||||
|
unpackOne(FLAG_BATTERY ,&battery ,pdata,sizeof(battery ));
|
||||||
|
unpackOne(FLAG_DEVICE ,&info ,pdata,sizeof(info ));
|
||||||
|
// clang-format on
|
||||||
|
vehicle->protocolLayer->getThreadHandle()->freeMSG();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::unpackOne(DataBroadcast::FLAG flag, void* data, uint8_t*& buf,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
if (flag & passFlag)
|
||||||
|
{
|
||||||
|
memcpy((uint8_t*)data, (uint8_t*)buf, size);
|
||||||
|
buf += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setVersionDefaults(uint8_t* frequencyBuffer)
|
||||||
|
{
|
||||||
|
if (vehicle->getFwVersion() >= Version::A3_3_2_20_test)
|
||||||
|
{
|
||||||
|
setFreqDefaults(frequencyBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setFreqDefaultsM100_31(frequencyBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setBroadcastFreqDefaults()
|
||||||
|
{
|
||||||
|
uint8_t frequencyBuffer[16];
|
||||||
|
setVersionDefaults(frequencyBuffer);
|
||||||
|
setBroadcastFreq(frequencyBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
DataBroadcast::setBroadcastFreqDefaults(int timeout)
|
||||||
|
{
|
||||||
|
uint8_t frequencyBuffer[16];
|
||||||
|
setVersionDefaults(frequencyBuffer);
|
||||||
|
return setBroadcastFreq(frequencyBuffer, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setFreqDefaultsM100_31(uint8_t* freq)
|
||||||
|
{
|
||||||
|
freq[0] = FREQ_1HZ;
|
||||||
|
freq[1] = FREQ_10HZ;
|
||||||
|
freq[2] = FREQ_50HZ;
|
||||||
|
freq[3] = FREQ_100HZ;
|
||||||
|
freq[4] = FREQ_50HZ;
|
||||||
|
freq[5] = FREQ_10HZ;
|
||||||
|
freq[6] = FREQ_0HZ;
|
||||||
|
freq[7] = FREQ_0HZ;
|
||||||
|
freq[8] = FREQ_1HZ;
|
||||||
|
freq[9] = FREQ_10HZ;
|
||||||
|
freq[10] = FREQ_50HZ;
|
||||||
|
freq[11] = FREQ_100HZ;
|
||||||
|
freq[12] = FREQ_50HZ;
|
||||||
|
freq[13] = FREQ_10HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setFreqDefaults(uint8_t* freq)
|
||||||
|
{
|
||||||
|
/* Channels definition:
|
||||||
|
* 0 - Timestamp
|
||||||
|
* 1 - Attitude Quaterniouns
|
||||||
|
* 2 - Acceleration
|
||||||
|
* 3 - Velocity (Ground Frame)
|
||||||
|
* 4 - Angular Velocity (Body Frame)
|
||||||
|
* 5 - Position
|
||||||
|
* 6 - Remote Controller Channel Data
|
||||||
|
* 7 - Gimbal Data
|
||||||
|
* 8 - Flight Status
|
||||||
|
* 9 - Battery Level
|
||||||
|
* 10 - Control Information
|
||||||
|
*/
|
||||||
|
|
||||||
|
freq[0] = FREQ_50HZ;
|
||||||
|
freq[1] = FREQ_50HZ;
|
||||||
|
freq[2] = FREQ_50HZ;
|
||||||
|
freq[3] = FREQ_50HZ;
|
||||||
|
freq[4] = FREQ_50HZ;
|
||||||
|
freq[5] = FREQ_50HZ;
|
||||||
|
/*
|
||||||
|
* GPS: DON'T SEND
|
||||||
|
*/
|
||||||
|
freq[6] = FREQ_0HZ;
|
||||||
|
/*
|
||||||
|
* RTK: DON'T SEND
|
||||||
|
*/
|
||||||
|
freq[7] = FREQ_0HZ;
|
||||||
|
/*
|
||||||
|
* Magnetometer: DON'T SEND
|
||||||
|
*/
|
||||||
|
freq[8] = FREQ_0HZ;
|
||||||
|
freq[9] = FREQ_50HZ;
|
||||||
|
freq[10] = FREQ_50HZ;
|
||||||
|
freq[11] = FREQ_10HZ;
|
||||||
|
freq[12] = FREQ_1HZ;
|
||||||
|
freq[13] = FREQ_1HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setBroadcastFreqToZero()
|
||||||
|
{
|
||||||
|
uint8_t freq[16];
|
||||||
|
|
||||||
|
freq[0] = FREQ_0HZ;
|
||||||
|
freq[1] = FREQ_0HZ;
|
||||||
|
freq[2] = FREQ_0HZ;
|
||||||
|
freq[3] = FREQ_0HZ;
|
||||||
|
freq[4] = FREQ_0HZ;
|
||||||
|
freq[5] = FREQ_0HZ;
|
||||||
|
freq[6] = FREQ_0HZ;
|
||||||
|
freq[7] = FREQ_0HZ;
|
||||||
|
freq[8] = FREQ_0HZ;
|
||||||
|
freq[9] = FREQ_0HZ;
|
||||||
|
freq[10] = FREQ_0HZ;
|
||||||
|
freq[11] = FREQ_0HZ;
|
||||||
|
freq[12] = FREQ_0HZ;
|
||||||
|
freq[13] = FREQ_0HZ;
|
||||||
|
setBroadcastFreq(freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setFrequencyCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
|
||||||
|
ACK::ErrorCode ackErrorCode;
|
||||||
|
ackErrorCode.data = OpenProtocol::ErrorCode::CommonACK::NO_RESPONSE_ERROR;
|
||||||
|
ackErrorCode.info = recvFrame.recvInfo;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <= 2)
|
||||||
|
{
|
||||||
|
// Two-byte ACK
|
||||||
|
ackErrorCode.data = recvFrame.recvData.ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ACK::getError(ackErrorCode))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ackErrorCode, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataBroadcast::setUserBroadcastCallback(VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
userCbHandler.callback = callback;
|
||||||
|
userCbHandler.userData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
DataBroadcast::getPassFlag()
|
||||||
|
{
|
||||||
|
return passFlag;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/** @file dji_camera.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Camera/Gimbal API for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_camera.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
Camera::Camera(Vehicle* vehicle)
|
||||||
|
: vehicle(vehicle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Camera::shootPhoto()
|
||||||
|
{
|
||||||
|
action(OpenProtocol::CMDSet::Control::cameraShot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Camera::videoStart()
|
||||||
|
{
|
||||||
|
action(OpenProtocol::CMDSet::Control::cameraVideoStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Camera::videoStop()
|
||||||
|
{
|
||||||
|
action(OpenProtocol::CMDSet::Control::cameraVideoStop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Camera::action(const uint8_t cmd[])
|
||||||
|
{
|
||||||
|
uint8_t sendData = 0;
|
||||||
|
vehicle->protocolLayer->send(0, encrypt, cmd, &sendData, 1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/** @file dji_command.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief All DJI OSDK OpenProtocol Command IDs
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_command.hpp"
|
||||||
|
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Activation::getVersion[] = {
|
||||||
|
OpenProtocol::CMDSet::activation, 0x00
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Activation::activate[] = {
|
||||||
|
OpenProtocol::CMDSet::activation, 0x01
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Activation::frequency[] = {
|
||||||
|
OpenProtocol::CMDSet::activation, 0x10
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Activation::toMobile[] = {
|
||||||
|
OpenProtocol::CMDSet::activation, 0xFE
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::broadcast[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0x00
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::lostCTRL[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0x01
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::fromMobile[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0x02
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::mission[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0x03
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::waypoint[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0x04
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::subscribe[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0x05
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Broadcast::test[] = {
|
||||||
|
OpenProtocol::CMDSet::broadcast, 0xEF
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::setControl[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x00
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::task[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x01
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::status[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x02
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::control[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x03
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::cameraShot[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x20
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::cameraVideoStart[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x21
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::cameraVideoStop[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x22
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::gimbalSpeed[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x1A
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Control::gimbalAngle[] = {
|
||||||
|
OpenProtocol::CMDSet::control, 0x1B
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointInit[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x10
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointAddPoint[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x11
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointSetStart[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x12
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointSetPause[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x13
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointDownload[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x14
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointIndex[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x15
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointSetVelocity[] =
|
||||||
|
{ OpenProtocol::CMDSet::mission, 0x16 };
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::waypointGetVelocity[] =
|
||||||
|
{ OpenProtocol::CMDSet::mission, 0x17 };
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointStart[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x20
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointStop[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x21
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointSetPause[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x22
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointYawRate[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x23
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointRadius[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x24
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointSetYaw[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x25
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::hotpointDownload[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x26
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::followStart[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x30
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::followStop[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x31
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::followSetPause[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x32
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Mission::followTarget[] = {
|
||||||
|
OpenProtocol::CMDSet::mission, 0x33
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::HardwareSync::broadcast[] = {
|
||||||
|
OpenProtocol::CMDSet::hardwareSync, 0x00
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::VirtualRC::settings[] = {
|
||||||
|
OpenProtocol::CMDSet::virtualRC
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::VirtualRC::data[] = {
|
||||||
|
OpenProtocol::CMDSet::virtualRC
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::MFIO::init[] = {
|
||||||
|
OpenProtocol::CMDSet::mfio, 0x02
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::MFIO::set[] = {
|
||||||
|
OpenProtocol::CMDSet::mfio, 0x03
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::MFIO::get[] = {
|
||||||
|
OpenProtocol::CMDSet::mfio, 0x04
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::versionMatch[] = {
|
||||||
|
OpenProtocol::CMDSet::subscribe, 0x00
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::addPackage[] = {
|
||||||
|
OpenProtocol::CMDSet::subscribe, 0x01
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::reset[] = {
|
||||||
|
OpenProtocol::CMDSet::subscribe, 0x02
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::removePackage[] = {
|
||||||
|
OpenProtocol::CMDSet::subscribe, 0x03
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::updatePackageFreq[] =
|
||||||
|
{ OpenProtocol::CMDSet::subscribe, 0x04 };
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::pauseResume[] = {
|
||||||
|
OpenProtocol::CMDSet::subscribe, 0x05
|
||||||
|
};
|
||||||
|
const uint8_t DJI::OSDK::OpenProtocol::CMDSet::Subscribe::getConfig[] = {
|
||||||
|
OpenProtocol::CMDSet::subscribe, 0x06
|
||||||
|
};
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
/** @file dji_control.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Control API for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_control.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
Control::Control(Vehicle* vehicle)
|
||||||
|
: vehicle(vehicle)
|
||||||
|
, wait_timeout(10)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Control::~Control()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::action(const int cmd, VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t data = cmd;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Support for default callbacks
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)actionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Control::task, &data,
|
||||||
|
sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
Control::action(const int cmd, int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t data = cmd;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Control::task, &data,
|
||||||
|
sizeof(data), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Control::task, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
Control::armMotors(int wait_timeout)
|
||||||
|
{
|
||||||
|
return this->action(FlightCommand::startMotor, wait_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::armMotors(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
this->action(FlightCommand::startMotor, callback, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
Control::disArmMotors(int wait_timeout)
|
||||||
|
{
|
||||||
|
return this->action(FlightCommand::stopMotor, wait_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::disArmMotors(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
this->action(FlightCommand::stopMotor, callback, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
Control::takeoff(int wait_timeout)
|
||||||
|
{
|
||||||
|
return this->action(FlightCommand::takeOff, wait_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::takeoff(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
this->action(FlightCommand::takeOff, callback, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
Control::goHome(int wait_timeout)
|
||||||
|
{
|
||||||
|
return this->action(FlightCommand::goHome, wait_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::goHome(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
this->action(FlightCommand::goHome, callback, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
Control::land(int wait_timeout)
|
||||||
|
{
|
||||||
|
return this->action(FlightCommand::landing, wait_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::land(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
this->action(FlightCommand::landing, callback, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::flightCtrl(CtrlData data)
|
||||||
|
{
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
0, DJI::OSDK::encrypt, OpenProtocol::CMDSet::Control::control,
|
||||||
|
static_cast<void*>(&data), sizeof(CtrlData), 500, 2, false, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::flightCtrl(AdvancedCtrlData data)
|
||||||
|
{
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
0, DJI::OSDK::encrypt, OpenProtocol::CMDSet::Control::control,
|
||||||
|
static_cast<void*>(&data), sizeof(AdvancedCtrlData), 500, 2, false, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::positionAndYawCtrl(float32_t x, float32_t y, float32_t z,
|
||||||
|
float32_t yaw)
|
||||||
|
{
|
||||||
|
//! @note 145 is the flag value of this mode
|
||||||
|
uint8_t ctrl_flag = (VERTICAL_POSITION | HORIZONTAL_POSITION | YAW_ANGLE |
|
||||||
|
HORIZONTAL_GROUND | STABLE_ENABLE);
|
||||||
|
CtrlData data(ctrl_flag, x, y, z, yaw);
|
||||||
|
|
||||||
|
return this->flightCtrl(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::velocityAndYawRateCtrl(float32_t Vx, float32_t Vy, float32_t Vz,
|
||||||
|
float32_t yawRate)
|
||||||
|
{
|
||||||
|
//! @note 72 is the flag value of this mode
|
||||||
|
uint8_t ctrl_flag =
|
||||||
|
(VERTICAL_VELOCITY | HORIZONTAL_VELOCITY | YAW_RATE | HORIZONTAL_GROUND);
|
||||||
|
CtrlData data(ctrl_flag, Vx, Vy, Vz, yawRate);
|
||||||
|
|
||||||
|
return this->flightCtrl(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::attitudeAndVertPosCtrl(float32_t roll, float32_t pitch, float32_t yaw,
|
||||||
|
float32_t z)
|
||||||
|
{
|
||||||
|
//! @note 18 is the flag value of this mode
|
||||||
|
uint8_t ctrl_flag =
|
||||||
|
(VERTICAL_POSITION | HORIZONTAL_ANGLE | YAW_ANGLE | HORIZONTAL_BODY);
|
||||||
|
CtrlData data(ctrl_flag, roll, pitch, z, yaw);
|
||||||
|
|
||||||
|
return this->flightCtrl(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::angularRateAndVertPosCtrl(float32_t rollRate, float32_t pitchRate,
|
||||||
|
float32_t yawRate, float32_t z)
|
||||||
|
{
|
||||||
|
//! @note 218 is the flag value of this mode
|
||||||
|
uint8_t ctrl_flag =
|
||||||
|
(VERTICAL_POSITION | HORIZONTAL_ANGULAR_RATE | YAW_RATE | HORIZONTAL_BODY);
|
||||||
|
CtrlData data(ctrl_flag, rollRate, pitchRate, z, yawRate);
|
||||||
|
|
||||||
|
return this->flightCtrl(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::emergencyBrake()
|
||||||
|
{
|
||||||
|
//! @note 75 is the flag value of this mode
|
||||||
|
AdvancedCtrlData data(72, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
return this->flightCtrl(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Control::actionCallback(Vehicle* vehiclePtr, RecvContainer recvFrame,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
Control* controlPtr = vehiclePtr->control;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <= sizeof(uint16_t))
|
||||||
|
{
|
||||||
|
|
||||||
|
ack.info = recvFrame.recvInfo;
|
||||||
|
ack.data = recvFrame.recvData.ack;
|
||||||
|
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("ACK is exception, sequence %d\n", recvFrame.recvInfo.seqNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Control::CtrlData::CtrlData(uint8_t in_flag, float32_t in_x, float32_t in_y,
|
||||||
|
float32_t in_z, float32_t in_yaw)
|
||||||
|
: flag(in_flag)
|
||||||
|
, x(in_x)
|
||||||
|
, y(in_y)
|
||||||
|
, z(in_z)
|
||||||
|
, yaw(in_yaw)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Control::AdvancedCtrlData::AdvancedCtrlData(uint8_t in_flag, float32_t in_x,
|
||||||
|
float32_t in_y, float32_t in_z,
|
||||||
|
float32_t in_yaw, float32_t x_forw,
|
||||||
|
float32_t y_forw)
|
||||||
|
: flag(in_flag)
|
||||||
|
, x(in_x)
|
||||||
|
, y(in_y)
|
||||||
|
, z(in_z)
|
||||||
|
, yaw(in_yaw)
|
||||||
|
, xFeedforward(x_forw)
|
||||||
|
, yFeedforward(y_forw)
|
||||||
|
, advFlag(0x01)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,277 @@
|
|||||||
|
/** @file dji_error.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief All DJI OSDK OpenProtocol ACK Error Codes
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_error.hpp"
|
||||||
|
// clang-format off
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::CommonACK::SUCCESS = 0x0000;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::CommonACK::KEY_ERROR = 0xFF00;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::CommonACK::NO_AUTHORIZATION_ERROR = 0xFF01;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::CommonACK::NO_RIGHTS_ERROR = 0xFF02;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::CommonACK::NO_RESPONSE_ERROR = 0xFFFF;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_NONE = 0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_COMPASS_ABNORMAL = 1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ASSISTANT_PROTECTED = 2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_DEVICE_LOCKED = 3;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_NEED_ADV_CALIBRATION = 5;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_SN_ERROR = 6;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_PREHEATING = 7;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_COMPASS_CALIBRATING = 8;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_NO_ATTITUDE = 9;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_NO_GPS_IN_NOVICE_MODE = 10;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_CELL_ERROR = 11;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_COMMUNICATION_ERROR = 12;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_VOLTAGE_TOO_LOW = 13;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_USER_LOW_LAND = 14;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_MAIN_VOL_LOW = 15;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_TEMP_VOL_LOW = 16;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_SMART_LOW_LAND = 17;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_NOT_READY = 18;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RUNNING_SIMULATOR = 19;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_PACK_MODE = 20;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_ATTI_LIMIT = 21;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_NOT_ACTIVATED = 22;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IN_FLYLIMIT_AREA = 23;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_BIAS_LIMIT = 24;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_ERROR = 25;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_INITING = 26;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_UPGRADING = 27;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_HAVE_RUN_SIM = 28;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_CALIBRATING = 29;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_TAKEOFF_TILT_TOO_LARGE = 30;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_31 = 31;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_32 = 32;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_33 = 33;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_34 = 34;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_35 = 35;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_36 = 36;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_37 = 37;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_38 = 38;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_39 = 39;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_40 = 40;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_INVALID_SN = 41;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_42 = 42;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_43 = 43;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_FLASH_OPERATING = 44;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GPS_DISCONNECT = 45;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_INTERNAL_46 = 46;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RECORDER_ERROR = 47;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_INVALID_PRODUCT = 48;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_49 = 49;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_50 = 50;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_51 = 51;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_52 = 52;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_53 = 53;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_54 = 54;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_55 = 55;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_56 = 56;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_57 = 57;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_58 = 58;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_59 = 59;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_60 = 60;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_DISCONNECTED = 61;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RC_CALIBRATING = 62;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RC_CALI_DATA_OUT_RANGE = 63;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RC_QUIT_CALI = 64;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RC_CENTER_OUT_RANGE = 65;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RC_MAP_ERROR = 66;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_WRONG_AIRCRAFT_TYPE = 67;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_SOME_MODULE_NOT_CONFIGURED = 68;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_69 = 69;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_70 = 70;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_71 = 71;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_72 = 72;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_73 = 73;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_NS_ABNORMAL = 74;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_TOPOLOGY_ABNORMAL = 75;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RC_NEED_CALI = 76;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_INVALID_FLOAT = 77;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_M600_BAT_TOO_FEW = 78;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_M600_BAT_AUTH_ERR = 79;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_M600_BAT_COMM_ERR = 80;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_M600_BAT_DIF_VOLT_LARGE_1 = 81;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BATTERY_BOLTAHGE_DIFF_82 = 82;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_INVALID_VERSION = 83;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_GYRO_ABNORMAL = 84;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_ESC_PITCH_NO_DATA = 85;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_ESC_ROLL_NO_DATA = 86;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_ESC_YAW_NO_DATA = 87;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_FIRM_IS_UPDATING = 88;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_OUT_OF_CONTROL = 89;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_PITCH_SHOCK = 90;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_ROLL_SHOCK = 91;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_YAW_SHOCK = 92;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_IMU_CALI_SUCCESS = 93;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_TAKEOFF_EXCEPTION = 94;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_STALL_NEAR_GOUND = 95;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_UNBALANCE_ON_GRD = 96;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_PART_EMPTY_ON_GRD = 97;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ENGINE_START_FAILED = 98;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_AUTO_TAKEOFF_LAUNCH_FAILED = 99;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ROLL_OVER_ON_GRD = 100;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BAT_VERSION_ERR = 101;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RTK_INITING = 102;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RTK_FAIL_TO_INIT = 103;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_104 = 104;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_105 = 105;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_106 = 106;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_107 = 107;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_108 = 108;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_RESERVED_109 = 109;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::START_MOTOR_FAIL_MOTOR_STARTED = 110;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_INTERNAL_111 = 111;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_CALIBRATING = 112;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GPS_SIGNATURE_INVALID = 113;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GIMBAL_CALIBRATING = 114;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_FORCE_DISABLE = 115;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::TAKEOFF_HEIGHT_EXCEPTION = 116;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_NEED_UPGRADE = 117;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_GYRO_DATA_NOT_MATCH = 118;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_APP_NOT_ALLOW = 119;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_COMPASS_IMU_MISALIGN = 120;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_FLASH_UNLOCK = 121;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_SCREAMING = 122;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_ESC_TEMP_HIGH = 123;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_BAT_ERR = 124;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::IMPACT_IS_DETECTED = 125;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_MODE_FAILURE = 126;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_CRAFT_FAIL_LATELY = 127;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::MOTOR_FAIL_MOTOR_CODE_ERROR = 255;
|
||||||
|
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::FlightStatus::STOPED = 0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::FlightStatus::ON_GROUND = 1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::CommonACK::FlightStatus::IN_AIR = 2;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::SUCCESS = 0x0000;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::PARAMETER_ERROR = 0x0001;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::ENCODE_ERROR = 0x0002;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::NEW_DEVICE_ERROR = 0x0003;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::DJIGO_APP_NOT_CONNECTED = 0x0004;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::NETWORK_ERROR = 0x0005;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::SERVER_ACCESS_REFUSED = 0x0006;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::ACCESS_LEVEL_ERROR = 0x0007;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ActivationACK::OSDK_VERSION_ERROR = 0x0008;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RC_MODE_ERROR = 0x0000;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RELEASE_CONTROL_SUCCESS = 0x0001;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::OBTAIN_CONTROL_SUCCESS = 0x0002;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::OBTAIN_CONTROL_IN_PROGRESS = 0x0003;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RELEASE_CONTROL_IN_PROGRESS = 0x0004;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RC_NEED_MODE_F = 0x0006;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::RC_NEED_MODE_P = 0x0005;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::SetControl::IOC_OBTAIN_CONTROL_ERROR = 0x00C9;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::SUCCESS = 0x0000;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::MOTOR_ON = 0x0001;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::MOTOR_OFF = 0x0002;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::IN_AIR = 0x0003;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::NOT_IN_AIR = 0x0004;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::NO_HOMEPOINT = 0x0005;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::BAD_GPS = 0x0006;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::IN_SIMULATOR_MODE = 0x0007;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::ALREADY_RUNNING = 0x0008;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::NOT_RUNNING = 0x0009;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::INVAILD_COMMAND = 0x0010;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::NO_LANDING_GEAR = 0x0011;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::GIMBAL_MOUNTED = 0x0012;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::BAD_SENSOR = 0x0013;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::ALREADY_PACKED = 0x0014;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::NO_PACKED = 0x0015;
|
||||||
|
const uint16_t DJI::OSDK::ErrorCode::ControlACK::Task::PACKED_MODE_NOT_SUPPORTED = 0x0016;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::SUCCESS = 0x00;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::ILLEGAL_INPUT = 0x01;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::VERSION_DOES_NOT_MATCH = 0x02;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PACKAGE_OUT_OF_RANGE = 0x03;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PACKAGE_ALREADY_EXISTS = 0x04;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PACKAGE_DOES_NOT_EXIST = 0x05;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::ILLEGAL_FREQUENCY = 0x06;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PACKAGE_TOO_LARGE = 0x07;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PIPELINE_OVERFLOW = 0x08;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::INTERNAL_ERROR_0X09 = 0x09;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PACKAGE_EMPTY = 0x20;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::INPUT_SEGMENTATION_FAULT = 0x21;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::ILLEGAL_UID = 0x22;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PERMISSION_DENY = 0x23;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::MULTIPLE_SUBSCRIBE = 0x24;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::SOUCE_DEVICE_OFFLINE = 0x25;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::PAUSED = 0x48;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::RESUMED = 0x49;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::INTERNAL_ERROR_0X4A = 0x4A;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::INTERNAL_ERROR_0X50 = 0x50;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::VERSION_VERSION_TOO_FAR = 0x51;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::VERSION_UNKNOWN_ERROR = 0x59;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::SubscribeACK::INTERNAL_ERROR_0XFF = 0xFF;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::SUCCESS = 0x00;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::WRONG_WAYPOINT_INDEX = 0x01;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::RC_NOT_IN_MODE_F = 0xD0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::OBTAIN_CONTROL_REQUIRED = 0xD1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::CLOSE_IOC_REQUIRED = 0xD2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::NOT_INITIALIZED = 0xD3;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::NOT_RUNNING = 0xD4;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::IN_PROGRESS = 0xD5;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::TASK_TIMEOUT = 0xD6;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::OTHER_MISSION_RUNNING = 0xD7;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::BAD_GPS = 0xD8;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::RTK_NOT_READY = 0xCD;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::LOW_BATTERY = 0xD9;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::VEHICLE_DID_NOT_TAKE_OFF = 0xDA;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::INVALID_PARAMETER = 0xDB;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::CONDITIONS_NOT_SATISFIED = 0xDC;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::CROSSING_NO_FLY_ZONE = 0xDD;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::UNRECORDED_HOME = 0xDE;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::AT_NO_FLY_ZONE = 0xDF;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::TOO_HIGH = 0xC0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::TOO_LOW = 0xC1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::TOO_FAR_FROM_HOME = 0xC7;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::NOT_SUPPORTED = 0xC8;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::TOO_FAR_FROM_CURRENT_POSITION = 0xC9;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::BEGGINER_MODE_NOT_SUPPORTED = 0xCA;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::TAKE_OFF_IN_PROGRESS = 0xF0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::LANDING_IN_PROGRESS = 0xF1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::RRETURN_HOME_IN_PROGRESS = 0xF2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::START_MOTORS_IN_PROGRESS = 0xF3;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::INVALID_COMMAND = 0xF4;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Common::UNKNOWN_ERROR = 0xFF;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Follow::TOO_FAR_FROM_YOUR_POSITION_LACK_OF_RADIO_CONNECTION = 0xB0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Follow::CUTOFF_TIME_OVERFLOW = 0xB1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::Follow::GIMBAL_PITCH_ANGLE_OVERFLOW = 0xB2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::INVALID_RADIUS = 0xC2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::YAW_RATE_OVERFLOW = 0xC3;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::INVALID_START_POINT = 0xC4;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::INVALID_YAW_MODE = 0xC5;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::TOO_FAR_FROM_HOTPOINT = 0xC6;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::INVALID_PAREMETER = 0xA2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::INVALID_LATITUDE_OR_LONGITUTE = 0xA3;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::INVALID_DIRECTION = 0xA6;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::IN_PAUSED_MODE = 0xA9;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::HotPoint::FAILED_TO_PAUSE = 0xAA;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::INVALID_DATA = 0xE0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::INVALID_POINT_DATA = 0xE1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::DISTANCE_OVERFLOW = 0xE2;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::TIMEOUT = 0xE3;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::POINT_OVERFLOW = 0xE4;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::POINTS_TOO_CLOSE = 0xE5;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::POINTS_TOO_FAR = 0xE6;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::CHECK_FAILED = 0xE7;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::INVALID_ACTION = 0xE8;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::POINT_DATA_NOT_ENOUGH = 0xE9;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::DATA_NOT_ENOUGH = 0xEA;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::POINTS_NOT_ENOUGH = 0xEB;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::IN_PROGRESS = 0xEC;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::NOT_IN_PROGRESS = 0xED;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::WayPoint::INVALID_VELOCITY = 0xEE;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::IOC::TOO_CLOSE_TO_HOME = 0xA0;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MissionACK::IOC::UNKNOWN_TYPE = 0xA1;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::init::SUCCESS = 0x00;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::init::UNKNOWN_ERROR = 0x01;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::init::PORT_NUMBER_ERROR = 0x02;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::init::PORT_MODE_ERROR = 0x03;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::init::PORT_DATA_ERROR = 0x04;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::set::SUCCESS = 0x00;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::set::CHANNEL_ERROR = 0x01;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::set::PORT_NOT_MAPPED_ERROR = 0x02;
|
||||||
|
const uint8_t DJI::OSDK::ErrorCode::MFIOACK::get::SUCCESS = 0x00;
|
||||||
|
// clang-format on
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/** @file dji_gimbal.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Gimbal API for OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_gimbal.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
DJI::OSDK::Gimbal::Gimbal(Vehicle* vehicle)
|
||||||
|
: vehicle(vehicle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DJI::OSDK::Gimbal::~Gimbal()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DJI::OSDK::Gimbal::setAngle(Gimbal::AngleData* data)
|
||||||
|
{
|
||||||
|
vehicle->protocolLayer->send(0, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Control::gimbalAngle,
|
||||||
|
(unsigned char*)data, sizeof(Gimbal::AngleData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DJI::OSDK::Gimbal::setSpeed(Gimbal::SpeedData* data)
|
||||||
|
{
|
||||||
|
data->reserved = 0x80;
|
||||||
|
vehicle->protocolLayer->send(0, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Control::gimbalSpeed,
|
||||||
|
(unsigned char*)data, sizeof(Gimbal::SpeedData));
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/** @file dji_hardware_sync.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Hardware Sync API for DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_hardware_sync.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
HardwareSync::HardwareSync(Vehicle* vehiclePtr)
|
||||||
|
: vehicle(vehiclePtr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardwareSync::setSyncFreq(uint32_t freqInHz, uint16_t tag)
|
||||||
|
{
|
||||||
|
SyncSettings data;
|
||||||
|
data.freq = freqInHz;
|
||||||
|
data.tag = tag;
|
||||||
|
startSync(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardwareSync::startSync(SyncSettings& data)
|
||||||
|
{
|
||||||
|
vehicle->protocolLayer->send(0, encrypt,
|
||||||
|
OpenProtocol::CMDSet::HardwareSync::broadcast,
|
||||||
|
&data, sizeof(data));
|
||||||
|
}
|
||||||
@@ -0,0 +1,469 @@
|
|||||||
|
/** @file dji_hotpoint.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Implementation of HotPoint (Point of Interest) Missions for DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_hotpoint.hpp"
|
||||||
|
#include "dji_mission_manager.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
HotpointMission::HotpointMission(Vehicle* vehicle)
|
||||||
|
: MissionBase(vehicle)
|
||||||
|
{
|
||||||
|
initData();
|
||||||
|
hotPointCallback.callback = 0;
|
||||||
|
hotPointCallback.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HotpointMission::~HotpointMission()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::initData()
|
||||||
|
{
|
||||||
|
hotPointData.version = 0;
|
||||||
|
|
||||||
|
/*! @todo find a method to replace these
|
||||||
|
hotPointData.height = api->getBroadcastData().pos.altitude;
|
||||||
|
hotPointData.longitude = api->getBroadcastData().pos.longitude;
|
||||||
|
hotPointData.latitude = api->getBroadcastData().pos.latitude;
|
||||||
|
*/
|
||||||
|
|
||||||
|
hotPointData.radius = 10;
|
||||||
|
hotPointData.yawRate = 15;
|
||||||
|
hotPointData.clockwise = 1;
|
||||||
|
hotPointData.startPoint = HotpointMission::VIEW_NEARBY;
|
||||||
|
hotPointData.yawMode = HotpointMission::YAW_INSIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HotPointSettings
|
||||||
|
HotpointMission::getData() const
|
||||||
|
{
|
||||||
|
return hotPointData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::start(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, encrypt, OpenProtocol::CMDSet::Mission::hotpointStart, &hotPointData,
|
||||||
|
sizeof(hotPointData), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::start(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, encrypt, OpenProtocol::CMDSet::Mission::hotpointStart, &hotPointData,
|
||||||
|
sizeof(hotPointData), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointStart, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::stop(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t zero = 0;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointStop,
|
||||||
|
&zero, sizeof(zero), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::stop(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t zero = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointStop,
|
||||||
|
&zero, sizeof(zero), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointStop, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::pause(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t data = 0;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::pause(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t data = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetPause, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::resume(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t data = 1;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::resume(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t data = 1;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetPause, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::updateYawRate(HotpointMission::YawRate& Data,
|
||||||
|
VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
hotPointData.yawRate = Data.yawRate;
|
||||||
|
hotPointData.clockwise = Data.clockwise ? 1 : 0;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointYawRate,
|
||||||
|
&Data, sizeof(Data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::updateYawRate(HotpointMission::YawRate& Data, int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
hotPointData.yawRate = Data.yawRate;
|
||||||
|
hotPointData.clockwise = Data.clockwise ? 1 : 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointYawRate,
|
||||||
|
&Data, sizeof(Data), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointYawRate, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::updateYawRate(float32_t yawRate, bool isClockwise,
|
||||||
|
VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
YawRate p;
|
||||||
|
p.yawRate = yawRate;
|
||||||
|
p.clockwise = isClockwise ? 1 : 0;
|
||||||
|
updateYawRate(p, callback, userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::updateRadius(float32_t meter, VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointRadius,
|
||||||
|
&meter, sizeof(meter), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::updateRadius(float32_t meter, int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointRadius,
|
||||||
|
&meter, sizeof(meter), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointRadius, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::resetYaw(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t zero = 0;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetYaw,
|
||||||
|
&zero, sizeof(zero), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::resetYaw(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t zero = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetYaw,
|
||||||
|
&zero, sizeof(zero), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointSetYaw, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::readData(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t zero = 0;
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointDownload,
|
||||||
|
&zero, sizeof(zero), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
HotpointMission::readData(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t zero = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointDownload,
|
||||||
|
&zero, sizeof(zero), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::hotpointDownload, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::startCallback(RecvContainer recvFrame, UserData userData)
|
||||||
|
{
|
||||||
|
HotpointMission* hp = (HotpointMission*)userData;
|
||||||
|
ACK::HotPointStartInternal hpStartInfo;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <=
|
||||||
|
sizeof(ACK::HotPointStartInternal))
|
||||||
|
{
|
||||||
|
hpStartInfo = recvFrame.recvData.hpStartACK;
|
||||||
|
|
||||||
|
DSTATUS("Start ack has max radius: %f, ACK 0x%X\n", hpStartInfo.maxRadius,
|
||||||
|
hpStartInfo.ack);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("ACK is exception, sequence %d\n", recvFrame.recvInfo.seqNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::readCallback(RecvContainer recvFrame, UserData userData)
|
||||||
|
{
|
||||||
|
HotpointMission* hp = (HotpointMission*)userData;
|
||||||
|
ACK::HotPointReadInternal hpReadInfo;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <=
|
||||||
|
sizeof(ACK::HotPointReadInternal))
|
||||||
|
{
|
||||||
|
hpReadInfo = recvFrame.recvData.hpReadACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("ACK is exception, sequence %d\n", recvFrame.recvInfo.seqNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
ack.info = recvFrame.recvInfo;
|
||||||
|
ack.data = hpReadInfo.ack;
|
||||||
|
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
|
||||||
|
DERROR("Decod ACK error 0x%X\n", hpReadInfo.ack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setHotpointCallback(VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
hotPointCallback.callback = callback;
|
||||||
|
hotPointCallback.userData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setData(HotPointSettings* data)
|
||||||
|
{
|
||||||
|
hotPointData = *data;
|
||||||
|
hotPointData.version = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setHotPoint(float64_t longitude, float64_t latitude,
|
||||||
|
float64_t altitude)
|
||||||
|
{
|
||||||
|
hotPointData.longitude = longitude;
|
||||||
|
hotPointData.latitude = latitude;
|
||||||
|
hotPointData.height = altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setHotPoint(Telemetry::GlobalPosition gps)
|
||||||
|
{
|
||||||
|
hotPointData.longitude = gps.longitude;
|
||||||
|
hotPointData.latitude = gps.latitude;
|
||||||
|
hotPointData.height = gps.altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setRadius(float64_t meter)
|
||||||
|
{
|
||||||
|
hotPointData.radius = meter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setYawRate(float32_t degree)
|
||||||
|
{
|
||||||
|
hotPointData.yawRate = degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setClockwise(bool isClockwise)
|
||||||
|
{
|
||||||
|
hotPointData.clockwise = isClockwise ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setCameraView(HotpointMission::View view)
|
||||||
|
{
|
||||||
|
hotPointData.startPoint = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HotpointMission::setYawMode(HotpointMission::YawMode mode)
|
||||||
|
{
|
||||||
|
hotPointData.yawMode = mode;
|
||||||
|
}
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
/** @file dji_mfio.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* MFIO API for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_mfio.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
MFIO::MFIO(Vehicle* vehicle)
|
||||||
|
{
|
||||||
|
this->vehicle = vehicle;
|
||||||
|
channelUsage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MFIO::~MFIO()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFIO::config(MFIO::MODE mode, CHANNEL channel, uint32_t defaultValue,
|
||||||
|
uint16_t freq, VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
InitData data;
|
||||||
|
if ((channelUsage & (1 << channel)) == 0)
|
||||||
|
{
|
||||||
|
// channelUsage |= (1 << channel);
|
||||||
|
data.channel = channel;
|
||||||
|
data.mode = mode;
|
||||||
|
data.value = defaultValue;
|
||||||
|
data.freq = freq;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)&MFIO::initCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, 0, OpenProtocol::CMDSet::MFIO::init, &data,
|
||||||
|
sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("channel already used 0x%X,0x%X", channelUsage, 1 << channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
MFIO::config(MFIO::MODE mode, CHANNEL channel, uint32_t defaultValue,
|
||||||
|
uint16_t freq, int wait_timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
InitData data;
|
||||||
|
|
||||||
|
if ((channelUsage & (1 << channel)) == 0)
|
||||||
|
{
|
||||||
|
// channelUsage |= (1 << channel);
|
||||||
|
data.channel = channel;
|
||||||
|
data.mode = mode;
|
||||||
|
data.value = defaultValue;
|
||||||
|
data.freq = freq;
|
||||||
|
DSTATUS("sent");
|
||||||
|
vehicle->protocolLayer->send(2, 0, OpenProtocol::CMDSet::MFIO::init, &data,
|
||||||
|
sizeof(data), 500, 2, false, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::MFIO::init, wait_timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("Channel already used 0x%X,0x%X", channelUsage, 1 << channel);
|
||||||
|
ack.info.cmd_set = OpenProtocol::CMDSet::mfio;
|
||||||
|
ack.data = 0xFF;
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFIO::initCallback(RecvContainer recvFrame, UserData data)
|
||||||
|
{
|
||||||
|
/* Comment out API_LOG until we have a nicer solution, or we update calback
|
||||||
|
* prototype
|
||||||
|
* DSTATUS( "MFIO initMFIOCallback");
|
||||||
|
*/
|
||||||
|
uint16_t ack_length =
|
||||||
|
recvFrame.recvInfo.len - static_cast<uint16_t>(Protocol::PackageMin);
|
||||||
|
uint8_t* ackPtr = recvFrame.recvData.raw_ack_array;
|
||||||
|
|
||||||
|
uint8_t errorFlag;
|
||||||
|
|
||||||
|
memcpy((uint8_t*)&errorFlag, ackPtr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFIO::setValue(MFIO::CHANNEL channel, uint32_t value, VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
|
||||||
|
SetData data;
|
||||||
|
data.channel = channel;
|
||||||
|
data.value = value;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)&MFIO::setValueCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, 0, OpenProtocol::CMDSet::MFIO::set, &data,
|
||||||
|
sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
MFIO::setValue(CHANNEL channel, uint32_t value, int wait_timeout)
|
||||||
|
{
|
||||||
|
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
SetData data;
|
||||||
|
data.channel = channel;
|
||||||
|
data.value = value;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, 0, OpenProtocol::CMDSet::MFIO::set, &data,
|
||||||
|
sizeof(data), 500, 2, false, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(OpenProtocol::CMDSet::MFIO::set,
|
||||||
|
wait_timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFIO::setValueCallback(RecvContainer recvFrame, UserData data)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t ack_length =
|
||||||
|
recvFrame.recvInfo.len - static_cast<uint16_t>(Protocol::PackageMin);
|
||||||
|
uint8_t* ackPtr = recvFrame.recvData.raw_ack_array;
|
||||||
|
|
||||||
|
uint8_t errorFlag;
|
||||||
|
|
||||||
|
memcpy((uint8_t*)&errorFlag, ackPtr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFIO::getValue(MFIO::CHANNEL channel, VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
|
||||||
|
GetData data;
|
||||||
|
data = channel;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)&MFIO::getValueCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, 0, OpenProtocol::CMDSet::MFIO::get, &data,
|
||||||
|
sizeof(data), 500, 3, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::MFIOGet
|
||||||
|
MFIO::getValue(CHANNEL channel, int wait_timeout)
|
||||||
|
{
|
||||||
|
ACK::MFIOGet ack;
|
||||||
|
|
||||||
|
GetData data;
|
||||||
|
data = channel;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, 0, OpenProtocol::CMDSet::MFIO::get, &data,
|
||||||
|
sizeof(data), 500, 3, false, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::MFIOGet*)vehicle->waitForACK(OpenProtocol::CMDSet::MFIO::get,
|
||||||
|
wait_timeout));
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFIO::getValueCallback(RecvContainer recvFrame, UserData data)
|
||||||
|
{
|
||||||
|
uint16_t ack_length =
|
||||||
|
recvFrame.recvInfo.len - static_cast<uint16_t>(Protocol::PackageMin);
|
||||||
|
uint8_t* ackPtr = recvFrame.recvData.raw_ack_array;
|
||||||
|
|
||||||
|
uint8_t result;
|
||||||
|
uint32_t value;
|
||||||
|
|
||||||
|
memcpy((uint8_t*)&result, ackPtr, 1);
|
||||||
|
memcpy((uint8_t*)&value, ackPtr + 1, 4);
|
||||||
|
|
||||||
|
DSTATUS("\n status: %d\n", result);
|
||||||
|
DSTATUS("\n value: %d\n", value);
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
/** @file dji_mission_manager.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Mission Manager API for DJI OSDK library
|
||||||
|
* @details This is a high-level abstraction for handling/chaining missions
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "dji_mission_manager.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
MissionManager::MissionManager(Vehicle* vehiclePtr)
|
||||||
|
: vehicle(vehiclePtr)
|
||||||
|
, wpMission(NULL)
|
||||||
|
, wayptCounter(0)
|
||||||
|
, hotptCounter(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MissionManager::~MissionManager()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < wayptCounter; ++i)
|
||||||
|
{
|
||||||
|
delete wpMissionArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < hotptCounter; ++i)
|
||||||
|
{
|
||||||
|
delete hpMissionArray[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
MissionManager::init(DJI_MISSION_TYPE type, int timeout, UserData missionData)
|
||||||
|
{
|
||||||
|
if (type == WAYPOINT)
|
||||||
|
{
|
||||||
|
return this->initWayptMission(timeout, missionData);
|
||||||
|
}
|
||||||
|
else if (type == HOTPOINT)
|
||||||
|
{
|
||||||
|
return this->initHotptMission(timeout, missionData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("Cannot recognize the mission type provided\n");
|
||||||
|
// @todo return a false ack
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
ack.data = false;
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MissionManager::init(DJI_MISSION_TYPE type, VehicleCallBack callback,
|
||||||
|
UserData missionData)
|
||||||
|
{
|
||||||
|
if (type == WAYPOINT)
|
||||||
|
{
|
||||||
|
this->initWayptMission(callback, missionData);
|
||||||
|
}
|
||||||
|
else if (type == HOTPOINT)
|
||||||
|
{
|
||||||
|
// @note hotpoint init() doesn't have blocking calls, timeout use 10
|
||||||
|
this->initHotptMission(10, missionData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("Cannot recognize the mission type provided\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
MissionManager::initWayptMission(int timeout, UserData wayptData)
|
||||||
|
{
|
||||||
|
|
||||||
|
wpMissionArray[wayptCounter] = new WaypointMission(this->vehicle);
|
||||||
|
wpMission = wpMissionArray[wayptCounter];
|
||||||
|
wayptCounter++;
|
||||||
|
|
||||||
|
// @todo timeout needs to be defined somewhere globally
|
||||||
|
return wpMission->init((WayPointInitSettings*)wayptData, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MissionManager::initWayptMission(VehicleCallBack callback, UserData wayptData)
|
||||||
|
{
|
||||||
|
wpMissionArray[wayptCounter] = new WaypointMission(this->vehicle);
|
||||||
|
wpMission = wpMissionArray[wayptCounter];
|
||||||
|
wayptCounter++;
|
||||||
|
|
||||||
|
wpMission->init((WayPointInitSettings*)wayptData, callback, wayptData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
MissionManager::initHotptMission(int timeout, UserData hotptData)
|
||||||
|
{
|
||||||
|
|
||||||
|
hpMissionArray[hotptCounter] = new HotpointMission(this->vehicle);
|
||||||
|
hpMission = hpMissionArray[hotptCounter];
|
||||||
|
hotptCounter++;
|
||||||
|
|
||||||
|
if (hotptData)
|
||||||
|
{
|
||||||
|
hpMission->setData((HotPointSettings*)hotptData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hpMission->initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @todo this initData() does not return ack
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
ack.data = ACK::SUCCESS;
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MissionManager::initHotptMission(VehicleCallBack callback, UserData wayptData)
|
||||||
|
{
|
||||||
|
/*! @note hotpoint init() doesn't have blocking calls
|
||||||
|
* put it here for future uses
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MissionManager::missionCallback(Vehicle* vehiclePtr, RecvContainer recvFrame,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
char func[50];
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <= sizeof(ACK::ErrorCode))
|
||||||
|
{
|
||||||
|
ack.info = recvFrame.recvInfo;
|
||||||
|
ack.data = recvFrame.recvData.missionACK;
|
||||||
|
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("ACK is exception,sequence %d\n", recvFrame.recvInfo.seqNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WaypointMission*
|
||||||
|
MissionManager::getWaypt(int index)
|
||||||
|
{
|
||||||
|
if (index >= wayptCounter)
|
||||||
|
{
|
||||||
|
DERROR("The waypt index does not exist in Mission Manager\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wpMissionArray[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
HotpointMission*
|
||||||
|
MissionManager::getHotpt(int index)
|
||||||
|
{
|
||||||
|
if (index >= hotptCounter)
|
||||||
|
{
|
||||||
|
DERROR("The hotpt index does not exist in Mission Manager\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hpMissionArray[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MissionManager::printInfo()
|
||||||
|
{
|
||||||
|
DSTATUS("Mission Manager status: \n");
|
||||||
|
DSTATUS("There are %d waypt missions and %d hotpoint missions\n",
|
||||||
|
wayptCounter, hotptCounter);
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/** @file dji_mobile_communication.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Implementation of DJI Mobile-Onboard SDK Communication (MOC)
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_mobile_communication.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
MobileCommunication::MobileCommunication(Vehicle* vehicle)
|
||||||
|
: vehicle(vehicle)
|
||||||
|
{
|
||||||
|
this->fromMSDKHandler.callback = getDataFromMSDKCallback;
|
||||||
|
this->fromMSDKHandler.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MobileCommunication::~MobileCommunication()
|
||||||
|
{
|
||||||
|
this->fromMSDKHandler.callback = 0;
|
||||||
|
this->fromMSDKHandler.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vehicle*
|
||||||
|
MobileCommunication::getVehicle() const
|
||||||
|
{
|
||||||
|
return vehicle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MobileCommunication::setVehicle(Vehicle* value)
|
||||||
|
{
|
||||||
|
vehicle = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MobileCommunication::sendDataToMSDK(uint8_t* data, uint8_t len)
|
||||||
|
{
|
||||||
|
if (len > 100)
|
||||||
|
{
|
||||||
|
DERROR("Too much data to send");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vehicle->protocolLayer->send(0, 0, OpenProtocol::CMDSet::Activation::toMobile,
|
||||||
|
data, len, 500, 1, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MobileCommunication::getDataFromMSDKCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer recvFrame,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <= 100)
|
||||||
|
{
|
||||||
|
DSTATUS("Received mobile Data of len %d\n", recvFrame.recvInfo.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MobileCommunication::setFromMSDKCallback(VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
this->fromMSDKHandler.callback = callback;
|
||||||
|
this->fromMSDKHandler.userData = userData;
|
||||||
|
}
|
||||||
@@ -0,0 +1,658 @@
|
|||||||
|
/** @file dji_subscription.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Telemetry Subscription API for DJI OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_subscription.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
using namespace DJI::OSDK::Telemetry;
|
||||||
|
const uint8_t ADD_PACKAEG_DATA_LENGTH = 200;
|
||||||
|
const uint32_t DBVersion = 0x00000100;
|
||||||
|
//
|
||||||
|
// @note: make sure the order of entry is the same as in the enum TopicName
|
||||||
|
// definition
|
||||||
|
//
|
||||||
|
// clang-format off
|
||||||
|
TopicInfo Telemetry::TopicDataBase[] =
|
||||||
|
{ // Topic Name , UID,
|
||||||
|
{TOPIC_QUATERNION , UID_QUATERNION , sizeof(TypeMap<TOPIC_QUATERNION >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_ACCELERATION_GROUND , UID_ACCELERATION_GROUND , sizeof(TypeMap<TOPIC_ACCELERATION_GROUND >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_ACCELERATION_BODY , UID_ACCELERATION_BODY , sizeof(TypeMap<TOPIC_ACCELERATION_BODY >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_ACCELERATION_RAW , UID_ACCELERATION_RAW , sizeof(TypeMap<TOPIC_ACCELERATION_RAW >::type), 400 , 0, 255, 0},
|
||||||
|
{TOPIC_VELOCITY , UID_VELOCITY , sizeof(TypeMap<TOPIC_VELOCITY >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_ANGULAR_RATE_FUSIONED , UID_ANGULAR_RATE_FUSIONED , sizeof(TypeMap<TOPIC_ANGULAR_RATE_FUSIONED >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_ANGULAR_RATE_RAW , UID_ANGULAR_RATE_RAW , sizeof(TypeMap<TOPIC_ANGULAR_RATE_RAW >::type), 400 , 0, 255, 0},
|
||||||
|
{TOPIC_ALTITUDE_FUSIONED , UID_ALTITUDE_FUSIONED , sizeof(TypeMap<TOPIC_ALTITUDE_FUSIONED >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_ALTITUDE_BAROMETER , UID_ALTITUDE_BAROMETER , sizeof(TypeMap<TOPIC_ALTITUDE_BAROMETER >::type), 200 , 0, 255, 0},
|
||||||
|
{TOPIC_HEIGHT_HOMEPOOINT , UID_HEIGHT_HOMEPOOINT , sizeof(TypeMap<TOPIC_HEIGHT_HOMEPOOINT >::type), 1 , 0, 255, 0},
|
||||||
|
{TOPIC_HEIGHT_FUSION , UID_HEIGHT_FUSION , sizeof(TypeMap<TOPIC_HEIGHT_FUSION >::type), 100 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_FUSED , UID_GPS_FUSED , sizeof(TypeMap<TOPIC_GPS_FUSED >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_DATE , UID_GPS_DATE , sizeof(TypeMap<TOPIC_GPS_DATE >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_TIME , UID_GPS_TIME , sizeof(TypeMap<TOPIC_GPS_TIME >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_POSITION , UID_GPS_POSITION , sizeof(TypeMap<TOPIC_GPS_POSITION >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_VELOCITY , UID_GPS_VELOCITY , sizeof(TypeMap<TOPIC_GPS_VELOCITY >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_DETAILS , UID_GPS_DETAILS , sizeof(TypeMap<TOPIC_GPS_DETAILS >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_RTK_POSITION , UID_RTK_POSITION , sizeof(TypeMap<TOPIC_RTK_POSITION >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_RTK_VELOCITY , UID_RTK_VELOCITY , sizeof(TypeMap<TOPIC_RTK_VELOCITY >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_RTK_YAW , UID_RTK_YAW , sizeof(TypeMap<TOPIC_RTK_YAW >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_RTK_POSITION_INFO , UID_RTK_POSITION_INFO , sizeof(TypeMap<TOPIC_RTK_POSITION_INFO >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_RTK_YAW_INFO , UID_RTK_YAW_INFO , sizeof(TypeMap<TOPIC_RTK_YAW_INFO >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_COMPASS , UID_COMPASS , sizeof(TypeMap<TOPIC_COMPASS >::type), 100 , 0, 255, 0},
|
||||||
|
{TOPIC_RC , UID_RC , sizeof(TypeMap<TOPIC_RC >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GIMBAL_ANGLES , UID_GIMBAL_ANGLES , sizeof(TypeMap<TOPIC_GIMBAL_ANGLES >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GIMBAL_STATUS , UID_GIMBAL_STATUS , sizeof(TypeMap<TOPIC_GIMBAL_STATUS >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_STATUS_FLIGHT , UID_STATUS_FLIGHT , sizeof(TypeMap<TOPIC_STATUS_FLIGHT >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_STATUS_DISPLAYMODE , UID_STATUS_DISPLAYMODE , sizeof(TypeMap<TOPIC_STATUS_DISPLAYMODE >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_STATUS_LANDINGGEAR , UID_STATUS_LANDINGGEAR , sizeof(TypeMap<TOPIC_STATUS_LANDINGGEAR >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_STATUS_MOTOR_START_ERROR , UID_STATUS_MOTOR_START_ERROR , sizeof(TypeMap<TOPIC_STATUS_MOTOR_START_ERROR>::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_BATTERY_INFO , UID_BATTERY_INFO , sizeof(TypeMap<TOPIC_BATTERY_INFO >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_CONTROL_DEVICE , UID_CONTROL_DEVICE , sizeof(TypeMap<TOPIC_CONTROL_DEVICE >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_HARD_SYNC , UID_HARD_SYNC , sizeof(TypeMap<TOPIC_HARD_SYNC >::type), 400 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_SIGNAL_LEVEL , UID_GPS_SIGNAL_LEVEL , sizeof(TypeMap<TOPIC_GPS_SIGNAL_LEVEL >::type), 50 , 0, 255, 0},
|
||||||
|
{TOPIC_GPS_CONTROL_LEVEL , UID_GPS_CONTROL_LEVEL , sizeof(TypeMap<TOPIC_GPS_CONTROL_LEVEL >::type), 50 , 0, 255, 0}
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @details 1. Initialize the api member
|
||||||
|
* 2. Set each package[i] entry with packageID = i
|
||||||
|
* 3. Set the decodeCallback function
|
||||||
|
*/
|
||||||
|
DataSubscription::DataSubscription(Vehicle* vehiclePtr)
|
||||||
|
: vehicle(vehiclePtr)
|
||||||
|
, protocol(vehicle->protocolLayer)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MAX_NUMBER_OF_PACKAGE; i++)
|
||||||
|
{
|
||||||
|
package[i].setPackageID(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
subscriptionDataDecodeHandler.callback = decodeCallback;
|
||||||
|
subscriptionDataDecodeHandler.userData = this;
|
||||||
|
// protocol->setSubscribeCallback(decodeCallback, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSubscription::~DataSubscription()
|
||||||
|
{
|
||||||
|
// protocol->setSubscribeCallback(NULL, NULL);
|
||||||
|
subscriptionDataDecodeHandler.callback = 0;
|
||||||
|
subscriptionDataDecodeHandler.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vehicle*
|
||||||
|
DataSubscription::getVehicle()
|
||||||
|
{
|
||||||
|
return vehicle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @details: decodeCallback is a static function and cannot access object
|
||||||
|
* member.
|
||||||
|
* In order to access members, it needs a pointer to the
|
||||||
|
* subscription.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
DataSubscription::decodeCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer rcvContainer, UserData subPtr)
|
||||||
|
{
|
||||||
|
DataSubscription* subscriptionHandle = (DataSubscription*)subPtr;
|
||||||
|
|
||||||
|
// uint8_t pkgID = *(((uint8_t *)header) + sizeof(Header) + 2);
|
||||||
|
uint8_t pkgID = rcvContainer.recvData.subscribeACK;
|
||||||
|
|
||||||
|
if (pkgID >= MAX_NUMBER_OF_PACKAGE)
|
||||||
|
{
|
||||||
|
DERROR("Unexpected package id %d received.", pkgID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SubscriptionPackage* p = &subscriptionHandle->package[pkgID];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: handle the case that the FC is already sending subscription packages
|
||||||
|
* when the program starts,
|
||||||
|
*/
|
||||||
|
|
||||||
|
subscriptionHandle->extractOnePackage(&rcvContainer, p);
|
||||||
|
|
||||||
|
VehicleCallBackHandler h = p->getUnpackHandler();
|
||||||
|
if (NULL != h.callback)
|
||||||
|
{
|
||||||
|
(*(h.callback))(vehiclePtr, rcvContainer, h.userData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @details Setup members of package[packageID]
|
||||||
|
* Do basic gate keeping. No api->send call involved
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
DataSubscription::initPackageFromTopicList(int packageID, int numberOfTopics,
|
||||||
|
TopicName* topicList,
|
||||||
|
bool sendTimeStamp, uint16_t freq)
|
||||||
|
{
|
||||||
|
if (package[packageID].isOccupied())
|
||||||
|
{
|
||||||
|
DERROR("package [%d] is being occupied.", packageID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
package[packageID].setConfig(sendTimeStamp ? 1 : 0);
|
||||||
|
return package[packageID].setTopicList(topicList, numberOfTopics, freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::registerUserPackageUnpackCallback(
|
||||||
|
int packageID, VehicleCallBack userFunctionAfterPackageExtraction,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
package[packageID].setUserUnpackCallback(userFunctionAfterPackageExtraction,
|
||||||
|
userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DataSubscription::pausePackage(int packageID)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DataSubscription::resumePackage(int packageID)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::verify()
|
||||||
|
{
|
||||||
|
uint32_t data = DBVersion;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)verifyCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
|
||||||
|
protocol->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Subscribe::versionMatch, &data,
|
||||||
|
sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::verifyCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer rcvContainer, UserData userData)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ackErrorCode;
|
||||||
|
ackErrorCode.info = rcvContainer.recvInfo;
|
||||||
|
ackErrorCode.data = rcvContainer.recvData.subscribeACK;
|
||||||
|
|
||||||
|
DSTATUS("Verify result: %d.", ackErrorCode.data);
|
||||||
|
|
||||||
|
if (ACK::getError(ackErrorCode))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ackErrorCode, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
DataSubscription::verify(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint32_t data = DBVersion;
|
||||||
|
|
||||||
|
protocol->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Subscribe::versionMatch, &data,
|
||||||
|
sizeof(data), 500, 2, NULL, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)getVehicle()->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Subscribe::versionMatch, timeout));
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::startPackage(int packageID)
|
||||||
|
{
|
||||||
|
// We need to prevent running startPackage multiple times
|
||||||
|
// The reason is that allocateDataBuffer will delete and reallocating the
|
||||||
|
// memory
|
||||||
|
// During this period, data will be copied to illegal memory
|
||||||
|
if (package[packageID].isOccupied())
|
||||||
|
{
|
||||||
|
DERROR("Cannot start package [%d] which "
|
||||||
|
"is being occupied. Call "
|
||||||
|
"removePackage first.",
|
||||||
|
packageID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buffer[ADD_PACKAEG_DATA_LENGTH];
|
||||||
|
|
||||||
|
int bufferLength = package[packageID].serializePackageInfo(buffer);
|
||||||
|
package[packageID].allocateDataBuffer();
|
||||||
|
|
||||||
|
// Register Callback
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)DataSubscription::addPackageCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = &package[packageID];
|
||||||
|
|
||||||
|
protocol->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Subscribe::addPackage, buffer,
|
||||||
|
bufferLength, 500, 1, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::addPackageCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer rcvContainer,
|
||||||
|
UserData pkgHandle)
|
||||||
|
{
|
||||||
|
// First, check ACK value
|
||||||
|
SubscriptionPackage* packageHandle = (SubscriptionPackage*)pkgHandle;
|
||||||
|
|
||||||
|
ACK::ErrorCode ackErrorCode;
|
||||||
|
ackErrorCode.info = rcvContainer.recvInfo;
|
||||||
|
ackErrorCode.data = rcvContainer.recvData.subscribeACK;
|
||||||
|
|
||||||
|
DSTATUS("Start package %d result: %d.", packageHandle->getInfo().packageID,
|
||||||
|
ackErrorCode.data);
|
||||||
|
DSTATUS("Package %d info: freq=%d, nTopics=%d.",
|
||||||
|
packageHandle->getInfo().packageID, packageHandle->getInfo().freq,
|
||||||
|
packageHandle->getInfo().numberOfTopics);
|
||||||
|
if (!ACK::getError(ackErrorCode))
|
||||||
|
{
|
||||||
|
packageHandle->packageAddSuccessHandler();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ackErrorCode, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
DataSubscription::startPackage(int packageID, int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
// We need to prevent running startPackage multiple times
|
||||||
|
// The reason is that allocateDataBuffer will delete and reallocating the
|
||||||
|
// memory
|
||||||
|
// During this period, data will be copied to illegal memory
|
||||||
|
if (package[packageID].isOccupied())
|
||||||
|
{
|
||||||
|
DERROR("Cannot start package [%d] which "
|
||||||
|
"is being occupied. Call "
|
||||||
|
"removePackage first.",
|
||||||
|
packageID);
|
||||||
|
|
||||||
|
ack.info.cmd_set = OpenProtocol::CMDSet::subscribe;
|
||||||
|
|
||||||
|
// @TODO: the SUBSCRIBER_MULTIPLE_SUBSCRIBE is not returned from FC, we may
|
||||||
|
// need to distinguish between "short circuit return" from "round trip
|
||||||
|
// return"
|
||||||
|
ack.data = OpenProtocol::ErrorCode::SubscribeACK::MULTIPLE_SUBSCRIBE;
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buffer[ADD_PACKAEG_DATA_LENGTH];
|
||||||
|
|
||||||
|
int bufferLength = package[packageID].serializePackageInfo(buffer);
|
||||||
|
package[packageID].allocateDataBuffer();
|
||||||
|
|
||||||
|
protocol->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Subscribe::addPackage, buffer,
|
||||||
|
bufferLength, 500, 1, NULL, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)getVehicle()->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Subscribe::addPackage, timeout));
|
||||||
|
|
||||||
|
DSTATUS("Start package %d result: %d.",
|
||||||
|
package[packageID].getInfo().packageID, ack.data);
|
||||||
|
DSTATUS("Package %d info: freq=%d, nTopics=%d.",
|
||||||
|
package[packageID].getInfo().packageID,
|
||||||
|
package[packageID].getInfo().freq,
|
||||||
|
package[packageID].getInfo().numberOfTopics);
|
||||||
|
|
||||||
|
if (!ACK::getError(ack))
|
||||||
|
{
|
||||||
|
package[packageID].packageAddSuccessHandler();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO Remove. User should do it on the application side
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
// todo: More clean-up?
|
||||||
|
}
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// adapted from DataSubscribe::Package::unpack
|
||||||
|
void
|
||||||
|
DataSubscription::extractOnePackage(RecvContainer* pRcvContainer,
|
||||||
|
SubscriptionPackage* pkg)
|
||||||
|
{
|
||||||
|
// uint8_t *data = ((uint8_t *)header) + sizeof(Header) + 2;
|
||||||
|
// DDEBUG(
|
||||||
|
// "%d unpacking %d %d 0x%x 0x%x.", pkg->getBufferSize(),
|
||||||
|
// header->length - CoreAPI::PackageMin - 3, *((uint8_t *)data + 1),
|
||||||
|
// *((uint32_t *)data), *((uint32_t *)data + 1));
|
||||||
|
// data++;
|
||||||
|
|
||||||
|
uint8_t* data = pRcvContainer->recvData.raw_ack_array;
|
||||||
|
data++; // skip the package ID
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Handle the time stamp field if it exists
|
||||||
|
*/
|
||||||
|
|
||||||
|
protocol->getThreadHandle()->lockMSG();
|
||||||
|
if (pkg->getDataBuffer())
|
||||||
|
{
|
||||||
|
// TODO: the length needs to come from the header, not package
|
||||||
|
memcpy(pkg->getDataBuffer(), data, pkg->getBufferSize());
|
||||||
|
// memcpy(pkg->getDataBuffer(), data, header->length - CoreAPI::PackageMin -
|
||||||
|
// 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("Package does not have a valid DataBuffer");
|
||||||
|
}
|
||||||
|
protocol->getThreadHandle()->freeMSG();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::removePackage(int packageID)
|
||||||
|
{
|
||||||
|
uint8_t data = packageID;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)DataSubscription::removePackageCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = &package[packageID];
|
||||||
|
|
||||||
|
protocol->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Subscribe::removePackage, &data,
|
||||||
|
sizeof(data), 500, 1, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DataSubscription::removePackageCallback(Vehicle* vehiclePtr,
|
||||||
|
RecvContainer rcvContainer,
|
||||||
|
UserData pkgHandle)
|
||||||
|
{
|
||||||
|
SubscriptionPackage* packageHandle = (SubscriptionPackage*)pkgHandle;
|
||||||
|
|
||||||
|
uint8_t packageID = packageHandle->getInfo().packageID;
|
||||||
|
|
||||||
|
ACK::ErrorCode ackErrorCode;
|
||||||
|
ackErrorCode.info = rcvContainer.recvInfo;
|
||||||
|
ackErrorCode.data = rcvContainer.recvData.subscribeACK;
|
||||||
|
|
||||||
|
if (!ACK::getError(ackErrorCode))
|
||||||
|
{
|
||||||
|
DSTATUS("Remove package %d successful.", packageID);
|
||||||
|
packageHandle->packageRemoveSuccessHandler();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ackErrorCode, __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
DataSubscription::removePackage(int packageID, int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t data = packageID;
|
||||||
|
|
||||||
|
protocol->send(2, DJI::OSDK::encrypt,
|
||||||
|
OpenProtocol::CMDSet::Subscribe::removePackage, &data,
|
||||||
|
sizeof(data), 500, 1, NULL, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)getVehicle()->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Subscribe::removePackage, timeout));
|
||||||
|
|
||||||
|
if (!ACK::getError(ack))
|
||||||
|
{
|
||||||
|
DSTATUS("Remove package %d successful.", packageID);
|
||||||
|
package[packageID].packageRemoveSuccessHandler();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
SubscriptionPackage::SubscriptionPackage()
|
||||||
|
: occupied(false)
|
||||||
|
, incomingDataBuffer(NULL)
|
||||||
|
, packageDataSize(0)
|
||||||
|
{
|
||||||
|
userUnpackHandler.callback = NULL;
|
||||||
|
userUnpackHandler.userData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SubscriptionPackage::~SubscriptionPackage()
|
||||||
|
{
|
||||||
|
cleanUpPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::setPackageID(uint8_t id)
|
||||||
|
{
|
||||||
|
info.packageID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::setConfig(uint8_t config)
|
||||||
|
{
|
||||||
|
info.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SubscriptionPackage::isOccupied()
|
||||||
|
{
|
||||||
|
return occupied;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::setOccupied(bool status)
|
||||||
|
{
|
||||||
|
occupied = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in the necessary information for ADD_PACKAGE call
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
SubscriptionPackage::setTopicList(TopicName* topics, int numberOfTopics,
|
||||||
|
uint16_t freq)
|
||||||
|
{
|
||||||
|
if (isOccupied())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// It's not simply copy entries of topics to topicList. Two Details needs to
|
||||||
|
// be taken care of:
|
||||||
|
// 1. Make sure the frequency is valid, i.e., less than the max frequency for
|
||||||
|
// each topic
|
||||||
|
// 2. The total data payload does not exceed limit
|
||||||
|
int totalSize = (info.config == 1) ? 8 : 0;
|
||||||
|
for (int i = 0; i < numberOfTopics; i++)
|
||||||
|
{
|
||||||
|
if (TopicDataBase[topics[i]].maxFreq < freq)
|
||||||
|
{
|
||||||
|
DDEBUG("Requesting Frequency %d, Max Frequency %d\n", freq,
|
||||||
|
TopicDataBase[topics[i]].maxFreq);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
totalSize += TopicDataBase[topics[i]].size;
|
||||||
|
if (totalSize > ADD_PACKAEG_DATA_LENGTH)
|
||||||
|
{
|
||||||
|
DDEBUG(
|
||||||
|
"Too many topics, data payload of the first %d topic is already %d", i,
|
||||||
|
totalSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After passing the above 2 checks, we are safe to fill the data fields
|
||||||
|
packageDataSize = (info.config == 1) ? 8 : 0;
|
||||||
|
info.numberOfTopics = numberOfTopics;
|
||||||
|
info.freq = freq;
|
||||||
|
|
||||||
|
for (int i = 0; i < numberOfTopics; i++)
|
||||||
|
{
|
||||||
|
offsetList[i] = packageDataSize;
|
||||||
|
topicList[i] = topics[i];
|
||||||
|
uidList[i] = TopicDataBase[topicList[i]].uid;
|
||||||
|
packageDataSize += TopicDataBase[topicList[i]].size;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::allocateDataBuffer()
|
||||||
|
{
|
||||||
|
if (incomingDataBuffer)
|
||||||
|
{
|
||||||
|
delete incomingDataBuffer;
|
||||||
|
incomingDataBuffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
incomingDataBuffer = new uint8_t[packageDataSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::cleanUpPackage()
|
||||||
|
{
|
||||||
|
info.freq = 0;
|
||||||
|
info.config = 0;
|
||||||
|
info.numberOfTopics = 0;
|
||||||
|
|
||||||
|
memset(uidList, 0xFF, sizeof(uidList));
|
||||||
|
memset(topicList, 0xFF, sizeof(topicList));
|
||||||
|
memset(offsetList, 0, sizeof(offsetList));
|
||||||
|
|
||||||
|
packageDataSize = 0;
|
||||||
|
userUnpackHandler.callback = NULL;
|
||||||
|
userUnpackHandler.userData = NULL;
|
||||||
|
clearDataBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::clearDataBuffer()
|
||||||
|
{
|
||||||
|
if (incomingDataBuffer)
|
||||||
|
{
|
||||||
|
delete incomingDataBuffer;
|
||||||
|
incomingDataBuffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SubscriptionPackage::serializePackageInfo(uint8_t* buffer)
|
||||||
|
{
|
||||||
|
// First, copy the info part of the package
|
||||||
|
memcpy(buffer, (uint8_t*)&info, sizeof(info));
|
||||||
|
|
||||||
|
// Next copy the uid list
|
||||||
|
memcpy(buffer + sizeof(PackageInfo), (uint8_t*)uidList,
|
||||||
|
sizeof(uint32_t) * info.numberOfTopics);
|
||||||
|
|
||||||
|
return sizeof(info) + sizeof(uint32_t) * info.numberOfTopics;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::setUserUnpackCallback(
|
||||||
|
VehicleCallBack userFunctionAfterPackageExtraction, UserData userData)
|
||||||
|
{
|
||||||
|
userUnpackHandler.callback = userFunctionAfterPackageExtraction;
|
||||||
|
userUnpackHandler.userData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
SubscriptionPackage::PackageInfo
|
||||||
|
SubscriptionPackage::getInfo()
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t*
|
||||||
|
SubscriptionPackage::getUidList()
|
||||||
|
{
|
||||||
|
return &uidList[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
TopicName*
|
||||||
|
SubscriptionPackage::getTopicList()
|
||||||
|
{
|
||||||
|
return &topicList[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t*
|
||||||
|
SubscriptionPackage::getOffsetList()
|
||||||
|
{
|
||||||
|
return &offsetList[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t*
|
||||||
|
SubscriptionPackage::getDataBuffer()
|
||||||
|
{
|
||||||
|
return incomingDataBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
SubscriptionPackage::getBufferSize()
|
||||||
|
{
|
||||||
|
return packageDataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleCallBackHandler
|
||||||
|
SubscriptionPackage::getUnpackHandler()
|
||||||
|
{
|
||||||
|
return userUnpackHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::packageAddSuccessHandler()
|
||||||
|
{
|
||||||
|
// In the TopicDataBase, we set the freq, protocoland data pointer for each
|
||||||
|
// subscribed topic
|
||||||
|
for (size_t i = 0; i < info.numberOfTopics; ++i)
|
||||||
|
{
|
||||||
|
TopicDataBase[topicList[i]].pkgID = info.packageID;
|
||||||
|
TopicDataBase[topicList[i]].freq = info.freq;
|
||||||
|
|
||||||
|
// The offset already takes time stamp into consideration
|
||||||
|
TopicDataBase[topicList[i]].latest = incomingDataBuffer + offsetList[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
setOccupied(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SubscriptionPackage::packageRemoveSuccessHandler()
|
||||||
|
{
|
||||||
|
// Clean up
|
||||||
|
// Step 1. Clear fields in TopicDataBase
|
||||||
|
for (size_t i = 0; i < info.numberOfTopics; ++i)
|
||||||
|
{
|
||||||
|
TopicDataBase[topicList[i]].freq = 0;
|
||||||
|
TopicDataBase[topicList[i]].pkgID = 255; // Set pkgID to invalid
|
||||||
|
TopicDataBase[topicList[i]].latest = NULL; // Clear data pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2. Clean up package content, except packageID
|
||||||
|
cleanUpPackage();
|
||||||
|
|
||||||
|
setOccupied(false);
|
||||||
|
}
|
||||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,27 @@
|
|||||||
|
/*! @file dji_version.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Drone/SDK Version definition for DJI onboardSDK library
|
||||||
|
*
|
||||||
|
* @note Since OSDK 3.2.2 (Feb 2017), versioning is handled by the SDK.
|
||||||
|
* You can use the Version::FW macro to target your code towards specific
|
||||||
|
* platforms/firmware.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* Copyright 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "dji_version.hpp"
|
||||||
|
#include "dji_open_protocol.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
const Version::FirmWare
|
||||||
|
Version::FW(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
|
||||||
|
{
|
||||||
|
return (((a << 24) & 0xff000000) | ((b << 16) & 0x00ff0000) |
|
||||||
|
((c << 8) & 0x0000ff00) | (d & 0x000000ff));
|
||||||
|
}
|
||||||
@@ -0,0 +1,493 @@
|
|||||||
|
/** @file dji_waypoint.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief Implementation of GPS Waypoint Missions for DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_waypoint.hpp"
|
||||||
|
#include "dji_mission_manager.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
WaypointMission::WaypointMission(Vehicle* vehicle)
|
||||||
|
: MissionBase(vehicle)
|
||||||
|
, index(NULL)
|
||||||
|
{
|
||||||
|
wayPointEventCallback.callback = 0;
|
||||||
|
wayPointEventCallback.userData = 0;
|
||||||
|
wayPointCallback.callback = 0;
|
||||||
|
wayPointCallback.userData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WaypointMission::~WaypointMission()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::init(WayPointInitSettings* Info, VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
if (Info)
|
||||||
|
setInfo(*Info);
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointInit,
|
||||||
|
&info, sizeof(info), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
WaypointMission::init(WayPointInitSettings* Info, int timeout)
|
||||||
|
{
|
||||||
|
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
if (Info)
|
||||||
|
{
|
||||||
|
setInfo(*Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointInit,
|
||||||
|
&info, sizeof(info), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointInit, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::start(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t start = 0;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetStart,
|
||||||
|
&start, sizeof(start), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
WaypointMission::start(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t start = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetStart,
|
||||||
|
&start, sizeof(start), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetStart, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::stop(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t stop = 1;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetStart,
|
||||||
|
&stop, sizeof(stop), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
WaypointMission::stop(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t stop = 1;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetStart,
|
||||||
|
&stop, sizeof(stop), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetStart, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::pause(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t data = 0;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
WaypointMission::pause(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t data = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetPause, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::resume(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t data = 1;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&MissionManager::missionCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
WaypointMission::resume(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t data = 1;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetPause,
|
||||||
|
&data, sizeof(data), 500, 2, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetPause, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
WayPointInitSettings
|
||||||
|
WaypointMission::getInfo() const
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::setInfo(const WayPointInitSettings& value)
|
||||||
|
{
|
||||||
|
//! @todo set information for way point
|
||||||
|
info = value;
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
info.reserved[i] = 0;
|
||||||
|
|
||||||
|
// TODO this might affect something, don't delete it yet for future debug use
|
||||||
|
//#ifndef STATIC_MEMORY
|
||||||
|
// if (index != 0) delete index;
|
||||||
|
// index = 0;
|
||||||
|
//#else
|
||||||
|
// if (maxIndex < info.indexNumber) index = 0;
|
||||||
|
//#endif // STATIC_MEMORY
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::setIndex(WayPointSettings* value, size_t pos)
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
index = new WayPointSettings[info.indexNumber];
|
||||||
|
if (index == NULL)
|
||||||
|
{
|
||||||
|
DERROR("Lack of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index[pos] = *value;
|
||||||
|
for (int i = 0; i < 8; ++i)
|
||||||
|
index[pos].reserved[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WayPointSettings*
|
||||||
|
WaypointMission::getIndex() const
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
WayPointSettings*
|
||||||
|
WaypointMission::getIndex(size_t pos) const
|
||||||
|
{
|
||||||
|
return &(index[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WaypointMission::uploadIndexData(WayPointSettings* data,
|
||||||
|
VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
setIndex(data, data->index);
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&WaypointMission::uploadIndexDataCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
WayPointSettings send;
|
||||||
|
if (data->index < info.indexNumber)
|
||||||
|
send = index[data->index];
|
||||||
|
else
|
||||||
|
return false; //! @note range error
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointAddPoint,
|
||||||
|
&send, sizeof(send), 1000, 4, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::WayPointIndex
|
||||||
|
WaypointMission::uploadIndexData(WayPointSettings* data, int timeout)
|
||||||
|
{
|
||||||
|
WayPointSettings wpData;
|
||||||
|
ACK::WayPointIndex ack;
|
||||||
|
|
||||||
|
setIndex(data, data->index);
|
||||||
|
|
||||||
|
if (data->index < info.indexNumber)
|
||||||
|
{
|
||||||
|
wpData = index[data->index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO add error handling
|
||||||
|
DERROR("Range error\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(2, encrypt,
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointAddPoint,
|
||||||
|
&wpData, sizeof(wpData), 1000, 4, false, 2);
|
||||||
|
|
||||||
|
ack = *((ACK::WayPointIndex*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointAddPoint, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::readIdleVelocity(VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
uint8_t zero = 0;
|
||||||
|
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&WaypointMission::idleVelocityCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, encrypt, OpenProtocol::CMDSet::Mission::waypointGetVelocity, &zero,
|
||||||
|
sizeof(zero), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode
|
||||||
|
WaypointMission::readIdleVelocity(int timeout)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint8_t zero = 0;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, encrypt, OpenProtocol::CMDSet::Mission::waypointGetVelocity, &zero,
|
||||||
|
sizeof(zero), 500, 2, false, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::ErrorCode*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointGetVelocity, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::updateIdleVelocity(float32_t meterPreSecond,
|
||||||
|
VehicleCallBack callback, UserData userData)
|
||||||
|
{
|
||||||
|
int cbIndex = vehicle->callbackIdIndex();
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] = (void*)callback;
|
||||||
|
vehicle->nbUserData[cbIndex] = userData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vehicle->nbCallbackFunctions[cbIndex] =
|
||||||
|
(void*)&WaypointMission::idleVelocityCallback;
|
||||||
|
vehicle->nbUserData[cbIndex] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, encrypt, OpenProtocol::CMDSet::Mission::waypointSetVelocity,
|
||||||
|
&meterPreSecond, sizeof(meterPreSecond), 500, 2, true, cbIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::WayPointVelocity
|
||||||
|
WaypointMission::updateIdleVelocity(float32_t meterPreSecond, int timeout)
|
||||||
|
{
|
||||||
|
ACK::WayPointVelocity ack;
|
||||||
|
|
||||||
|
vehicle->protocolLayer->send(
|
||||||
|
2, encrypt, OpenProtocol::CMDSet::Mission::waypointSetVelocity,
|
||||||
|
&meterPreSecond, sizeof(meterPreSecond), 500, 2, false, 0);
|
||||||
|
|
||||||
|
ack = *((ACK::WayPointVelocity*)vehicle->waitForACK(
|
||||||
|
OpenProtocol::CMDSet::Mission::waypointSetVelocity, timeout));
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::idleVelocityCallback(Vehicle* vehicle, RecvContainer recvFrame,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
ACK::WayPointVelocityInternal wpIdleVelocityInfo;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <=
|
||||||
|
sizeof(ACK::WayPointVelocityInternal))
|
||||||
|
{
|
||||||
|
wpIdleVelocityInfo = recvFrame.recvData.wpVelocityACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("ACK is exception, sequence %d\n", recvFrame.recvInfo.seqNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
ack.data = wpIdleVelocityInfo.ack;
|
||||||
|
ack.info = recvFrame.recvInfo;
|
||||||
|
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
|
||||||
|
vehicle->missionManager->wpMission->info.idleVelocity =
|
||||||
|
wpIdleVelocityInfo.idleVelocity;
|
||||||
|
|
||||||
|
DSTATUS("Current idle velocity: %f\n",
|
||||||
|
vehicle->missionManager->wpMission->info.idleVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::uploadIndexDataCallback(Vehicle* vehicle,
|
||||||
|
RecvContainer recvFrame,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
ACK::WayPointDataInternal wpDataInfo;
|
||||||
|
|
||||||
|
if (recvFrame.recvInfo.len - Protocol::PackageMin <=
|
||||||
|
sizeof(ACK::WayPointDataInternal))
|
||||||
|
{
|
||||||
|
wpDataInfo = recvFrame.recvData.wpDataACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DERROR("ACK is exception, sequence %d\n", recvFrame.recvInfo.seqNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
ack.data = wpDataInfo.ack;
|
||||||
|
ack.info = recvFrame.recvInfo;
|
||||||
|
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
|
||||||
|
DSTATUS("Index number: %d\n", wpDataInfo.index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::setWaypointEventCallback(VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
wayPointEventCallback.callback = callback;
|
||||||
|
wayPointEventCallback.userData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaypointMission::setWaypointCallback(VehicleCallBack callback,
|
||||||
|
UserData userData)
|
||||||
|
{
|
||||||
|
wayPointCallback.callback = callback;
|
||||||
|
wayPointCallback.userData = userData;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# - Config file for the djiosdkcore package
|
||||||
|
# It defines the following variables
|
||||||
|
# DJIOSDK_INCLUDE_DIRS - include directories for djiosdk
|
||||||
|
# DJIOSDK_LIBRARIES - libraries to link against
|
||||||
|
|
||||||
|
# Compute paths
|
||||||
|
get_filename_component(DJIOSDK_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||||
|
set(DJIOSDK_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
|
||||||
|
|
||||||
|
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||||
|
include("${DJIOSDK_CMAKE_DIR}/djiosdkTargets.cmake")
|
||||||
|
|
||||||
|
# These are IMPORTED targets created by djiosdkTargets.cmake
|
||||||
|
set(DJIOSDK_LIBRARIES djiosdk-core)
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
set(PACKAGE_VERSION "@DJIOSDK_VERSION@")
|
||||||
|
|
||||||
|
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||||
|
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
else()
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||||
|
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||||
|
set(PACKAGE_VERSION_EXACT TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/*! @file dji_hard_driver.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Serial device driver abstraction. Provided as an abstract class. Please
|
||||||
|
* inherit and implement for individual platforms.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef DJI_HARDDRIVER_H
|
||||||
|
#define DJI_HARDDRIVER_H
|
||||||
|
|
||||||
|
#include "dji_log.hpp"
|
||||||
|
#include "dji_memory.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <ctime>
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
class HardDriver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HardDriver();
|
||||||
|
virtual ~HardDriver();
|
||||||
|
/*! @note How to use
|
||||||
|
* In order to provide platform crossable DJI onboardSDK library,
|
||||||
|
* we abstract this class as a hardware level.
|
||||||
|
*
|
||||||
|
* @note function descriptions:
|
||||||
|
*
|
||||||
|
* void init();
|
||||||
|
* @brief After calling this function, HardDriver should be able to
|
||||||
|
* read and send correctly, through a correct UART part.
|
||||||
|
*
|
||||||
|
* NOTE: STM32 does nnot implement support for this function.
|
||||||
|
*
|
||||||
|
* uint32_t getTimeStamp();
|
||||||
|
* @brief returns a TimeStamp data in unit msec.
|
||||||
|
* The difference between the return value of the function call two times
|
||||||
|
* is the excat time between them in msec.
|
||||||
|
*
|
||||||
|
* size_t send(const uint8_t *buf, size_t len);
|
||||||
|
* @brief return sent data length.
|
||||||
|
*
|
||||||
|
* size_t readall(uint8_t *buf, size_t maxlen)Thread safety - = 0;
|
||||||
|
* @brief return read data length.
|
||||||
|
*
|
||||||
|
* void delay_nms(uint16_t time) = 0;
|
||||||
|
* @brief delay in milliseconds
|
||||||
|
*
|
||||||
|
* void displayLog(char *buf);
|
||||||
|
* @brief Micro "API_LOG" invoked this function, to pass datalog.
|
||||||
|
* In order to pass data through different stream or channel.
|
||||||
|
* We abstract this virtual function for user.
|
||||||
|
* And different from others, this interface is not a pure virtual funcion.
|
||||||
|
* The default data-passing channel is stdout (printf).
|
||||||
|
* See also "DJI_HardDriver.cpp".
|
||||||
|
*
|
||||||
|
* @attention
|
||||||
|
* when writting and reading data, there might have multi-thread problems.
|
||||||
|
* Abstract class HardDriver did not consider these issue.
|
||||||
|
* Please be careful when you are going to implement send and readall
|
||||||
|
* funtions.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* we strongly suggest you to inherit this class in your own file, not just
|
||||||
|
* implement
|
||||||
|
* it in DJI_HardDriver.cpp or inside this class
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
public:
|
||||||
|
virtual void init() = 0;
|
||||||
|
virtual time_ms getTimeStamp() = 0;
|
||||||
|
virtual size_t send(const uint8_t* buf, size_t len) = 0;
|
||||||
|
virtual size_t readall(uint8_t* buf, size_t maxlen) = 0;
|
||||||
|
virtual bool getDeviceStatus()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! @todo move to Logging class
|
||||||
|
virtual void displayLog(const char* buf = 0);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const int bufsize = 1024;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MMU* getMmu();
|
||||||
|
MMU mmu;
|
||||||
|
friend class Protocol;
|
||||||
|
};
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // DJI_HARDDRIVER_H
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/** @file dji_log.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Logging mechanism for printing status and error messages to the screen.
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOG_H
|
||||||
|
#define LOG_H
|
||||||
|
|
||||||
|
#include "dji_memory.hpp"
|
||||||
|
#include "dji_singleton.hpp"
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define __func__ __FUNCTION__
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
#define DLOG(_title_) \
|
||||||
|
DJI::OSDK::Log::instance() \
|
||||||
|
.title((_title_), #_title_, __func__, __LINE__) \
|
||||||
|
.print
|
||||||
|
|
||||||
|
#define STATUS 1
|
||||||
|
#define ERROR 1
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#define DSTATUS DLOG(STATUS)
|
||||||
|
#define DERROR DLOG(ERROR)
|
||||||
|
#define DDEBUG DLOG(DEBUG)
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
//! @todo text stream and string class
|
||||||
|
|
||||||
|
class Log : public Singleton<Log>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Log(Mutex* m = 0);
|
||||||
|
~Log();
|
||||||
|
|
||||||
|
//! @note if title level is 0, this log would not be print at all
|
||||||
|
//! this feature is used for dynamical/statical optional log output
|
||||||
|
Log& title(int level, const char* prefix, const char* func, int line);
|
||||||
|
|
||||||
|
Log& print();
|
||||||
|
|
||||||
|
//! @note basic io function
|
||||||
|
virtual Log& print(const char* fmt, ...);
|
||||||
|
|
||||||
|
Log& operator<<(bool val);
|
||||||
|
Log& operator<<(short val);
|
||||||
|
Log& operator<<(uint16_t val);
|
||||||
|
Log& operator<<(int val);
|
||||||
|
Log& operator<<(uint32_t val);
|
||||||
|
Log& operator<<(long val);
|
||||||
|
Log& operator<<(unsigned long val);
|
||||||
|
Log& operator<<(long long val);
|
||||||
|
Log& operator<<(unsigned long long val);
|
||||||
|
Log& operator<<(float val);
|
||||||
|
Log& operator<<(double val);
|
||||||
|
Log& operator<<(long double val);
|
||||||
|
Log& operator<<(void* val);
|
||||||
|
Log& operator<<(char c);
|
||||||
|
Log& operator<<(uint8_t c);
|
||||||
|
Log& operator<<(int8_t c);
|
||||||
|
Log& operator<<(const char* str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex* mutex;
|
||||||
|
bool vaild;
|
||||||
|
|
||||||
|
//! @todo implement
|
||||||
|
typedef enum NUMBER_STYLE {
|
||||||
|
STYLE_DEC,
|
||||||
|
STYLE_HEX,
|
||||||
|
STYLE_BIN,
|
||||||
|
STYLE_OCT
|
||||||
|
} NUMBER_STYLE;
|
||||||
|
|
||||||
|
static const bool release = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // LOG_H
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/** @file dji_memory.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Implement memory management for DJI OSDK .
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DJI_MEMORY_H
|
||||||
|
#define DJI_MEMORY_H
|
||||||
|
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
#define PRO_PURE_DATA_MAX_SIZE 1007 // 2^10 - header size
|
||||||
|
|
||||||
|
class MMU
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MMU();
|
||||||
|
void setupMMU(void);
|
||||||
|
void freeMemory(MMU_Tab* mmu_tab);
|
||||||
|
MMU_Tab* allocMemory(uint16_t size);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const int MMU_TABLE_NUM = 32;
|
||||||
|
static const int MEMORY_SIZE = 1024;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MMU_Tab memoryTable[MMU_TABLE_NUM];
|
||||||
|
uint8_t memory[MEMORY_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // OSDK
|
||||||
|
} // DJI
|
||||||
|
#endif // DJI_MEMORY_H
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*! @file dji_thread_manager.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 2017
|
||||||
|
*
|
||||||
|
* @brief Data protection and thread management abstract classes.
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_THREADMANAGER_H
|
||||||
|
#define ONBOARDSDK_THREADMANAGER_H
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
//! Forward Declaration of vehicle
|
||||||
|
class Vehicle;
|
||||||
|
|
||||||
|
//! @todo start use this class
|
||||||
|
class Mutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
virtual ~Mutex();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void lock() = 0;
|
||||||
|
virtual void unlock() = 0;
|
||||||
|
}; // class Mutex
|
||||||
|
|
||||||
|
class ThreadAbstract
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThreadAbstract();
|
||||||
|
virtual ~ThreadAbstract();
|
||||||
|
|
||||||
|
//! Mutex operations
|
||||||
|
public:
|
||||||
|
virtual void lockMemory() = 0;
|
||||||
|
virtual void freeMemory() = 0;
|
||||||
|
|
||||||
|
virtual void lockMSG() = 0;
|
||||||
|
virtual void freeMSG() = 0;
|
||||||
|
|
||||||
|
virtual void lockACK() = 0;
|
||||||
|
virtual void freeACK() = 0;
|
||||||
|
|
||||||
|
virtual void lockProtocolHeader();
|
||||||
|
virtual void freeProtocolHeader();
|
||||||
|
|
||||||
|
virtual void lockNonBlockCBAck();
|
||||||
|
virtual void freeNonBlockCBAck();
|
||||||
|
|
||||||
|
virtual void notifyNonBlockCBAckRecv();
|
||||||
|
virtual void nonBlockWait();
|
||||||
|
|
||||||
|
virtual void lockStopCond();
|
||||||
|
virtual void freeStopCond();
|
||||||
|
|
||||||
|
virtual void lockFrame();
|
||||||
|
virtual void freeFrame();
|
||||||
|
|
||||||
|
//! Thread comm/sync
|
||||||
|
public:
|
||||||
|
virtual void notify() = 0;
|
||||||
|
virtual void wait(int timeout) = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void init() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Thread();
|
||||||
|
virtual ~Thread();
|
||||||
|
|
||||||
|
virtual bool createThread() = 0;
|
||||||
|
virtual int stopThread() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Vehicle* vehicle;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace DJI
|
||||||
|
} // namespace OSDK
|
||||||
|
|
||||||
|
#endif // ONBOARDSDK_THREADMANAGER_H
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*! @file dji_hard_driver.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Serial device driver abstraction. Provided as an abstract class. Please
|
||||||
|
* inherit and implement for individual platforms.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "dji_hard_driver.hpp"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
//! @todo change to dji_logging method
|
||||||
|
char DJI::OSDK::buffer[DJI::OSDK::HardDriver::bufsize];
|
||||||
|
|
||||||
|
HardDriver::HardDriver()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HardDriver::~HardDriver()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*bool
|
||||||
|
HardDriver::getDeviceStatus()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriver::displayLog(const char* buf)
|
||||||
|
{
|
||||||
|
if (buf)
|
||||||
|
DDEBUG("%s", buf);
|
||||||
|
else
|
||||||
|
DDEBUG("%s", DJI::OSDK::buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
MMU*
|
||||||
|
HardDriver::getMmu()
|
||||||
|
{
|
||||||
|
return &mmu;
|
||||||
|
}
|
||||||
@@ -0,0 +1,213 @@
|
|||||||
|
/** @file dji_log.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Logging mechanism for printing status and error messages to the screen.
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_log.hpp"
|
||||||
|
#include "dji_memory_default.hpp"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
Log::Log(Mutex* m)
|
||||||
|
{
|
||||||
|
if (m)
|
||||||
|
{
|
||||||
|
mutex = m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mutex = new MutexDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::~Log()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::title(int level, const char* prefix, const char* func, int line)
|
||||||
|
{
|
||||||
|
if (level)
|
||||||
|
{
|
||||||
|
vaild = true;
|
||||||
|
|
||||||
|
const char str[] = "\n%s/%d @ %s, L%d: ";
|
||||||
|
print(str, prefix, level, func, line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vaild = false;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::print()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::print(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
if ((!release) && vaild)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
mutex->lock();
|
||||||
|
vprintf(fmt, args);
|
||||||
|
mutex->unlock();
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(bool val)
|
||||||
|
{
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
print("True");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print("False");
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(short val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%d", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(uint16_t val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%u", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(int val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%d", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(uint32_t val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%u", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(long val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%ld", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(unsigned long val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%lu", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(long long val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%lld", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(unsigned long long val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%llu", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(float val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%f", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(double val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%lf", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(long double val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%Lf", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(void* val)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("ptr:0x%X", val);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(const char* str)
|
||||||
|
{
|
||||||
|
print("%s", str);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(char c)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%c", c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(int8_t c)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("%c", c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log&
|
||||||
|
Log::operator<<(uint8_t c)
|
||||||
|
{
|
||||||
|
//! @todo NUMBER_STYLE
|
||||||
|
print("0x%.2X", c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/** @file dji_memory.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Implement memory management for OSDK library
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @attention
|
||||||
|
* It is not necessary to include dji_memory.hpp in any custom code file.
|
||||||
|
* The functions in this file are not API functions.
|
||||||
|
* Do not modify this file if you are unsure about it.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_memory.hpp"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
MMU::MMU()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MMU::setupMMU()
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
memoryTable[0].tabIndex = 0;
|
||||||
|
memoryTable[0].usageFlag = 1;
|
||||||
|
memoryTable[0].pmem = memory;
|
||||||
|
memoryTable[0].memSize = 0;
|
||||||
|
for (i = 1; i < (MMU_TABLE_NUM - 1); i++)
|
||||||
|
{
|
||||||
|
memoryTable[i].tabIndex = i;
|
||||||
|
memoryTable[i].usageFlag = 0;
|
||||||
|
}
|
||||||
|
memoryTable[MMU_TABLE_NUM - 1].tabIndex = MMU_TABLE_NUM - 1;
|
||||||
|
memoryTable[MMU_TABLE_NUM - 1].usageFlag = 1;
|
||||||
|
memoryTable[MMU_TABLE_NUM - 1].pmem = memory + MEMORY_SIZE;
|
||||||
|
memoryTable[MMU_TABLE_NUM - 1].memSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MMU::freeMemory(MMU_Tab* mmu_tab)
|
||||||
|
{
|
||||||
|
if (mmu_tab == (MMU_Tab*)0)
|
||||||
|
return;
|
||||||
|
if (mmu_tab->tabIndex == 0 || mmu_tab->tabIndex == (MMU_TABLE_NUM - 1))
|
||||||
|
return;
|
||||||
|
mmu_tab->usageFlag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMU_Tab*
|
||||||
|
MMU::allocMemory(uint16_t size)
|
||||||
|
{
|
||||||
|
uint32_t mem_used = 0;
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t j = 0;
|
||||||
|
uint8_t mmu_tab_used_num = 0;
|
||||||
|
uint8_t mmu_tab_used_index[MMU_TABLE_NUM];
|
||||||
|
|
||||||
|
uint32_t temp32;
|
||||||
|
uint32_t temp_area[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
|
||||||
|
|
||||||
|
uint32_t record_temp32 = 0;
|
||||||
|
uint8_t magic_flag = 0;
|
||||||
|
|
||||||
|
if (size > PRO_PURE_DATA_MAX_SIZE || size > MEMORY_SIZE)
|
||||||
|
return (MMU_Tab*)0;
|
||||||
|
|
||||||
|
for (i = 0; i < MMU_TABLE_NUM; i++)
|
||||||
|
if (memoryTable[i].usageFlag == 1)
|
||||||
|
{
|
||||||
|
mem_used += memoryTable[i].memSize;
|
||||||
|
mmu_tab_used_index[mmu_tab_used_num++] = memoryTable[i].tabIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MEMORY_SIZE < (mem_used + size))
|
||||||
|
return (MMU_Tab*)0;
|
||||||
|
|
||||||
|
if (mem_used == 0)
|
||||||
|
{
|
||||||
|
memoryTable[1].pmem = memoryTable[0].pmem;
|
||||||
|
memoryTable[1].memSize = size;
|
||||||
|
memoryTable[1].usageFlag = 1;
|
||||||
|
return &memoryTable[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (mmu_tab_used_num - 1); i++)
|
||||||
|
for (j = 0; j < (mmu_tab_used_num - i - 1); j++)
|
||||||
|
if (memoryTable[mmu_tab_used_index[j]].pmem >
|
||||||
|
memoryTable[mmu_tab_used_index[j + 1]].pmem)
|
||||||
|
{
|
||||||
|
mmu_tab_used_index[j + 1] ^= mmu_tab_used_index[j];
|
||||||
|
mmu_tab_used_index[j] ^= mmu_tab_used_index[j + 1];
|
||||||
|
mmu_tab_used_index[j + 1] ^= mmu_tab_used_index[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (mmu_tab_used_num - 1); i++)
|
||||||
|
{
|
||||||
|
temp32 = static_cast<uint32_t>(memoryTable[mmu_tab_used_index[i + 1]].pmem -
|
||||||
|
memoryTable[mmu_tab_used_index[i]].pmem);
|
||||||
|
|
||||||
|
if ((temp32 - memoryTable[mmu_tab_used_index[i]].memSize) >= size)
|
||||||
|
{
|
||||||
|
if (temp_area[1] > (temp32 - memoryTable[mmu_tab_used_index[i]].memSize))
|
||||||
|
{
|
||||||
|
temp_area[0] = memoryTable[mmu_tab_used_index[i]].tabIndex;
|
||||||
|
temp_area[1] = temp32 - memoryTable[mmu_tab_used_index[i]].memSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record_temp32 += temp32 - memoryTable[mmu_tab_used_index[i]].memSize;
|
||||||
|
if (record_temp32 >= size && magic_flag == 0)
|
||||||
|
{
|
||||||
|
j = i;
|
||||||
|
magic_flag = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_area[0] == 0xFFFFFFFF && temp_area[1] == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
for (i = 0; i < j; i++)
|
||||||
|
{
|
||||||
|
if (memoryTable[mmu_tab_used_index[i + 1]].pmem >
|
||||||
|
(memoryTable[mmu_tab_used_index[i]].pmem +
|
||||||
|
memoryTable[mmu_tab_used_index[i]].memSize))
|
||||||
|
{
|
||||||
|
memmove(memoryTable[mmu_tab_used_index[i]].pmem +
|
||||||
|
memoryTable[mmu_tab_used_index[i]].memSize,
|
||||||
|
memoryTable[mmu_tab_used_index[i + 1]].pmem,
|
||||||
|
memoryTable[mmu_tab_used_index[i + 1]].memSize);
|
||||||
|
memoryTable[mmu_tab_used_index[i + 1]].pmem =
|
||||||
|
memoryTable[mmu_tab_used_index[i]].pmem +
|
||||||
|
memoryTable[mmu_tab_used_index[i]].memSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < (MMU_TABLE_NUM - 1); i++)
|
||||||
|
{
|
||||||
|
if (memoryTable[i].usageFlag == 0)
|
||||||
|
{
|
||||||
|
memoryTable[i].pmem = memoryTable[mmu_tab_used_index[j]].pmem +
|
||||||
|
memoryTable[mmu_tab_used_index[j]].memSize;
|
||||||
|
|
||||||
|
memoryTable[i].memSize = size;
|
||||||
|
memoryTable[i].usageFlag = 1;
|
||||||
|
return &memoryTable[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (MMU_Tab*)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < (MMU_TABLE_NUM - 1); i++)
|
||||||
|
{
|
||||||
|
if (memoryTable[i].usageFlag == 0)
|
||||||
|
{
|
||||||
|
memoryTable[i].pmem =
|
||||||
|
memoryTable[temp_area[0]].pmem + memoryTable[temp_area[0]].memSize;
|
||||||
|
|
||||||
|
memoryTable[i].memSize = size;
|
||||||
|
memoryTable[i].usageFlag = 1;
|
||||||
|
return &memoryTable[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (MMU_Tab*)0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*! @file dji_thread_manager.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 2017
|
||||||
|
*
|
||||||
|
* @brief Data protection and thread management abstract classes.
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
Thread::Thread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::~Thread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadAbstract::ThreadAbstract()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadAbstract::~ThreadAbstract()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::lockProtocolHeader()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::freeProtocolHeader()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::lockNonBlockCBAck()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::freeNonBlockCBAck()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::notifyNonBlockCBAckRecv()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::nonBlockWait()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::lockStopCond()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::freeStopCond()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::lockFrame()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadAbstract::freeFrame()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutex::Mutex()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutex::~Mutex()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
#### Unified Serial Device Driver for the Linux platform. Please refer to [Programming Guide](https://developer.dji.com/onboard-sdk/documentation/application-development-guides/programming-guide.html).
|
||||||
|
|
||||||
|
If you're new here, we recommend going through the [Getting Started Guide](https://developer.dji.com/onboard-sdk/documentation/quick-start/index.html).
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*! @file STM32F4DataGuard.h
|
||||||
|
* @version 3.3
|
||||||
|
* @date Apr 12th, 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Data protection for thread access for DJI Onboard SDK Linux/*NIX platforms
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2017 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef STM32F4DATAGUARD_H
|
||||||
|
#define STM32F4DATAGUARD_H
|
||||||
|
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief Data Protection
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class STM32F4DataGuard : public DJI::OSDK::ThreadAbstract
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
STM32F4DataGuard();
|
||||||
|
~STM32F4DataGuard();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void lockMemory();
|
||||||
|
void freeMemory();
|
||||||
|
|
||||||
|
void lockMSG();
|
||||||
|
void freeMSG();
|
||||||
|
|
||||||
|
void lockACK();
|
||||||
|
void freeACK();
|
||||||
|
|
||||||
|
void lockProtocolHeader();
|
||||||
|
void freeProtocolHeader();
|
||||||
|
|
||||||
|
void lockNonBlockCBAck();
|
||||||
|
void freeNonBlockCBAck();
|
||||||
|
|
||||||
|
void lockStopCond();
|
||||||
|
void freeStopCond();
|
||||||
|
|
||||||
|
void lockFrame();
|
||||||
|
void freeFrame();
|
||||||
|
|
||||||
|
void notify();
|
||||||
|
void notifyNonBlockCBAckRecv();
|
||||||
|
void wait(int timeoutInSeconds);
|
||||||
|
void nonBlockWait();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // STM32F4DATAGUARD_H
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*! @file STM32F4SerialDriver.h
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Implementation of HardDriver for the STM32F4Discovery board.
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "dji_hard_driver.hpp"
|
||||||
|
|
||||||
|
class STM32F4 : public DJI::OSDK::HardDriver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual size_t send(const uint8_t* buf, size_t len);
|
||||||
|
virtual DJI::OSDK::time_ms getTimeStamp();
|
||||||
|
virtual bool getDeviceStatus()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual size_t readall(uint8_t* buf, size_t maxlen)
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
static void delay_nms(uint16_t time);
|
||||||
|
};
|
||||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,106 @@
|
|||||||
|
#include "STM32F4DataGuard.h"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
STM32F4DataGuard::STM32F4DataGuard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
STM32F4DataGuard::~STM32F4DataGuard()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockMemory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeMemory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockMSG()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeMSG()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockACK()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeACK()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockProtocolHeader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeProtocolHeader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockNonBlockCBAck()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeNonBlockCBAck()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockStopCond()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeStopCond()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::lockFrame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::freeFrame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::notify()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::notifyNonBlockCBAckRecv()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::nonBlockWait()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4DataGuard::wait(int timeoutInSeconds)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*! @file STM32F4SerialDriver.cpp
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Implementation of HardDriver for the STM32F4Discovery board.
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include <STM32F4SerialDriver.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
extern uint32_t tick;
|
||||||
|
|
||||||
|
void
|
||||||
|
STM32F4::delay_nms(uint16_t time)
|
||||||
|
{
|
||||||
|
u32 i = 0;
|
||||||
|
while (time--)
|
||||||
|
{
|
||||||
|
i = 30000;
|
||||||
|
while (i--)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
STM32F4::send(const uint8_t* buf, size_t len)
|
||||||
|
{
|
||||||
|
char* p = (char*)buf;
|
||||||
|
|
||||||
|
if (NULL == buf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
|
||||||
|
;
|
||||||
|
USART_SendData(USART3, *p++);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DJI::OSDK::time_ms
|
||||||
|
STM32F4::getTimeStamp()
|
||||||
|
{
|
||||||
|
return tick;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef MEMORY_DEFAULT_HPP
|
||||||
|
#define MEMORY_DEFAULT_HPP
|
||||||
|
|
||||||
|
#include "dji_memory.hpp"
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
class MutexPrivate;
|
||||||
|
|
||||||
|
class MutexDefault : public Mutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MutexDefault();
|
||||||
|
~MutexDefault();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MutexPrivate* instance;
|
||||||
|
}; // class MutexDefault
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // MEMORY_DEFAULT_HPP
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
default platform driver. close source. Linux only at first
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#include "dji_memory_default.hpp"
|
||||||
|
|
||||||
|
#include "dji_log.hpp"
|
||||||
|
|
||||||
|
#ifdef qt
|
||||||
|
#elif defined(stm32)
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
class MutexPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MutexPrivate()
|
||||||
|
{
|
||||||
|
_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
}
|
||||||
|
~MutexPrivate()
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void lock()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&_mutex);
|
||||||
|
}
|
||||||
|
inline void unlock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&_mutex);
|
||||||
|
}
|
||||||
|
pthread_mutex_t _mutex;
|
||||||
|
}; // class DJI::OSDK::MutexPrivate
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
#else // default non-functional driver
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
class MutexPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MutexPrivate()
|
||||||
|
{
|
||||||
|
//! @note cannot use DLOG here
|
||||||
|
}
|
||||||
|
~MutexPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void lock()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline void unlock()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}; // class MutexPrivate
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // ugly cross platform support
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
MutexDefault::MutexDefault()
|
||||||
|
: instance(new MutexPrivate())
|
||||||
|
{
|
||||||
|
//! @note cannot use DLOG here
|
||||||
|
}
|
||||||
|
|
||||||
|
MutexDefault::~MutexDefault()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MutexDefault::lock()
|
||||||
|
{
|
||||||
|
instance->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MutexDefault::unlock()
|
||||||
|
{
|
||||||
|
instance->unlock();
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*! @file linux_serial_device.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Serial device hardware implementation for *NIX machines.
|
||||||
|
*
|
||||||
|
* @details
|
||||||
|
* This is a generic POSIX-compatible serial device implementation.
|
||||||
|
*
|
||||||
|
* The Vehicle class handles Serial drivers, so you do not need to
|
||||||
|
* instantiate drivers in your code.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef LINUXSERIALDEVICE_H
|
||||||
|
#define LINUXSERIALDEVICE_H
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dji_hard_driver.hpp"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief POSIX-Compatible Serial Driver for *NIX platforms
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class LinuxSerialDevice : public HardDriver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const int BUFFER_SIZE = 2048;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinuxSerialDevice(const char* device, uint32_t baudrate);
|
||||||
|
~LinuxSerialDevice();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
bool getDeviceStatus();
|
||||||
|
|
||||||
|
void setBaudrate(uint32_t baudrate);
|
||||||
|
void setDevice(const char* device);
|
||||||
|
|
||||||
|
//! Public interfaces to private functions. Use these functions to validate
|
||||||
|
//! your serial connection
|
||||||
|
int checkBaudRate(uint8_t (&buf)[BUFFER_SIZE])
|
||||||
|
{
|
||||||
|
_checkBaudRate(buf);
|
||||||
|
}
|
||||||
|
int setSerialPureTimedRead();
|
||||||
|
int unsetSerialPureTimedRead();
|
||||||
|
int serialRead(uint8_t* buf, int len);
|
||||||
|
|
||||||
|
//! Start of DJI_HardDriver virtual function implementations
|
||||||
|
size_t send(const uint8_t* buf, size_t len);
|
||||||
|
size_t readall(uint8_t* buf, size_t maxlen);
|
||||||
|
|
||||||
|
//! Implemented here because ..
|
||||||
|
DJI::OSDK::time_ms getTimeStamp();
|
||||||
|
|
||||||
|
void delay_nms(uint16_t time)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* m_device;
|
||||||
|
uint32_t m_baudrate;
|
||||||
|
|
||||||
|
int m_serial_fd;
|
||||||
|
fd_set m_serial_fd_set;
|
||||||
|
bool deviceStatus;
|
||||||
|
|
||||||
|
bool _serialOpen(const char* dev);
|
||||||
|
bool _serialClose();
|
||||||
|
bool _serialFlush();
|
||||||
|
bool _serialConfig(int baudrate, char data_bits, char parity_bits,
|
||||||
|
char stop_bits, bool testForData = false);
|
||||||
|
|
||||||
|
int _serialStart(const char* dev_name, int baud_rate);
|
||||||
|
int _serialWrite(const uint8_t* buf, int len);
|
||||||
|
int _serialRead(uint8_t* buf, int len);
|
||||||
|
|
||||||
|
int _checkBaudRate(uint8_t (&buf)[BUFFER_SIZE]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LINUXSERIALDEVICE_H
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*! @file posix_thread.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Pthread-based threading for DJI Onboard SDK Linux/*NIX platforms
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef LINUXTHREAD_H
|
||||||
|
#define LINUXTHREAD_H
|
||||||
|
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief POSIX-compatible threading implementation for *NIX systems
|
||||||
|
*
|
||||||
|
* @details Threading is handled by the Vehicle, you do not need to
|
||||||
|
* manage threads for nominal usage.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class PosixThread : public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PosixThread();
|
||||||
|
PosixThread(Vehicle* vehicle, int type);
|
||||||
|
~PosixThread()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool createThread();
|
||||||
|
int stopThread();
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_t threadID;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
|
||||||
|
static void* send_call(void* param);
|
||||||
|
static void* read_call(void* param);
|
||||||
|
static void* callback_call(void* param);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace DJI
|
||||||
|
} // namespace onboardSDK
|
||||||
|
|
||||||
|
#endif // LINUXTHREAD_H
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*! @file posix_thread_manager.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Thread safety and data protection for DJI Onboard SDK on linux platforms
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2017 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef POSIXTHREADMANAGER_H
|
||||||
|
#define POSIXTHREADMANAGER_H
|
||||||
|
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
#include "pthread.h"
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief POSIX-COmpatible Data Protection and Condition Variables for *NIX
|
||||||
|
* platforms
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class PosixThreadManager : public ThreadAbstract
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PosixThreadManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~PosixThreadManager();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
//! Implementing virtual functions from ThreadManager
|
||||||
|
public:
|
||||||
|
void lockMemory();
|
||||||
|
void freeMemory();
|
||||||
|
|
||||||
|
void lockMSG();
|
||||||
|
void freeMSG();
|
||||||
|
|
||||||
|
void lockACK();
|
||||||
|
void freeACK();
|
||||||
|
|
||||||
|
void lockProtocolHeader();
|
||||||
|
void freeProtocolHeader();
|
||||||
|
|
||||||
|
void lockNonBlockCBAck();
|
||||||
|
void freeNonBlockCBAck();
|
||||||
|
|
||||||
|
void lockStopCond();
|
||||||
|
void freeStopCond();
|
||||||
|
|
||||||
|
void lockFrame();
|
||||||
|
void freeFrame();
|
||||||
|
|
||||||
|
void notify();
|
||||||
|
void notifyNonBlockCBAckRecv();
|
||||||
|
void wait(int timeoutInSeconds);
|
||||||
|
void nonBlockWait();
|
||||||
|
|
||||||
|
private:
|
||||||
|
pthread_mutex_t m_memLock;
|
||||||
|
pthread_mutex_t m_msgLock;
|
||||||
|
pthread_mutex_t m_ackLock;
|
||||||
|
pthread_cond_t m_ackRecvCv;
|
||||||
|
|
||||||
|
pthread_mutex_t m_headerLock;
|
||||||
|
pthread_mutex_t m_nbAckLock;
|
||||||
|
pthread_cond_t m_nbAckRecv;
|
||||||
|
|
||||||
|
//! Thread protection for setting stop condition for threads
|
||||||
|
pthread_mutex_t m_stopCondLock;
|
||||||
|
|
||||||
|
//! Thread protection for last received frame storage
|
||||||
|
pthread_mutex_t m_frameLock;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // POSIXTHREADMANAGER_H
|
||||||
@@ -0,0 +1,334 @@
|
|||||||
|
/*! @file linux_serial_device.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Serial device hardware implementation for Linux machines.
|
||||||
|
* This is a generic Linux serial device implementation.
|
||||||
|
*
|
||||||
|
* Use this in your own Linux-based DJI Onboard SDK implementations.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "linux_serial_device.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
/*! Implementing inherited functions from abstract class DJI_HardDriver */
|
||||||
|
|
||||||
|
LinuxSerialDevice::LinuxSerialDevice(const char* device, uint32_t baudrate)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
m_baudrate = baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinuxSerialDevice::~LinuxSerialDevice()
|
||||||
|
{
|
||||||
|
_serialClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LinuxSerialDevice::init()
|
||||||
|
{
|
||||||
|
DSTATUS("Attempting to open device %s with baudrate %u...\n", m_device,
|
||||||
|
m_baudrate);
|
||||||
|
if (_serialStart(m_device, m_baudrate) < 0)
|
||||||
|
{
|
||||||
|
_serialClose();
|
||||||
|
DERROR("...Failed to start serial\n");
|
||||||
|
deviceStatus = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS("...Serial started successfully.\n");
|
||||||
|
deviceStatus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LinuxSerialDevice::getDeviceStatus()
|
||||||
|
{
|
||||||
|
return deviceStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
DJI::OSDK::time_ms
|
||||||
|
LinuxSerialDevice::getTimeStamp()
|
||||||
|
{
|
||||||
|
return (uint32_t)time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
LinuxSerialDevice::send(const uint8_t* buf, size_t len)
|
||||||
|
{
|
||||||
|
return _serialWrite(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
LinuxSerialDevice::readall(uint8_t* buf, size_t maxlen)
|
||||||
|
{
|
||||||
|
return _serialRead(buf, maxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Implement functions specific to this hardware driver */
|
||||||
|
|
||||||
|
/****
|
||||||
|
The next few functions set serial port I/O parameters and implement serial R/W
|
||||||
|
functions.
|
||||||
|
Implement termios-based serial i/o.
|
||||||
|
****/
|
||||||
|
void
|
||||||
|
LinuxSerialDevice::setBaudrate(uint32_t baudrate)
|
||||||
|
{
|
||||||
|
m_baudrate = baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LinuxSerialDevice::setDevice(const char* device)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LinuxSerialDevice::setSerialPureTimedRead()
|
||||||
|
{
|
||||||
|
_serialConfig(m_baudrate, 8, 'N', 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LinuxSerialDevice::unsetSerialPureTimedRead()
|
||||||
|
{
|
||||||
|
_serialConfig(m_baudrate, 8, 'N', 1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LinuxSerialDevice::serialRead(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
_serialRead(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LinuxSerialDevice::_checkBaudRate(uint8_t (&buf)[BUFFER_SIZE])
|
||||||
|
{
|
||||||
|
int lengthForCheck = 200;
|
||||||
|
int timeoutInSeconds = 2;
|
||||||
|
|
||||||
|
struct timespec curTime, absTimeout;
|
||||||
|
// Use clock_gettime instead of getttimeofday for compatibility with POSIX
|
||||||
|
// APIs
|
||||||
|
clock_gettime(CLOCK_REALTIME, &curTime);
|
||||||
|
absTimeout.tv_sec = curTime.tv_sec + timeoutInSeconds;
|
||||||
|
absTimeout.tv_nsec = curTime.tv_nsec;
|
||||||
|
|
||||||
|
int receivedBytes = _serialRead(buf, lengthForCheck);
|
||||||
|
|
||||||
|
while (curTime.tv_sec < absTimeout.tv_sec)
|
||||||
|
{
|
||||||
|
if (receivedBytes < lengthForCheck)
|
||||||
|
receivedBytes +=
|
||||||
|
_serialRead(buf + receivedBytes, lengthForCheck - receivedBytes);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_REALTIME, &curTime);
|
||||||
|
}
|
||||||
|
if (curTime.tv_sec >= absTimeout.tv_sec)
|
||||||
|
return -1;
|
||||||
|
if (std::end(buf) == std::find(std::begin(buf), std::end(buf), 0xAA))
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LinuxSerialDevice::_serialOpen(const char* dev)
|
||||||
|
{
|
||||||
|
#ifdef __arm__
|
||||||
|
m_serial_fd = open(dev, O_RDWR | O_NONBLOCK);
|
||||||
|
#elif __x86_64__
|
||||||
|
m_serial_fd = open(dev, O_RDWR | O_NOCTTY);
|
||||||
|
#else
|
||||||
|
m_serial_fd = open(dev, O_RDWR | O_NOCTTY);
|
||||||
|
#endif
|
||||||
|
if (m_serial_fd < 0)
|
||||||
|
{
|
||||||
|
DERROR("cannot open device %s\n", dev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LinuxSerialDevice::_serialClose()
|
||||||
|
{
|
||||||
|
close(m_serial_fd);
|
||||||
|
m_serial_fd = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LinuxSerialDevice::_serialFlush()
|
||||||
|
{
|
||||||
|
if (m_serial_fd < 0)
|
||||||
|
{
|
||||||
|
DERROR("flushing fail because no device is opened\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcflush(m_serial_fd, TCIFLUSH);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LinuxSerialDevice::_serialConfig(int baudrate, char data_bits, char parity_bits,
|
||||||
|
char stop_bits, bool testForData)
|
||||||
|
{
|
||||||
|
int st_baud[] = { B4800, B9600, B19200, B38400,
|
||||||
|
B57600, B115200, B230400, B921600 };
|
||||||
|
int std_rate[] = { 4800, 9600, 19200, 38400, 57600, 115200,
|
||||||
|
230400, 921600, 1000000, 1152000, 3000000 };
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
struct termios newtio, oldtio;
|
||||||
|
/* save current port parameter */
|
||||||
|
if (tcgetattr(m_serial_fd, &oldtio) != 0)
|
||||||
|
{
|
||||||
|
DERROR("fail to save current port\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(&newtio, 0, sizeof(newtio));
|
||||||
|
|
||||||
|
/* config the size of char */
|
||||||
|
newtio.c_cflag |= CLOCAL | CREAD;
|
||||||
|
newtio.c_cflag &= ~CSIZE;
|
||||||
|
|
||||||
|
/* config data bit */
|
||||||
|
switch (data_bits)
|
||||||
|
{
|
||||||
|
case 7:
|
||||||
|
newtio.c_cflag |= CS7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
newtio.c_cflag |= CS8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* config the parity bit */
|
||||||
|
switch (parity_bits)
|
||||||
|
{
|
||||||
|
/* odd */
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
newtio.c_cflag |= PARENB;
|
||||||
|
newtio.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
/* even */
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
newtio.c_cflag |= PARENB;
|
||||||
|
newtio.c_cflag &= ~PARODD;
|
||||||
|
break;
|
||||||
|
/* none */
|
||||||
|
case 'N':
|
||||||
|
case 'n':
|
||||||
|
newtio.c_cflag &= ~PARENB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* config baudrate */
|
||||||
|
j = sizeof(std_rate) / 4;
|
||||||
|
for (i = 0; i < j; ++i)
|
||||||
|
{
|
||||||
|
if (std_rate[i] == baudrate)
|
||||||
|
{
|
||||||
|
/* set standard baudrate */
|
||||||
|
cfsetispeed(&newtio, st_baud[i]);
|
||||||
|
cfsetospeed(&newtio, st_baud[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* config stop bit */
|
||||||
|
if (stop_bits == 1)
|
||||||
|
newtio.c_cflag &= ~CSTOPB;
|
||||||
|
else if (stop_bits == 2)
|
||||||
|
newtio.c_cflag |= CSTOPB;
|
||||||
|
|
||||||
|
/* config waiting time & min number of char */
|
||||||
|
//! If you just want to see if there is data on the line, put the serial config
|
||||||
|
//! in an unconditional timeout state
|
||||||
|
#if __x86_64__
|
||||||
|
if (testForData)
|
||||||
|
{
|
||||||
|
newtio.c_cc[VTIME] = 8;
|
||||||
|
newtio.c_cc[VMIN] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newtio.c_cc[VTIME] = 1;
|
||||||
|
newtio.c_cc[VMIN] = 18;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* using the raw data mode */
|
||||||
|
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||||
|
newtio.c_oflag &= ~OPOST;
|
||||||
|
|
||||||
|
/* flush the hardware fifo */
|
||||||
|
tcflush(m_serial_fd, TCIFLUSH);
|
||||||
|
|
||||||
|
/* activite the configuration */
|
||||||
|
if ((tcsetattr(m_serial_fd, TCSANOW, &newtio)) != 0)
|
||||||
|
{
|
||||||
|
DERROR("failed to activate serial configuration\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LinuxSerialDevice::_serialStart(const char* dev_name, int baud_rate)
|
||||||
|
{
|
||||||
|
const char* ptemp;
|
||||||
|
if (dev_name == NULL)
|
||||||
|
{
|
||||||
|
ptemp = "/dev/ttyUSB0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptemp = dev_name;
|
||||||
|
}
|
||||||
|
if (true == _serialOpen(ptemp) && true == _serialConfig(baud_rate, 8, 'N', 1))
|
||||||
|
{
|
||||||
|
|
||||||
|
FD_ZERO(&m_serial_fd_set);
|
||||||
|
FD_SET(m_serial_fd, &m_serial_fd_set);
|
||||||
|
return m_serial_fd;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LinuxSerialDevice::_serialWrite(const uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
return write(m_serial_fd, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Current _serialRead behavior: Wait for 500 ms between characters till 18
|
||||||
|
//! char, read 18 characters if data available & return
|
||||||
|
//! 500 ms: long timeout to make sure that if we query the input buffer in the
|
||||||
|
//! middle of a packet we still get the full packet
|
||||||
|
//! 18 char: len of most ACK packets.
|
||||||
|
int
|
||||||
|
LinuxSerialDevice::_serialRead(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (NULL == buf)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = read(m_serial_fd, buf, len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
/*! @file posix_thread.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Pthread-based threading for DJI Onboard SDK on linux platforms
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016-17 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "posix_thread.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
PosixThread::PosixThread()
|
||||||
|
{
|
||||||
|
vehicle = 0;
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PosixThread::PosixThread(Vehicle* vehicle, int Type)
|
||||||
|
{
|
||||||
|
this->vehicle = vehicle;
|
||||||
|
this->type = Type;
|
||||||
|
vehicle->setStopCond(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PosixThread::createThread()
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
std::string infoStr;
|
||||||
|
|
||||||
|
/* Initialize and set thread detached attribute */
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
|
||||||
|
if (1 == type)
|
||||||
|
{
|
||||||
|
ret = pthread_create(&threadID, NULL, send_call, (void*)vehicle);
|
||||||
|
infoStr = "sendPoll";
|
||||||
|
}
|
||||||
|
else if (2 == type)
|
||||||
|
{
|
||||||
|
ret = pthread_create(&threadID, NULL, read_call, vehicle);
|
||||||
|
infoStr = "readPoll";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (3 == type)
|
||||||
|
{
|
||||||
|
ret = pthread_create(&threadID, NULL, callback_call, (void*)vehicle);
|
||||||
|
infoStr = "callback";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoStr = "error type number";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != ret)
|
||||||
|
{
|
||||||
|
DERROR("fail to create thread for %s!\n", infoStr.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pthread_setname_np(threadID, infoStr.c_str());
|
||||||
|
if (0 != ret)
|
||||||
|
{
|
||||||
|
DERROR("fail to set thread name for %s!\n", infoStr.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
PosixThread::stopThread()
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
void* status;
|
||||||
|
vehicle->setStopCond(true);
|
||||||
|
|
||||||
|
/* Free attribute and wait for the other threads */
|
||||||
|
if (int i = pthread_attr_destroy(&attr))
|
||||||
|
{
|
||||||
|
DERROR("fail to destroy thread %d\n", i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DDEBUG("success to distory thread\n");
|
||||||
|
}
|
||||||
|
ret = pthread_join(threadID, &status);
|
||||||
|
|
||||||
|
DDEBUG("Main: completed join with thread code: %d\n", ret);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
// Return error code
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
PosixThread::send_call(void* param)
|
||||||
|
{
|
||||||
|
Vehicle* vehiclePtr = (Vehicle*)param;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
vehiclePtr->protocolLayer->sendPoll();
|
||||||
|
usleep(10); //! @note CPU optimization, reduce the CPU usage a lot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
PosixThread::read_call(void* param)
|
||||||
|
{
|
||||||
|
|
||||||
|
RecvContainer recvContainer;
|
||||||
|
Vehicle* vehiclePtr = (Vehicle*)param;
|
||||||
|
while (!(vehiclePtr->getStopCond()))
|
||||||
|
{
|
||||||
|
// receive() implemented on the OpenProtocol side
|
||||||
|
recvContainer = vehiclePtr->protocolLayer->receive();
|
||||||
|
vehiclePtr->processReceivedData(recvContainer);
|
||||||
|
usleep(10); //! @note CPU optimization, reduce the CPU usage a lot
|
||||||
|
}
|
||||||
|
DDEBUG("Quit read function\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
PosixThread::callback_call(void* param)
|
||||||
|
{
|
||||||
|
Vehicle* vehiclePtr = (Vehicle*)param;
|
||||||
|
while (!(vehiclePtr->getStopCond()))
|
||||||
|
{
|
||||||
|
vehiclePtr->callbackPoll();
|
||||||
|
usleep(10); //! @note CPU optimization, reduce the CPU usage a lot
|
||||||
|
}
|
||||||
|
DDEBUG("Quit callback function\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*! @file posix_thread_manager.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 15 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Thread safety and data protection for DJI Onboard SDK on linux platforms
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2017 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "posix_thread_manager.hpp"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
PosixThreadManager::~PosixThreadManager()
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&m_memLock);
|
||||||
|
pthread_mutex_destroy(&m_msgLock);
|
||||||
|
pthread_mutex_destroy(&m_ackLock);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&m_nbAckLock);
|
||||||
|
pthread_mutex_destroy(&m_headerLock);
|
||||||
|
|
||||||
|
pthread_cond_destroy(&m_nbAckRecv);
|
||||||
|
pthread_cond_destroy(&m_ackRecvCv);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&m_frameLock);
|
||||||
|
pthread_mutex_destroy(&m_stopCondLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::init()
|
||||||
|
{
|
||||||
|
m_memLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
m_msgLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
m_ackLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
pthread_cond_init(&m_ackRecvCv, NULL);
|
||||||
|
|
||||||
|
/*! These mutexes are used for the non blocking callback ACK mechanism */
|
||||||
|
m_nbAckLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
m_headerLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
pthread_cond_init(&m_nbAckRecv, NULL);
|
||||||
|
|
||||||
|
/*! Mutex initializations
|
||||||
|
* These are newly added mutexes
|
||||||
|
*/
|
||||||
|
m_frameLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
m_stopCondLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockMemory()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_memLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeMemory()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_memLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockMSG()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_msgLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeMSG()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_msgLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockACK()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_ackLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeACK()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_ackLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockProtocolHeader()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_headerLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeProtocolHeader()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_headerLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockNonBlockCBAck()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_nbAckLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeNonBlockCBAck()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_nbAckLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockStopCond()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_stopCondLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeStopCond()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_stopCondLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::lockFrame()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_frameLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::freeFrame()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_frameLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::notify()
|
||||||
|
{
|
||||||
|
pthread_cond_signal(&m_ackRecvCv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::notifyNonBlockCBAckRecv()
|
||||||
|
{
|
||||||
|
pthread_cond_signal(&m_nbAckRecv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::nonBlockWait()
|
||||||
|
{
|
||||||
|
|
||||||
|
pthread_cond_wait(&m_nbAckRecv, &m_nbAckLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PosixThreadManager::wait(int timeoutInSeconds)
|
||||||
|
{
|
||||||
|
struct timespec curTime, absTimeout;
|
||||||
|
// Use clock_gettime instead of getttimeofday for compatibility with POSIX
|
||||||
|
// APIs
|
||||||
|
clock_gettime(CLOCK_REALTIME, &curTime);
|
||||||
|
// absTimeout = curTime;
|
||||||
|
absTimeout.tv_sec = curTime.tv_sec + timeoutInSeconds;
|
||||||
|
absTimeout.tv_nsec = curTime.tv_nsec;
|
||||||
|
pthread_cond_timedwait(&m_ackRecvCv, &m_ackLock, &absTimeout);
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*! @file DJIHardDriverManifold.h
|
||||||
|
* @version 3.1.7
|
||||||
|
* @date Jul 01 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Old serial device hardware abstraction for DJI Onboard SDK command line example.
|
||||||
|
*
|
||||||
|
* @warning Deprecated. Please use linux_serial_device.hpp/.cpp for the most current implementation.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef __DJIHARDDRIVERMANIFOLD_H__
|
||||||
|
#define __DJIHARDDRIVERMANIFOLD_H__
|
||||||
|
|
||||||
|
#include <DJI_HardDriver.h>
|
||||||
|
#include <dji_type.hpp>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace onboardSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
class HardDriverManifold : public HardDriver
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
HardDriverManifold(std::string device, uint32_t baudrate);
|
||||||
|
~HardDriverManifold();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implement a USB hand-shaking protocol for SDK
|
||||||
|
*/
|
||||||
|
void usbHandshake(std::string device);
|
||||||
|
|
||||||
|
void setBaudrate(uint32_t baudrate);
|
||||||
|
void setDevice(std::string device);
|
||||||
|
|
||||||
|
DJI::OSDK::time_ms getTimeStamp();
|
||||||
|
|
||||||
|
size_t send(const uint8_t* buf, size_t len);
|
||||||
|
size_t readall(uint8_t* buf, size_t maxlen);
|
||||||
|
|
||||||
|
void lockMemory();
|
||||||
|
void freeMemory();
|
||||||
|
void lockMSG();
|
||||||
|
void freeMSG();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_device;
|
||||||
|
uint32_t m_baudrate;
|
||||||
|
pthread_mutex_t m_memLock;
|
||||||
|
pthread_mutex_t m_msgLock;
|
||||||
|
|
||||||
|
int m_serial_fd;
|
||||||
|
fd_set m_serial_fd_set;
|
||||||
|
|
||||||
|
bool _serialOpen(const char* dev);
|
||||||
|
bool _serialClose();
|
||||||
|
bool _serialFlush();
|
||||||
|
bool _serialConfig(int baudrate, char data_bits, char parity_bits,
|
||||||
|
char stop_bits);
|
||||||
|
|
||||||
|
int _serialStart(const char* dev_name, int baud_rate);
|
||||||
|
int _serialWrite(const uint8_t* buf, int len);
|
||||||
|
int _serialRead(uint8_t* buf, int len);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/*! @file DJI_HardDriver_Manifold.h
|
||||||
|
* @version 3.1.7
|
||||||
|
* @date Jul 01 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Old serial device hardware abstraction for DJI Onboard SDK ROS.
|
||||||
|
*
|
||||||
|
* @warning Deprecated. Please use linux_serial_device.hpp/.cpp for the most current implementation.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __DJI_HARDDRIVER_MANIFOLD_H__
|
||||||
|
#define __DJI_HARDDRIVER_MANIFOLD_H__
|
||||||
|
|
||||||
|
#include <DJI_HardDriver.h>
|
||||||
|
#include <dji_type.hpp>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace onboardSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
class HardDriver_Manifold : public HardDriver
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
HardDriver_Manifold(std::string device, uint32_t baudrate)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
m_baudrate = baudrate;
|
||||||
|
m_memLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
m_msgLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
~HardDriver_Manifold()
|
||||||
|
{
|
||||||
|
_serialClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
DSTATUS( "Open serial device %s with baudrate %u...\n",
|
||||||
|
m_device.c_str(), m_baudrate);
|
||||||
|
if (_serialStart(m_device.c_str(), m_baudrate) < 0)
|
||||||
|
{
|
||||||
|
_serialClose();
|
||||||
|
DERROR( "Failed to start serial device\n");
|
||||||
|
deviceStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buf[BUFFER_SIZE];
|
||||||
|
usleep(5000);
|
||||||
|
|
||||||
|
//! Check if serial connection valid
|
||||||
|
if (_serialRead(buf, BUFFER_SIZE) > 0)
|
||||||
|
{
|
||||||
|
DSTATUS( "Succeeded to read from serial device\n");
|
||||||
|
deviceStatus = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DERROR( "Failed to read from serial device\n");
|
||||||
|
deviceStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implement a USB hand-shaking protocol for SDK
|
||||||
|
*/
|
||||||
|
void usbHandshake(std::string device)
|
||||||
|
{
|
||||||
|
_serialStart(device.c_str(), 38400);
|
||||||
|
_serialStart(device.c_str(), 19200);
|
||||||
|
_serialStart(device.c_str(), 38400);
|
||||||
|
_serialStart(device.c_str(), 19200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBaudrate(uint32_t baudrate)
|
||||||
|
{
|
||||||
|
m_baudrate = baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDevice(std::string device)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getDevieStatus()
|
||||||
|
{
|
||||||
|
return deviceStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_ms getTimeStamp()
|
||||||
|
{
|
||||||
|
#ifdef __MACH__
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
return (uint64_t)now.tv_sec * 1000 + (uint64_t)(now.tv_usec / 1.0e3);
|
||||||
|
#else
|
||||||
|
struct timespec time;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &time);
|
||||||
|
return (uint64_t)time.tv_sec * 1000 + (uint64_t)(time.tv_nsec / 1.0e6);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t send(const uint8_t* buf, size_t len)
|
||||||
|
{
|
||||||
|
return _serialWrite(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t readall(uint8_t* buf, size_t maxlen)
|
||||||
|
{
|
||||||
|
return _serialRead(buf, maxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lockMemory()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_memLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeMemory()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_memLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lockMSG()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_msgLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeMSG()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_msgLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_device;
|
||||||
|
uint32_t m_baudrate;
|
||||||
|
pthread_mutex_t m_memLock;
|
||||||
|
pthread_mutex_t m_msgLock;
|
||||||
|
|
||||||
|
int m_serial_fd;
|
||||||
|
fd_set m_serial_fd_set;
|
||||||
|
|
||||||
|
bool deviceStatus;
|
||||||
|
|
||||||
|
bool _serialOpen(const char* dev)
|
||||||
|
{
|
||||||
|
// notice: use O_NONBLOCK to raise the frequency that read data from buffer
|
||||||
|
m_serial_fd = open(dev, O_RDWR | O_NONBLOCK);
|
||||||
|
if (m_serial_fd < 0)
|
||||||
|
{
|
||||||
|
DERROR( "Failed to open serial device %s\n", dev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _serialClose()
|
||||||
|
{
|
||||||
|
close(m_serial_fd);
|
||||||
|
m_serial_fd = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _serialFlush()
|
||||||
|
{
|
||||||
|
if (m_serial_fd < 0)
|
||||||
|
{
|
||||||
|
DERROR( "flushing fail because no device is opened\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcflush(m_serial_fd, TCIFLUSH);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _serialConfig(int baudrate, char data_bits, char parity_bits,
|
||||||
|
char stop_bits)
|
||||||
|
{
|
||||||
|
int st_baud[] = { B4800, B9600, B19200, B38400,
|
||||||
|
B57600, B115200, B230400, B921600 };
|
||||||
|
int std_rate[] = {
|
||||||
|
4800, 9600, 19200, 38400, 57600, 115200,
|
||||||
|
230400, 921600, 1000000, 1152000, 3000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
struct termios newtio, oldtio;
|
||||||
|
/* save current port parameter */
|
||||||
|
if (tcgetattr(m_serial_fd, &oldtio) != 0)
|
||||||
|
{
|
||||||
|
DERROR( "fail to save current port\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(&newtio, 0, sizeof(newtio));
|
||||||
|
|
||||||
|
/* config the size of char */
|
||||||
|
newtio.c_cflag |= CLOCAL | CREAD;
|
||||||
|
newtio.c_cflag &= ~CSIZE;
|
||||||
|
|
||||||
|
/* config data bit */
|
||||||
|
switch (data_bits)
|
||||||
|
{
|
||||||
|
case 7:
|
||||||
|
newtio.c_cflag |= CS7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
newtio.c_cflag |= CS8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* config the parity bit */
|
||||||
|
switch (parity_bits)
|
||||||
|
{
|
||||||
|
/* odd */
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
newtio.c_cflag |= PARENB;
|
||||||
|
newtio.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
/* even */
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
newtio.c_cflag |= PARENB;
|
||||||
|
newtio.c_cflag &= ~PARODD;
|
||||||
|
break;
|
||||||
|
/* none */
|
||||||
|
case 'N':
|
||||||
|
case 'n':
|
||||||
|
newtio.c_cflag &= ~PARENB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* config baudrate */
|
||||||
|
j = sizeof(std_rate) / 4;
|
||||||
|
for (i = 0; i < j; ++i)
|
||||||
|
{
|
||||||
|
if (std_rate[i] == baudrate)
|
||||||
|
{
|
||||||
|
/* set standard baudrate */
|
||||||
|
cfsetispeed(&newtio, st_baud[i]);
|
||||||
|
cfsetospeed(&newtio, st_baud[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* config stop bit */
|
||||||
|
if (stop_bits == 1)
|
||||||
|
newtio.c_cflag &= ~CSTOPB;
|
||||||
|
else if (stop_bits == 2)
|
||||||
|
newtio.c_cflag |= CSTOPB;
|
||||||
|
|
||||||
|
/* config waiting time & min number of char */
|
||||||
|
newtio.c_cc[VTIME] = 1;
|
||||||
|
newtio.c_cc[VMIN] = 1;
|
||||||
|
|
||||||
|
/* using the raw data mode */
|
||||||
|
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||||
|
newtio.c_oflag &= ~OPOST;
|
||||||
|
|
||||||
|
/* flush the hardware fifo */
|
||||||
|
tcflush(m_serial_fd, TCIFLUSH);
|
||||||
|
|
||||||
|
/* activite the configuration */
|
||||||
|
if ((tcsetattr(m_serial_fd, TCSANOW, &newtio)) != 0)
|
||||||
|
{
|
||||||
|
DERROR( "fail to active configuration\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _serialStart(const char* dev_name, int baud_rate)
|
||||||
|
{
|
||||||
|
const char* ptemp;
|
||||||
|
if (dev_name == NULL)
|
||||||
|
{
|
||||||
|
ptemp = "/dev/ttyUSB0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptemp = dev_name;
|
||||||
|
}
|
||||||
|
if (true == _serialOpen(ptemp) &&
|
||||||
|
true == _serialConfig(baud_rate, 8, 'N', 1))
|
||||||
|
{
|
||||||
|
|
||||||
|
FD_ZERO(&m_serial_fd_set);
|
||||||
|
FD_SET(m_serial_fd, &m_serial_fd_set);
|
||||||
|
return m_serial_fd;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _serialWrite(const uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
return write(m_serial_fd, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _serialRead(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
int saved = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (NULL == buf)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; saved < len;)
|
||||||
|
{
|
||||||
|
ret = read(m_serial_fd, buf + saved, len - saved);
|
||||||
|
if (ret > 0)
|
||||||
|
saved += ret;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
/*! @file DJIHardDriverManifold.cpp
|
||||||
|
* @version 3.1.7
|
||||||
|
* @date Jul 01 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Serial device hardware abstraction for DJI Onboard SDK command line example.
|
||||||
|
* Note that this is a generic Linux serial device abstraction even though it
|
||||||
|
* is called HardDriverManifold.
|
||||||
|
* This may be changed in a future release.
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "DJIHardDriverManifold.h"
|
||||||
|
|
||||||
|
using namespace DJI::onboardSDK;
|
||||||
|
|
||||||
|
HardDriverManifold::HardDriverManifold(std::string device, uint32_t baudrate)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
m_baudrate = baudrate;
|
||||||
|
m_memLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
m_msgLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
HardDriverManifold::~HardDriverManifold()
|
||||||
|
{
|
||||||
|
_serialClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::init()
|
||||||
|
{
|
||||||
|
DSTATUS( "going to open device %s with baudrate %u...\n",
|
||||||
|
m_device.c_str(), m_baudrate);
|
||||||
|
if (_serialStart(m_device.c_str(), m_baudrate) < 0)
|
||||||
|
{
|
||||||
|
_serialClose();
|
||||||
|
DERROR( "...fail to start serial\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DSTATUS( "...succeed to start serial\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implement a USB hand-shaking protocol for SDK
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
HardDriverManifold::usbHandshake(std::string device)
|
||||||
|
{
|
||||||
|
_serialStart(device.c_str(), 38400);
|
||||||
|
_serialStart(device.c_str(), 19200);
|
||||||
|
_serialStart(device.c_str(), 38400);
|
||||||
|
_serialStart(device.c_str(), 19200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::setBaudrate(uint32_t baudrate)
|
||||||
|
{
|
||||||
|
m_baudrate = baudrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::setDevice(std::string device)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
DJI::OSDK::time_ms
|
||||||
|
HardDriverManifold::getTimeStamp()
|
||||||
|
{
|
||||||
|
return (uint32_t)time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
HardDriverManifold::send(const uint8_t* buf, size_t len)
|
||||||
|
{
|
||||||
|
return _serialWrite(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
HardDriverManifold::readall(uint8_t* buf, size_t maxlen)
|
||||||
|
{
|
||||||
|
return _serialRead(buf, maxlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::lockMemory()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_memLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::freeMemory()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_memLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::lockMSG()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&m_msgLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HardDriverManifold::freeMSG()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&m_msgLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HardDriverManifold::_serialOpen(const char* dev)
|
||||||
|
{
|
||||||
|
m_serial_fd = open(dev, O_RDWR | O_NOCTTY);
|
||||||
|
if (m_serial_fd < 0)
|
||||||
|
{
|
||||||
|
DERROR( "cannot open device %s\n", dev);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HardDriverManifold::_serialClose()
|
||||||
|
{
|
||||||
|
close(m_serial_fd);
|
||||||
|
m_serial_fd = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HardDriverManifold::_serialFlush()
|
||||||
|
{
|
||||||
|
if (m_serial_fd < 0)
|
||||||
|
{
|
||||||
|
DERROR( "flushing fail because no device is opened\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcflush(m_serial_fd, TCIFLUSH);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HardDriverManifold::_serialConfig(int baudrate, char data_bits,
|
||||||
|
char parity_bits, char stop_bits)
|
||||||
|
{
|
||||||
|
int st_baud[] = { B4800, B9600, B19200, B38400, B57600, B115200, B230400 };
|
||||||
|
int std_rate[] = {
|
||||||
|
4800, 9600, 19200, 38400, 57600, 115200, 230400, 1000000, 1152000, 3000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
struct termios newtio, oldtio;
|
||||||
|
/* save current port parameter */
|
||||||
|
if (tcgetattr(m_serial_fd, &oldtio) != 0)
|
||||||
|
{
|
||||||
|
DERROR( "fail to save current port\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(&newtio, 0, sizeof(newtio));
|
||||||
|
|
||||||
|
/* config the size of char */
|
||||||
|
newtio.c_cflag |= CLOCAL | CREAD;
|
||||||
|
newtio.c_cflag &= ~CSIZE;
|
||||||
|
|
||||||
|
/* config data bit */
|
||||||
|
switch (data_bits)
|
||||||
|
{
|
||||||
|
case 7:
|
||||||
|
newtio.c_cflag |= CS7;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
newtio.c_cflag |= CS8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* config the parity bit */
|
||||||
|
switch (parity_bits)
|
||||||
|
{
|
||||||
|
/* odd */
|
||||||
|
case 'O':
|
||||||
|
case 'o':
|
||||||
|
newtio.c_cflag |= PARENB;
|
||||||
|
newtio.c_cflag |= PARODD;
|
||||||
|
break;
|
||||||
|
/* even */
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
newtio.c_cflag |= PARENB;
|
||||||
|
newtio.c_cflag &= ~PARODD;
|
||||||
|
break;
|
||||||
|
/* none */
|
||||||
|
case 'N':
|
||||||
|
case 'n':
|
||||||
|
newtio.c_cflag &= ~PARENB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* config baudrate */
|
||||||
|
j = sizeof(std_rate) / 4;
|
||||||
|
for (i = 0; i < j; ++i)
|
||||||
|
{
|
||||||
|
if (std_rate[i] == baudrate)
|
||||||
|
{
|
||||||
|
/* set standard baudrate */
|
||||||
|
cfsetispeed(&newtio, st_baud[i]);
|
||||||
|
cfsetospeed(&newtio, st_baud[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* config stop bit */
|
||||||
|
if (stop_bits == 1)
|
||||||
|
newtio.c_cflag &= ~CSTOPB;
|
||||||
|
else if (stop_bits == 2)
|
||||||
|
newtio.c_cflag |= CSTOPB;
|
||||||
|
|
||||||
|
/* config waiting time & min number of char */
|
||||||
|
newtio.c_cc[VTIME] = 5;
|
||||||
|
newtio.c_cc[VMIN] = 18;
|
||||||
|
|
||||||
|
/* using the raw data mode */
|
||||||
|
newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||||
|
newtio.c_oflag &= ~OPOST;
|
||||||
|
|
||||||
|
/* flush the hardware fifo */
|
||||||
|
tcflush(m_serial_fd, TCIFLUSH);
|
||||||
|
|
||||||
|
/* activite the configuration */
|
||||||
|
if ((tcsetattr(m_serial_fd, TCSANOW, &newtio)) != 0)
|
||||||
|
{
|
||||||
|
DERROR( "fail to active configuration\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
HardDriverManifold::_serialStart(const char* dev_name, int baud_rate)
|
||||||
|
{
|
||||||
|
const char* ptemp;
|
||||||
|
if (dev_name == NULL)
|
||||||
|
{
|
||||||
|
ptemp = "/dev/ttyUSB0";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptemp = dev_name;
|
||||||
|
}
|
||||||
|
if (true == _serialOpen(ptemp) && true == _serialConfig(baud_rate, 8, 'N', 1))
|
||||||
|
{
|
||||||
|
|
||||||
|
FD_ZERO(&m_serial_fd_set);
|
||||||
|
FD_SET(m_serial_fd, &m_serial_fd_set);
|
||||||
|
return m_serial_fd;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
HardDriverManifold::_serialWrite(const uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
return write(m_serial_fd, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
HardDriverManifold::_serialRead(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
int saved = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (NULL == buf)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = read(m_serial_fd, buf + saved, len - saved);
|
||||||
|
if (ret > 0)
|
||||||
|
saved += ret;
|
||||||
|
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*! @file DJI_HardDriver_Qt.h
|
||||||
|
* @version 3.1.7
|
||||||
|
* @date Jul 01 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Serial device hardware abstraction for DJI Onboard SDK Qt example.
|
||||||
|
*
|
||||||
|
* @note New Qt sample coming soon!
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* 2016 DJI. All rights reserved.
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef QONBOARDSDK_H
|
||||||
|
#define QONBOARDSDK_H
|
||||||
|
|
||||||
|
#include <DJI_API.h>
|
||||||
|
#include <DJI_Flight.h>
|
||||||
|
#include <DJI_Follow.h>
|
||||||
|
#include <DJI_HardDriver.h>
|
||||||
|
#include <DJI_VirtualRC.h>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QItemDelegate>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QSerialPort>
|
||||||
|
#include <QSerialPortInfo>
|
||||||
|
#include <QThread>
|
||||||
|
#include <dji_camera.hpp>
|
||||||
|
#include <dji_hot_point.hpp>
|
||||||
|
#include <dji_waypoint.hpp>
|
||||||
|
|
||||||
|
#include <QTextBrowser>
|
||||||
|
|
||||||
|
//! @warning not good to use using in header file
|
||||||
|
using namespace DJI::onboardSDK;
|
||||||
|
|
||||||
|
class QHardDriver : public HardDriver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QHardDriver(QSerialPort* Port);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
DJI::OSDK::time_ms getTimeStamp();
|
||||||
|
size_t send(const uint8_t* buf, size_t len);
|
||||||
|
size_t readall(uint8_t* buf, size_t maxlen);
|
||||||
|
|
||||||
|
void lockMemory();
|
||||||
|
void freeMemory();
|
||||||
|
|
||||||
|
void lockMSG();
|
||||||
|
void freeMSG();
|
||||||
|
|
||||||
|
void displayLog(const char* buf = 0);
|
||||||
|
|
||||||
|
void setBaudrate(int value);
|
||||||
|
|
||||||
|
QTextBrowser* getDisplay() const;
|
||||||
|
void setDisplay(QTextBrowser* value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHardDriver();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int baudrate;
|
||||||
|
QSerialPort* port;
|
||||||
|
QMutex memory;
|
||||||
|
QMutex msg;
|
||||||
|
QMutex sendLock;
|
||||||
|
QMutex bufferLock;
|
||||||
|
QTextBrowser* display;
|
||||||
|
};
|
||||||
|
|
||||||
|
class APIThread : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
APIThread();
|
||||||
|
APIThread(CoreAPI* API, int Type, QObject* parent = 0);
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
size_t getCallTimes() const;
|
||||||
|
void setCallTimes(const size_t& value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CoreAPI* api;
|
||||||
|
int type;
|
||||||
|
size_t callTimes;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @note widget for GUI
|
||||||
|
class TurnModeDelegate : public QItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
TurnModeDelegate(QObject* parent = 0)
|
||||||
|
: QItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QWidget* createEditor(QWidget* parent,
|
||||||
|
const QStyleOptionViewItem& option __UNUSED,
|
||||||
|
const QModelIndex& index __UNUSED) const
|
||||||
|
{
|
||||||
|
QComboBox* editor = new QComboBox(parent);
|
||||||
|
editor->addItem("Clockwise");
|
||||||
|
editor->addItem("Counter-clockwise");
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
void setEditorData(QWidget* editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QString text = index.model()->data(index, Qt::EditRole).toString();
|
||||||
|
QComboBox* comboBox = static_cast<QComboBox*>(editor);
|
||||||
|
int tindex = comboBox->findText(text);
|
||||||
|
comboBox->setCurrentIndex(tindex);
|
||||||
|
}
|
||||||
|
void setModelData(QWidget* editor, QAbstractItemModel* model,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QComboBox* comboBox = static_cast<QComboBox*>(editor);
|
||||||
|
QString text = comboBox->currentText();
|
||||||
|
model->setData(index, text, Qt::EditRole);
|
||||||
|
}
|
||||||
|
void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index __UNUSED) const
|
||||||
|
{
|
||||||
|
editor->setGeometry(option.rect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionDelegate : public QItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ActionDelegate(QObject* parent = 0)
|
||||||
|
: QItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QWidget* createEditor(QWidget* parent,
|
||||||
|
const QStyleOptionViewItem& option __UNUSED,
|
||||||
|
const QModelIndex& index __UNUSED) const
|
||||||
|
{
|
||||||
|
QComboBox* editor = new QComboBox(parent);
|
||||||
|
editor->addItem("Stay");
|
||||||
|
editor->addItem("Take picture");
|
||||||
|
editor->addItem("Start recording");
|
||||||
|
editor->addItem("Stop recording");
|
||||||
|
editor->addItem("Yaw");
|
||||||
|
editor->addItem("Gimbal pitch");
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
void setEditorData(QWidget* editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QString text = index.model()->data(index, Qt::EditRole).toString();
|
||||||
|
QComboBox* comboBox = static_cast<QComboBox*>(editor);
|
||||||
|
int tindex = comboBox->findText(text);
|
||||||
|
comboBox->setCurrentIndex(tindex);
|
||||||
|
}
|
||||||
|
void setModelData(QWidget* editor, QAbstractItemModel* model,
|
||||||
|
const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QComboBox* comboBox = static_cast<QComboBox*>(editor);
|
||||||
|
QString text = comboBox->currentText();
|
||||||
|
model->setData(index, text, Qt::EditRole);
|
||||||
|
}
|
||||||
|
void updateEditorGeometry(QWidget* editor,
|
||||||
|
const QStyleOptionViewItem& option __UNUSED,
|
||||||
|
const QModelIndex& index __UNUSED) const
|
||||||
|
{
|
||||||
|
editor->setGeometry(option.rect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReadOnlyDelegate : public QItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ReadOnlyDelegate(QObject* parent = 0)
|
||||||
|
: QItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QWidget* createEditor(QWidget* parent __UNUSED,
|
||||||
|
const QStyleOptionViewItem& option __UNUSED,
|
||||||
|
const QModelIndex& index __UNUSED) const
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QONBOARDSDK_H
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
#include "QonboardSDK.h"
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
|
QHardDriver::QHardDriver()
|
||||||
|
{
|
||||||
|
port = 0;
|
||||||
|
baudrate = 9600;
|
||||||
|
}
|
||||||
|
QTextBrowser*
|
||||||
|
QHardDriver::getDisplay() const
|
||||||
|
{
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::setDisplay(QTextBrowser* value)
|
||||||
|
{
|
||||||
|
display = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHardDriver::QHardDriver(QSerialPort* Port)
|
||||||
|
{
|
||||||
|
port = Port;
|
||||||
|
baudrate = 9600;
|
||||||
|
display = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::init()
|
||||||
|
{
|
||||||
|
if (port != 0)
|
||||||
|
{
|
||||||
|
if (port->isOpen())
|
||||||
|
port->close();
|
||||||
|
port->setBaudRate(baudrate);
|
||||||
|
port->setParity(QSerialPort::NoParity);
|
||||||
|
port->setDataBits(QSerialPort::Data8);
|
||||||
|
port->setStopBits(QSerialPort::OneStop);
|
||||||
|
if (port->open(QIODevice::ReadWrite))
|
||||||
|
{
|
||||||
|
API_LOG(this, STATUS_LOG, "port %s open success",
|
||||||
|
port->portName().toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
API_LOG(this, ERROR_LOG, "fail to open port %s",
|
||||||
|
port->portName().toLocal8Bit().data());
|
||||||
|
}
|
||||||
|
API_LOG(this, STATUS_LOG, "BaudRate: %d", port->baudRate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DJI::time_ms
|
||||||
|
QHardDriver::getTimeStamp()
|
||||||
|
{
|
||||||
|
return QDateTime::currentMSecsSinceEpoch();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
QHardDriver::send(const uint8_t* buf, size_t len)
|
||||||
|
{
|
||||||
|
sendLock.lock();
|
||||||
|
size_t sent = 0;
|
||||||
|
if (port != 0)
|
||||||
|
{
|
||||||
|
if (port->isOpen())
|
||||||
|
while (sent != len)
|
||||||
|
{
|
||||||
|
sent += port->write((char*)(buf + sent), len);
|
||||||
|
port->waitForBytesWritten(2);
|
||||||
|
}
|
||||||
|
sendLock.unlock();
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sendLock.unlock();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sendLock.unlock();
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
QHardDriver::readall(uint8_t* buf, size_t maxlen)
|
||||||
|
{
|
||||||
|
size_t ans = 0;
|
||||||
|
if (port != 0)
|
||||||
|
{
|
||||||
|
if (port->isOpen())
|
||||||
|
if (port->bytesAvailable() > 0)
|
||||||
|
ans = port->read((char*)buf, maxlen);
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::lockMemory()
|
||||||
|
{
|
||||||
|
memory.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::freeMemory()
|
||||||
|
{
|
||||||
|
memory.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::lockMSG()
|
||||||
|
{
|
||||||
|
msg.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::freeMSG()
|
||||||
|
{
|
||||||
|
msg.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::displayLog(const char* buf)
|
||||||
|
{
|
||||||
|
if (buf)
|
||||||
|
qDebug("%s", buf);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (display)
|
||||||
|
{
|
||||||
|
bufferLock.lock();
|
||||||
|
QString data = QString(DJI::onboardSDK::buffer);
|
||||||
|
size_t len = data.length();
|
||||||
|
if (len < DJI::onboardSDK::bufsize)
|
||||||
|
display->append(data);
|
||||||
|
bufferLock.unlock();
|
||||||
|
display->verticalScrollBar()->setValue(
|
||||||
|
display->verticalScrollBar()->maximum());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufferLock.lock();
|
||||||
|
qDebug("%s", DJI::onboardSDK::buffer);
|
||||||
|
bufferLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QHardDriver::setBaudrate(int value)
|
||||||
|
{
|
||||||
|
baudrate = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
APIThread::APIThread(CoreAPI* API, int Type, QObject* parent)
|
||||||
|
: QThread(parent)
|
||||||
|
{
|
||||||
|
api = API;
|
||||||
|
type = Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
APIThread::run()
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
callTimes++;
|
||||||
|
if (type == 1)
|
||||||
|
api->sendPoll();
|
||||||
|
else if (type == 2)
|
||||||
|
api->readPoll();
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t
|
||||||
|
APIThread::getCallTimes() const
|
||||||
|
{
|
||||||
|
return callTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
APIThread::setCallTimes(const size_t& value)
|
||||||
|
{
|
||||||
|
callTimes = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
APIThread::APIThread()
|
||||||
|
{
|
||||||
|
api = 0;
|
||||||
|
type = 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/** @file AES256.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 12th, 2017
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_AES256_H
|
||||||
|
#define ONBOARDSDK_AES256_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct tagAES256Context
|
||||||
|
{
|
||||||
|
uint8_t key[32];
|
||||||
|
uint8_t enckey[32];
|
||||||
|
uint8_t deckey[32];
|
||||||
|
} aes256_context;
|
||||||
|
|
||||||
|
typedef void (*ptr_aes256_codec)(aes256_context* ctx, uint8_t* buf);
|
||||||
|
|
||||||
|
uint8_t rj_xtime(uint8_t x);
|
||||||
|
void aes_subBytes(uint8_t* buf);
|
||||||
|
void aes_subBytes_inv(uint8_t* buf);
|
||||||
|
void aes_addRoundKey(uint8_t* buf, uint8_t* key);
|
||||||
|
void aes_addRoundKey_cpy(uint8_t* buf, uint8_t* key, uint8_t* cpk);
|
||||||
|
void aes_shiftRows(uint8_t* buf);
|
||||||
|
void aes_shiftRows_inv(uint8_t* buf);
|
||||||
|
void aes_mixColumns(uint8_t* buf);
|
||||||
|
void aes_mixColumns_inv(uint8_t* buf);
|
||||||
|
void aes_expandEncKey(uint8_t* k, uint8_t* rc);
|
||||||
|
void aes_expandDecKey(uint8_t* k, uint8_t* rc);
|
||||||
|
void aes256_init(aes256_context* ctx, uint8_t* k);
|
||||||
|
void aes256_done(aes256_context* ctx);
|
||||||
|
void aes256_encrypt_ecb(aes256_context* ctx, uint8_t* buf);
|
||||||
|
void aes256_decrypt_ecb(aes256_context* ctx, uint8_t* buf);
|
||||||
|
|
||||||
|
#endif // ONBOARDSDK_AES256_H
|
||||||
@@ -0,0 +1,383 @@
|
|||||||
|
/** @file dji_open_protocol.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* OPEN Protocol implementation for DJI Onboard SDK library
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ONBOARDSDK_INTERNAL_DJI_PROTOCOLLAYER_H
|
||||||
|
#define ONBOARDSDK_INTERNAL_DJI_PROTOCOLLAYER_H
|
||||||
|
|
||||||
|
#include "dji_ack.hpp"
|
||||||
|
#include "dji_aes.hpp"
|
||||||
|
#include "dji_hard_driver.hpp"
|
||||||
|
#include "dji_log.hpp"
|
||||||
|
#include "dji_thread_manager.hpp"
|
||||||
|
#include "dji_type.hpp"
|
||||||
|
/*! Platform includes:
|
||||||
|
* This set of macros figures out which files to include based on your
|
||||||
|
* platform.
|
||||||
|
*/
|
||||||
|
#ifdef __linux__
|
||||||
|
//! handle array of characters
|
||||||
|
#include "linux_serial_device.hpp"
|
||||||
|
#include "posix_thread_manager.hpp"
|
||||||
|
#include <cstring>
|
||||||
|
#elif STM32
|
||||||
|
//! handle array of characters
|
||||||
|
#include <STM32F4DataGuard.h>
|
||||||
|
#include <STM32F4SerialDriver.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#elif defined(qt)
|
||||||
|
#include <QHardDriver.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/****************************Globals**************************************/
|
||||||
|
|
||||||
|
#define MSG_ENABLE_FLAG_LEN 2
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// App layer function
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t sequence_number;
|
||||||
|
uint8_t session_id : 5;
|
||||||
|
uint8_t need_encrypt : 1;
|
||||||
|
uint8_t reserve : 2;
|
||||||
|
} req_id_t;
|
||||||
|
|
||||||
|
#define SET_CMD_SIZE (2u)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Session Management
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define ACK_SESSION_IDLE 0
|
||||||
|
#define ACK_SESSION_PROCESS 1
|
||||||
|
#define ACK_SESSION_USING 2
|
||||||
|
#define CMD_SESSION_0 0
|
||||||
|
#define CMD_SESSION_1 1
|
||||||
|
#define CMD_SESSION_AUTO 32
|
||||||
|
|
||||||
|
#define POLL_TICK 20 // unit is ms
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Receive Management
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct RecvContainer
|
||||||
|
{
|
||||||
|
DJI::OSDK::ACK::Entry recvInfo;
|
||||||
|
DJI::OSDK::ACK::TypeUnion recvData;
|
||||||
|
DJI::OSDK::DispatchInfo dispatchInfo;
|
||||||
|
} RecvContainer;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Codec Management
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define _SDK_U32_SET(_addr, _val) (*((uint32_t*)(_addr)) = (_val))
|
||||||
|
#define _SDK_U16_SET(_addr, _val) (*((uint16_t*)(_addr)) = (_val))
|
||||||
|
|
||||||
|
#define _SDK_CALC_CRC_HEAD(_msg, _len) \
|
||||||
|
sdk_stream_crc16_calc((const uint8_t*)(_msg), _len)
|
||||||
|
#define _SDK_CALC_CRC_TAIL(_msg, _len) \
|
||||||
|
sdk_stream_crc32_calc((const uint8_t*)(_msg), _len)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// CRC Management
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
const uint16_t crc_tab16[] = {
|
||||||
|
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601,
|
||||||
|
0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0,
|
||||||
|
0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81,
|
||||||
|
0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941,
|
||||||
|
0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01,
|
||||||
|
0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0,
|
||||||
|
0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081,
|
||||||
|
0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
|
||||||
|
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00,
|
||||||
|
0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0,
|
||||||
|
0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981,
|
||||||
|
0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41,
|
||||||
|
0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700,
|
||||||
|
0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0,
|
||||||
|
0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281,
|
||||||
|
0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
|
||||||
|
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01,
|
||||||
|
0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1,
|
||||||
|
0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80,
|
||||||
|
0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541,
|
||||||
|
0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101,
|
||||||
|
0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0,
|
||||||
|
0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481,
|
||||||
|
0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
|
||||||
|
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801,
|
||||||
|
0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1,
|
||||||
|
0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581,
|
||||||
|
0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341,
|
||||||
|
0x4100, 0x81c1, 0x8081, 0x4040
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t crc_tab32[] = {
|
||||||
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||||
|
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||||
|
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||||
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||||
|
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||||
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||||
|
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||||
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||||
|
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||||
|
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||||
|
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||||
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||||
|
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||||
|
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||||
|
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||||
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||||
|
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||||
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||||
|
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||||
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||||
|
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||||
|
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||||
|
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||||
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||||
|
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||||
|
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||||
|
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||||
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||||
|
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||||
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||||
|
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||||
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||||
|
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||||
|
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||||
|
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||||
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||||
|
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||||
|
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||||
|
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||||
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||||
|
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t CRC_INIT = 0x3AA3;
|
||||||
|
|
||||||
|
// const uint8_t encrypt = 0;
|
||||||
|
/*
|
||||||
|
#else
|
||||||
|
uint8_t encrypt = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! @todo template Protocol for V1 V2 and SDK
|
||||||
|
//! more abstaction
|
||||||
|
class Protocol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
Protocol(const char* device, uint32_t baudRate);
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
~Protocol()
|
||||||
|
{
|
||||||
|
delete (this->serialDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************Public Interfaces**********************************/
|
||||||
|
//! Send - callers are from above the ProtocolLayer
|
||||||
|
|
||||||
|
/*
|
||||||
|
void send(uint8_t session_mode, uint8_t is_enc, DJI_CONTROLLER_CMD
|
||||||
|
cmd_set,
|
||||||
|
uint8_t cmd_id, void *pdata, int len, bool isCallback, int
|
||||||
|
callbackID,
|
||||||
|
/** @note Compatible for DJI_APP_Pro_send
|
||||||
|
int timeout = 0, int retry_time = 1);
|
||||||
|
*/
|
||||||
|
void send(uint8_t session_mode, bool is_enc, const uint8_t cmd[], void* pdata,
|
||||||
|
size_t len, int timeout = 0, int retry_time = 1,
|
||||||
|
bool hasCallback = false, int callbackID = 0
|
||||||
|
/** @note Better interface entrance*/
|
||||||
|
);
|
||||||
|
/** @note Main interface*/
|
||||||
|
void send(Command* parameter);
|
||||||
|
|
||||||
|
//! SendPoll:
|
||||||
|
void sendPoll();
|
||||||
|
|
||||||
|
/************************Receive Management********************************/
|
||||||
|
|
||||||
|
RecvContainer receive();
|
||||||
|
/************************Getters and setters*******************************/
|
||||||
|
/**
|
||||||
|
* Get serial device handler.
|
||||||
|
*/
|
||||||
|
HardDriver* getDriver() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get handler to thread data.
|
||||||
|
*/
|
||||||
|
ThreadAbstract* getThreadHandle() const;
|
||||||
|
|
||||||
|
/**********************************Fitlered******************************/
|
||||||
|
void setKey(const char* key);
|
||||||
|
|
||||||
|
/************************Useful frame-related constants*******************/
|
||||||
|
public:
|
||||||
|
static const int BUFFER_SIZE = 1024;
|
||||||
|
static const int ACK_SIZE = 10;
|
||||||
|
static const uint8_t SOF = 0xAA;
|
||||||
|
static const int maxRecv = BUFFER_SIZE;
|
||||||
|
static const int CRCHead = sizeof(uint16_t);
|
||||||
|
static const int CRCData = sizeof(uint32_t);
|
||||||
|
static const int CRCHeadLen = sizeof(Header) - CRCHead;
|
||||||
|
static const int PackageMin = sizeof(Header) + CRCData;
|
||||||
|
uint8_t buf[BUFFER_SIZE];
|
||||||
|
|
||||||
|
private:
|
||||||
|
/***************************Init*******************************************/
|
||||||
|
void init(HardDriver* Driver, MMU* mmuPtr, bool userCallbackThread = false);
|
||||||
|
|
||||||
|
/***************************Receive Pipeline*******************************/
|
||||||
|
|
||||||
|
typedef struct SDKFilter
|
||||||
|
{
|
||||||
|
uint16_t reuseIndex;
|
||||||
|
uint16_t reuseCount;
|
||||||
|
uint16_t recvIndex;
|
||||||
|
uint8_t recvBuf[BUFFER_SIZE];
|
||||||
|
// for encrypt
|
||||||
|
uint8_t sdkKey[32];
|
||||||
|
uint8_t encode;
|
||||||
|
} SDKFilter;
|
||||||
|
|
||||||
|
//! Lowest-level function interfaces with SerialDevice
|
||||||
|
bool readPoll(RecvContainer* allocatedRecvObject);
|
||||||
|
//! Handle incoming data - byte level
|
||||||
|
//! STM32 uses it directly
|
||||||
|
public:
|
||||||
|
bool byteHandler(const uint8_t in_data, RecvContainer* allocatedRecvObject);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Integrity checks for incoming data.
|
||||||
|
bool streamHandler(SDKFilter* p_filter, uint8_t in_data,
|
||||||
|
RecvContainer* allocatedRecvObject);
|
||||||
|
void storeData(SDKFilter* p_filter, uint8_t in_data);
|
||||||
|
bool checkStream(SDKFilter* p_filter, RecvContainer* allocatedRecvObject);
|
||||||
|
bool verifyHead(SDKFilter* p_filter, RecvContainer* allocatedRecvObject);
|
||||||
|
bool verifyData(SDKFilter* p_filter, RecvContainer* allocatedRecvObject);
|
||||||
|
|
||||||
|
//! Once checks are done, find out which branch of the receive pipeline to go
|
||||||
|
//! to
|
||||||
|
bool callApp(SDKFilter* p_filter, RecvContainer* allocatedRecvObject);
|
||||||
|
|
||||||
|
//! For CMD-Frame data (push data) handling
|
||||||
|
bool recvReqData(Header* protocolHeader, RecvContainer* allocatedRecvObject);
|
||||||
|
|
||||||
|
//! A lot of ACK parsing logic is implemented here! It shouldn't be. @todo:
|
||||||
|
//! Update the function
|
||||||
|
bool appHandler(Header* protocolHeader, RecvContainer* allocatedRecvObject);
|
||||||
|
|
||||||
|
//! CMD receive
|
||||||
|
uint8_t getCmdCode(Header* protocolHeader);
|
||||||
|
uint8_t getCmdSet(Header* protocolHeader);
|
||||||
|
|
||||||
|
/*******************************Send Pipeline*****************************/
|
||||||
|
|
||||||
|
int sendInterface(Command* cmdContainer);
|
||||||
|
void sendData(uint8_t* buf);
|
||||||
|
|
||||||
|
/****************************Multithreading support***********************/
|
||||||
|
//! Thread sync for ACK
|
||||||
|
ACK::TypeUnion allocateACK(Header* protocolHeader);
|
||||||
|
|
||||||
|
void setACKFrameStatus(uint32_t usageFlag);
|
||||||
|
|
||||||
|
/****************************Session Management***************************/
|
||||||
|
|
||||||
|
void setup(void);
|
||||||
|
void setupSession(void);
|
||||||
|
|
||||||
|
void freeSession(CMDSession* session);
|
||||||
|
CMDSession* allocSession(uint16_t session_id, uint16_t size);
|
||||||
|
|
||||||
|
void freeACK(ACKSession* session);
|
||||||
|
ACKSession* allocACK(uint16_t session_id, uint16_t size);
|
||||||
|
|
||||||
|
/*******************************Encryption*******************************/
|
||||||
|
uint16_t encrypt(uint8_t* pdest, const uint8_t* psrc, uint16_t w_len,
|
||||||
|
uint8_t is_ack, uint8_t is_enc, uint8_t session_id,
|
||||||
|
uint16_t seq_num);
|
||||||
|
void encodeData(SDKFilter* p_filter, Header* p_head,
|
||||||
|
ptr_aes256_codec codec_func);
|
||||||
|
|
||||||
|
/*******************************Utility Functions************************/
|
||||||
|
uint16_t calculateLength(uint16_t size, uint16_t encrypt_flag);
|
||||||
|
|
||||||
|
void transformTwoByte(const char* pstr, uint8_t* pdata);
|
||||||
|
/***********************************CRC***********************************/
|
||||||
|
void calculateCRC(void* p_data);
|
||||||
|
uint16_t crc16_update(uint16_t crc, uint8_t ch);
|
||||||
|
uint32_t crc32_update(uint32_t crc, uint8_t ch);
|
||||||
|
uint16_t sdk_stream_crc16_calc(const uint8_t* pMsg, size_t nLen);
|
||||||
|
uint32_t sdk_stream_crc32_calc(const uint8_t* pMsg, size_t nLen);
|
||||||
|
void sdk_stream_prepare_lambda(SDKFilter* p_filter);
|
||||||
|
void sdk_stream_shift_data_lambda(SDKFilter* p_filter);
|
||||||
|
void sdk_stream_update_reuse_part_lambda(SDKFilter* p_filter);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/********************************Member variables*************************/
|
||||||
|
|
||||||
|
//! Serial driver pointer
|
||||||
|
HardDriver* serialDevice;
|
||||||
|
|
||||||
|
//! Memory management
|
||||||
|
MMU* mmu;
|
||||||
|
|
||||||
|
//! Session Management
|
||||||
|
CMDSession CMDSessionTab[SESSION_TABLE_NUM];
|
||||||
|
ACKSession ACKSessionTab[SESSION_TABLE_NUM - 1];
|
||||||
|
|
||||||
|
//! Serial filter
|
||||||
|
SDKFilter filter;
|
||||||
|
|
||||||
|
//! Encode buffers
|
||||||
|
uint8_t encodeSendData[BUFFER_SIZE];
|
||||||
|
uint8_t encodeACK[ACK_SIZE];
|
||||||
|
|
||||||
|
//! Thread data
|
||||||
|
bool stopCond;
|
||||||
|
ThreadAbstract* threadHandle;
|
||||||
|
|
||||||
|
//! Frame-related.
|
||||||
|
uint16_t seq_num;
|
||||||
|
uint32_t ackFrameStatus;
|
||||||
|
bool broadcastFrameStatus;
|
||||||
|
|
||||||
|
//! Buffer management
|
||||||
|
|
||||||
|
int buf_read_pos;
|
||||||
|
int read_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // ONBOARDSDK_INTERNAL_DJI_PROTOCOLLAYER_H
|
||||||
@@ -0,0 +1,436 @@
|
|||||||
|
/** @file AES256.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date April 12th, 2017
|
||||||
|
*
|
||||||
|
* @copyright 2016-17 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_aes.hpp"
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// BEGIN OF AES-256
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
* Byte-oriented AES-256 implementation.
|
||||||
|
* All lookup tables replaced with 'on the fly' calculations.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
|
||||||
|
* Other contributors: Hal Finney
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define F(x) (((x) << 1) ^ ((((x) >> 7) & 1) * 0x1b))
|
||||||
|
#define FD(x) (((x) >> 1) ^ (((x)&1) ? 0x8d : 0))
|
||||||
|
|
||||||
|
#define BACK_TO_TABLES
|
||||||
|
#ifdef BACK_TO_TABLES
|
||||||
|
|
||||||
|
const uint8_t sbox[256] = {
|
||||||
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe,
|
||||||
|
0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4,
|
||||||
|
0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7,
|
||||||
|
0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3,
|
||||||
|
0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09,
|
||||||
|
0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3,
|
||||||
|
0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe,
|
||||||
|
0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||||
|
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92,
|
||||||
|
0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,
|
||||||
|
0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
|
||||||
|
0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
|
||||||
|
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2,
|
||||||
|
0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5,
|
||||||
|
0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25,
|
||||||
|
0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||||
|
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86,
|
||||||
|
0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e,
|
||||||
|
0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42,
|
||||||
|
0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||||
|
};
|
||||||
|
const uint8_t sboxinv[256] = {
|
||||||
|
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81,
|
||||||
|
0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e,
|
||||||
|
0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23,
|
||||||
|
0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66,
|
||||||
|
0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72,
|
||||||
|
0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65,
|
||||||
|
0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46,
|
||||||
|
0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
|
||||||
|
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca,
|
||||||
|
0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91,
|
||||||
|
0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
|
||||||
|
0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
|
||||||
|
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f,
|
||||||
|
0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2,
|
||||||
|
0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8,
|
||||||
|
0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||||
|
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93,
|
||||||
|
0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb,
|
||||||
|
0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,
|
||||||
|
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||||
|
};
|
||||||
|
|
||||||
|
#define rj_sbox(x) sbox[(x)]
|
||||||
|
#define rj_sbox_inv(x) sboxinv[(x)]
|
||||||
|
|
||||||
|
#else /* tableless subroutines */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
|
||||||
|
{
|
||||||
|
uint8_t atb = 1, z;
|
||||||
|
|
||||||
|
while (x--)
|
||||||
|
{
|
||||||
|
z = atb;
|
||||||
|
atb <<= 1;
|
||||||
|
if (z & 0x80)
|
||||||
|
atb ^= 0x1b;
|
||||||
|
atb ^= z;
|
||||||
|
}
|
||||||
|
|
||||||
|
return atb;
|
||||||
|
} /* gf_alog */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
|
||||||
|
{
|
||||||
|
uint8_t atb = 1, i = 0, z;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (atb == x)
|
||||||
|
break;
|
||||||
|
z = atb;
|
||||||
|
atb <<= 1;
|
||||||
|
if (z & 0x80)
|
||||||
|
atb ^= 0x1b;
|
||||||
|
atb ^= z;
|
||||||
|
} while (++i > 0);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
} /* gf_log */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
|
||||||
|
{
|
||||||
|
return (x) ? gf_alog(255 - gf_log(x)) : 0;
|
||||||
|
} /* gf_mulinv */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
uint8_t
|
||||||
|
rj_sbox(uint8_t x)
|
||||||
|
{
|
||||||
|
uint8_t y, sb;
|
||||||
|
|
||||||
|
sb = y = gf_mulinv(x);
|
||||||
|
y = (y << 1) | (y >> 7);
|
||||||
|
sb ^= y;
|
||||||
|
y = (y << 1) | (y >> 7);
|
||||||
|
sb ^= y;
|
||||||
|
y = (y << 1) | (y >> 7);
|
||||||
|
sb ^= y;
|
||||||
|
y = (y << 1) | (y >> 7);
|
||||||
|
sb ^= y;
|
||||||
|
|
||||||
|
return (sb ^ 0x63);
|
||||||
|
} /* rj_sbox */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
uint8_t
|
||||||
|
rj_sbox_inv(uint8_t x)
|
||||||
|
{
|
||||||
|
uint8_t y, sb;
|
||||||
|
|
||||||
|
y = x ^ 0x63;
|
||||||
|
sb = y = (y << 1) | (y >> 7);
|
||||||
|
y = (y << 2) | (y >> 6);
|
||||||
|
sb ^= y;
|
||||||
|
y = (y << 3) | (y >> 5);
|
||||||
|
sb ^= y;
|
||||||
|
|
||||||
|
return gf_mulinv(sb);
|
||||||
|
} /* rj_sbox_inv */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
uint8_t
|
||||||
|
rj_xtime(uint8_t x)
|
||||||
|
{
|
||||||
|
return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);
|
||||||
|
} /* rj_xtime */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_subBytes(uint8_t* buf)
|
||||||
|
{
|
||||||
|
register uint8_t i = 16;
|
||||||
|
|
||||||
|
while (i--)
|
||||||
|
buf[i] = rj_sbox(buf[i]);
|
||||||
|
} /* aes_subBytes */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_subBytes_inv(uint8_t* buf)
|
||||||
|
{
|
||||||
|
register uint8_t i = 16;
|
||||||
|
|
||||||
|
while (i--)
|
||||||
|
buf[i] = rj_sbox_inv(buf[i]);
|
||||||
|
} /* aes_subBytes_inv */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_addRoundKey(uint8_t* buf, uint8_t* key)
|
||||||
|
{
|
||||||
|
register uint8_t i = 16;
|
||||||
|
|
||||||
|
while (i--)
|
||||||
|
buf[i] ^= key[i];
|
||||||
|
} /* aes_addRoundKey */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_addRoundKey_cpy(uint8_t* buf, uint8_t* key, uint8_t* cpk)
|
||||||
|
{
|
||||||
|
register uint8_t i = 16;
|
||||||
|
|
||||||
|
while (i--)
|
||||||
|
buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];
|
||||||
|
} /* aes_addRoundKey_cpy */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_shiftRows(uint8_t* buf)
|
||||||
|
{
|
||||||
|
register uint8_t i, j; /* to make it potentially parallelable :) */
|
||||||
|
|
||||||
|
i = buf[1];
|
||||||
|
buf[1] = buf[5];
|
||||||
|
buf[5] = buf[9];
|
||||||
|
buf[9] = buf[13];
|
||||||
|
buf[13] = i;
|
||||||
|
i = buf[10];
|
||||||
|
buf[10] = buf[2];
|
||||||
|
buf[2] = i;
|
||||||
|
j = buf[3];
|
||||||
|
buf[3] = buf[15];
|
||||||
|
buf[15] = buf[11];
|
||||||
|
buf[11] = buf[7];
|
||||||
|
buf[7] = j;
|
||||||
|
j = buf[14];
|
||||||
|
buf[14] = buf[6];
|
||||||
|
buf[6] = j;
|
||||||
|
|
||||||
|
} /* aes_shiftRows */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_shiftRows_inv(uint8_t* buf)
|
||||||
|
{
|
||||||
|
register uint8_t i, j; /* same as above :) */
|
||||||
|
|
||||||
|
i = buf[1];
|
||||||
|
buf[1] = buf[13];
|
||||||
|
buf[13] = buf[9];
|
||||||
|
buf[9] = buf[5];
|
||||||
|
buf[5] = i;
|
||||||
|
i = buf[2];
|
||||||
|
buf[2] = buf[10];
|
||||||
|
buf[10] = i;
|
||||||
|
j = buf[3];
|
||||||
|
buf[3] = buf[7];
|
||||||
|
buf[7] = buf[11];
|
||||||
|
buf[11] = buf[15];
|
||||||
|
buf[15] = j;
|
||||||
|
j = buf[6];
|
||||||
|
buf[6] = buf[14];
|
||||||
|
buf[14] = j;
|
||||||
|
|
||||||
|
} /* aes_shiftRows_inv */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_mixColumns(uint8_t* buf)
|
||||||
|
{
|
||||||
|
register uint8_t i, a, b, c, d, e;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i += 4)
|
||||||
|
{
|
||||||
|
a = buf[i];
|
||||||
|
b = buf[i + 1];
|
||||||
|
c = buf[i + 2];
|
||||||
|
d = buf[i + 3];
|
||||||
|
e = a ^ b ^ c ^ d;
|
||||||
|
buf[i] ^= e ^ rj_xtime(a ^ b);
|
||||||
|
buf[i + 1] ^= e ^ rj_xtime(b ^ c);
|
||||||
|
buf[i + 2] ^= e ^ rj_xtime(c ^ d);
|
||||||
|
buf[i + 3] ^= e ^ rj_xtime(d ^ a);
|
||||||
|
}
|
||||||
|
} /* aes_mixColumns */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_mixColumns_inv(uint8_t* buf)
|
||||||
|
{
|
||||||
|
register uint8_t i, a, b, c, d, e, x, y, z;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i += 4)
|
||||||
|
{
|
||||||
|
a = buf[i];
|
||||||
|
b = buf[i + 1];
|
||||||
|
c = buf[i + 2];
|
||||||
|
d = buf[i + 3];
|
||||||
|
e = a ^ b ^ c ^ d;
|
||||||
|
z = rj_xtime(e);
|
||||||
|
x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
|
||||||
|
y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
|
||||||
|
buf[i] ^= x ^ rj_xtime(a ^ b);
|
||||||
|
buf[i + 1] ^= y ^ rj_xtime(b ^ c);
|
||||||
|
buf[i + 2] ^= x ^ rj_xtime(c ^ d);
|
||||||
|
buf[i + 3] ^= y ^ rj_xtime(d ^ a);
|
||||||
|
}
|
||||||
|
} /* aes_mixColumns_inv */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_expandEncKey(uint8_t* k, uint8_t* rc)
|
||||||
|
{
|
||||||
|
register uint8_t i;
|
||||||
|
|
||||||
|
k[0] ^= rj_sbox(k[29]) ^ (*rc);
|
||||||
|
k[1] ^= rj_sbox(k[30]);
|
||||||
|
k[2] ^= rj_sbox(k[31]);
|
||||||
|
k[3] ^= rj_sbox(k[28]);
|
||||||
|
*rc = F(*rc);
|
||||||
|
|
||||||
|
for (i = 4; i < 16; i += 4)
|
||||||
|
k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2],
|
||||||
|
k[i + 3] ^= k[i - 1];
|
||||||
|
k[16] ^= rj_sbox(k[12]);
|
||||||
|
k[17] ^= rj_sbox(k[13]);
|
||||||
|
k[18] ^= rj_sbox(k[14]);
|
||||||
|
k[19] ^= rj_sbox(k[15]);
|
||||||
|
|
||||||
|
for (i = 20; i < 32; i += 4)
|
||||||
|
k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2],
|
||||||
|
k[i + 3] ^= k[i - 1];
|
||||||
|
|
||||||
|
} /* aes_expandEncKey */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes_expandDecKey(uint8_t* k, uint8_t* rc)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i = 28; i > 16; i -= 4)
|
||||||
|
k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2],
|
||||||
|
k[i + 3] ^= k[i - 1];
|
||||||
|
|
||||||
|
k[16] ^= rj_sbox(k[12]);
|
||||||
|
k[17] ^= rj_sbox(k[13]);
|
||||||
|
k[18] ^= rj_sbox(k[14]);
|
||||||
|
k[19] ^= rj_sbox(k[15]);
|
||||||
|
|
||||||
|
for (i = 12; i > 0; i -= 4)
|
||||||
|
k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], k[i + 2] ^= k[i - 2],
|
||||||
|
k[i + 3] ^= k[i - 1];
|
||||||
|
|
||||||
|
*rc = FD(*rc);
|
||||||
|
k[0] ^= rj_sbox(k[29]) ^ (*rc);
|
||||||
|
k[1] ^= rj_sbox(k[30]);
|
||||||
|
k[2] ^= rj_sbox(k[31]);
|
||||||
|
k[3] ^= rj_sbox(k[28]);
|
||||||
|
} /* aes_expandDecKey */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes256_init(aes256_context* ctx, uint8_t* k)
|
||||||
|
{
|
||||||
|
uint8_t rcon = 1;
|
||||||
|
register uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ctx->key); i++)
|
||||||
|
ctx->enckey[i] = ctx->deckey[i] = k[i];
|
||||||
|
for (i = 8; --i;)
|
||||||
|
aes_expandEncKey(ctx->deckey, &rcon);
|
||||||
|
} /* aes256_init */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes256_done(aes256_context* ctx)
|
||||||
|
{
|
||||||
|
register uint8_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ctx->key); i++)
|
||||||
|
ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
|
||||||
|
} /* aes256_done */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes256_encrypt_ecb(aes256_context* ctx, uint8_t* buf)
|
||||||
|
{
|
||||||
|
uint8_t i, rcon;
|
||||||
|
|
||||||
|
aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
|
||||||
|
for (i = 1, rcon = 1; i < 14; ++i)
|
||||||
|
{
|
||||||
|
aes_subBytes(buf);
|
||||||
|
aes_shiftRows(buf);
|
||||||
|
aes_mixColumns(buf);
|
||||||
|
if (i & 1)
|
||||||
|
{
|
||||||
|
aes_addRoundKey(buf, &ctx->key[16]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aes_subBytes(buf);
|
||||||
|
aes_shiftRows(buf);
|
||||||
|
aes_expandEncKey(ctx->key, &rcon);
|
||||||
|
aes_addRoundKey(buf, ctx->key);
|
||||||
|
} /* aes256_encrypt */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
void
|
||||||
|
aes256_decrypt_ecb(aes256_context* ctx, uint8_t* buf)
|
||||||
|
{
|
||||||
|
uint8_t i, rcon;
|
||||||
|
|
||||||
|
aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
|
||||||
|
aes_shiftRows_inv(buf);
|
||||||
|
aes_subBytes_inv(buf);
|
||||||
|
|
||||||
|
for (i = 14, rcon = 0x80; --i;) //! @note exit when --i == 0;
|
||||||
|
{
|
||||||
|
if ((i & 1))
|
||||||
|
{
|
||||||
|
aes_expandDecKey(ctx->key, &rcon);
|
||||||
|
aes_addRoundKey(buf, &ctx->key[16]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
aes_addRoundKey(buf, ctx->key);
|
||||||
|
aes_mixColumns_inv(buf);
|
||||||
|
aes_shiftRows_inv(buf);
|
||||||
|
aes_subBytes_inv(buf);
|
||||||
|
}
|
||||||
|
aes_addRoundKey(buf, ctx->key);
|
||||||
|
} /* aes256_decrypt */
|
||||||
|
|
||||||
|
// END OF AES-256
|
||||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,48 @@
|
|||||||
|
/** @file dji_circular_buffer.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 2017
|
||||||
|
*
|
||||||
|
* @brief Circular buffer class for the DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_open_protocol.hpp"
|
||||||
|
#include "dji_vehicle_callback.hpp"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#if STM32
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/*! @brief Circular buffer for callback function storage
|
||||||
|
*
|
||||||
|
* @details This buffer is not currently generic, so do not use it for any other
|
||||||
|
* purpose.
|
||||||
|
*/
|
||||||
|
class CircularBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int cbPush(CircularBuffer* CBuffer, VehicleCallBackHandler data,
|
||||||
|
RecvContainer data2);
|
||||||
|
int cbPop(CircularBuffer* CBuffer, VehicleCallBackHandler* data,
|
||||||
|
RecvContainer* data2);
|
||||||
|
CircularBuffer();
|
||||||
|
~CircularBuffer();
|
||||||
|
int head;
|
||||||
|
int tail;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VehicleCallBackHandler* buffer;
|
||||||
|
RecvContainer* buffer2;
|
||||||
|
const int maxLen;
|
||||||
|
}; // class CircularBuffer
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/** @file dji_singleton.hpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 2017
|
||||||
|
*
|
||||||
|
* @brief Singleton Template Class implementation for use with the DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SINGLETON_H
|
||||||
|
#define SINGLETON_H
|
||||||
|
|
||||||
|
namespace DJI
|
||||||
|
{
|
||||||
|
namespace OSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Singleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef T type;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Singleton();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~Singleton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static T& instance();
|
||||||
|
static T* instancePTR();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static T* singleInstance;
|
||||||
|
}; // class Singleton<T>
|
||||||
|
|
||||||
|
// template implementation
|
||||||
|
template <class T>
|
||||||
|
Singleton<T>::Singleton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T&
|
||||||
|
Singleton<T>::instance()
|
||||||
|
{
|
||||||
|
return *Singleton<T>::singleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T*
|
||||||
|
Singleton<T>::instancePTR()
|
||||||
|
{
|
||||||
|
return Singleton<T>::singleInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T* Singleton<T>::singleInstance = new T();
|
||||||
|
|
||||||
|
} // namespace OSDK
|
||||||
|
} // namespace DJI
|
||||||
|
|
||||||
|
#endif // SINGLETON_H
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/** @file dji_circular_buffer.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date Jun 2017
|
||||||
|
*
|
||||||
|
* @brief Circular buffer class for the DJI OSDK
|
||||||
|
*
|
||||||
|
* @copyright 2017 DJI. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dji_circular_buffer.hpp"
|
||||||
|
|
||||||
|
using namespace DJI;
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
CircularBuffer::CircularBuffer()
|
||||||
|
: maxLen(5000)
|
||||||
|
{
|
||||||
|
buffer =
|
||||||
|
(VehicleCallBackHandler*)malloc(5000 * sizeof(VehicleCallBackHandler));
|
||||||
|
buffer2 = (RecvContainer*)malloc(5000 * sizeof(RecvContainer));
|
||||||
|
head = 0;
|
||||||
|
tail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CircularBuffer::cbPush(CircularBuffer* CBuffer,
|
||||||
|
DJI::OSDK::VehicleCallBackHandler cbData,
|
||||||
|
RecvContainer recvData)
|
||||||
|
{
|
||||||
|
int next = head + 1;
|
||||||
|
if (next >= maxLen)
|
||||||
|
{
|
||||||
|
next = 0;
|
||||||
|
}
|
||||||
|
//! Circular buffer is full, pop the old value and discard.
|
||||||
|
if (next == tail)
|
||||||
|
{
|
||||||
|
CBuffer->cbPop(CBuffer, &cbData, &recvData);
|
||||||
|
DSTATUS("Warning: Circular Buffer Full. Discarded Callback from Tail \n");
|
||||||
|
}
|
||||||
|
buffer2[head] = recvData;
|
||||||
|
buffer[head] = cbData;
|
||||||
|
head = next;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
CircularBuffer::cbPop(CircularBuffer* CBuffer,
|
||||||
|
DJI::OSDK::VehicleCallBackHandler* cbData,
|
||||||
|
RecvContainer* recvData)
|
||||||
|
{
|
||||||
|
if (head == tail)
|
||||||
|
{
|
||||||
|
DSTATUS("Circular Buffer empty \n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*cbData = buffer[tail];
|
||||||
|
*recvData = buffer2[tail];
|
||||||
|
|
||||||
|
//! Clear data
|
||||||
|
memset(&buffer[tail], 0, sizeof(VehicleCallBackHandler));
|
||||||
|
memset(&buffer2[tail], 0, sizeof(RecvContainer));
|
||||||
|
|
||||||
|
int next = tail + 1;
|
||||||
|
if (next >= maxLen)
|
||||||
|
next = 0;
|
||||||
|
tail = next;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#include "dji_singleton.hpp"
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#comming soon
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
/*! @file BspUsart.cpp
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Usart helper functions and ISR for board STM32F4Discovery
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "BspUsart.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
extern int Rx_Handle_Flag;
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
extern Vehicle vehicle;
|
||||||
|
extern Vehicle* v;
|
||||||
|
extern Control control;
|
||||||
|
|
||||||
|
extern bool isFrame;
|
||||||
|
bool isACKProcessed = false;
|
||||||
|
bool ackReceivedByUser = false;
|
||||||
|
extern RecvContainer receivedFramie;
|
||||||
|
extern RecvContainer* rFrame;
|
||||||
|
|
||||||
|
// extern CoreAPI defaultAPI;
|
||||||
|
// extern CoreAPI *coreApi;
|
||||||
|
// extern Flight flight;
|
||||||
|
// extern FlightData flightData;
|
||||||
|
|
||||||
|
extern uint8_t come_data;
|
||||||
|
extern uint8_t Rx_length;
|
||||||
|
extern int Rx_adr;
|
||||||
|
extern int Rx_Handle_Flag;
|
||||||
|
extern uint8_t Rx_buff[];
|
||||||
|
|
||||||
|
void
|
||||||
|
USART2_Gpio_Config(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
||||||
|
|
||||||
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||||
|
|
||||||
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // tx
|
||||||
|
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // rx
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USART3_Gpio_Config(void)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef GPIO_InitStructure;
|
||||||
|
|
||||||
|
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
||||||
|
|
||||||
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
|
||||||
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||||
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||||
|
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||||
|
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||||
|
|
||||||
|
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); // tx
|
||||||
|
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3); // rx
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USART2 is used for receiving commands from PC and
|
||||||
|
* printing debug information to PC
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
USART2_Config(void)
|
||||||
|
{
|
||||||
|
USART2_Gpio_Config();
|
||||||
|
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||||
|
USART_InitTypeDef USART_InitStructure;
|
||||||
|
|
||||||
|
USART_InitStructure.USART_BaudRate = 115200;
|
||||||
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||||
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||||
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||||
|
USART_InitStructure.USART_HardwareFlowControl =
|
||||||
|
USART_HardwareFlowControl_None;
|
||||||
|
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||||
|
|
||||||
|
USART_Init(USART2, &USART_InitStructure);
|
||||||
|
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
|
||||||
|
|
||||||
|
USART_Cmd(USART2, ENABLE);
|
||||||
|
|
||||||
|
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) != SET)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USART3 is used for communicating with the DJI flight controller
|
||||||
|
* The Baud rate needs to match the Baud rate used by the flight controller
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
USART3_Config(void)
|
||||||
|
{
|
||||||
|
USART3_Gpio_Config();
|
||||||
|
|
||||||
|
USART_InitTypeDef USART_InitStructure;
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||||
|
|
||||||
|
USART_InitStructure.USART_BaudRate = 230400;
|
||||||
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||||
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||||
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||||
|
USART_InitStructure.USART_HardwareFlowControl =
|
||||||
|
USART_HardwareFlowControl_None;
|
||||||
|
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||||
|
|
||||||
|
USART_Init(USART3, &USART_InitStructure);
|
||||||
|
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
|
||||||
|
|
||||||
|
USART_Cmd(USART3, ENABLE);
|
||||||
|
while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) != SET)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
USARTxNVIC_Config()
|
||||||
|
{
|
||||||
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
|
||||||
|
|
||||||
|
NVIC_InitTypeDef NVIC_InitStructure_USART3;
|
||||||
|
NVIC_InitStructure_USART3.NVIC_IRQChannelPreemptionPriority = 0x04;
|
||||||
|
NVIC_InitStructure_USART3.NVIC_IRQChannelSubPriority = 0x03;
|
||||||
|
NVIC_InitStructure_USART3.NVIC_IRQChannel = USART3_IRQn;
|
||||||
|
NVIC_InitStructure_USART3.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure_USART3);
|
||||||
|
|
||||||
|
NVIC_InitTypeDef NVIC_InitStructure_USART2;
|
||||||
|
NVIC_InitStructure_USART2.NVIC_IRQChannelPreemptionPriority = 0x03;
|
||||||
|
NVIC_InitStructure_USART2.NVIC_IRQChannelSubPriority = 0x02;
|
||||||
|
NVIC_InitStructure_USART2.NVIC_IRQChannel = USART2_IRQn;
|
||||||
|
NVIC_InitStructure_USART2.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure_USART2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UsartConfig()
|
||||||
|
{
|
||||||
|
USART2_Config();
|
||||||
|
USART3_Config();
|
||||||
|
USARTxNVIC_Config();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
DJI::OSDK::ACK::ErrorCode
|
||||||
|
waitForACK()
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
ack.data = ACK_NO_RESPONSE_ERROR;
|
||||||
|
memset(&(ack.data), 0, sizeof(ack.data));
|
||||||
|
uint32_t next500MilTick;
|
||||||
|
uint8_t cmd[] = {rFrame->recvInfo.cmd_set, rFrame->recvInfo.cmd_id};
|
||||||
|
|
||||||
|
// next500MilTick = v->protocolLayer->getDriver()->getTimeStamp() + 500;
|
||||||
|
|
||||||
|
// while(rFrame->dispatchInfo.isCallback != true &&
|
||||||
|
// v->protocolLayer->getDriver()->getTimeStamp() < next500MilTick)
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (isACKProcessed == true)
|
||||||
|
{
|
||||||
|
if (rFrame->recvInfo.cmd_set == DJI::OSDK::CMD_SET_ACTIVATION &&
|
||||||
|
rFrame->recvInfo.cmd_id == DJI::OSDK::CMD_ID_ACTIVATE)
|
||||||
|
{
|
||||||
|
ack.data = rFrame->recvData.ack;
|
||||||
|
ack.info = rFrame->recvInfo;
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
else if (rFrame->recvInfo.cmd_set == DJI::OSDK::CMD_SET_SUBSCRIBE &&
|
||||||
|
rFrame->recvInfo.cmd_id ==
|
||||||
|
DJI::OSDK::CMD_ID_SUBSCRIBE_VERSION_MATCH)
|
||||||
|
{
|
||||||
|
ack.data = rFrame->recvData.ack;
|
||||||
|
ack.info = rFrame->recvInfo;
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
else if (rFrame->recvInfo.cmd_set == DJI::OSDK::CMD_SET_SUBSCRIBE &&
|
||||||
|
rFrame->recvInfo.cmd_id ==
|
||||||
|
DJI::OSDK::CMD_ID_SUBSCRIBE_ADD_PACKAGE)
|
||||||
|
{
|
||||||
|
ack.data = rFrame->recvData.ack;
|
||||||
|
ack.info = rFrame->recvInfo;
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
else if (rFrame->recvInfo.cmd_set == DJI::OSDK::CMD_SET_CONTROL &&
|
||||||
|
rFrame->recvInfo.cmd_id == DJI::OSDK::CMD_ID_TASK)
|
||||||
|
{
|
||||||
|
ack.data = rFrame->recvData.ack;
|
||||||
|
ack.info = rFrame->recvInfo;
|
||||||
|
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return ack;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
void
|
||||||
|
USART3_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET)
|
||||||
|
{
|
||||||
|
isACKProcessed = false;
|
||||||
|
isFrame = v->protocolLayer->byteHandler(USART_ReceiveData(USART3), rFrame);
|
||||||
|
if (isFrame == true)
|
||||||
|
{
|
||||||
|
//! Trigger default or user defined callback
|
||||||
|
v->processReceivedData(*rFrame);
|
||||||
|
|
||||||
|
//! Reset
|
||||||
|
isFrame = false;
|
||||||
|
isACKProcessed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif //__cplusplus
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*! @file BspUsart.h
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Usart helper functions and ISR for board STM32F4Discovery
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef _BSPUSART_H
|
||||||
|
#define _BSPUSART_H
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
#include "stdio.h"
|
||||||
|
void USART2_Config(void);
|
||||||
|
void USART3_Config(void);
|
||||||
|
void USARTxNVIC_Config(void);
|
||||||
|
void UsartConfig(void);
|
||||||
|
void NVIC_Config(void);
|
||||||
|
void Rx_buff_Handler();
|
||||||
|
DJI::OSDK::ACK::ErrorCode waitForACK();
|
||||||
|
#endif //_USART_H
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*! @file bsp.cpp
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Helper functions for board STM32F4Discovery
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "bsp.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
BSPinit()
|
||||||
|
{
|
||||||
|
UsartConfig();
|
||||||
|
SystickConfig();
|
||||||
|
Timer1Config();
|
||||||
|
Timer2Config();
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
/*! @file bsp.h
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Helper functions for board STM32F4Discovery
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef BSP_H
|
||||||
|
#define BSP_H
|
||||||
|
|
||||||
|
void BSPinit();
|
||||||
|
|
||||||
|
#endif // BSP_H
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
/*! @file timer.cpp
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Timer helper functions and ISR for board STM32F4Discovery
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "stm32f4xx.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
uint32_t tick = 0; // tick is the time stamp,which record how many ms since u
|
||||||
|
// initialize the system.
|
||||||
|
/*extern VirtualRC virtualrc;
|
||||||
|
extern VirtualRCData myVRCdata;
|
||||||
|
extern FlightData flightData;
|
||||||
|
extern Flight flight;
|
||||||
|
*/
|
||||||
|
extern uint8_t Rx_buff[];
|
||||||
|
extern TerminalCommand myTerminal;
|
||||||
|
|
||||||
|
void
|
||||||
|
Timer1Config()
|
||||||
|
{
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
|
||||||
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
|
|
||||||
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
|
||||||
|
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||||
|
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
TIM_TimeBaseInitStructure.TIM_Period =
|
||||||
|
(200 - 1); // t is the time between each Timer irq.
|
||||||
|
TIM_TimeBaseInitStructure.TIM_Prescaler =
|
||||||
|
(8400 - 1); // t = (1+TIM_Prescaler/SystemCoreClock)*(1+TIM_Period)
|
||||||
|
TIM_TimeBaseInitStructure.TIM_RepetitionCounter =
|
||||||
|
0x00; // here configure TIM1 in 50Hz
|
||||||
|
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
|
||||||
|
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
|
|
||||||
|
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
|
||||||
|
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
|
||||||
|
TIM_Cmd(TIM1, DISABLE);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
Timer2Config()
|
||||||
|
{
|
||||||
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||||||
|
NVIC_InitTypeDef NVIC_InitStructure;
|
||||||
|
|
||||||
|
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
|
||||||
|
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||||
|
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
|
TIM_TimeBaseInitStructure.TIM_Period =
|
||||||
|
(200 - 1); // t is the time between each Timer irq.
|
||||||
|
TIM_TimeBaseInitStructure.TIM_Period =
|
||||||
|
(40 - 1); // t is the time between each Timer irq.
|
||||||
|
TIM_TimeBaseInitStructure.TIM_Prescaler =
|
||||||
|
(42000 - 1); // t = (1+TIM_Prescaler/SystemCoreClock)*(1+TIM_Period)
|
||||||
|
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
|
||||||
|
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
|
||||||
|
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||||
|
NVIC_Init(&NVIC_InitStructure);
|
||||||
|
|
||||||
|
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
|
||||||
|
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
|
||||||
|
TIM_Cmd(TIM2, DISABLE);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
SystickConfig()
|
||||||
|
{
|
||||||
|
if (SysTick_Config(SystemCoreClock / 1000)) // 1000 ticks per second.
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
; // run here when error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
delay_nms(uint16_t time)
|
||||||
|
{
|
||||||
|
u32 i = 0;
|
||||||
|
while (time--)
|
||||||
|
{
|
||||||
|
i = 30000;
|
||||||
|
while (i--)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
void
|
||||||
|
SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
if (tick > 4233600000ll) // 49 days non-reset would cost a tick reset.
|
||||||
|
{
|
||||||
|
tick = 0;
|
||||||
|
}
|
||||||
|
tick++;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
TIM1_UP_TIM10_IRQHandler(void)
|
||||||
|
{
|
||||||
|
if (TIM_GetITStatus(TIM1, TIM_IT_Update) == SET)
|
||||||
|
{
|
||||||
|
// virtualrc.sendData(myVRCdata);
|
||||||
|
}
|
||||||
|
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TIM2_IRQHandler()
|
||||||
|
{
|
||||||
|
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
|
||||||
|
{
|
||||||
|
if ((myTerminal.cmdIn[2] == 0x04) && (myTerminal.cmdIn[3] == 0x01))
|
||||||
|
{
|
||||||
|
// flight.setFlight(&flightData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TIM_Cmd(TIM2, DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
|
||||||
|
}
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif //__cplusplus
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*! @file timer.h
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Timer helper functions and ISR for board STM32F4Discovery
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
void SystickConfig();
|
||||||
|
void Timer1Config();
|
||||||
|
void Timer2Config();
|
||||||
|
void delay_nms(uint16_t time);
|
||||||
|
|
||||||
|
#endif // TIMER_H
|
||||||
@@ -0,0 +1,435 @@
|
|||||||
|
;******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
|
||||||
|
;* File Name : startup_stm32f40_41xxx.s
|
||||||
|
;* Author : MCD Application Team
|
||||||
|
;* Version : V1.3.0
|
||||||
|
;* Date : 08-November-2013
|
||||||
|
;* Description : STM32F40xxx/41xxx devices vector table for MDK-ARM toolchain.
|
||||||
|
;* This module performs:
|
||||||
|
;* - Set the initial SP
|
||||||
|
;* - Set the initial PC == Reset_Handler
|
||||||
|
;* - Set the vector table entries with the exceptions ISR address
|
||||||
|
;* - Configure the system clock and the external SRAM mounted on
|
||||||
|
;* STM324xG-EVAL board to be used as data memory (optional,
|
||||||
|
;* to be enabled by user)
|
||||||
|
;* - Branches to __main in the C library (which eventually
|
||||||
|
;* calls main()).
|
||||||
|
;* After Reset the CortexM4 processor is in Thread mode,
|
||||||
|
;* priority is Privileged, and the Stack is set to Main.
|
||||||
|
;* <<< Use Configuration Wizard in Context Menu >>>
|
||||||
|
;*******************************************************************************
|
||||||
|
;
|
||||||
|
; Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||||
|
; You may not use this file except in compliance with the License.
|
||||||
|
; You may obtain a copy of the License at:
|
||||||
|
;
|
||||||
|
; http://www.st.com/software_license_agreement_liberty_v2
|
||||||
|
;
|
||||||
|
; Unless required by applicable law or agreed to in writing, software
|
||||||
|
; distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
; See the License for the specific language governing permissions and
|
||||||
|
; limitations under the License.
|
||||||
|
;
|
||||||
|
;*******************************************************************************
|
||||||
|
|
||||||
|
; Amount of memory (in bytes) allocated for Stack
|
||||||
|
; Tailor this value to your application needs
|
||||||
|
; <h> Stack Configuration
|
||||||
|
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||||
|
; </h>
|
||||||
|
|
||||||
|
Stack_Size EQU 0x00000400
|
||||||
|
|
||||||
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
|
Stack_Mem SPACE Stack_Size
|
||||||
|
__initial_sp
|
||||||
|
|
||||||
|
|
||||||
|
; <h> Heap Configuration
|
||||||
|
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||||
|
; </h>
|
||||||
|
|
||||||
|
;<h>Heap_Size EQU 0x00019990;<>
|
||||||
|
Heap_Size EQU 0x0008000
|
||||||
|
|
||||||
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
|
__heap_base
|
||||||
|
Heap_Mem SPACE Heap_Size
|
||||||
|
__heap_limit
|
||||||
|
|
||||||
|
PRESERVE8
|
||||||
|
THUMB
|
||||||
|
|
||||||
|
|
||||||
|
; Vector Table Mapped to Address 0 at Reset
|
||||||
|
AREA RESET, DATA, READONLY
|
||||||
|
EXPORT __Vectors
|
||||||
|
EXPORT __Vectors_End
|
||||||
|
EXPORT __Vectors_Size
|
||||||
|
|
||||||
|
__Vectors DCD __initial_sp ; Top of Stack
|
||||||
|
DCD Reset_Handler ; Reset Handler
|
||||||
|
DCD NMI_Handler ; NMI Handler
|
||||||
|
DCD HardFault_Handler ; Hard Fault Handler
|
||||||
|
DCD MemManage_Handler ; MPU Fault Handler
|
||||||
|
DCD BusFault_Handler ; Bus Fault Handler
|
||||||
|
DCD UsageFault_Handler ; Usage Fault Handler
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD SVC_Handler ; SVCall Handler
|
||||||
|
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||||
|
DCD 0 ; Reserved
|
||||||
|
DCD PendSV_Handler ; PendSV Handler
|
||||||
|
DCD SysTick_Handler ; SysTick Handler
|
||||||
|
|
||||||
|
; External Interrupts
|
||||||
|
DCD WWDG_IRQHandler ; Window WatchDog
|
||||||
|
DCD PVD_IRQHandler ; PVD through EXTI Line detection
|
||||||
|
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
|
||||||
|
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
|
||||||
|
DCD FLASH_IRQHandler ; FLASH
|
||||||
|
DCD RCC_IRQHandler ; RCC
|
||||||
|
DCD EXTI0_IRQHandler ; EXTI Line0
|
||||||
|
DCD EXTI1_IRQHandler ; EXTI Line1
|
||||||
|
DCD EXTI2_IRQHandler ; EXTI Line2
|
||||||
|
DCD EXTI3_IRQHandler ; EXTI Line3
|
||||||
|
DCD EXTI4_IRQHandler ; EXTI Line4
|
||||||
|
DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0
|
||||||
|
DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1
|
||||||
|
DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2
|
||||||
|
DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3
|
||||||
|
DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4
|
||||||
|
DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5
|
||||||
|
DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6
|
||||||
|
DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s
|
||||||
|
DCD CAN1_TX_IRQHandler ; CAN1 TX
|
||||||
|
DCD CAN1_RX0_IRQHandler ; CAN1 RX0
|
||||||
|
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
|
||||||
|
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
|
||||||
|
DCD EXTI9_5_IRQHandler ; External Line[9:5]s
|
||||||
|
DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
|
||||||
|
DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
|
||||||
|
DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
|
||||||
|
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
|
||||||
|
DCD TIM2_IRQHandler ; TIM2
|
||||||
|
DCD TIM3_IRQHandler ; TIM3
|
||||||
|
DCD TIM4_IRQHandler ; TIM4
|
||||||
|
DCD I2C1_EV_IRQHandler ; I2C1 Event
|
||||||
|
DCD I2C1_ER_IRQHandler ; I2C1 Error
|
||||||
|
DCD I2C2_EV_IRQHandler ; I2C2 Event
|
||||||
|
DCD I2C2_ER_IRQHandler ; I2C2 Error
|
||||||
|
DCD SPI1_IRQHandler ; SPI1
|
||||||
|
DCD SPI2_IRQHandler ; SPI2
|
||||||
|
DCD USART1_IRQHandler ; USART1
|
||||||
|
DCD USART2_IRQHandler ; USART2
|
||||||
|
DCD USART3_IRQHandler ; USART3
|
||||||
|
DCD EXTI15_10_IRQHandler ; External Line[15:10]s
|
||||||
|
DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line
|
||||||
|
DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
|
||||||
|
DCD TIM8_BRK_TIM12_IRQHandler ; TIM8 Break and TIM12
|
||||||
|
DCD TIM8_UP_TIM13_IRQHandler ; TIM8 Update and TIM13
|
||||||
|
DCD TIM8_TRG_COM_TIM14_IRQHandler ; TIM8 Trigger and Commutation and TIM14
|
||||||
|
DCD TIM8_CC_IRQHandler ; TIM8 Capture Compare
|
||||||
|
DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7
|
||||||
|
DCD FSMC_IRQHandler ; FSMC
|
||||||
|
DCD SDIO_IRQHandler ; SDIO
|
||||||
|
DCD TIM5_IRQHandler ; TIM5
|
||||||
|
DCD SPI3_IRQHandler ; SPI3
|
||||||
|
DCD UART4_IRQHandler ; UART4
|
||||||
|
DCD UART5_IRQHandler ; UART5
|
||||||
|
DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors
|
||||||
|
DCD TIM7_IRQHandler ; TIM7
|
||||||
|
DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0
|
||||||
|
DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1
|
||||||
|
DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2
|
||||||
|
DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3
|
||||||
|
DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4
|
||||||
|
DCD ETH_IRQHandler ; Ethernet
|
||||||
|
DCD ETH_WKUP_IRQHandler ; Ethernet Wakeup through EXTI line
|
||||||
|
DCD CAN2_TX_IRQHandler ; CAN2 TX
|
||||||
|
DCD CAN2_RX0_IRQHandler ; CAN2 RX0
|
||||||
|
DCD CAN2_RX1_IRQHandler ; CAN2 RX1
|
||||||
|
DCD CAN2_SCE_IRQHandler ; CAN2 SCE
|
||||||
|
DCD OTG_FS_IRQHandler ; USB OTG FS
|
||||||
|
DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5
|
||||||
|
DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6
|
||||||
|
DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7
|
||||||
|
DCD USART6_IRQHandler ; USART6
|
||||||
|
DCD I2C3_EV_IRQHandler ; I2C3 event
|
||||||
|
DCD I2C3_ER_IRQHandler ; I2C3 error
|
||||||
|
DCD OTG_HS_EP1_OUT_IRQHandler ; USB OTG HS End Point 1 Out
|
||||||
|
DCD OTG_HS_EP1_IN_IRQHandler ; USB OTG HS End Point 1 In
|
||||||
|
DCD OTG_HS_WKUP_IRQHandler ; USB OTG HS Wakeup through EXTI
|
||||||
|
DCD OTG_HS_IRQHandler ; USB OTG HS
|
||||||
|
DCD DCMI_IRQHandler ; DCMI
|
||||||
|
DCD CRYP_IRQHandler ; CRYP crypto
|
||||||
|
DCD HASH_RNG_IRQHandler ; Hash and Rng
|
||||||
|
DCD FPU_IRQHandler ; FPU
|
||||||
|
|
||||||
|
__Vectors_End
|
||||||
|
|
||||||
|
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||||
|
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
; Reset handler
|
||||||
|
Reset_Handler PROC
|
||||||
|
EXPORT Reset_Handler [WEAK]
|
||||||
|
IMPORT SystemInit
|
||||||
|
IMPORT __main
|
||||||
|
|
||||||
|
LDR R0, =SystemInit
|
||||||
|
BLX R0
|
||||||
|
LDR R0, =__main
|
||||||
|
BX R0
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||||
|
|
||||||
|
NMI_Handler PROC
|
||||||
|
EXPORT NMI_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
HardFault_Handler\
|
||||||
|
PROC
|
||||||
|
EXPORT HardFault_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
MemManage_Handler\
|
||||||
|
PROC
|
||||||
|
EXPORT MemManage_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
BusFault_Handler\
|
||||||
|
PROC
|
||||||
|
EXPORT BusFault_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
UsageFault_Handler\
|
||||||
|
PROC
|
||||||
|
EXPORT UsageFault_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
SVC_Handler PROC
|
||||||
|
EXPORT SVC_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
DebugMon_Handler\
|
||||||
|
PROC
|
||||||
|
EXPORT DebugMon_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
PendSV_Handler PROC
|
||||||
|
EXPORT PendSV_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
SysTick_Handler PROC
|
||||||
|
EXPORT SysTick_Handler [WEAK]
|
||||||
|
B .
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
Default_Handler PROC
|
||||||
|
|
||||||
|
EXPORT WWDG_IRQHandler [WEAK]
|
||||||
|
EXPORT PVD_IRQHandler [WEAK]
|
||||||
|
EXPORT TAMP_STAMP_IRQHandler [WEAK]
|
||||||
|
EXPORT RTC_WKUP_IRQHandler [WEAK]
|
||||||
|
EXPORT FLASH_IRQHandler [WEAK]
|
||||||
|
EXPORT RCC_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI0_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI1_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI2_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI3_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI4_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream0_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream1_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream2_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream3_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream4_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream5_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream6_IRQHandler [WEAK]
|
||||||
|
EXPORT ADC_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN1_TX_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN1_RX0_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN1_RX1_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN1_SCE_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI9_5_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM1_BRK_TIM9_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM1_UP_TIM10_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM1_TRG_COM_TIM11_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM1_CC_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM2_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM3_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM4_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C1_EV_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C1_ER_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C2_EV_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C2_ER_IRQHandler [WEAK]
|
||||||
|
EXPORT SPI1_IRQHandler [WEAK]
|
||||||
|
EXPORT SPI2_IRQHandler [WEAK]
|
||||||
|
EXPORT USART1_IRQHandler [WEAK]
|
||||||
|
EXPORT USART2_IRQHandler [WEAK]
|
||||||
|
EXPORT USART3_IRQHandler [WEAK]
|
||||||
|
EXPORT EXTI15_10_IRQHandler [WEAK]
|
||||||
|
EXPORT RTC_Alarm_IRQHandler [WEAK]
|
||||||
|
EXPORT OTG_FS_WKUP_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM8_BRK_TIM12_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM8_UP_TIM13_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM8_TRG_COM_TIM14_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM8_CC_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA1_Stream7_IRQHandler [WEAK]
|
||||||
|
EXPORT FSMC_IRQHandler [WEAK]
|
||||||
|
EXPORT SDIO_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM5_IRQHandler [WEAK]
|
||||||
|
EXPORT SPI3_IRQHandler [WEAK]
|
||||||
|
EXPORT UART4_IRQHandler [WEAK]
|
||||||
|
EXPORT UART5_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM6_DAC_IRQHandler [WEAK]
|
||||||
|
EXPORT TIM7_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream0_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream1_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream2_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream3_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream4_IRQHandler [WEAK]
|
||||||
|
EXPORT ETH_IRQHandler [WEAK]
|
||||||
|
EXPORT ETH_WKUP_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN2_TX_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN2_RX0_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN2_RX1_IRQHandler [WEAK]
|
||||||
|
EXPORT CAN2_SCE_IRQHandler [WEAK]
|
||||||
|
EXPORT OTG_FS_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream5_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream6_IRQHandler [WEAK]
|
||||||
|
EXPORT DMA2_Stream7_IRQHandler [WEAK]
|
||||||
|
EXPORT USART6_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C3_EV_IRQHandler [WEAK]
|
||||||
|
EXPORT I2C3_ER_IRQHandler [WEAK]
|
||||||
|
EXPORT OTG_HS_EP1_OUT_IRQHandler [WEAK]
|
||||||
|
EXPORT OTG_HS_EP1_IN_IRQHandler [WEAK]
|
||||||
|
EXPORT OTG_HS_WKUP_IRQHandler [WEAK]
|
||||||
|
EXPORT OTG_HS_IRQHandler [WEAK]
|
||||||
|
EXPORT DCMI_IRQHandler [WEAK]
|
||||||
|
EXPORT CRYP_IRQHandler [WEAK]
|
||||||
|
EXPORT HASH_RNG_IRQHandler [WEAK]
|
||||||
|
EXPORT FPU_IRQHandler [WEAK]
|
||||||
|
|
||||||
|
WWDG_IRQHandler
|
||||||
|
PVD_IRQHandler
|
||||||
|
TAMP_STAMP_IRQHandler
|
||||||
|
RTC_WKUP_IRQHandler
|
||||||
|
FLASH_IRQHandler
|
||||||
|
RCC_IRQHandler
|
||||||
|
EXTI0_IRQHandler
|
||||||
|
EXTI1_IRQHandler
|
||||||
|
EXTI2_IRQHandler
|
||||||
|
EXTI3_IRQHandler
|
||||||
|
EXTI4_IRQHandler
|
||||||
|
DMA1_Stream0_IRQHandler
|
||||||
|
DMA1_Stream1_IRQHandler
|
||||||
|
DMA1_Stream2_IRQHandler
|
||||||
|
DMA1_Stream3_IRQHandler
|
||||||
|
DMA1_Stream4_IRQHandler
|
||||||
|
DMA1_Stream5_IRQHandler
|
||||||
|
DMA1_Stream6_IRQHandler
|
||||||
|
ADC_IRQHandler
|
||||||
|
CAN1_TX_IRQHandler
|
||||||
|
CAN1_RX0_IRQHandler
|
||||||
|
CAN1_RX1_IRQHandler
|
||||||
|
CAN1_SCE_IRQHandler
|
||||||
|
EXTI9_5_IRQHandler
|
||||||
|
TIM1_BRK_TIM9_IRQHandler
|
||||||
|
TIM1_UP_TIM10_IRQHandler
|
||||||
|
TIM1_TRG_COM_TIM11_IRQHandler
|
||||||
|
TIM1_CC_IRQHandler
|
||||||
|
TIM2_IRQHandler
|
||||||
|
TIM3_IRQHandler
|
||||||
|
TIM4_IRQHandler
|
||||||
|
I2C1_EV_IRQHandler
|
||||||
|
I2C1_ER_IRQHandler
|
||||||
|
I2C2_EV_IRQHandler
|
||||||
|
I2C2_ER_IRQHandler
|
||||||
|
SPI1_IRQHandler
|
||||||
|
SPI2_IRQHandler
|
||||||
|
USART1_IRQHandler
|
||||||
|
USART2_IRQHandler
|
||||||
|
USART3_IRQHandler
|
||||||
|
EXTI15_10_IRQHandler
|
||||||
|
RTC_Alarm_IRQHandler
|
||||||
|
OTG_FS_WKUP_IRQHandler
|
||||||
|
TIM8_BRK_TIM12_IRQHandler
|
||||||
|
TIM8_UP_TIM13_IRQHandler
|
||||||
|
TIM8_TRG_COM_TIM14_IRQHandler
|
||||||
|
TIM8_CC_IRQHandler
|
||||||
|
DMA1_Stream7_IRQHandler
|
||||||
|
FSMC_IRQHandler
|
||||||
|
SDIO_IRQHandler
|
||||||
|
TIM5_IRQHandler
|
||||||
|
SPI3_IRQHandler
|
||||||
|
UART4_IRQHandler
|
||||||
|
UART5_IRQHandler
|
||||||
|
TIM6_DAC_IRQHandler
|
||||||
|
TIM7_IRQHandler
|
||||||
|
DMA2_Stream0_IRQHandler
|
||||||
|
DMA2_Stream1_IRQHandler
|
||||||
|
DMA2_Stream2_IRQHandler
|
||||||
|
DMA2_Stream3_IRQHandler
|
||||||
|
DMA2_Stream4_IRQHandler
|
||||||
|
ETH_IRQHandler
|
||||||
|
ETH_WKUP_IRQHandler
|
||||||
|
CAN2_TX_IRQHandler
|
||||||
|
CAN2_RX0_IRQHandler
|
||||||
|
CAN2_RX1_IRQHandler
|
||||||
|
CAN2_SCE_IRQHandler
|
||||||
|
OTG_FS_IRQHandler
|
||||||
|
DMA2_Stream5_IRQHandler
|
||||||
|
DMA2_Stream6_IRQHandler
|
||||||
|
DMA2_Stream7_IRQHandler
|
||||||
|
USART6_IRQHandler
|
||||||
|
I2C3_EV_IRQHandler
|
||||||
|
I2C3_ER_IRQHandler
|
||||||
|
OTG_HS_EP1_OUT_IRQHandler
|
||||||
|
OTG_HS_EP1_IN_IRQHandler
|
||||||
|
OTG_HS_WKUP_IRQHandler
|
||||||
|
OTG_HS_IRQHandler
|
||||||
|
DCMI_IRQHandler
|
||||||
|
CRYP_IRQHandler
|
||||||
|
HASH_RNG_IRQHandler
|
||||||
|
FPU_IRQHandler
|
||||||
|
|
||||||
|
B .
|
||||||
|
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
ALIGN
|
||||||
|
|
||||||
|
;*******************************************************************************
|
||||||
|
; User Stack and Heap initialization
|
||||||
|
;*******************************************************************************
|
||||||
|
IF :DEF:__MICROLIB
|
||||||
|
|
||||||
|
EXPORT __initial_sp
|
||||||
|
EXPORT __heap_base
|
||||||
|
EXPORT __heap_limit
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
|
||||||
|
IMPORT __use_two_region_memory
|
||||||
|
EXPORT __user_initial_stackheap
|
||||||
|
|
||||||
|
__user_initial_stackheap
|
||||||
|
|
||||||
|
LDR R0, = Heap_Mem
|
||||||
|
LDR R1, =(Stack_Mem + Stack_Size)
|
||||||
|
LDR R2, = (Heap_Mem + Heap_Size)
|
||||||
|
LDR R3, = Stack_Mem
|
||||||
|
BX LR
|
||||||
|
|
||||||
|
ALIGN
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
END
|
||||||
|
|
||||||
|
;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
|
||||||
@@ -0,0 +1,828 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
|
||||||
|
|
||||||
|
<SchemaVersion>2.1</SchemaVersion>
|
||||||
|
|
||||||
|
<Header>### uVision Project, (C) Keil Software</Header>
|
||||||
|
|
||||||
|
<Targets>
|
||||||
|
<Target>
|
||||||
|
<TargetName>DJI_LIB</TargetName>
|
||||||
|
<ToolsetNumber>0x4</ToolsetNumber>
|
||||||
|
<ToolsetName>ARM-ADS</ToolsetName>
|
||||||
|
<pCCUsed>5060422::V5.06 update 4 (build 422)::ARMCC</pCCUsed>
|
||||||
|
<TargetOption>
|
||||||
|
<TargetCommonOption>
|
||||||
|
<Device>STM32F407VGTx</Device>
|
||||||
|
<Vendor>STMicroelectronics</Vendor>
|
||||||
|
<PackID>Keil.STM32F4xx_DFP.2.11.0</PackID>
|
||||||
|
<PackURL>http://www.keil.com/pack</PackURL>
|
||||||
|
<Cpu>IROM(0x08000000,0x100000) IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
|
||||||
|
<FlashUtilSpec></FlashUtilSpec>
|
||||||
|
<StartupFile></StartupFile>
|
||||||
|
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:STM32F407VGTx$CMSIS/Flash/STM32F4xx_1024.FLM))</FlashDriverDll>
|
||||||
|
<DeviceId>0</DeviceId>
|
||||||
|
<RegisterFile>$$Device:STM32F407VGTx$Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h</RegisterFile>
|
||||||
|
<MemoryEnv></MemoryEnv>
|
||||||
|
<Cmp></Cmp>
|
||||||
|
<Asm></Asm>
|
||||||
|
<Linker></Linker>
|
||||||
|
<OHString></OHString>
|
||||||
|
<InfinionOptionDll></InfinionOptionDll>
|
||||||
|
<SLE66CMisc></SLE66CMisc>
|
||||||
|
<SLE66AMisc></SLE66AMisc>
|
||||||
|
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||||
|
<SFDFile>$$Device:STM32F407VGTx$CMSIS\SVD\STM32F40x.svd</SFDFile>
|
||||||
|
<bCustSvd>0</bCustSvd>
|
||||||
|
<UseEnv>0</UseEnv>
|
||||||
|
<BinPath></BinPath>
|
||||||
|
<IncludePath></IncludePath>
|
||||||
|
<LibPath></LibPath>
|
||||||
|
<RegisterFilePath></RegisterFilePath>
|
||||||
|
<DBRegisterFilePath></DBRegisterFilePath>
|
||||||
|
<TargetStatus>
|
||||||
|
<Error>0</Error>
|
||||||
|
<ExitCodeStop>0</ExitCodeStop>
|
||||||
|
<ButtonStop>0</ButtonStop>
|
||||||
|
<NotGenerated>0</NotGenerated>
|
||||||
|
<InvalidFlash>1</InvalidFlash>
|
||||||
|
</TargetStatus>
|
||||||
|
<OutputDirectory>.\Objects\</OutputDirectory>
|
||||||
|
<OutputName>osdk_stm32</OutputName>
|
||||||
|
<CreateExecutable>1</CreateExecutable>
|
||||||
|
<CreateLib>0</CreateLib>
|
||||||
|
<CreateHexFile>1</CreateHexFile>
|
||||||
|
<DebugInformation>1</DebugInformation>
|
||||||
|
<BrowseInformation>1</BrowseInformation>
|
||||||
|
<ListingPath>.\Listings\</ListingPath>
|
||||||
|
<HexFormatSelection>1</HexFormatSelection>
|
||||||
|
<Merge32K>0</Merge32K>
|
||||||
|
<CreateBatchFile>0</CreateBatchFile>
|
||||||
|
<BeforeCompile>
|
||||||
|
<RunUserProg1>0</RunUserProg1>
|
||||||
|
<RunUserProg2>0</RunUserProg2>
|
||||||
|
<UserProg1Name></UserProg1Name>
|
||||||
|
<UserProg2Name></UserProg2Name>
|
||||||
|
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||||
|
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||||
|
<nStopU1X>0</nStopU1X>
|
||||||
|
<nStopU2X>0</nStopU2X>
|
||||||
|
</BeforeCompile>
|
||||||
|
<BeforeMake>
|
||||||
|
<RunUserProg1>0</RunUserProg1>
|
||||||
|
<RunUserProg2>0</RunUserProg2>
|
||||||
|
<UserProg1Name></UserProg1Name>
|
||||||
|
<UserProg2Name></UserProg2Name>
|
||||||
|
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||||
|
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||||
|
<nStopB1X>0</nStopB1X>
|
||||||
|
<nStopB2X>0</nStopB2X>
|
||||||
|
</BeforeMake>
|
||||||
|
<AfterMake>
|
||||||
|
<RunUserProg1>0</RunUserProg1>
|
||||||
|
<RunUserProg2>0</RunUserProg2>
|
||||||
|
<UserProg1Name></UserProg1Name>
|
||||||
|
<UserProg2Name></UserProg2Name>
|
||||||
|
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||||
|
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||||
|
<nStopA1X>0</nStopA1X>
|
||||||
|
<nStopA2X>0</nStopA2X>
|
||||||
|
</AfterMake>
|
||||||
|
<SelectedForBatchBuild>0</SelectedForBatchBuild>
|
||||||
|
<SVCSIdString></SVCSIdString>
|
||||||
|
</TargetCommonOption>
|
||||||
|
<CommonProperty>
|
||||||
|
<UseCPPCompiler>0</UseCPPCompiler>
|
||||||
|
<RVCTCodeConst>0</RVCTCodeConst>
|
||||||
|
<RVCTZI>0</RVCTZI>
|
||||||
|
<RVCTOtherData>0</RVCTOtherData>
|
||||||
|
<ModuleSelection>0</ModuleSelection>
|
||||||
|
<IncludeInBuild>1</IncludeInBuild>
|
||||||
|
<AlwaysBuild>0</AlwaysBuild>
|
||||||
|
<GenerateAssemblyFile>0</GenerateAssemblyFile>
|
||||||
|
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||||
|
<PublicsOnly>0</PublicsOnly>
|
||||||
|
<StopOnExitCode>3</StopOnExitCode>
|
||||||
|
<CustomArgument></CustomArgument>
|
||||||
|
<IncludeLibraryModules></IncludeLibraryModules>
|
||||||
|
<ComprImg>1</ComprImg>
|
||||||
|
</CommonProperty>
|
||||||
|
<DllOption>
|
||||||
|
<SimDllName>SARMCM3.DLL</SimDllName>
|
||||||
|
<SimDllArguments> -REMAP -MPU</SimDllArguments>
|
||||||
|
<SimDlgDll>DCM.DLL</SimDlgDll>
|
||||||
|
<SimDlgDllArguments>-pCM4</SimDlgDllArguments>
|
||||||
|
<TargetDllName>SARMCM3.DLL</TargetDllName>
|
||||||
|
<TargetDllArguments> -MPU</TargetDllArguments>
|
||||||
|
<TargetDlgDll>TCM.DLL</TargetDlgDll>
|
||||||
|
<TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
|
||||||
|
</DllOption>
|
||||||
|
<DebugOption>
|
||||||
|
<OPTHX>
|
||||||
|
<HexSelection>1</HexSelection>
|
||||||
|
<HexRangeLowAddress>0</HexRangeLowAddress>
|
||||||
|
<HexRangeHighAddress>0</HexRangeHighAddress>
|
||||||
|
<HexOffset>0</HexOffset>
|
||||||
|
<Oh166RecLen>16</Oh166RecLen>
|
||||||
|
</OPTHX>
|
||||||
|
</DebugOption>
|
||||||
|
<Utilities>
|
||||||
|
<Flash1>
|
||||||
|
<UseTargetDll>1</UseTargetDll>
|
||||||
|
<UseExternalTool>0</UseExternalTool>
|
||||||
|
<RunIndependent>0</RunIndependent>
|
||||||
|
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
|
||||||
|
<Capability>1</Capability>
|
||||||
|
<DriverSelection>4096</DriverSelection>
|
||||||
|
</Flash1>
|
||||||
|
<bUseTDR>1</bUseTDR>
|
||||||
|
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||||
|
<Flash3>"" ()</Flash3>
|
||||||
|
<Flash4></Flash4>
|
||||||
|
<pFcarmOut></pFcarmOut>
|
||||||
|
<pFcarmGrp></pFcarmGrp>
|
||||||
|
<pFcArmRoot></pFcArmRoot>
|
||||||
|
<FcArmLst>0</FcArmLst>
|
||||||
|
</Utilities>
|
||||||
|
<TargetArmAds>
|
||||||
|
<ArmAdsMisc>
|
||||||
|
<GenerateListings>0</GenerateListings>
|
||||||
|
<asHll>1</asHll>
|
||||||
|
<asAsm>1</asAsm>
|
||||||
|
<asMacX>1</asMacX>
|
||||||
|
<asSyms>1</asSyms>
|
||||||
|
<asFals>1</asFals>
|
||||||
|
<asDbgD>1</asDbgD>
|
||||||
|
<asForm>1</asForm>
|
||||||
|
<ldLst>0</ldLst>
|
||||||
|
<ldmm>1</ldmm>
|
||||||
|
<ldXref>1</ldXref>
|
||||||
|
<BigEnd>0</BigEnd>
|
||||||
|
<AdsALst>1</AdsALst>
|
||||||
|
<AdsACrf>1</AdsACrf>
|
||||||
|
<AdsANop>0</AdsANop>
|
||||||
|
<AdsANot>0</AdsANot>
|
||||||
|
<AdsLLst>1</AdsLLst>
|
||||||
|
<AdsLmap>1</AdsLmap>
|
||||||
|
<AdsLcgr>1</AdsLcgr>
|
||||||
|
<AdsLsym>1</AdsLsym>
|
||||||
|
<AdsLszi>1</AdsLszi>
|
||||||
|
<AdsLtoi>1</AdsLtoi>
|
||||||
|
<AdsLsun>1</AdsLsun>
|
||||||
|
<AdsLven>1</AdsLven>
|
||||||
|
<AdsLsxf>1</AdsLsxf>
|
||||||
|
<RvctClst>0</RvctClst>
|
||||||
|
<GenPPlst>0</GenPPlst>
|
||||||
|
<AdsCpuType>"Cortex-M4"</AdsCpuType>
|
||||||
|
<RvctDeviceName></RvctDeviceName>
|
||||||
|
<mOS>0</mOS>
|
||||||
|
<uocRom>0</uocRom>
|
||||||
|
<uocRam>0</uocRam>
|
||||||
|
<hadIROM>1</hadIROM>
|
||||||
|
<hadIRAM>1</hadIRAM>
|
||||||
|
<hadXRAM>0</hadXRAM>
|
||||||
|
<uocXRam>0</uocXRam>
|
||||||
|
<RvdsVP>2</RvdsVP>
|
||||||
|
<hadIRAM2>1</hadIRAM2>
|
||||||
|
<hadIROM2>0</hadIROM2>
|
||||||
|
<StupSel>8</StupSel>
|
||||||
|
<useUlib>1</useUlib>
|
||||||
|
<EndSel>0</EndSel>
|
||||||
|
<uLtcg>0</uLtcg>
|
||||||
|
<nSecure>0</nSecure>
|
||||||
|
<RoSelD>3</RoSelD>
|
||||||
|
<RwSelD>3</RwSelD>
|
||||||
|
<CodeSel>0</CodeSel>
|
||||||
|
<OptFeed>0</OptFeed>
|
||||||
|
<NoZi1>0</NoZi1>
|
||||||
|
<NoZi2>0</NoZi2>
|
||||||
|
<NoZi3>0</NoZi3>
|
||||||
|
<NoZi4>0</NoZi4>
|
||||||
|
<NoZi5>0</NoZi5>
|
||||||
|
<Ro1Chk>0</Ro1Chk>
|
||||||
|
<Ro2Chk>0</Ro2Chk>
|
||||||
|
<Ro3Chk>0</Ro3Chk>
|
||||||
|
<Ir1Chk>1</Ir1Chk>
|
||||||
|
<Ir2Chk>0</Ir2Chk>
|
||||||
|
<Ra1Chk>0</Ra1Chk>
|
||||||
|
<Ra2Chk>0</Ra2Chk>
|
||||||
|
<Ra3Chk>0</Ra3Chk>
|
||||||
|
<Im1Chk>1</Im1Chk>
|
||||||
|
<Im2Chk>0</Im2Chk>
|
||||||
|
<OnChipMemories>
|
||||||
|
<Ocm1>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</Ocm1>
|
||||||
|
<Ocm2>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</Ocm2>
|
||||||
|
<Ocm3>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</Ocm3>
|
||||||
|
<Ocm4>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</Ocm4>
|
||||||
|
<Ocm5>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</Ocm5>
|
||||||
|
<Ocm6>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</Ocm6>
|
||||||
|
<IRAM>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x20000000</StartAddress>
|
||||||
|
<Size>0x20000</Size>
|
||||||
|
</IRAM>
|
||||||
|
<IROM>
|
||||||
|
<Type>1</Type>
|
||||||
|
<StartAddress>0x8000000</StartAddress>
|
||||||
|
<Size>0x100000</Size>
|
||||||
|
</IROM>
|
||||||
|
<XRAM>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</XRAM>
|
||||||
|
<OCR_RVCT1>
|
||||||
|
<Type>1</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT1>
|
||||||
|
<OCR_RVCT2>
|
||||||
|
<Type>1</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT2>
|
||||||
|
<OCR_RVCT3>
|
||||||
|
<Type>1</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT3>
|
||||||
|
<OCR_RVCT4>
|
||||||
|
<Type>1</Type>
|
||||||
|
<StartAddress>0x8000000</StartAddress>
|
||||||
|
<Size>0x80000</Size>
|
||||||
|
</OCR_RVCT4>
|
||||||
|
<OCR_RVCT5>
|
||||||
|
<Type>1</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT5>
|
||||||
|
<OCR_RVCT6>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT6>
|
||||||
|
<OCR_RVCT7>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT7>
|
||||||
|
<OCR_RVCT8>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x0</StartAddress>
|
||||||
|
<Size>0x0</Size>
|
||||||
|
</OCR_RVCT8>
|
||||||
|
<OCR_RVCT9>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x20000000</StartAddress>
|
||||||
|
<Size>0x20000</Size>
|
||||||
|
</OCR_RVCT9>
|
||||||
|
<OCR_RVCT10>
|
||||||
|
<Type>0</Type>
|
||||||
|
<StartAddress>0x10000000</StartAddress>
|
||||||
|
<Size>0x10000</Size>
|
||||||
|
</OCR_RVCT10>
|
||||||
|
</OnChipMemories>
|
||||||
|
<RvctStartVector></RvctStartVector>
|
||||||
|
</ArmAdsMisc>
|
||||||
|
<Cads>
|
||||||
|
<interw>1</interw>
|
||||||
|
<Optim>1</Optim>
|
||||||
|
<oTime>0</oTime>
|
||||||
|
<SplitLS>0</SplitLS>
|
||||||
|
<OneElfS>0</OneElfS>
|
||||||
|
<Strict>0</Strict>
|
||||||
|
<EnumInt>0</EnumInt>
|
||||||
|
<PlainCh>0</PlainCh>
|
||||||
|
<Ropi>0</Ropi>
|
||||||
|
<Rwpi>0</Rwpi>
|
||||||
|
<wLevel>1</wLevel>
|
||||||
|
<uThumb>0</uThumb>
|
||||||
|
<uSurpInc>0</uSurpInc>
|
||||||
|
<uC99>0</uC99>
|
||||||
|
<useXO>0</useXO>
|
||||||
|
<v6Lang>1</v6Lang>
|
||||||
|
<v6LangP>1</v6LangP>
|
||||||
|
<vShortEn>1</vShortEn>
|
||||||
|
<vShortWch>1</vShortWch>
|
||||||
|
<v6Lto>0</v6Lto>
|
||||||
|
<v6WtE>0</v6WtE>
|
||||||
|
<v6Rtti>0</v6Rtti>
|
||||||
|
<VariousControls>
|
||||||
|
<MiscControls>--exceptions --cpp11</MiscControls>
|
||||||
|
<Define>USE_STDPERIPH_DRIVER,STM32F40_41xxx,USE_STM324xG_EVAL,STM32,STM32F40x,ARM_MATH_CM4,__FPU_PRESENT</Define>
|
||||||
|
<Undefine></Undefine>
|
||||||
|
<IncludePath>..\Lib\CMSIS\inc;..\Lib\STM32F4xx_StdPeriph_Driver\inc;..\User;..\Bsp;..\..\..\..\osdk-core\api\inc;..\..\..\..\osdk-core\hal\inc;..\..\..\..\osdk-core\protocol\inc;..\..\..\..\osdk-core\platform\STM32\inc; ..\..\..\..\osdk-core\utility\inc;..\..\..\..\osdk-core\platform\default\inc</IncludePath>
|
||||||
|
</VariousControls>
|
||||||
|
</Cads>
|
||||||
|
<Aads>
|
||||||
|
<interw>1</interw>
|
||||||
|
<Ropi>0</Ropi>
|
||||||
|
<Rwpi>0</Rwpi>
|
||||||
|
<thumb>0</thumb>
|
||||||
|
<SplitLS>0</SplitLS>
|
||||||
|
<SwStkChk>0</SwStkChk>
|
||||||
|
<NoWarn>0</NoWarn>
|
||||||
|
<uSurpInc>0</uSurpInc>
|
||||||
|
<useXO>0</useXO>
|
||||||
|
<uClangAs>0</uClangAs>
|
||||||
|
<VariousControls>
|
||||||
|
<MiscControls>--exceptions</MiscControls>
|
||||||
|
<Define></Define>
|
||||||
|
<Undefine></Undefine>
|
||||||
|
<IncludePath></IncludePath>
|
||||||
|
</VariousControls>
|
||||||
|
</Aads>
|
||||||
|
<LDads>
|
||||||
|
<umfTarg>1</umfTarg>
|
||||||
|
<Ropi>0</Ropi>
|
||||||
|
<Rwpi>0</Rwpi>
|
||||||
|
<noStLib>0</noStLib>
|
||||||
|
<RepFail>1</RepFail>
|
||||||
|
<useFile>0</useFile>
|
||||||
|
<TextAddressRange>0x08000000</TextAddressRange>
|
||||||
|
<DataAddressRange>0x20000000</DataAddressRange>
|
||||||
|
<pXoBase></pXoBase>
|
||||||
|
<ScatterFile>.\Objects\osdk_stm32.sct</ScatterFile>
|
||||||
|
<IncludeLibs></IncludeLibs>
|
||||||
|
<IncludeLibsPath></IncludeLibsPath>
|
||||||
|
<Misc></Misc>
|
||||||
|
<LinkerInputFile></LinkerInputFile>
|
||||||
|
<DisabledWarnings></DisabledWarnings>
|
||||||
|
</LDads>
|
||||||
|
</TargetArmAds>
|
||||||
|
</TargetOption>
|
||||||
|
<Groups>
|
||||||
|
<Group>
|
||||||
|
<GroupName>User</GroupName>
|
||||||
|
<GroupOption>
|
||||||
|
<CommonProperty>
|
||||||
|
<UseCPPCompiler>0</UseCPPCompiler>
|
||||||
|
<RVCTCodeConst>0</RVCTCodeConst>
|
||||||
|
<RVCTZI>0</RVCTZI>
|
||||||
|
<RVCTOtherData>0</RVCTOtherData>
|
||||||
|
<ModuleSelection>0</ModuleSelection>
|
||||||
|
<IncludeInBuild>2</IncludeInBuild>
|
||||||
|
<AlwaysBuild>2</AlwaysBuild>
|
||||||
|
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||||
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
|
<PublicsOnly>2</PublicsOnly>
|
||||||
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
|
<CustomArgument></CustomArgument>
|
||||||
|
<IncludeLibraryModules></IncludeLibraryModules>
|
||||||
|
<ComprImg>1</ComprImg>
|
||||||
|
</CommonProperty>
|
||||||
|
<GroupArmAds>
|
||||||
|
<Cads>
|
||||||
|
<interw>2</interw>
|
||||||
|
<Optim>0</Optim>
|
||||||
|
<oTime>2</oTime>
|
||||||
|
<SplitLS>2</SplitLS>
|
||||||
|
<OneElfS>2</OneElfS>
|
||||||
|
<Strict>2</Strict>
|
||||||
|
<EnumInt>2</EnumInt>
|
||||||
|
<PlainCh>2</PlainCh>
|
||||||
|
<Ropi>2</Ropi>
|
||||||
|
<Rwpi>2</Rwpi>
|
||||||
|
<wLevel>0</wLevel>
|
||||||
|
<uThumb>2</uThumb>
|
||||||
|
<uSurpInc>2</uSurpInc>
|
||||||
|
<uC99>2</uC99>
|
||||||
|
<useXO>2</useXO>
|
||||||
|
<v6Lang>0</v6Lang>
|
||||||
|
<v6LangP>0</v6LangP>
|
||||||
|
<vShortEn>2</vShortEn>
|
||||||
|
<vShortWch>2</vShortWch>
|
||||||
|
<v6Lto>2</v6Lto>
|
||||||
|
<v6WtE>2</v6WtE>
|
||||||
|
<v6Rtti>2</v6Rtti>
|
||||||
|
<VariousControls>
|
||||||
|
<MiscControls>--exceptions</MiscControls>
|
||||||
|
<Define></Define>
|
||||||
|
<Undefine></Undefine>
|
||||||
|
<IncludePath></IncludePath>
|
||||||
|
</VariousControls>
|
||||||
|
</Cads>
|
||||||
|
<Aads>
|
||||||
|
<interw>2</interw>
|
||||||
|
<Ropi>2</Ropi>
|
||||||
|
<Rwpi>2</Rwpi>
|
||||||
|
<thumb>2</thumb>
|
||||||
|
<SplitLS>2</SplitLS>
|
||||||
|
<SwStkChk>2</SwStkChk>
|
||||||
|
<NoWarn>2</NoWarn>
|
||||||
|
<uSurpInc>2</uSurpInc>
|
||||||
|
<useXO>2</useXO>
|
||||||
|
<uClangAs>2</uClangAs>
|
||||||
|
<VariousControls>
|
||||||
|
<MiscControls></MiscControls>
|
||||||
|
<Define></Define>
|
||||||
|
<Undefine></Undefine>
|
||||||
|
<IncludePath></IncludePath>
|
||||||
|
</VariousControls>
|
||||||
|
</Aads>
|
||||||
|
</GroupArmAds>
|
||||||
|
</GroupOption>
|
||||||
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>cppforstm32.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\cppforstm32.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>main.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\main.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>FlightControlSample.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\FlightControlSample.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>MissionSample.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\MissionSample.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>CameraGimbalSample.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\CameraGimbalSample.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>MobileSample.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\MobileSample.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>TelemetrySample.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\TelemetrySample.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>Activate.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\Activate.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>Receive.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\User\Receive.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
</Group>
|
||||||
|
<Group>
|
||||||
|
<GroupName>Bsp</GroupName>
|
||||||
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>BspUsart.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\Bsp\BspUsart.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>timer.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\Bsp\timer.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>bsp.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\Bsp\bsp.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
</Group>
|
||||||
|
<Group>
|
||||||
|
<GroupName>doc</GroupName>
|
||||||
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>readme.txt</FileName>
|
||||||
|
<FileType>5</FileType>
|
||||||
|
<FilePath>..\doc\readme.txt</FilePath>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
</Group>
|
||||||
|
<Group>
|
||||||
|
<GroupName>LIB</GroupName>
|
||||||
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>misc.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\misc.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_adc.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_adc.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_can.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_can.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_crc.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_crc.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_dac.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dac.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_dcmi.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dcmi.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_dma.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dma.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_exti.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_flash.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_flash.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_fsmc.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_fsmc.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_gpio.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_i2c.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_i2c.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_iwdg.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_iwdg.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_pwr.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_pwr.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_rcc.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_rng.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rng.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_rtc.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rtc.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_sdio.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_sdio.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_spi.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_spi.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_syscfg.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_tim.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_usart.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>stm32f4xx_wwdg.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_wwdg.c</FilePath>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
</Group>
|
||||||
|
<Group>
|
||||||
|
<GroupName>CMSIS</GroupName>
|
||||||
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>system_stm32f4xx.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Lib\CMSIS\src\system_stm32f4xx.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>startup_stm32f40_41xxx.s</FileName>
|
||||||
|
<FileType>2</FileType>
|
||||||
|
<FilePath>..\Lib\CMSIS\src\startup_stm32f40_41xxx.s</FilePath>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
</Group>
|
||||||
|
<Group>
|
||||||
|
<GroupName>DJIlib</GroupName>
|
||||||
|
<Files>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_error.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_error.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_vehicle.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_vehicle.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_command.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_command.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_open_protocol.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\protocol\src\dji_open_protocol.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_camera.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_camera.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_control.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_control.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_hard_driver.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\hal\src\dji_hard_driver.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_hotpoint.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_hotpoint.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_mfio.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_mfio.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_mission_manager.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_mission_manager.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_mobile_communication.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_mobile_communication.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_hardware_sync.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_hardware_sync.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_subscription.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_subscription.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_memory.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\hal\src\dji_memory.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_ack.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_ack.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_waypoint.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_waypoint.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_broadcast.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_broadcast.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_singleton.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\utility\src\dji_singleton.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_aes.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\protocol\src\dji_aes.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_gimbal.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_gimbal.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_version.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\api\src\dji_version.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>STM32F4SerialDriver.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\platform\STM32\src\STM32F4SerialDriver.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>STM32F4DataGuard.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\platform\STM32\src\STM32F4DataGuard.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_thread_manager.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\hal\src\dji_thread_manager.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_memory_default.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\platform\default\src\dji_memory_default.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_circular_buffer.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\utility\src\dji_circular_buffer.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>dji_log.cpp</FileName>
|
||||||
|
<FileType>8</FileType>
|
||||||
|
<FilePath>..\..\..\..\osdk-core\hal\src\dji_log.cpp</FilePath>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
</Group>
|
||||||
|
<Group>
|
||||||
|
<GroupName>::CMSIS</GroupName>
|
||||||
|
</Group>
|
||||||
|
</Groups>
|
||||||
|
</Target>
|
||||||
|
</Targets>
|
||||||
|
|
||||||
|
<RTE>
|
||||||
|
<apis/>
|
||||||
|
<components>
|
||||||
|
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="4.3.0" condition="Cortex-M Device">
|
||||||
|
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="4.5.0"/>
|
||||||
|
<targetInfos>
|
||||||
|
<targetInfo name="DJI_LIB"/>
|
||||||
|
</targetInfos>
|
||||||
|
</component>
|
||||||
|
<component Cclass="CMSIS" Cgroup="DSP" Cvendor="ARM" Cversion="1.4.6" condition="CMSIS DSP">
|
||||||
|
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="4.5.0"/>
|
||||||
|
<targetInfos>
|
||||||
|
<targetInfo name="DJI_LIB"/>
|
||||||
|
</targetInfos>
|
||||||
|
</component>
|
||||||
|
</components>
|
||||||
|
<files/>
|
||||||
|
</RTE>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Auto generated Run-Time-Environment Component Configuration File
|
||||||
|
* *** Do not modify ! ***
|
||||||
|
*
|
||||||
|
* Project: 'OnBoardSDK_STM32'
|
||||||
|
* Target: 'DJI_LIB'
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTE_COMPONENTS_H
|
||||||
|
#define RTE_COMPONENTS_H
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the Device Header File:
|
||||||
|
*/
|
||||||
|
#define CMSIS_device_header "stm32f4xx.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* RTE_COMPONENTS_H */
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Auto generated Run-Time-Environment Component Configuration File
|
||||||
|
* *** Do not modify ! ***
|
||||||
|
*
|
||||||
|
* Project: 'BareProject'
|
||||||
|
* Target: 'Target 1'
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTE_COMPONENTS_H
|
||||||
|
#define RTE_COMPONENTS_H
|
||||||
|
|
||||||
|
#endif /* RTE_COMPONENTS_H */
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*! @file Activate.cpp
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Activation process for the STM32 example App.
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "Activate.h"
|
||||||
|
|
||||||
|
extern Vehicle vehicle;
|
||||||
|
extern Vehicle* v;
|
||||||
|
|
||||||
|
void
|
||||||
|
userActivate()
|
||||||
|
{
|
||||||
|
//! At your DJI developer account look for: app_key and app ID
|
||||||
|
|
||||||
|
static char key_buf[65] = "your app_key here";
|
||||||
|
|
||||||
|
DJI::OSDK::Vehicle::ActivateData user_act_data;
|
||||||
|
user_act_data.ID = 0000; /*your app ID here*/
|
||||||
|
|
||||||
|
user_act_data.encKey = key_buf;
|
||||||
|
|
||||||
|
v->activate(&user_act_data);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*! @file Activate.h
|
||||||
|
* @version 3.1.8
|
||||||
|
* @date Aug 05 2016
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Activation process for the STM32 example App.
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef ACTIVATE_H
|
||||||
|
#define ACTIVATE_H
|
||||||
|
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
void userActivate();
|
||||||
|
|
||||||
|
#endif // ACTIVATE_H
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
#include "CameraGimbalSample.h"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
extern Vehicle vehicle;
|
||||||
|
extern Vehicle* v;
|
||||||
|
|
||||||
|
bool
|
||||||
|
gimbalCameraControl()
|
||||||
|
{
|
||||||
|
int responseTimeout = 0;
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
GimbalContainer gimbal;
|
||||||
|
RotationAngle initialAngle;
|
||||||
|
RotationAngle currentAngle;
|
||||||
|
Gimbal::SpeedData gimbalSpeed;
|
||||||
|
|
||||||
|
// Telemetry: Subscribe to gimbal status and gimbal angle at freq 10 Hz
|
||||||
|
int pkgIndex = 0;
|
||||||
|
int freq = 10;
|
||||||
|
Telemetry::TopicName topicList10Hz[] = { Telemetry::TOPIC_GIMBAL_ANGLES,
|
||||||
|
Telemetry::TOPIC_GIMBAL_STATUS };
|
||||||
|
int numTopic = sizeof(topicList10Hz) / sizeof(topicList10Hz[0]);
|
||||||
|
bool enableTimestamp = false;
|
||||||
|
|
||||||
|
bool pkgStatus = v->subscribe->initPackageFromTopicList(
|
||||||
|
pkgIndex, numTopic, topicList10Hz, enableTimestamp, freq);
|
||||||
|
if (!(pkgStatus))
|
||||||
|
{
|
||||||
|
return pkgStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
v->subscribe->startPackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
/* ack = waitForACK();
|
||||||
|
if (ACK::getError(ack) != ACK::SUCCESS)
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
// Cleanup before return
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// Wait for data to arrive
|
||||||
|
delay_nms(2000);
|
||||||
|
|
||||||
|
// Get Gimbal initial values
|
||||||
|
initialAngle.roll =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().y;
|
||||||
|
initialAngle.pitch =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().x;
|
||||||
|
initialAngle.yaw = v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().z;
|
||||||
|
|
||||||
|
printf("Please note that the gimbal yaw angle you see \n"
|
||||||
|
"in the telemetry is w.r.t absolute North, and \n"
|
||||||
|
"the accuracy depends on your magnetometer calibration.\n\n");
|
||||||
|
|
||||||
|
printf("Initial Gimbal rotation angle: [ %0.3f, %0.3f, %0.3f ]\n\n",
|
||||||
|
initialAngle.roll, initialAngle.pitch, initialAngle.yaw);
|
||||||
|
|
||||||
|
// Re-set Gimbal to initial values
|
||||||
|
gimbal = GimbalContainer(0, 0, 0, 20, 1, false, false, false, initialAngle);
|
||||||
|
doSetGimbalAngle(&gimbal);
|
||||||
|
|
||||||
|
printf("Setting new Gimbal rotation angle to [0,20,180] using "
|
||||||
|
"incremental control:\n");
|
||||||
|
// Get current gimbal data to calc precision error in post processing
|
||||||
|
currentAngle.roll =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().y;
|
||||||
|
currentAngle.pitch =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().x;
|
||||||
|
currentAngle.yaw = v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().z;
|
||||||
|
|
||||||
|
gimbal = GimbalContainer(0, 200, 1800, 20, 0, false, false, false,
|
||||||
|
initialAngle, currentAngle);
|
||||||
|
doSetGimbalAngle(&gimbal);
|
||||||
|
|
||||||
|
currentAngle.roll =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().y;
|
||||||
|
currentAngle.pitch =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().x;
|
||||||
|
currentAngle.yaw = v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().z;
|
||||||
|
|
||||||
|
displayResult(¤tAngle);
|
||||||
|
|
||||||
|
// Take picture
|
||||||
|
printf("Ensure SD card is present.\n");
|
||||||
|
printf("Taking picture..\n");
|
||||||
|
v->camera->shootPhoto();
|
||||||
|
printf("Check DJI GO App or SD card for a new picture.\n");
|
||||||
|
|
||||||
|
printf("Setting new Gimbal rotation angle to [0,-50, 0] using absolute "
|
||||||
|
"control:\n");
|
||||||
|
gimbal =
|
||||||
|
GimbalContainer(0, -500, 0, 20, 1, false, false, false, initialAngle);
|
||||||
|
doSetGimbalAngle(&gimbal);
|
||||||
|
|
||||||
|
currentAngle.roll =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().y;
|
||||||
|
currentAngle.pitch =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().x;
|
||||||
|
currentAngle.yaw = v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().z;
|
||||||
|
displayResult(¤tAngle);
|
||||||
|
|
||||||
|
// Start video: We will keep the video doing for the duration of the speed
|
||||||
|
// control.
|
||||||
|
printf("Ensure SD card is present.\n");
|
||||||
|
printf("Starting video..\n");
|
||||||
|
v->camera->videoStart();
|
||||||
|
|
||||||
|
// Speed control
|
||||||
|
|
||||||
|
printf("Gimbal Speed Description: \n\n"
|
||||||
|
"Roll - unit 0.1 degrees/second input rate [-1800, 1800]\n"
|
||||||
|
"Pitch - unit 0.1 degrees/second input rate [-1800, 1800]\n"
|
||||||
|
"Yaw - unit 0.1 degrees/second input rate [-1800, 1800]\n\n");
|
||||||
|
|
||||||
|
printf("Setting Roll rate to 10, Pitch rate to 5, Yaw Rate to -20.\n");
|
||||||
|
gimbalSpeed.roll = 100;
|
||||||
|
gimbalSpeed.pitch = 50;
|
||||||
|
gimbalSpeed.yaw = -200;
|
||||||
|
|
||||||
|
int speedControlDurationMs = 4000;
|
||||||
|
int incrementMs = 100;
|
||||||
|
for (int timer = 0; timer < speedControlDurationMs; timer += incrementMs)
|
||||||
|
{
|
||||||
|
v->gimbal->setSpeed(&gimbalSpeed);
|
||||||
|
// usleep(incrementMs * 1000);
|
||||||
|
delay_nms(incrementMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentAngle.roll =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().y;
|
||||||
|
currentAngle.pitch =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().x;
|
||||||
|
currentAngle.yaw = v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().z;
|
||||||
|
displayResult(¤tAngle);
|
||||||
|
|
||||||
|
// Reset the position
|
||||||
|
printf("Resetting position...\n");
|
||||||
|
gimbal = GimbalContainer(0, 0, 0, 20, 1, false, false, false, initialAngle);
|
||||||
|
doSetGimbalAngle(&gimbal);
|
||||||
|
|
||||||
|
currentAngle.roll =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().y;
|
||||||
|
currentAngle.pitch =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().x;
|
||||||
|
currentAngle.yaw = v->subscribe->getValue<Telemetry::TOPIC_GIMBAL_ANGLES>().z;
|
||||||
|
displayResult(¤tAngle);
|
||||||
|
|
||||||
|
// Stop the video
|
||||||
|
printf("Stopping video...\n");
|
||||||
|
v->camera->videoStop();
|
||||||
|
delay_nms(1000);
|
||||||
|
printf("Check DJI GO App or SD card for a new video.\n");
|
||||||
|
|
||||||
|
// Cleanup and exit gimbal sample
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(3000);
|
||||||
|
/*ack = waitForAck();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
printf("Error unsubscribing; please restart the drone/FC to get back "
|
||||||
|
"to a clean state.\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
doSetGimbalAngle(GimbalContainer* gimbal)
|
||||||
|
{
|
||||||
|
Gimbal::AngleData gimbalAngle;
|
||||||
|
gimbalAngle.roll = gimbal->roll;
|
||||||
|
gimbalAngle.pitch = gimbal->pitch;
|
||||||
|
gimbalAngle.yaw = gimbal->yaw;
|
||||||
|
gimbalAngle.duration = gimbal->duration;
|
||||||
|
gimbalAngle.mode |= 0;
|
||||||
|
gimbalAngle.mode |= gimbal->isAbsolute;
|
||||||
|
gimbalAngle.mode |= gimbal->yaw_cmd_ignore << 1;
|
||||||
|
gimbalAngle.mode |= gimbal->roll_cmd_ignore << 2;
|
||||||
|
gimbalAngle.mode |= gimbal->pitch_cmd_ignore << 3;
|
||||||
|
|
||||||
|
v->gimbal->setAngle(&gimbalAngle);
|
||||||
|
// Give time for gimbal to sync
|
||||||
|
delay_nms(4000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
displayResult(RotationAngle* currentAngle)
|
||||||
|
{
|
||||||
|
printf("New Gimbal rotation angle is [ %0.3f, %0.3f, %0.3f ]\n\n",
|
||||||
|
currentAngle->roll, currentAngle->pitch, currentAngle->yaw);
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef CAMERAGIMBALSAMPLE_H
|
||||||
|
#define CAMERAGIMBALSAMPLE_H
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dji_vehicle.hpp>
|
||||||
|
#include <dji_gimbal.hpp>
|
||||||
|
#include <dji_camera.hpp>
|
||||||
|
|
||||||
|
struct RotationAngle
|
||||||
|
{
|
||||||
|
DJI::OSDK::float32_t roll;
|
||||||
|
DJI::OSDK::float32_t pitch;
|
||||||
|
DJI::OSDK::float32_t yaw;
|
||||||
|
|
||||||
|
RotationAngle(DJI::OSDK::float32_t roll = 0, DJI::OSDK::float32_t pitch = 0,
|
||||||
|
DJI::OSDK::float32_t yaw = 0)
|
||||||
|
: roll(roll)
|
||||||
|
, pitch(pitch)
|
||||||
|
, yaw(yaw)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GimbalContainer
|
||||||
|
{
|
||||||
|
DJI::OSDK::float32_t roll;
|
||||||
|
DJI::OSDK::float32_t pitch;
|
||||||
|
DJI::OSDK::float32_t yaw;
|
||||||
|
int duration;
|
||||||
|
int isAbsolute;
|
||||||
|
bool yaw_cmd_ignore;
|
||||||
|
bool pitch_cmd_ignore;
|
||||||
|
bool roll_cmd_ignore;
|
||||||
|
RotationAngle initialAngle;
|
||||||
|
RotationAngle currentAngle;
|
||||||
|
GimbalContainer(int roll = 0, int pitch = 0, int yaw = 0, int duration = 0,
|
||||||
|
int isAbsolute = 0, bool yaw_cmd_ignore = false,
|
||||||
|
bool pitch_cmd_ignore = false, bool roll_cmd_ignore = false,
|
||||||
|
RotationAngle initialAngle = RotationAngle(),
|
||||||
|
RotationAngle currentAngle = RotationAngle())
|
||||||
|
: roll(roll)
|
||||||
|
, pitch(pitch)
|
||||||
|
, yaw(yaw)
|
||||||
|
, duration(duration)
|
||||||
|
, isAbsolute(isAbsolute)
|
||||||
|
, yaw_cmd_ignore(yaw_cmd_ignore)
|
||||||
|
, pitch_cmd_ignore(pitch_cmd_ignore)
|
||||||
|
, roll_cmd_ignore(roll_cmd_ignore)
|
||||||
|
, initialAngle(initialAngle)
|
||||||
|
, currentAngle(currentAngle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
void doSetGimbalAngle(GimbalContainer* gimbal);
|
||||||
|
bool gimbalCameraControl();
|
||||||
|
void displayResult(RotationAngle* currentAngle);
|
||||||
|
|
||||||
|
#endif // CAMERAGIMBALSAMPLE_H
|
||||||
@@ -0,0 +1,591 @@
|
|||||||
|
/*! @file FlightControlSample.cpp
|
||||||
|
* @version 3.3
|
||||||
|
* @date May 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Flight control STM32 example.
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#include "FlightControlSample.h"
|
||||||
|
|
||||||
|
extern Vehicle vehicle;
|
||||||
|
extern Vehicle* v;
|
||||||
|
|
||||||
|
bool
|
||||||
|
monitoredTakeOff()
|
||||||
|
{
|
||||||
|
//@todo: remove this once the getErrorCode function signature changes
|
||||||
|
char func[50];
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
// Telemetry: Subscribe to flight status and mode at freq 10 Hz
|
||||||
|
int pkgIndex = 0;
|
||||||
|
int freq = 10;
|
||||||
|
Telemetry::TopicName topicList10Hz[] = {
|
||||||
|
Telemetry::TOPIC_STATUS_FLIGHT, Telemetry::TOPIC_STATUS_DISPLAYMODE
|
||||||
|
};
|
||||||
|
int numTopic = sizeof(topicList10Hz) / sizeof(topicList10Hz[0]);
|
||||||
|
bool enableTimestamp = false;
|
||||||
|
|
||||||
|
bool pkgStatus = v->subscribe->initPackageFromTopicList(
|
||||||
|
pkgIndex, numTopic, topicList10Hz, enableTimestamp, freq);
|
||||||
|
if (!(pkgStatus))
|
||||||
|
{
|
||||||
|
return pkgStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Start listening to subscribed packages
|
||||||
|
v->subscribe->startPackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if(ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
ack = waitForACK();
|
||||||
|
if(ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Start takeoff
|
||||||
|
v->control->takeoff();
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if(ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
ack = waitForACK();
|
||||||
|
if(ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// First check: Motors started
|
||||||
|
uint32_t CONTROL_TIMEOUT = 15000; // milliseconds
|
||||||
|
uint32_t RETRY_TICK = 500; // milliseconds
|
||||||
|
uint32_t nextRetryTick = 0; // millisesonds
|
||||||
|
uint32_t timeoutTick;
|
||||||
|
bool isTakeOffState = false;
|
||||||
|
bool isInAirState = false;
|
||||||
|
bool isHoverState = false;
|
||||||
|
|
||||||
|
timeoutTick = v->protocolLayer->getDriver()->getTimeStamp() + CONTROL_TIMEOUT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//! Two seconds delay
|
||||||
|
delay_nms(2000);
|
||||||
|
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_FLIGHT>() ==
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::FlightStatus::ON_GROUND &&
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() ==
|
||||||
|
VehicleStatus::MODE_ENGINE_START)
|
||||||
|
{
|
||||||
|
isTakeOffState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextRetryTick = v->protocolLayer->getDriver()->getTimeStamp() + RETRY_TICK;
|
||||||
|
} while (nextRetryTick < timeoutTick);
|
||||||
|
|
||||||
|
if (!isTakeOffState)
|
||||||
|
{
|
||||||
|
printf("Takeoff failed. Motors failed to start!\n");
|
||||||
|
|
||||||
|
//! Clean up
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(50);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\nSuccessful takeof!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutTick = v->protocolLayer->getDriver()->getTimeStamp() + CONTROL_TIMEOUT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//! Two seconds delay
|
||||||
|
delay_nms(2000);
|
||||||
|
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_FLIGHT>() ==
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::FlightStatus::IN_AIR &&
|
||||||
|
(v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() ==
|
||||||
|
VehicleStatus::MODE_ASSISTED_TAKEOFF ||
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() ==
|
||||||
|
VehicleStatus::MODE_AUTO_TAKEOFF))
|
||||||
|
{
|
||||||
|
isInAirState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextRetryTick = v->protocolLayer->getDriver()->getTimeStamp() + RETRY_TICK;
|
||||||
|
} while (nextRetryTick < timeoutTick);
|
||||||
|
|
||||||
|
if (!isInAirState)
|
||||||
|
{
|
||||||
|
printf("Takeoff failed. Aircraft is still on the ground, but the "
|
||||||
|
"motors are spinning.\n");
|
||||||
|
|
||||||
|
//! Clean up
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Vehicle ascending...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutTick = v->protocolLayer->getDriver()->getTimeStamp() + CONTROL_TIMEOUT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//! Two seconds delay
|
||||||
|
delay_nms(2000);
|
||||||
|
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_ASSISTED_TAKEOFF ||
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_AUTO_TAKEOFF)
|
||||||
|
{
|
||||||
|
isHoverState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextRetryTick = v->protocolLayer->getDriver()->getTimeStamp() + RETRY_TICK;
|
||||||
|
} while (nextRetryTick < timeoutTick);
|
||||||
|
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_P_GPS ||
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_ATTITUDE)
|
||||||
|
{
|
||||||
|
printf("Vehicle is hovering\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Takeoff finished, but the aircraft is in an unexpected mode. "
|
||||||
|
"Please connect DJI GO.\n");
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(3000);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if(ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Monitored Takeoff (Blocking API call). Return status as well as ack.
|
||||||
|
This version of takeoff makes sure your aircraft actually took off
|
||||||
|
and only returns when takeoff is complete.
|
||||||
|
Use unless you want to do other stuff during takeoff - this will block
|
||||||
|
the main thread.
|
||||||
|
!*/
|
||||||
|
bool
|
||||||
|
monitoredLanding()
|
||||||
|
{
|
||||||
|
//@todo: remove this once the getErrorCode function signature changes
|
||||||
|
char func[50];
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
uint32_t SUBSCRIBE_TIMOUT = 30000; // milliseconds
|
||||||
|
uint32_t RETRY_TICK = 500; // milliseconds
|
||||||
|
uint32_t nextRetryTick = 0; // millisesonds
|
||||||
|
uint32_t timeoutTick;
|
||||||
|
bool isLandingState = false;
|
||||||
|
bool isFinishedLandingState = false;
|
||||||
|
bool isHoverState = false;
|
||||||
|
|
||||||
|
// Telemetry: Subscribe to flight status and mode at freq 10 Hz
|
||||||
|
int pkgIndex = 0;
|
||||||
|
int freq = 10;
|
||||||
|
Telemetry::TopicName topicList10Hz[] = {
|
||||||
|
Telemetry::TOPIC_STATUS_FLIGHT, Telemetry::TOPIC_STATUS_DISPLAYMODE
|
||||||
|
};
|
||||||
|
int numTopic = sizeof(topicList10Hz) / sizeof(topicList10Hz[0]);
|
||||||
|
bool enableTimestamp = false;
|
||||||
|
|
||||||
|
bool pkgStatus = v->subscribe->initPackageFromTopicList(
|
||||||
|
pkgIndex, numTopic, topicList10Hz, enableTimestamp, freq);
|
||||||
|
if (!(pkgStatus))
|
||||||
|
{
|
||||||
|
return pkgStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
v->subscribe->startPackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack) != ACK::SUCCESS)
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Start landing
|
||||||
|
v->control->land();
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack) != ACK::SUCCESS)
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// First check: Landing started
|
||||||
|
|
||||||
|
timeoutTick =
|
||||||
|
v->protocolLayer->getDriver()->getTimeStamp() + SUBSCRIBE_TIMOUT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//! Two seconds delay
|
||||||
|
delay_nms(2000);
|
||||||
|
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() ==
|
||||||
|
VehicleStatus::MODE_AUTO_LANDING)
|
||||||
|
{
|
||||||
|
isLandingState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextRetryTick = v->protocolLayer->getDriver()->getTimeStamp() + RETRY_TICK;
|
||||||
|
} while (nextRetryTick < timeoutTick);
|
||||||
|
|
||||||
|
if (!isLandingState)
|
||||||
|
{
|
||||||
|
printf("Landing failed. Aircraft is still in the air.\n");
|
||||||
|
// Cleanup before return
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Vehicle landing...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second check: Finished landing
|
||||||
|
|
||||||
|
timeoutTick =
|
||||||
|
v->protocolLayer->getDriver()->getTimeStamp() + SUBSCRIBE_TIMOUT;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//! Two seconds delay
|
||||||
|
delay_nms(2000);
|
||||||
|
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_AUTO_LANDING &&
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_STATUS_FLIGHT>() !=
|
||||||
|
OpenProtocol::ErrorCode::CommonACK::FlightStatus::IN_AIR)
|
||||||
|
{
|
||||||
|
if (v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_P_GPS ||
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_STATUS_DISPLAYMODE>() !=
|
||||||
|
VehicleStatus::MODE_ATTITUDE)
|
||||||
|
{
|
||||||
|
isFinishedLandingState = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextRetryTick = v->protocolLayer->getDriver()->getTimeStamp() + RETRY_TICK;
|
||||||
|
} while (nextRetryTick < timeoutTick);
|
||||||
|
|
||||||
|
if (isFinishedLandingState)
|
||||||
|
{
|
||||||
|
printf("Successful landing!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Landing finished, but the aircraft is in an unexpected mode. "
|
||||||
|
"Please connect DJI GO.\n");
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup before return
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(3000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Position Control. Allows you to set an offset from your current
|
||||||
|
location. The aircraft will move to that position and stay there.
|
||||||
|
Typical use would be as a building block in an outer loop that does not
|
||||||
|
require many fast changes, perhaps a few-waypoint trajectory. For smoother
|
||||||
|
transition and response you should convert your trajectory to attitude
|
||||||
|
setpoints and use attitude control or convert to velocity setpoints
|
||||||
|
and use velocity control.
|
||||||
|
!*/
|
||||||
|
int
|
||||||
|
moveByPositionOffset(float xOffsetDesired, float yOffsetDesired,
|
||||||
|
float zOffsetDesired, float yawDesired,
|
||||||
|
float posThresholdInM, float yawThresholdInDeg)
|
||||||
|
{
|
||||||
|
// Set timeout: this timeout is the time you allow the drone to take to finish
|
||||||
|
// the
|
||||||
|
// mission
|
||||||
|
int timeoutInMilSec = 100000;
|
||||||
|
int controlFreqInHz = 50; // Hz
|
||||||
|
int cycleTimeInMs = 1000 / controlFreqInHz;
|
||||||
|
int outOfControlBoundsTimeLimit = 10 * cycleTimeInMs; // 10 cycles
|
||||||
|
int withinControlBoundsTimeReqmt = 50 * cycleTimeInMs; // 50 cycles
|
||||||
|
|
||||||
|
//@todo: remove this once the getErrorCode function signature changes
|
||||||
|
char func[50];
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
// Telemetry: Subscribe to quaternion, fused lat/lon and altitude at freq 50
|
||||||
|
// Hz
|
||||||
|
int pkgIndex = 0;
|
||||||
|
int freq = 50;
|
||||||
|
Telemetry::TopicName topicList50Hz[] = { Telemetry::TOPIC_QUATERNION,
|
||||||
|
Telemetry::TOPIC_GPS_FUSED };
|
||||||
|
int numTopic = sizeof(topicList50Hz) / sizeof(topicList50Hz[0]);
|
||||||
|
bool enableTimestamp = false;
|
||||||
|
|
||||||
|
bool pkgStatus = v->subscribe->initPackageFromTopicList(
|
||||||
|
pkgIndex, numTopic, topicList50Hz, enableTimestamp, freq);
|
||||||
|
if (!(pkgStatus))
|
||||||
|
{
|
||||||
|
return pkgStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
v->subscribe->startPackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack) != ACK::SUCCESS)
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, func);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Wait for data to come in
|
||||||
|
delay_nms(8000);
|
||||||
|
|
||||||
|
// Get data
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_GPS_FUSED>::type currentGPS =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GPS_FUSED>();
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_GPS_FUSED>::type originGPS = currentGPS;
|
||||||
|
|
||||||
|
// Convert position offset from first position to local coordinates
|
||||||
|
Telemetry::Vector3f localOffset;
|
||||||
|
localOffsetFromGpsOffset(localOffset, currentGPS, originGPS);
|
||||||
|
|
||||||
|
// Get initial offset. We will update this in a loop later.
|
||||||
|
double xOffsetRemaining = xOffsetDesired - localOffset.x;
|
||||||
|
double yOffsetRemaining = yOffsetDesired - localOffset.y;
|
||||||
|
double zOffsetRemaining = zOffsetDesired - (-localOffset.z);
|
||||||
|
|
||||||
|
// Conversions
|
||||||
|
double yawDesiredRad = DEG2RAD * yawDesired;
|
||||||
|
double yawThresholdInRad = DEG2RAD * yawThresholdInDeg;
|
||||||
|
|
||||||
|
//! Get Euler angle
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_QUATERNION>::type q =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_QUATERNION>();
|
||||||
|
double yawInRad = toEulerAngle(q).z / DEG2RAD;
|
||||||
|
|
||||||
|
int elapsedTimeInMs = 0;
|
||||||
|
int withinBoundsCounter = 0;
|
||||||
|
int outOfBounds = 0;
|
||||||
|
int brakeCounter = 0;
|
||||||
|
int speedFactor = 2;
|
||||||
|
float xCmd, yCmd, zCmd;
|
||||||
|
// There is a deadband in position control
|
||||||
|
// the z cmd is absolute height
|
||||||
|
// while x and y are in relative
|
||||||
|
float zDeadband = 0.12;
|
||||||
|
|
||||||
|
/*! Calculate the inputs to send the position controller. We implement basic
|
||||||
|
* receding setpoint position control and the setpoint is always 1 m away
|
||||||
|
* from the current position - until we get within a threshold of the goal.
|
||||||
|
* From that point on, we send the remaining distance as the setpoint.
|
||||||
|
*/
|
||||||
|
if (xOffsetDesired > 0)
|
||||||
|
xCmd = (xOffsetDesired < speedFactor) ? xOffsetDesired : speedFactor;
|
||||||
|
else if (xOffsetDesired < 0)
|
||||||
|
xCmd =
|
||||||
|
(xOffsetDesired > -1 * speedFactor) ? xOffsetDesired : -1 * speedFactor;
|
||||||
|
else
|
||||||
|
xCmd = 0;
|
||||||
|
|
||||||
|
if (yOffsetDesired > 0)
|
||||||
|
yCmd = (yOffsetDesired < speedFactor) ? yOffsetDesired : speedFactor;
|
||||||
|
else if (yOffsetDesired < 0)
|
||||||
|
yCmd =
|
||||||
|
(yOffsetDesired > -1 * speedFactor) ? yOffsetDesired : -1 * speedFactor;
|
||||||
|
else
|
||||||
|
yCmd = 0;
|
||||||
|
|
||||||
|
zCmd = currentGPS.altitude + zOffsetDesired;
|
||||||
|
|
||||||
|
//! Main closed-loop receding setpoint position control
|
||||||
|
while (elapsedTimeInMs < timeoutInMilSec)
|
||||||
|
{
|
||||||
|
v->control->positionAndYawCtrl(xCmd, yCmd, zCmd, yawDesiredRad / DEG2RAD);
|
||||||
|
|
||||||
|
delay_nms(cycleTimeInMs);
|
||||||
|
elapsedTimeInMs += cycleTimeInMs;
|
||||||
|
|
||||||
|
//! Get current position in required coordinates and units
|
||||||
|
q = v->subscribe->getValue<Telemetry::TOPIC_QUATERNION>();
|
||||||
|
yawInRad = toEulerAngle(q).z;
|
||||||
|
currentGPS = v->subscribe->getValue<Telemetry::TOPIC_GPS_FUSED>();
|
||||||
|
localOffsetFromGpsOffset(localOffset, currentGPS, originGPS);
|
||||||
|
|
||||||
|
//! See how much farther we have to go
|
||||||
|
xOffsetRemaining = xOffsetDesired - localOffset.x;
|
||||||
|
yOffsetRemaining = yOffsetDesired - localOffset.y;
|
||||||
|
zOffsetRemaining = zOffsetDesired - (-localOffset.z);
|
||||||
|
|
||||||
|
//! See if we need to modify the setpoint
|
||||||
|
if (std::abs(xOffsetRemaining) < speedFactor)
|
||||||
|
xCmd = xOffsetRemaining;
|
||||||
|
if (std::abs(yOffsetRemaining) < speedFactor)
|
||||||
|
yCmd = yOffsetRemaining;
|
||||||
|
|
||||||
|
if (std::abs(xOffsetRemaining) < posThresholdInM &&
|
||||||
|
std::abs(yOffsetRemaining) < posThresholdInM &&
|
||||||
|
std::abs(zOffsetRemaining) < zDeadband &&
|
||||||
|
std::abs(yawInRad - yawDesiredRad) < yawThresholdInRad)
|
||||||
|
{
|
||||||
|
//! 1. We are within bounds; start incrementing our in-bound counter
|
||||||
|
withinBoundsCounter += cycleTimeInMs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (withinBoundsCounter != 0)
|
||||||
|
{
|
||||||
|
//! 2. Start incrementing an out-of-bounds counter
|
||||||
|
outOfBounds += cycleTimeInMs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//! 3. Reset withinBoundsCounter if necessary
|
||||||
|
if (outOfBounds > outOfControlBoundsTimeLimit)
|
||||||
|
{
|
||||||
|
withinBoundsCounter = 0;
|
||||||
|
outOfBounds = 0;
|
||||||
|
}
|
||||||
|
//! 4. If within bounds, set flag and break
|
||||||
|
if (withinBoundsCounter >= withinControlBoundsTimeReqmt)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Set velocity to zero, to prevent any residual velocity from position
|
||||||
|
//! command
|
||||||
|
|
||||||
|
while (brakeCounter < withinControlBoundsTimeReqmt)
|
||||||
|
{
|
||||||
|
v->control->emergencyBrake();
|
||||||
|
delay_nms(cycleTimeInMs);
|
||||||
|
brakeCounter += cycleTimeInMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elapsedTimeInMs >= timeoutInMilSec)
|
||||||
|
{
|
||||||
|
printf("Task timeout!\n");
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
|
||||||
|
return ACK::FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(3000);
|
||||||
|
return ACK::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper Functions
|
||||||
|
|
||||||
|
/*! Very simple calculation of local NED offset between two pairs of GPS
|
||||||
|
* coordinates (accurate when distances are small).
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
localOffsetFromGpsOffset(Telemetry::Vector3f& deltaNed,
|
||||||
|
Telemetry::GPSFused& target,
|
||||||
|
Telemetry::GPSFused& origin)
|
||||||
|
{
|
||||||
|
double deltaLon = target.longitude - origin.longitude;
|
||||||
|
double deltaLat = target.latitude - origin.latitude;
|
||||||
|
deltaNed.x = deltaLat * C_EARTH;
|
||||||
|
deltaNed.y = deltaLon * C_EARTH * cos(target.latitude);
|
||||||
|
deltaNed.z = target.altitude - origin.altitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
Telemetry::Vector3f
|
||||||
|
toEulerAngle(
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_QUATERNION>::type& quaternionData)
|
||||||
|
{
|
||||||
|
Telemetry::Vector3f ans;
|
||||||
|
|
||||||
|
double q2sqr = quaternionData.q2 * quaternionData.q2;
|
||||||
|
double t0 = -2.0 * (q2sqr + quaternionData.q3 * quaternionData.q3) + 1.0;
|
||||||
|
double t1 = +2.0 * (quaternionData.q1 * quaternionData.q2 +
|
||||||
|
quaternionData.q0 * quaternionData.q3);
|
||||||
|
double t2 = -2.0 * (quaternionData.q1 * quaternionData.q3 -
|
||||||
|
quaternionData.q0 * quaternionData.q2);
|
||||||
|
double t3 = +2.0 * (quaternionData.q2 * quaternionData.q3 +
|
||||||
|
quaternionData.q0 * quaternionData.q1);
|
||||||
|
double t4 = -2.0 * (quaternionData.q1 * quaternionData.q1 + q2sqr) + 1.0;
|
||||||
|
|
||||||
|
t2 = (t2 > 1.0) ? 1.0 : t2;
|
||||||
|
t2 = (t2 < -1.0) ? -1.0 : t2;
|
||||||
|
|
||||||
|
ans.x = asin(t2);
|
||||||
|
ans.y = atan2(t3, t4);
|
||||||
|
ans.z = atan2(t1, t0);
|
||||||
|
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*! @file FlightControlSample.h
|
||||||
|
* @version 3.3
|
||||||
|
* @date May 2017
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
* Flight control STM32 example.
|
||||||
|
*
|
||||||
|
* Copyright 2016 DJI. All right reserved.
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
#ifndef FLIGHTCONTROLSAMPLE_H
|
||||||
|
#define FLIGHTCONTROLSAMPLE_H
|
||||||
|
|
||||||
|
#include "BspUsart.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "dji_vehicle.hpp"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
#define C_EARTH (double)6378137.0
|
||||||
|
#define DEG2RAD 0.01745329252
|
||||||
|
|
||||||
|
bool monitoredTakeOff();
|
||||||
|
bool monitoredLanding();
|
||||||
|
int moveByPositionOffset(float xOffsetDesired, float yOffsetDesired,
|
||||||
|
float zOffsetDesired, float yawDesired,
|
||||||
|
float posThresholdInM = 0.2,
|
||||||
|
float yawThresholdInDeg = 1.0);
|
||||||
|
|
||||||
|
//! Helper functions
|
||||||
|
void localOffsetFromGpsOffset(Telemetry::Vector3f& deltaNed,
|
||||||
|
Telemetry::GPSFused& target,
|
||||||
|
Telemetry::GPSFused& origin);
|
||||||
|
Telemetry::Vector3f toEulerAngle(
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_QUATERNION>::type &quaternionData);
|
||||||
|
|
||||||
|
#endif // FLIGHTCONTROLSAMPLE_H
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
#include "MissionSample.h"
|
||||||
|
|
||||||
|
using namespace DJI::OSDK;
|
||||||
|
|
||||||
|
extern Vehicle vehicle;
|
||||||
|
extern Vehicle* v;
|
||||||
|
|
||||||
|
bool
|
||||||
|
runWaypointMission(uint8_t numWaypoints)
|
||||||
|
{
|
||||||
|
// Telemetry: Subscribe to flight status and mode at freq 10 Hz
|
||||||
|
int pkgIndex = 0;
|
||||||
|
int freq = 10;
|
||||||
|
Telemetry::TopicName topicList10Hz[] = { Telemetry::TOPIC_GPS_FUSED,
|
||||||
|
Telemetry::TOPIC_ALTITUDE_FUSIONED };
|
||||||
|
int numTopic = sizeof(topicList10Hz) / sizeof(topicList10Hz[0]);
|
||||||
|
bool enableTimestamp = false;
|
||||||
|
|
||||||
|
bool pkgStatus = v->subscribe->initPackageFromTopicList(
|
||||||
|
pkgIndex, numTopic, topicList10Hz, enableTimestamp, freq);
|
||||||
|
if (!(pkgStatus))
|
||||||
|
{
|
||||||
|
return pkgStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
v->subscribe->startPackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
|
||||||
|
// Waypoint Mission : Initialization
|
||||||
|
WayPointInitSettings fdata;
|
||||||
|
setWaypointInitDefaults(&fdata);
|
||||||
|
fdata.indexNumber =
|
||||||
|
numWaypoints + 1; // We add 1 to get the aircarft back to the start.
|
||||||
|
float64_t increment = 0.000001;
|
||||||
|
float32_t start_alt = 10;
|
||||||
|
|
||||||
|
v->missionManager->init(WAYPOINT, 1, &fdata);
|
||||||
|
delay_nms(500);
|
||||||
|
|
||||||
|
v->missionManager->printInfo();
|
||||||
|
printf("Initializing Waypoint Mission..\n");
|
||||||
|
|
||||||
|
// Waypoint Mission: Create Waypoints
|
||||||
|
std::vector<WayPointSettings> generatedWaypts =
|
||||||
|
createWaypoints(numWaypoints, increment, start_alt);
|
||||||
|
|
||||||
|
printf("Creating Waypoints..\n");
|
||||||
|
|
||||||
|
// Waypoint Mission: Upload the waypoints
|
||||||
|
uploadWaypoints(generatedWaypts);
|
||||||
|
|
||||||
|
printf("Uploading Waypoints..\n");
|
||||||
|
|
||||||
|
// Waypoint Mission: Start
|
||||||
|
v->missionManager->wpMission->start();
|
||||||
|
delay_nms(500);
|
||||||
|
|
||||||
|
printf("Starting Waypoint Mission.\n");
|
||||||
|
|
||||||
|
// Cleanup before return. The mission isn't done yet, but it doesn't need any
|
||||||
|
// more input from our side.
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(3000);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setWaypointDefaults(WayPointSettings* wp)
|
||||||
|
{
|
||||||
|
wp->damping = 0;
|
||||||
|
wp->yaw = 0;
|
||||||
|
wp->gimbalPitch = 0;
|
||||||
|
wp->turnMode = 0;
|
||||||
|
wp->hasAction = 0;
|
||||||
|
wp->actionTimeLimit = 100;
|
||||||
|
wp->actionNumber = 0;
|
||||||
|
wp->actionRepeat = 0;
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
wp->commandList[i] = 0;
|
||||||
|
wp->commandParameter[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setWaypointInitDefaults(WayPointInitSettings* fdata)
|
||||||
|
{
|
||||||
|
fdata->maxVelocity = 10;
|
||||||
|
fdata->idleVelocity = 5;
|
||||||
|
fdata->finishAction = 0;
|
||||||
|
fdata->executiveTimes = 1;
|
||||||
|
fdata->yawMode = 0;
|
||||||
|
fdata->traceMode = 0;
|
||||||
|
fdata->RCLostAction = 1;
|
||||||
|
fdata->gimbalPitch = 0;
|
||||||
|
fdata->latitude = 0;
|
||||||
|
fdata->longitude = 0;
|
||||||
|
fdata->altitude = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DJI::OSDK::WayPointSettings>
|
||||||
|
createWaypoints(int numWaypoints, float64_t distanceIncrement,
|
||||||
|
float32_t start_alt)
|
||||||
|
{
|
||||||
|
delay_nms(8000);
|
||||||
|
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_GPS_FUSED>::type gPosition =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GPS_FUSED>();
|
||||||
|
|
||||||
|
// Create Start Waypoint
|
||||||
|
WayPointSettings start_wp;
|
||||||
|
setWaypointDefaults(&start_wp);
|
||||||
|
start_wp.latitude = gPosition.latitude;
|
||||||
|
start_wp.longitude = gPosition.longitude;
|
||||||
|
start_wp.altitude = start_alt;
|
||||||
|
|
||||||
|
printf("Waypoint created at (LLA): %f \t%f \t%f\n", gPosition.latitude,
|
||||||
|
gPosition.longitude, start_alt);
|
||||||
|
|
||||||
|
std::vector<DJI::OSDK::WayPointSettings> wpVector =
|
||||||
|
generateWaypointsPolygon(&start_wp, distanceIncrement, numWaypoints);
|
||||||
|
return wpVector;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<DJI::OSDK::WayPointSettings>
|
||||||
|
generateWaypointsPolygon(WayPointSettings* start_data, float64_t increment,
|
||||||
|
int num_wp)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Let's create a vector to store our waypoints in.
|
||||||
|
std::vector<DJI::OSDK::WayPointSettings> wp_list;
|
||||||
|
|
||||||
|
// Some calculation for the polygon
|
||||||
|
float64_t extAngle = 2 * M_PI / num_wp;
|
||||||
|
|
||||||
|
// First waypoint
|
||||||
|
start_data->index = 0;
|
||||||
|
wp_list.push_back(*start_data);
|
||||||
|
|
||||||
|
// Iterative algorithm
|
||||||
|
for (int i = 1; i < num_wp; i++)
|
||||||
|
{
|
||||||
|
WayPointSettings wp;
|
||||||
|
WayPointSettings* prevWp = &wp_list[i - 1];
|
||||||
|
setWaypointDefaults(&wp);
|
||||||
|
wp.index = i;
|
||||||
|
wp.latitude = (prevWp->latitude + (increment * cos(i * extAngle)));
|
||||||
|
wp.longitude = (prevWp->longitude + (increment * sin(i * extAngle)));
|
||||||
|
wp.altitude = (prevWp->altitude + 1);
|
||||||
|
wp_list.push_back(wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Come back home
|
||||||
|
start_data->index = num_wp;
|
||||||
|
wp_list.push_back(*start_data);
|
||||||
|
|
||||||
|
return wp_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
uploadWaypoints(std::vector<DJI::OSDK::WayPointSettings>& wp_list)
|
||||||
|
{
|
||||||
|
for (std::vector<WayPointSettings>::iterator wp = wp_list.begin();
|
||||||
|
wp != wp_list.end(); ++wp)
|
||||||
|
{
|
||||||
|
printf("Waypoint created at (LLA): %f \t%f \t%f\n ", wp->latitude,
|
||||||
|
wp->longitude, wp->altitude);
|
||||||
|
|
||||||
|
v->missionManager->wpMission->uploadIndexData(&(*wp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
runHotpointMission(int initialRadius)
|
||||||
|
{
|
||||||
|
ACK::ErrorCode ack;
|
||||||
|
|
||||||
|
// Takeoff
|
||||||
|
monitoredTakeOff();
|
||||||
|
|
||||||
|
int pkgIndex = 0;
|
||||||
|
int freq = 10;
|
||||||
|
Telemetry::TopicName topicList10Hz[] = { Telemetry::TOPIC_GPS_FUSED };
|
||||||
|
int numTopic = sizeof(topicList10Hz) / sizeof(topicList10Hz[0]);
|
||||||
|
bool enableTimestamp = false;
|
||||||
|
|
||||||
|
bool pkgStatus = v->subscribe->initPackageFromTopicList(
|
||||||
|
pkgIndex, numTopic, topicList10Hz, enableTimestamp, freq);
|
||||||
|
if (!(pkgStatus))
|
||||||
|
{
|
||||||
|
return pkgStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
v->subscribe->startPackage(pkgIndex);
|
||||||
|
delay_nms(500);
|
||||||
|
|
||||||
|
// Wait for data to arrive
|
||||||
|
delay_nms(8000);
|
||||||
|
|
||||||
|
// Hotpoint Mission Initialize
|
||||||
|
v->missionManager->init(HOTPOINT, 1, NULL);
|
||||||
|
|
||||||
|
v->missionManager->printInfo();
|
||||||
|
Telemetry::TypeMap<Telemetry::TOPIC_GPS_FUSED>::type gPosition =
|
||||||
|
v->subscribe->getValue<Telemetry::TOPIC_GPS_FUSED>();
|
||||||
|
v->missionManager->hpMission->setHotPoint(gPosition.longitude,
|
||||||
|
gPosition.latitude, initialRadius);
|
||||||
|
|
||||||
|
// Start
|
||||||
|
printf("Start with default rotation rate: 15 deg/s");
|
||||||
|
|
||||||
|
v->missionManager->hpMission->start();
|
||||||
|
delay_nms(500);
|
||||||
|
/*ack = waitForAck();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
ACK::ErrorCode ack =
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
printf("Error unsubscribing; please restart the drone/FC to get "
|
||||||
|
"back to a clean state.\n");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
delay_nms(4000);
|
||||||
|
|
||||||
|
// Pause
|
||||||
|
printf("Pause for 5s\n");
|
||||||
|
v->missionManager->hpMission->pause();
|
||||||
|
delay_nms(5000);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Resume
|
||||||
|
printf("Resume\n");
|
||||||
|
v->missionManager->hpMission->resume();
|
||||||
|
delay_nms(4000);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
ACK::getErrorCodeMessage(ack, __func__);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Update radius, no ACK
|
||||||
|
printf("Update radius to 1.5x: new radius = %0.3f\n", 1.5 * initialRadius);
|
||||||
|
v->missionManager->hpMission->updateRadius(1.5 * initialRadius);
|
||||||
|
delay_nms(10000);
|
||||||
|
|
||||||
|
// Update velocity (yawRate), no ACK
|
||||||
|
printf("Update hotpoint rotation rate: new rate = 5 deg/s\n");
|
||||||
|
HotpointMission::YawRate yawRateStruct;
|
||||||
|
yawRateStruct.clockwise = 1;
|
||||||
|
yawRateStruct.yawRate = 5;
|
||||||
|
|
||||||
|
v->missionManager->hpMission->updateYawRate(yawRateStruct);
|
||||||
|
delay_nms(10000);
|
||||||
|
|
||||||
|
// Give it a bit more time to finish a circle
|
||||||
|
delay_nms(20000);
|
||||||
|
|
||||||
|
// Stop
|
||||||
|
printf("Stop\n");
|
||||||
|
v->missionManager->hpMission->stop();
|
||||||
|
delay_nms(1000);
|
||||||
|
|
||||||
|
printf("Land\n");
|
||||||
|
|
||||||
|
// Free existing packages
|
||||||
|
v->subscribe->removePackage(pkgIndex);
|
||||||
|
delay_nms(3000);
|
||||||
|
/*ack = waitForACK();
|
||||||
|
if (ACK::getError(ack))
|
||||||
|
{
|
||||||
|
printf("Error unsubscribing; please restart the drone/FC to get back "
|
||||||
|
"to a clean state.\n");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return monitoredLanding() ? true : false;
|
||||||
|
}
|
||||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário