Esse commit está contido em:
Rohit Sant
2017-06-15 15:46:01 -07:00
commit 4c8d43f615
136 arquivos alterados com 32183 adições e 0 exclusões
+9
Ver Arquivo
@@ -0,0 +1,9 @@
BasedOnStyle: Mozilla
Standard: Cpp03
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BreakBeforeBraces: Allman
+52
Ver Arquivo
@@ -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
+14
Ver Arquivo
@@ -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
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+20
Ver Arquivo
@@ -0,0 +1,20 @@
# DJI Onboard SDK (OSDK) 3.3
[![Join the chat at https://gitter.im/dji-sdk/Onboard-SDK](https://badges.gitter.im/Join%20Chat.svg)](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)
+161
Ver Arquivo
@@ -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)
+275
Ver Arquivo
@@ -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
+343
Ver Arquivo
@@ -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
+62
Ver Arquivo
@@ -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
+135
Ver Arquivo
@@ -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 */
+421
Ver Arquivo
@@ -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 controlHORIZONTAL_VELOCITYrelated 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
+553
Ver Arquivo
@@ -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 */
+118
Ver Arquivo
@@ -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
+76
Ver Arquivo
@@ -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
+306
Ver Arquivo
@@ -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
+170
Ver Arquivo
@@ -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
+70
Ver Arquivo
@@ -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
+156
Ver Arquivo
@@ -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
+155
Ver Arquivo
@@ -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
+149
Ver Arquivo
@@ -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 */
+278
Ver Arquivo
@@ -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
+554
Ver Arquivo
@@ -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
+162
Ver Arquivo
@@ -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
+360
Ver Arquivo
@@ -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_ */
+46
Ver Arquivo
@@ -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 */
+91
Ver Arquivo
@@ -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
+240
Ver Arquivo
@@ -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
+747
Ver Arquivo
@@ -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
+316
Ver Arquivo
@@ -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;
}
+50
Ver Arquivo
@@ -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);
}
+165
Ver Arquivo
@@ -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
};
+244
Ver Arquivo
@@ -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)
{
}
+277
Ver Arquivo
@@ -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
+41
Ver Arquivo
@@ -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));
}
+37
Ver Arquivo
@@ -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));
}
+469
Ver Arquivo
@@ -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;
}
+221
Ver Arquivo
@@ -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);
}
+185
Ver Arquivo
@@ -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;
}
+658
Ver Arquivo
@@ -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
+27
Ver Arquivo
@@ -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));
}
+493
Ver Arquivo
@@ -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()
+101
Ver Arquivo
@@ -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
+94
Ver Arquivo
@@ -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
+43
Ver Arquivo
@@ -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
+91
Ver Arquivo
@@ -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
+47
Ver Arquivo
@@ -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;
}
+213
Ver Arquivo
@@ -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;
}
+171
Ver Arquivo
@@ -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;
}
+97
Ver Arquivo
@@ -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()
{
}
+3
Ver Arquivo
@@ -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
+1
Ver Arquivo
@@ -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;
}
}
+141
Ver Arquivo
@@ -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;
}
}
+191
Ver Arquivo
@@ -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;
}
+39
Ver Arquivo
@@ -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
+383
Ver Arquivo
@@ -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
+436
Ver Arquivo
@@ -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
+67
Ver Arquivo
@@ -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;
}
+1
Ver Arquivo
@@ -0,0 +1 @@
#include "dji_singleton.hpp"
+1
Ver Arquivo
@@ -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
+23
Ver Arquivo
@@ -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
+23
Ver Arquivo
@@ -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();
}
+17
Ver Arquivo
@@ -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
+145
Ver Arquivo
@@ -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
+25
Ver Arquivo
@@ -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(&currentAngle);
// 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(&currentAngle);
// 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(&currentAngle);
// 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(&currentAngle);
// 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