최예리

Upload code file

############################################################################
#
# Copyright (c) 2017 - 2019 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#=============================================================================
# CMAKE CODING STANDARD FOR PX4
#
# Structure
# ---------------------------------------------------------------------------
#
# * Common functions should be included in px_base.cmake.
#
# * OS/ board specific fucntions should be include in
# px_impl_${PX4_PLATFORM}.cmake or px4_impl_${PX4_PLATFORM}_${PX4_BOARD}.cmake.
#
# Formatting
# ---------------------------------------------------------------------------
#
# * Use hard indents to match the px4 source code.
#
# * All function and script arguments are upper case.
#
# * All local variables are lower case.
#
# * All cmake functions are lowercase.
#
# * For else, endif, endfunction, etc, never put the name of the statement
#
# Functions/Macros
# ---------------------------------------------------------------------------
#
# * Use px4_parse_function_args to parse functions and check for required
# arguments. Unless there is only one argument in the function and it is clear.
#
# * Never use macros. They allow overwriting global variables and this
# makes variable declarations hard to locate.
#
# * If a target from add_custom_* is set in a function, explicitly pass it
# as an output argument so that the target name is clear to the user.
#
# * Avoid use of global variables in functions. Functions in a nested
# scope may use global variables, but this makes it difficult to
# reuse functions.
#
# Included CMake Files
# ---------------------------------------------------------------------------
#
# * All variables in config files must have the prefix "config_".
#
# * Never set global variables in an included cmake file,
# you may only define functions. This excludes config and Toolchain files.
# This makes it clear to the user when variables are being set or targets
# are being created.
#
# * Setting a global variable in a CMakeLists.txt file is ok, because
# each CMakeLists.txt file has scope in the current directory and all
# subdirectories, so it is not truly global.
#
# * All toolchain files should be included in the cmake
# directory and named Toolchain-"name".cmake.
#
# Misc
# ---------------------------------------------------------------------------
#
# * If referencing a string variable, don't put it in quotes.
# Don't do "${PX4_PLATFORM}" STREQUAL "posix",
# instead type ${PX4_PLATFORM} STREQUAL "posix". This will throw an
# error when ${PX4_PLATFORM} is not defined instead of silently
# evaluating to false.
#
#=============================================================================
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
set(PX4_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(PX4_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake)
include(px4_parse_function_args)
#=============================================================================
# git
#
include(px4_git)
execute_process(
COMMAND git describe --exclude ext/* --always --tags
OUTPUT_VARIABLE PX4_GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${PX4_SOURCE_DIR}
)
message(STATUS "PX4 version: ${PX4_GIT_TAG}")
define_property(GLOBAL PROPERTY PX4_MODULE_LIBRARIES
BRIEF_DOCS "PX4 module libs"
FULL_DOCS "List of all PX4 module libraries"
)
define_property(GLOBAL PROPERTY PX4_MODULE_PATHS
BRIEF_DOCS "PX4 module paths"
FULL_DOCS "List of paths to all PX4 modules"
)
#=============================================================================
# configuration
#
set(CONFIG "px4_sitl_default" CACHE STRING "desired configuration")
include(px4_add_module)
set(config_module_list)
include(px4_config)
include(px4_add_board)
include(${PX4_CONFIG_FILE})
message(STATUS "PX4 config: ${PX4_CONFIG}")
message(STATUS "PX4 platform: ${PX4_PLATFORM}")
if(${PX4_PLATFORM} STREQUAL "posix")
if(ENABLE_LOCKSTEP_SCHEDULER)
add_definitions(-DENABLE_LOCKSTEP_SCHEDULER)
message(STATUS "PX4 lockstep: enabled")
else()
message(STATUS "PX4 lockstep: disabled")
endif()
endif()
# external modules
set(EXTERNAL_MODULES_LOCATION "" CACHE STRING "External modules source location")
if(NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
get_filename_component(EXTERNAL_MODULES_LOCATION "${EXTERNAL_MODULES_LOCATION}" ABSOLUTE)
endif()
set_property(GLOBAL PROPERTY PX4_MODULE_CONFIG_FILES)
include(platforms/${PX4_PLATFORM}/cmake/px4_impl_os.cmake)
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/platforms/${PX4_PLATFORM}/cmake)
if(EXISTS "${PX4_SOURCE_DIR}/platforms/${PX4_PLATFORM}/cmake/init.cmake")
include(init)
endif()
# CMake build type (Debug Release RelWithDebInfo MinSizeRel Coverage)
if(NOT CMAKE_BUILD_TYPE)
if(${PX4_PLATFORM} STREQUAL "nuttx")
set(PX4_BUILD_TYPE "MinSizeRel")
else()
set(PX4_BUILD_TYPE "RelWithDebInfo")
endif()
set(CMAKE_BUILD_TYPE ${PX4_BUILD_TYPE} CACHE STRING "Build type" FORCE)
endif()
if((CMAKE_BUILD_TYPE STREQUAL "Debug") OR (CMAKE_BUILD_TYPE STREQUAL "Coverage"))
set(MAX_CUSTOM_OPT_LEVEL -O0)
elseif(CMAKE_BUILD_TYPE MATCHES "Sanitizer")
set(MAX_CUSTOM_OPT_LEVEL -O1)
elseif(CMAKE_BUILD_TYPE MATCHES "Release")
set(MAX_CUSTOM_OPT_LEVEL -O3)
else()
if(px4_constrained_flash_build)
set(MAX_CUSTOM_OPT_LEVEL -Os)
else()
set(MAX_CUSTOM_OPT_LEVEL -O2)
endif()
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel;Coverage;AddressSanitizer;UndefinedBehaviorSanitizer")
message(STATUS "cmake build type: ${CMAKE_BUILD_TYPE}")
#=============================================================================
# project definition
#
project(px4 CXX C ASM)
set(package-contact "px4users@googlegroups.com")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# For the catkin build process, unset build of dynamically-linked binaries
# and do not change CMAKE_RUNTIME_OUTPUT_DIRECTORY
if (NOT CATKIN_DEVEL_PREFIX)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PX4_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PX4_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PX4_BINARY_DIR})
else()
SET(BUILD_SHARED_LIBS OFF)
endif()
#=============================================================================
# gold linker - use if available (posix only for now)
if(${PX4_PLATFORM} STREQUAL "posix")
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(USE_LD_GOLD
"Use GNU gold linker" ON
"NOT WIN32;NOT APPLE" OFF
)
if(USE_LD_GOLD)
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
if("${LD_VERSION}" MATCHES "GNU gold")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lcrypto -fuse-ld=gold")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -lcrypto -fuse-ld=gold")
else()
set(USE_LD_GOLD OFF)
endif()
endif()
endif()
#=============================================================================
# Setup install paths
if(${PX4_PLATFORM} STREQUAL "posix")
# This makes it possible to dynamically load code which depends on symbols
# inside the px4 executable.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_ENABLE_EXPORTS ON)
include(coverage)
include(sanitizers)
# Define GNU standard installation directories
include(GNUInstallDirs)
if (NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Install path prefix" FORCE)
endif()
endif()
include(ccache)
#=============================================================================
# find programs and packages
#
# see if catkin was invoked to build this
if (CATKIN_DEVEL_PREFIX)
message(STATUS "catkin ENABLED")
find_package(catkin REQUIRED)
if (catkin_FOUND)
catkin_package()
else()
message(FATAL_ERROR "catkin not found")
endif()
endif()
# Python
# If using catkin, Python 2 is found since it points
# to the Python libs installed with the ROS distro
if (NOT CATKIN_DEVEL_PREFIX)
find_package(PythonInterp 3)
# We have a custom error message to tell users how to install python3.
if (NOT PYTHONINTERP_FOUND)
message(FATAL_ERROR "Python 3 not found. Please install Python 3:\n"
" Ubuntu: sudo apt install python3 python3-dev python3-pip\n"
" macOS: brew install python")
endif()
else()
find_package(PythonInterp REQUIRED)
endif()
option(PYTHON_COVERAGE "Python code coverage" OFF)
if(PYTHON_COVERAGE)
message(STATUS "python coverage enabled")
set(PYTHON_EXECUTABLE coverage run -p)
endif()
#=============================================================================
# get chip and chip manufacturer
#
px4_os_determine_build_chip()
if(NOT PX4_CHIP_MANUFACTURER)
message(FATAL_ERROR "px4_os_determine_build_chip() needs to set PX4_CHIP_MANUFACTURER")
endif()
if(NOT PX4_CHIP)
message(FATAL_ERROR "px4_os_determine_build_chip() needs to set PX4_CHIP")
endif()
#=============================================================================
# build flags
#
include(px4_add_common_flags)
px4_add_common_flags()
px4_os_add_flags()
#=============================================================================
# board cmake init (optional)
#
if(EXISTS ${PX4_BOARD_DIR}/cmake/init.cmake)
include(${PX4_BOARD_DIR}/cmake/init.cmake)
endif()
#=============================================================================
# message, and airframe generation
#
include(px4_metadata)
add_subdirectory(msg EXCLUDE_FROM_ALL)
px4_generate_airframes_xml(BOARD ${PX4_BOARD})
#=============================================================================
# external projects
#
set(ep_base ${PX4_BINARY_DIR}/external)
set_property(DIRECTORY PROPERTY EP_BASE ${ep_base})
# add external project install folders to build
# add the directories so cmake won't warn
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base})
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base}/Install)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base}/Install/lib)
link_directories(${ep_base}/Install/lib)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base}/Install/include)
include_directories(${ep_base}/Install/include)
#=============================================================================
# external modules
#
set(external_module_paths)
if (NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
message(STATUS "External modules: ${EXTERNAL_MODULES_LOCATION}")
add_subdirectory("${EXTERNAL_MODULES_LOCATION}/src" external_modules)
foreach(external_module ${config_module_list_external})
add_subdirectory(${EXTERNAL_MODULES_LOCATION}/src/${external_module} external_modules/${external_module})
list(APPEND external_module_paths ${EXTERNAL_MODULES_LOCATION}/src/${external_module})
endforeach()
endif()
#=============================================================================
# Testing - Automatic unit and integration testing with CTest
#
# optionally enable cmake testing (supported only on posix)
option(CMAKE_TESTING "Configure test targets" OFF)
if(${PX4_CONFIG} STREQUAL "px4_sitl_test")
set(CMAKE_TESTING ON)
endif()
if(CMAKE_TESTING)
include(CTest) # sets BUILD_TESTING variable
endif()
# enable test filtering to run only specific tests with the ctest -R regex functionality
set(TESTFILTER "" CACHE STRING "Filter string for ctest to selectively only run specific tests (ctest -R)")
# if testing is enabled download and configure gtest
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake/gtest/)
include(px4_add_gtest)
if(BUILD_TESTING)
include(gtest)
add_custom_target(test_results
COMMAND GTEST_COLOR=1 ${CMAKE_CTEST_COMMAND} --output-on-failure -T Test -R ${TESTFILTER} USES_TERMINAL
DEPENDS
px4
examples__dyn_hello
test_mixer_multirotor
USES_TERMINAL
COMMENT "Running tests"
WORKING_DIRECTORY ${PX4_BINARY_DIR})
set_target_properties(test_results PROPERTIES EXCLUDE_FROM_ALL TRUE)
endif()
#=============================================================================
# subdirectories
#
add_library(parameters_interface INTERFACE)
include(px4_add_library)
add_subdirectory(src/lib EXCLUDE_FROM_ALL)
add_subdirectory(platforms/${PX4_PLATFORM}/src/px4)
add_subdirectory(platforms EXCLUDE_FROM_ALL)
if(EXISTS "${PX4_BOARD_DIR}/CMakeLists.txt")
add_subdirectory(${PX4_BOARD_DIR})
endif()
foreach(module ${config_module_list})
add_subdirectory(src/${module})
endforeach()
# must be the last module before firmware
add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
target_link_libraries(parameters_interface INTERFACE parameters)
# firmware added last to generate the builtin for included modules
add_subdirectory(platforms/${PX4_PLATFORM})
#=============================================================================
# uORB graph generation: add a custom target 'uorb_graph'
#
set(uorb_graph_config ${PX4_BOARD})
set(graph_module_list "")
foreach(module ${config_module_list})
set(graph_module_list "${graph_module_list}" "--src-path" "src/${module}")
endforeach()
add_custom_command(OUTPUT ${uorb_graph_config}
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/uorb_graph/create.py
${graph_module_list}
--exclude-path src/examples
--file ${PX4_SOURCE_DIR}/Tools/uorb_graph/graph_${uorb_graph_config}
WORKING_DIRECTORY ${PX4_SOURCE_DIR}
COMMENT "Generating uORB graph"
)
add_custom_target(uorb_graph DEPENDS ${uorb_graph_config})
include(doxygen)
include(metadata)
include(package)
# print size
add_custom_target(size
COMMAND size $<TARGET_FILE:px4>
DEPENDS px4
WORKING_DIRECTORY ${PX4_BINARY_DIR}
USES_TERMINAL
)
# install python requirements using configured python
add_custom_target(install_python_requirements
COMMAND ${PYTHON_EXECUTABLE} -m pip install --requirement ${PX4_SOURCE_DIR}/Tools/setup/requirements.txt
DEPENDS ${PX4_SOURCE_DIR}/Tools/setup/requirements.txt
USES_TERMINAL
)
No preview for this file type
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;
int generate_key()
{
ofstream fout;
BIO* bio;
// generate key pair
EVP_PKEY* key = NULL;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
if(EVP_PKEY_keygen_init(pctx) != 1)
{
cout << "Error: EVP_PKEY_keygen_init" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
if(EVP_PKEY_keygen(pctx, &key) != 1)
{
cout << "Error: EVP_PKEY_keygen" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
EVP_PKEY_CTX_free(pctx);
// save private key
bio = BIO_new( BIO_s_mem() );
if(PEM_write_bio_PrivateKey(bio, key, NULL, NULL, 0, NULL, NULL) != 1)
{
cout << "Error: PEM_write_bio_PrivateKey" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
unsigned char private_key[120] = { 0 };
BIO_read(bio, private_key, 120);
BIO_free(bio);
cout << private_key << endl;
fout.open("private_key");
fout << private_key;
fout.close();
// save public key
bio = BIO_new( BIO_s_mem() );
if(PEM_write_bio_PUBKEY(bio, key) != 1)
{
cout << "Error: PEM_write_bio_PUBKEY" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
EVP_PKEY_free(key);
unsigned char public_key[120] = { 0 };
BIO_read(bio, public_key, 120);
BIO_free(bio);
cout << public_key << endl;
fout.open("public_key");
fout << public_key;
fout.close();
return 1;
}
int sign(char* signee_file, char* key_file)
{
ifstream fin;
ofstream fout;
BIO* bio;
EVP_PKEY* pkey = NULL;
int signee_size = 0, key_size = 0;
// open signee_file
fin.open(signee_file);
if (fin.fail()) {
cout << "Error: Can't open signee file." << endl;
return 0;
}
fin.seekg(0, ios::end);
signee_size = fin.tellg();
fin.seekg(0, ios::beg);
unsigned char* signee = new unsigned char[signee_size];
fin.read((char*)signee, signee_size);
fin.close();
// open private key
fin.open(key_file);
if (fin.fail()) {
cout << "Error: Can't open key file." << endl;
return 0;
}
fin.seekg(0, ios::end);
key_size = fin.tellg();
fin.seekg(0, ios::beg);
unsigned char* key = new unsigned char[key_size];
fin.read((char*)key, key_size);
fin.close();
cout << key << endl;
bio = BIO_new( BIO_s_mem() );
BIO_write(bio, key, key_size);
if(PEM_read_bio_PrivateKey(bio, &pkey, NULL, NULL) == NULL)
{
cout << "Error: PEM_read_bio_PrivateKey" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
BIO_free(bio);
// File Signing, Make Signature
unsigned char sig[65] = { 0 };
size_t sig_size = 64;
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
if(EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey) != 1)
{
cout << "Error: EVP_DigestSignInit" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
if(EVP_DigestSign(ctx, sig, &sig_size, signee, signee_size) != 1)
{
cout << "Error: EVP_DigestSign" << endl;
cout << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
EVP_MD_CTX_free(ctx);
EVP_PKEY_free(pkey);
fout.open("./signature");
cout << hex << setfill('0');
fout << hex << setfill('0');
for(int i = 0; i < sig_size; i++)
{
cout << setw(2) << (int)sig[i];
fout << setw(2) << (int)sig[i];
}
cout << endl;
fout.close();
return 1;
}
/*
int verify(char* signee_file, char* sig_file, char* key_file)
{
ifstream fin;
BIO* bio;
EVP_PKEY* pkey = NULL;
int signee_size = 0, key_size = 0, sig_size = 0;
// open signee_file
fin.open(signee_file);
fin.seekg(0, ios::end);
signee_size = fin.tellg();
fin.seekg(0, ios::beg);
unsigned char* signee = new unsigned char[signee_size];
fin.read((char*)signee, signee_size);
fin.close();
// open public key
fin.open(key_file);
fin.seekg(0, ios::end);
key_size = fin.tellg();
fin.seekg(0, ios::beg);
unsigned char* key = new unsigned char[key_size];
fin.read((char*)key, key_size);
fin.close();
cout << key << endl;
bio = BIO_new( BIO_s_mem() );
BIO_write(bio, key, key_size);
if(PEM_read_bio_PUBKEY(bio, &pkey, NULL, NULL) == NULL)
{
cout << "Error: " << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
BIO_free(bio);
fin.open(sig_file);
fin.seekg(0, ios::end);
sig_size = fin.tellg();
fin.seekg(0, ios::beg);
unsigned char* sig_char = new unsigned char[sig_size];
fin.read((char*)sig_char, sig_size);
fin.close();
unsigned char sig[65] = { 0 };
char temp[3] = { 0 };
for(int i = 0; i < sig_size; i+=2)
{
temp[0] = sig_char[i];
temp[1] = sig_char[i+1];
sig[i/2] = (unsigned char) strtol(temp, NULL, 16);
}
sig_size /= 2;
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
if(EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey) != 1)
{
cout << "Error: " << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
if(EVP_DigestVerify(ctx, sig, sig_size, signee, signee_size) != 1)
{
cout << "Error: " << ERR_error_string(ERR_get_error(),NULL) << endl;
return 0;
}
EVP_PKEY_free(pkey);
cout << "Success" << endl;
return 1;
}
*/
bool cmdOptionExists(char** begin, char** end, const string& option)
{
return find(begin, end, option) != end;
}
char* getCmdOption(char** begin, char** end, const string& option)
{
char** itr = find(begin, end, option);
if (itr != end && ++itr != end)
return *itr;
return 0;
}
int main(int argc, char* argv[])
{
if (cmdOptionExists(argv, argv+argc, "-h")\
|| cmdOptionExists(argv, argv+argc, "--help"))
{
cout << "Usage" << endl;
cout << "Generate key: " << argv[0] << " --genkey" << endl;
cout << "Signing file: " << argv[0] << " -f signee_path -k key_path" << endl;
return 0;
}
if (cmdOptionExists(argv, argv+argc, "--genkey"))
{
generate_key();
return 0;
}
if (cmdOptionExists(argv, argv+argc, "-f")\
&& cmdOptionExists(argv, argv+argc, "-k"))
{
char* signee_path = getCmdOption(argv, argv+argc, "-f");
char* key_path = getCmdOption(argv, argv+argc, "-k");
if (sign(signee_path, key_path) != 1)
cout << "Error occured" << endl;
return 0;
}
else
{
cout << "Usage" << endl;
cout << "Generate key: " << argv[0] << " --genkey" << endl;
cout << "Signing file: " << argv[0] << " -f signee_path -k key_path" << endl;
}
// generate_key();
// sign(argv[1], argv[2]);
// verify(argv[1], argv[2], argv[3]);
return 0;
}
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
* Copyright (c) 2016-2019 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file simulator.cpp
*
* This module interfaces via MAVLink to a software in the loop simulator (SITL)
* such as jMAVSim or Gazebo.
*/
#include <px4_platform_common/log.h>
#include <px4_platform_common/tasks.h>
#include <px4_platform_common/time.h>
#include <systemlib/err.h>
#include <drivers/drv_board_led.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <fstream>
#include <cstring>
#include "simulator.h"
static px4_task_t g_sim_task = -1;
Simulator *Simulator::_instance = nullptr;
void Simulator::parameters_update(bool force)
{
// check for parameter updates
if (_parameter_update_sub.updated() || force) {
// clear update
parameter_update_s pupdate;
_parameter_update_sub.copy(&pupdate);
// update parameters from storage
updateParams();
}
}
int Simulator::verify()
{
/*
char path[256];
if(getcwd(path, 256) == NULL)
PX4_INFO("Test path: %s", strerror(errno));
else
PX4_INFO("Test path: %s", path);
*/
std::ifstream fin;
BIO* bio;
EVP_PKEY* pkey = NULL;
const char* file_path = "../../bin/px4";
// const char* file_path = "../../../../Tools/test.txt";
const char* sig_path = "../../../../Tools/signature";
const char* key_path = "../../../../Tools/public_key";
int file_size = 0, sig_size = 0, key_size = 0;
// open exe file
fin.open(file_path);
if (fin.fail()) {
PX4_WARN("Error: Can't open exe file during signature verifying.");
return 0;
}
fin.seekg(0, std::ios::end);
file_size = fin.tellg();
fin.seekg(0, std::ios::beg);
unsigned char* file = new unsigned char[file_size];
fin.read((char*)file, file_size);
fin.close();
// open signature file
fin.open(sig_path);
if (fin.fail()) {
PX4_WARN("Error: Can't open signature file during signature verifying.");
return 0;
}
fin.seekg(0, std::ios::end);
sig_size = fin.tellg();
fin.seekg(0, std::ios::beg);
unsigned char* sig_char = new unsigned char[sig_size];
fin.read((char*)sig_char, sig_size);
fin.close();
unsigned char sig[65] = { 0 };
char temp[3] = { 0 };
for (int i = 0; i < sig_size; i+=2)
{
temp[0] = sig_char[i];
temp[1] = sig_char[i+1];
sig[i/2] = (unsigned char)strtol(temp, NULL, 16);
}
delete[] sig_char;
sig_size /= 2;
// open public key file
fin.open(key_path);
if (fin.fail()) {
PX4_WARN("Error: Can't open public key file during signature verifying.");
return 0;
}
fin.seekg(0, std::ios::end);
key_size = fin.tellg();
fin.seekg(0, std::ios::beg);
unsigned char* key = new unsigned char[key_size];
fin.read((char*)key, key_size);
fin.close();
// make key file to pkey
bio = BIO_new( BIO_s_mem() );
BIO_write(bio, key, key_size);
if (PEM_read_bio_PUBKEY(bio, &pkey, NULL, NULL) == NULL) {
PX4_WARN("Error: PEM_read_bio_PUBKEY"); //ERR_error_string(ERR_get_error(), NULL)
return 0;
}
delete[] key;
BIO_free(bio);
// verifying signature
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
if (EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey) != 1) {
PX4_WARN("Error: EVP_DigestVerifyInit"); //ERR_error_string(ERR_get_error(), NULL)
return 0;
}
if (EVP_DigestVerify(ctx, sig, sig_size, file, file_size) != 1) {
return 0;
}
EVP_PKEY_free(pkey);
EVP_MD_CTX_free(ctx);
delete[] file;
PX4_INFO("Success: Verifying Signature");
return 1;
}
int Simulator::start(int argc, char *argv[])
{
_instance = new Simulator();
if (_instance->verify() != 1) {
PX4_ERR("Signature Verifying failed");
return 1;
}
if (_instance) {
if (argc == 5 && strcmp(argv[3], "-u") == 0) {
_instance->set_ip(InternetProtocol::UDP);
_instance->set_port(atoi(argv[4]));
}
if (argc == 5 && strcmp(argv[3], "-c") == 0) {
_instance->set_ip(InternetProtocol::TCP);
_instance->set_port(atoi(argv[4]));
}
if (argc == 6 && strcmp(argv[3], "-t") == 0) {
PX4_INFO("Simulator using TCP on remote host %s port %s", argv[4], argv[5]);
PX4_WARN("Please ensure port %s is not blocked by a firewall.", argv[5]);
_instance->set_ip(InternetProtocol::TCP);
_instance->set_tcp_remote_ipaddr(argv[4]);
_instance->set_port(atoi(argv[5]));
}
if (argc == 6 && strcmp(argv[3], "-h") == 0) {
PX4_INFO("Simulator using TCP on remote host %s port %s", argv[4], argv[5]);
PX4_WARN("Please ensure port %s is not blocked by a firewall.", argv[5]);
_instance->set_ip(InternetProtocol::TCP);
_instance->set_hostname(argv[4]);
_instance->set_port(atoi(argv[5]));
}
_instance->run();
return 0;
} else {
PX4_WARN("Simulator creation failed");
return 1;
}
}
static void usage()
{
PX4_INFO("Usage: simulator {start -[spt] [-u udp_port / -c tcp_port] |stop|status}");
PX4_INFO("Start simulator: simulator start");
PX4_INFO("Connect using UDP: simulator start -u udp_port");
PX4_INFO("Connect using TCP: simulator start -c tcp_port");
PX4_INFO("Connect to a remote server using TCP: simulator start -t ip_addr tcp_port");
PX4_INFO("Connect to a remote server via hostname using TCP: simulator start -h hostname tcp_port");
}
__BEGIN_DECLS
extern int simulator_main(int argc, char *argv[]);
__END_DECLS
int simulator_main(int argc, char *argv[])
{
if (argc > 1 && strcmp(argv[1], "start") == 0) {
if (g_sim_task >= 0) {
PX4_WARN("Simulator already started");
return 0;
}
g_sim_task = px4_task_spawn_cmd("simulator",
SCHED_DEFAULT,
SCHED_PRIORITY_MAX,
1500,
Simulator::start,
argv);
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
// We want to prevent the rest of the startup script from running until time
// is initialized by the HIL_SENSOR messages from the simulator.
while (true) {
if (Simulator::getInstance() && Simulator::getInstance()->has_initialized()) {
break;
}
system_usleep(100);
}
#endif
} else if (argc == 2 && strcmp(argv[1], "stop") == 0) {
if (g_sim_task < 0) {
PX4_WARN("Simulator not running");
return 1;
} else {
px4_task_delete(g_sim_task);
g_sim_task = -1;
}
} else if (argc == 2 && strcmp(argv[1], "status") == 0) {
if (g_sim_task < 0) {
PX4_WARN("Simulator not running");
return 1;
} else {
PX4_INFO("running");
}
} else {
usage();
return 1;
}
return 0;
}
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
* Copyright (c) 2016-2019 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file simulator.h
*
* This module interfaces via MAVLink to a software in the loop simulator (SITL)
* such as jMAVSim or Gazebo.
*/
#pragma once
#include <drivers/drv_hrt.h>
#include <drivers/drv_rc_input.h>
#include <lib/drivers/accelerometer/PX4Accelerometer.hpp>
#include <lib/drivers/barometer/PX4Barometer.hpp>
#include <lib/drivers/gyroscope/PX4Gyroscope.hpp>
#include <lib/drivers/magnetometer/PX4Magnetometer.hpp>
#include <lib/ecl/geo/geo.h>
#include <lib/perf/perf_counter.h>
#include <px4_platform_common/atomic.h>
#include <px4_platform_common/bitmask.h>
#include <px4_platform_common/module_params.h>
#include <px4_platform_common/posix.h>
#include <uORB/Publication.hpp>
#include <uORB/Subscription.hpp>
#include <uORB/SubscriptionInterval.hpp>
#include <uORB/topics/actuator_outputs.h>
#include <uORB/topics/differential_pressure.h>
#include <uORB/topics/distance_sensor.h>
#include <uORB/topics/irlock_report.h>
#include <uORB/topics/manual_control_setpoint.h>
#include <uORB/topics/optical_flow.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_gps.h>
#include <uORB/topics/vehicle_angular_velocity.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/vehicle_local_position.h>
#include <uORB/topics/vehicle_odometry.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_command_ack.h>
#include <random>
#include <v2.0/common/mavlink.h>
#include <v2.0/mavlink_types.h>
using namespace time_literals;
//! Enumeration to use on the bitmask in HIL_SENSOR
enum class SensorSource {
ACCEL = 0b111,
GYRO = 0b111000,
MAG = 0b111000000,
BARO = 0b1101000000000,
DIFF_PRESS = 0b10000000000
};
ENABLE_BIT_OPERATORS(SensorSource)
//! AND operation for the enumeration and unsigned types that returns the bitmask
template<typename A, typename B>
static inline SensorSource operator &(A lhs, B rhs)
{
// make it type safe
static_assert((std::is_same<A, uint32_t>::value || std::is_same<A, SensorSource>::value),
"first argument is not uint32_t or SensorSource enum type");
static_assert((std::is_same<B, uint32_t>::value || std::is_same<B, SensorSource>::value),
"second argument is not uint32_t or SensorSource enum type");
typedef typename std::underlying_type<SensorSource>::type underlying;
return static_cast<SensorSource>(
static_cast<underlying>(lhs) &
static_cast<underlying>(rhs)
);
}
class Simulator : public ModuleParams
{
public:
static Simulator *getInstance() { return _instance; }
enum class InternetProtocol {
TCP,
UDP
};
static int start(int argc, char *argv[]);
void set_ip(InternetProtocol ip) { _ip = ip; }
void set_port(unsigned port) { _port = port; }
void set_hostname(std::string hostname) { _hostname = hostname; }
void set_tcp_remote_ipaddr(char *tcp_remote_ipaddr) { _tcp_remote_ipaddr = tcp_remote_ipaddr; }
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
bool has_initialized() { return _has_initialized.load(); }
#endif
private:
Simulator() : ModuleParams(nullptr)
{
}
~Simulator()
{
// free perf counters
perf_free(_perf_sim_delay);
perf_free(_perf_sim_interval);
for (size_t i = 0; i < sizeof(_dist_pubs) / sizeof(_dist_pubs[0]); i++) {
delete _dist_pubs[i];
}
px4_lockstep_unregister_component(_lockstep_component);
for (size_t i = 0; i < sizeof(_sensor_gps_pubs) / sizeof(_sensor_gps_pubs[0]); i++) {
delete _sensor_gps_pubs[i];
}
_instance = nullptr;
}
void check_failure_injections();
int publish_flow_topic(const mavlink_hil_optical_flow_t *flow);
int publish_odometry_topic(const mavlink_message_t *odom_mavlink);
int publish_distance_topic(const mavlink_distance_sensor_t *dist);
static Simulator *_instance;
// simulated sensor instances
static constexpr uint8_t ACCEL_COUNT_MAX = 3;
PX4Accelerometer _px4_accel[ACCEL_COUNT_MAX] {
{1310988, ROTATION_NONE}, // 1310988: DRV_IMU_DEVTYPE_SIM, BUS: 1, ADDR: 1, TYPE: SIMULATION
{1310996, ROTATION_NONE}, // 1310996: DRV_IMU_DEVTYPE_SIM, BUS: 2, ADDR: 1, TYPE: SIMULATION
{1311004, ROTATION_NONE}, // 1311004: DRV_IMU_DEVTYPE_SIM, BUS: 3, ADDR: 1, TYPE: SIMULATION
};
static constexpr uint8_t GYRO_COUNT_MAX = 3;
PX4Gyroscope _px4_gyro[GYRO_COUNT_MAX] {
{1310988, ROTATION_NONE}, // 1310988: DRV_IMU_DEVTYPE_SIM, BUS: 1, ADDR: 1, TYPE: SIMULATION
{1310996, ROTATION_NONE}, // 1310996: DRV_IMU_DEVTYPE_SIM, BUS: 2, ADDR: 1, TYPE: SIMULATION
{1311004, ROTATION_NONE}, // 1311004: DRV_IMU_DEVTYPE_SIM, BUS: 3, ADDR: 1, TYPE: SIMULATION
};
PX4Magnetometer _px4_mag_0{197388, ROTATION_NONE}; // 197388: DRV_MAG_DEVTYPE_MAGSIM, BUS: 1, ADDR: 1, TYPE: SIMULATION
PX4Magnetometer _px4_mag_1{197644, ROTATION_NONE}; // 197644: DRV_MAG_DEVTYPE_MAGSIM, BUS: 2, ADDR: 1, TYPE: SIMULATION
PX4Barometer _px4_baro_0{6620172}; // 6620172: DRV_BARO_DEVTYPE_BAROSIM, BUS: 1, ADDR: 4, TYPE: SIMULATION
PX4Barometer _px4_baro_1{6620428}; // 6620428: DRV_BARO_DEVTYPE_BAROSIM, BUS: 2, ADDR: 4, TYPE: SIMULATION
float _sensors_temperature{0};
perf_counter_t _perf_sim_delay{perf_alloc(PC_ELAPSED, MODULE_NAME": network delay")};
perf_counter_t _perf_sim_interval{perf_alloc(PC_INTERVAL, MODULE_NAME": network interval")};
// uORB publisher handlers
uORB::Publication<differential_pressure_s> _differential_pressure_pub{ORB_ID(differential_pressure)};
uORB::PublicationMulti<optical_flow_s> _flow_pub{ORB_ID(optical_flow)};
uORB::Publication<irlock_report_s> _irlock_report_pub{ORB_ID(irlock_report)};
uORB::Publication<vehicle_odometry_s> _visual_odometry_pub{ORB_ID(vehicle_visual_odometry)};
uORB::Publication<vehicle_odometry_s> _mocap_odometry_pub{ORB_ID(vehicle_mocap_odometry)};
uORB::Publication<vehicle_command_ack_s> _command_ack_pub{ORB_ID(vehicle_command_ack)};
uORB::PublicationMulti<distance_sensor_s> *_dist_pubs[ORB_MULTI_MAX_INSTANCES] {};
uint32_t _dist_sensor_ids[ORB_MULTI_MAX_INSTANCES] {};
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
unsigned int _port{14560};
InternetProtocol _ip{InternetProtocol::UDP};
std::string _hostname{""};
char *_tcp_remote_ipaddr{nullptr};
double _realtime_factor{1.0}; ///< How fast the simulation runs in comparison to real system time
hrt_abstime _last_sim_timestamp{0};
hrt_abstime _last_sitl_timestamp{0};
int verify();
void run();
void handle_message(const mavlink_message_t *msg);
void handle_message_distance_sensor(const mavlink_message_t *msg);
void handle_message_hil_gps(const mavlink_message_t *msg);
void handle_message_hil_sensor(const mavlink_message_t *msg);
void handle_message_hil_state_quaternion(const mavlink_message_t *msg);
void handle_message_landing_target(const mavlink_message_t *msg);
void handle_message_odometry(const mavlink_message_t *msg);
void handle_message_optical_flow(const mavlink_message_t *msg);
void handle_message_rc_channels(const mavlink_message_t *msg);
void handle_message_vision_position_estimate(const mavlink_message_t *msg);
void parameters_update(bool force);
void poll_for_MAVLink_messages();
void request_hil_state_quaternion();
void send();
void send_controls();
void send_heartbeat();
void send_mavlink_message(const mavlink_message_t &aMsg);
void update_sensors(const hrt_abstime &time, const mavlink_hil_sensor_t &sensors);
static void *sending_trampoline(void *);
void actuator_controls_from_outputs(mavlink_hil_actuator_controls_t *msg);
// uORB publisher handlers
uORB::Publication<vehicle_angular_velocity_s> _vehicle_angular_velocity_ground_truth_pub{ORB_ID(vehicle_angular_velocity_groundtruth)};
uORB::Publication<vehicle_attitude_s> _attitude_ground_truth_pub{ORB_ID(vehicle_attitude_groundtruth)};
uORB::Publication<vehicle_global_position_s> _gpos_ground_truth_pub{ORB_ID(vehicle_global_position_groundtruth)};
uORB::Publication<vehicle_local_position_s> _lpos_ground_truth_pub{ORB_ID(vehicle_local_position_groundtruth)};
uORB::Publication<input_rc_s> _input_rc_pub{ORB_ID(input_rc)};
// HIL GPS
static constexpr int MAX_GPS = 3;
uORB::PublicationMulti<sensor_gps_s> *_sensor_gps_pubs[MAX_GPS] {};
uint8_t _gps_ids[MAX_GPS] {};
std::default_random_engine _gen{};
// uORB subscription handlers
int _actuator_outputs_sub{-1};
actuator_outputs_s _actuator_outputs{};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)};
// hil map_ref data
map_projection_reference_s _global_local_proj_ref{};
float _global_local_alt0{NAN};
vehicle_status_s _vehicle_status{};
bool _accel_blocked[ACCEL_COUNT_MAX] {};
bool _accel_stuck[ACCEL_COUNT_MAX] {};
sensor_accel_fifo_s _last_accel_fifo{};
matrix::Vector3f _last_accel[GYRO_COUNT_MAX] {};
bool _gyro_blocked[GYRO_COUNT_MAX] {};
bool _gyro_stuck[GYRO_COUNT_MAX] {};
sensor_gyro_fifo_s _last_gyro_fifo{};
matrix::Vector3f _last_gyro[GYRO_COUNT_MAX] {};
bool _baro_blocked{false};
bool _baro_stuck{false};
bool _mag_blocked{false};
bool _mag_stuck{false};
bool _gps_blocked{false};
bool _airspeed_blocked{false};
float _last_magx{0.0f};
float _last_magy{0.0f};
float _last_magz{0.0f};
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
px4::atomic<bool> _has_initialized {false};
#endif
int _lockstep_component{-1};
DEFINE_PARAMETERS(
(ParamInt<px4::params::MAV_TYPE>) _param_mav_type,
(ParamInt<px4::params::MAV_SYS_ID>) _param_mav_sys_id,
(ParamInt<px4::params::MAV_COMP_ID>) _param_mav_comp_id
)
};
############################################################################
#
# Copyright (c) 2017 - 2019 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
#=============================================================================
# CMAKE CODING STANDARD FOR PX4
#
# Structure
# ---------------------------------------------------------------------------
#
# * Common functions should be included in px_base.cmake.
#
# * OS/ board specific fucntions should be include in
# px_impl_${PX4_PLATFORM}.cmake or px4_impl_${PX4_PLATFORM}_${PX4_BOARD}.cmake.
#
# Formatting
# ---------------------------------------------------------------------------
#
# * Use hard indents to match the px4 source code.
#
# * All function and script arguments are upper case.
#
# * All local variables are lower case.
#
# * All cmake functions are lowercase.
#
# * For else, endif, endfunction, etc, never put the name of the statement
#
# Functions/Macros
# ---------------------------------------------------------------------------
#
# * Use px4_parse_function_args to parse functions and check for required
# arguments. Unless there is only one argument in the function and it is clear.
#
# * Never use macros. They allow overwriting global variables and this
# makes variable declarations hard to locate.
#
# * If a target from add_custom_* is set in a function, explicitly pass it
# as an output argument so that the target name is clear to the user.
#
# * Avoid use of global variables in functions. Functions in a nested
# scope may use global variables, but this makes it difficult to
# reuse functions.
#
# Included CMake Files
# ---------------------------------------------------------------------------
#
# * All variables in config files must have the prefix "config_".
#
# * Never set global variables in an included cmake file,
# you may only define functions. This excludes config and Toolchain files.
# This makes it clear to the user when variables are being set or targets
# are being created.
#
# * Setting a global variable in a CMakeLists.txt file is ok, because
# each CMakeLists.txt file has scope in the current directory and all
# subdirectories, so it is not truly global.
#
# * All toolchain files should be included in the cmake
# directory and named Toolchain-"name".cmake.
#
# Misc
# ---------------------------------------------------------------------------
#
# * If referencing a string variable, don't put it in quotes.
# Don't do "${PX4_PLATFORM}" STREQUAL "posix",
# instead type ${PX4_PLATFORM} STREQUAL "posix". This will throw an
# error when ${PX4_PLATFORM} is not defined instead of silently
# evaluating to false.
#
#=============================================================================
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
set(PX4_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(PX4_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake)
include(px4_parse_function_args)
#=============================================================================
# git
#
include(px4_git)
execute_process(
COMMAND git describe --always --tags
OUTPUT_VARIABLE PX4_GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${PX4_SOURCE_DIR}
)
message(STATUS "PX4 version: ${PX4_GIT_TAG}")
define_property(GLOBAL PROPERTY PX4_MODULE_LIBRARIES
BRIEF_DOCS "PX4 module libs"
FULL_DOCS "List of all PX4 module libraries"
)
define_property(GLOBAL PROPERTY PX4_MODULE_PATHS
BRIEF_DOCS "PX4 module paths"
FULL_DOCS "List of paths to all PX4 modules"
)
#=============================================================================
# configuration
#
set(CONFIG "px4_sitl_default" CACHE STRING "desired configuration")
include(px4_add_module)
set(config_module_list)
include(px4_config)
include(px4_add_board)
include(${PX4_CONFIG_FILE})
message(STATUS "PX4 config: ${PX4_CONFIG}")
message(STATUS "PX4 platform: ${PX4_PLATFORM}")
if(${PX4_PLATFORM} STREQUAL "posix")
if(ENABLE_LOCKSTEP_SCHEDULER)
add_definitions(-DENABLE_LOCKSTEP_SCHEDULER)
message(STATUS "PX4 lockstep: enabled")
else()
message(STATUS "PX4 lockstep: disabled")
endif()
endif()
# external modules
set(EXTERNAL_MODULES_LOCATION "" CACHE STRING "External modules source location")
if(NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
get_filename_component(EXTERNAL_MODULES_LOCATION "${EXTERNAL_MODULES_LOCATION}" ABSOLUTE)
endif()
set_property(GLOBAL PROPERTY PX4_MODULE_CONFIG_FILES)
include(platforms/${PX4_PLATFORM}/cmake/px4_impl_os.cmake)
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/platforms/${PX4_PLATFORM}/cmake)
if(EXISTS "${PX4_SOURCE_DIR}/platforms/${PX4_PLATFORM}/cmake/init.cmake")
include(init)
endif()
# CMake build type (Debug Release RelWithDebInfo MinSizeRel Coverage)
if(NOT CMAKE_BUILD_TYPE)
if(${PX4_PLATFORM} STREQUAL "nuttx")
set(PX4_BUILD_TYPE "MinSizeRel")
else()
set(PX4_BUILD_TYPE "RelWithDebInfo")
endif()
set(CMAKE_BUILD_TYPE ${PX4_BUILD_TYPE} CACHE STRING "Build type" FORCE)
endif()
if((CMAKE_BUILD_TYPE STREQUAL "Debug") OR (CMAKE_BUILD_TYPE STREQUAL "Coverage"))
set(MAX_CUSTOM_OPT_LEVEL -O0)
elseif(CMAKE_BUILD_TYPE MATCHES "Sanitizer")
set(MAX_CUSTOM_OPT_LEVEL -O1)
else()
if(px4_constrained_flash_build)
set(MAX_CUSTOM_OPT_LEVEL -Os)
else()
set(MAX_CUSTOM_OPT_LEVEL -O2)
endif()
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel;Coverage;AddressSanitizer;UndefinedBehaviorSanitizer")
message(STATUS "cmake build type: ${CMAKE_BUILD_TYPE}")
#=============================================================================
# project definition
#
project(px4 CXX C ASM)
set(package-contact "px4users@googlegroups.com")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# For the catkin build process, unset build of dynamically-linked binaries
# and do not change CMAKE_RUNTIME_OUTPUT_DIRECTORY
if (NOT CATKIN_DEVEL_PREFIX)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PX4_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PX4_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PX4_BINARY_DIR})
else()
SET(BUILD_SHARED_LIBS OFF)
endif()
#=============================================================================
# gold linker - use if available (posix only for now)
if(${PX4_PLATFORM} STREQUAL "posix")
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(USE_LD_GOLD
"Use GNU gold linker" ON
"NOT WIN32;NOT APPLE" OFF
)
if(USE_LD_GOLD)
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
if("${LD_VERSION}" MATCHES "GNU gold")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold")
else()
set(USE_LD_GOLD OFF)
endif()
endif()
endif()
#=============================================================================
# Setup install paths
if(${PX4_PLATFORM} STREQUAL "posix")
# This makes it possible to dynamically load code which depends on symbols
# inside the px4 executable.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_ENABLE_EXPORTS ON)
include(coverage)
include(sanitizers)
# Define GNU standard installation directories
include(GNUInstallDirs)
if (NOT CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Install path prefix" FORCE)
endif()
endif()
include(ccache)
#=============================================================================
# find programs and packages
#
# see if catkin was invoked to build this
if (CATKIN_DEVEL_PREFIX)
message(STATUS "catkin ENABLED")
find_package(catkin REQUIRED)
if (catkin_FOUND)
catkin_package()
else()
message(FATAL_ERROR "catkin not found")
endif()
endif()
# Python
# If using catkin, Python 2 is found since it points
# to the Python libs installed with the ROS distro
if (NOT CATKIN_DEVEL_PREFIX)
find_package(PythonInterp 3)
# We have a custom error message to tell users how to install python3.
if (NOT PYTHONINTERP_FOUND)
message(FATAL_ERROR "Python 3 not found. Please install Python 3:\n"
" Ubuntu: sudo apt install python3 python3-dev python3-pip\n"
" macOS: brew install python")
endif()
else()
find_package(PythonInterp REQUIRED)
endif()
option(PYTHON_COVERAGE "Python code coverage" OFF)
if(PYTHON_COVERAGE)
message(STATUS "python coverage enabled")
set(PYTHON_EXECUTABLE coverage run -p)
endif()
#=============================================================================
# get chip and chip manufacturer
#
px4_os_determine_build_chip()
if(NOT PX4_CHIP_MANUFACTURER)
message(FATAL_ERROR "px4_os_determine_build_chip() needs to set PX4_CHIP_MANUFACTURER")
endif()
if(NOT PX4_CHIP)
message(FATAL_ERROR "px4_os_determine_build_chip() needs to set PX4_CHIP")
endif()
#=============================================================================
# build flags
#
include(px4_add_common_flags)
px4_add_common_flags()
px4_os_add_flags()
#=============================================================================
# board cmake init (optional)
#
if(EXISTS ${PX4_BOARD_DIR}/cmake/init.cmake)
include(${PX4_BOARD_DIR}/cmake/init.cmake)
endif()
#=============================================================================
# message, and airframe generation
#
include(px4_metadata)
add_subdirectory(msg EXCLUDE_FROM_ALL)
px4_generate_airframes_xml(BOARD ${PX4_BOARD})
#=============================================================================
# external projects
#
set(ep_base ${PX4_BINARY_DIR}/external)
set_property(DIRECTORY PROPERTY EP_BASE ${ep_base})
# add external project install folders to build
# add the directories so cmake won't warn
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base})
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base}/Install)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base}/Install/lib)
link_directories(${ep_base}/Install/lib)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${ep_base}/Install/include)
include_directories(${ep_base}/Install/include)
#=============================================================================
# external modules
#
set(external_module_paths)
if (NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
message(STATUS "External modules: ${EXTERNAL_MODULES_LOCATION}")
add_subdirectory("${EXTERNAL_MODULES_LOCATION}/src" external_modules)
foreach(external_module ${config_module_list_external})
add_subdirectory(${EXTERNAL_MODULES_LOCATION}/src/${external_module} external_modules/${external_module})
list(APPEND external_module_paths ${EXTERNAL_MODULES_LOCATION}/src/${external_module})
endforeach()
endif()
#=============================================================================
# Testing - Automatic unit and integration testing with CTest
#
# optionally enable cmake testing (supported only on posix)
option(CMAKE_TESTING "Configure test targets" OFF)
if(${PX4_CONFIG} STREQUAL "px4_sitl_test")
set(CMAKE_TESTING ON)
endif()
if(CMAKE_TESTING)
include(CTest) # sets BUILD_TESTING variable
endif()
# enable test filtering to run only specific tests with the ctest -R regex functionality
set(TESTFILTER "" CACHE STRING "Filter string for ctest to selectively only run specific tests (ctest -R)")
# if testing is enabled download and configure gtest
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake/gtest/)
include(px4_add_gtest)
if(BUILD_TESTING)
include(gtest)
add_custom_target(test_results
COMMAND GTEST_COLOR=1 ${CMAKE_CTEST_COMMAND} --output-on-failure -T Test -R ${TESTFILTER} USES_TERMINAL
DEPENDS
px4
examples__dyn_hello
test_mixer_multirotor
USES_TERMINAL
COMMENT "Running tests"
WORKING_DIRECTORY ${PX4_BINARY_DIR})
set_target_properties(test_results PROPERTIES EXCLUDE_FROM_ALL TRUE)
endif()
#=============================================================================
# subdirectories
#
add_library(parameters_interface INTERFACE)
include(px4_add_library)
add_subdirectory(src/lib EXCLUDE_FROM_ALL)
add_subdirectory(platforms/${PX4_PLATFORM}/src/px4)
add_subdirectory(platforms EXCLUDE_FROM_ALL)
if(EXISTS "${PX4_BOARD_DIR}/CMakeLists.txt")
add_subdirectory(${PX4_BOARD_DIR})
endif()
foreach(module ${config_module_list})
add_subdirectory(src/${module})
endforeach()
# must be the last module before firmware
add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
target_link_libraries(parameters_interface INTERFACE parameters)
# firmware added last to generate the builtin for included modules
add_subdirectory(platforms/${PX4_PLATFORM})
#=============================================================================
# uORB graph generation: add a custom target 'uorb_graph'
#
set(uorb_graph_config ${PX4_BOARD})
set(graph_module_list "")
foreach(module ${config_module_list})
set(graph_module_list "${graph_module_list}" "--src-path" "src/${module}")
endforeach()
add_custom_command(OUTPUT ${uorb_graph_config}
COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/uorb_graph/create.py
${graph_module_list}
--exclude-path src/examples
--file ${PX4_SOURCE_DIR}/Tools/uorb_graph/graph_${uorb_graph_config}
WORKING_DIRECTORY ${PX4_SOURCE_DIR}
COMMENT "Generating uORB graph"
)
add_custom_target(uorb_graph DEPENDS ${uorb_graph_config})
include(doxygen)
include(metadata)
include(package)
# print size
add_custom_target(size
COMMAND size $<TARGET_FILE:px4>
DEPENDS px4
WORKING_DIRECTORY ${PX4_BINARY_DIR}
USES_TERMINAL
)
# install python requirements using configured python
add_custom_target(install_python_requirements
COMMAND ${PYTHON_EXECUTABLE} -m pip install --requirement ${PX4_SOURCE_DIR}/Tools/setup/requirements.txt
DEPENDS ${PX4_SOURCE_DIR}/Tools/setup/requirements.txt
USES_TERMINAL
)
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
* Copyright (c) 2016-2019 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file simulator.cpp
*
* This module interfaces via MAVLink to a software in the loop simulator (SITL)
* such as jMAVSim or Gazebo.
*/
#include <px4_platform_common/log.h>
#include <px4_platform_common/tasks.h>
#include <px4_platform_common/time.h>
#include <systemlib/err.h>
#include <drivers/drv_board_led.h>
#include "simulator.h"
static px4_task_t g_sim_task = -1;
Simulator *Simulator::_instance = nullptr;
void Simulator::parameters_update(bool force)
{
// check for parameter updates
if (_parameter_update_sub.updated() || force) {
// clear update
parameter_update_s pupdate;
_parameter_update_sub.copy(&pupdate);
// update parameters from storage
updateParams();
}
}
int Simulator::start(int argc, char *argv[])
{
_instance = new Simulator();
if (_instance) {
if (argc == 5 && strcmp(argv[3], "-u") == 0) {
_instance->set_ip(InternetProtocol::UDP);
_instance->set_port(atoi(argv[4]));
}
if (argc == 5 && strcmp(argv[3], "-c") == 0) {
_instance->set_ip(InternetProtocol::TCP);
_instance->set_port(atoi(argv[4]));
}
if (argc == 6 && strcmp(argv[3], "-t") == 0) {
_instance->set_ip(InternetProtocol::TCP);
_instance->set_tcp_remote_ipaddr(argv[4]);
_instance->set_port(atoi(argv[5]));
}
_instance->run();
return 0;
} else {
PX4_WARN("Simulator creation failed");
return 1;
}
}
static void usage()
{
PX4_INFO("Usage: simulator {start -[spt] [-u udp_port / -c tcp_port] |stop|status}");
PX4_INFO("Start simulator: simulator start");
PX4_INFO("Connect using UDP: simulator start -u udp_port");
PX4_INFO("Connect using TCP: simulator start -c tcp_port");
PX4_INFO("Connect to a remote server using TCP: simulator start -t ip_addr tcp_port");
}
__BEGIN_DECLS
extern int simulator_main(int argc, char *argv[]);
__END_DECLS
int simulator_main(int argc, char *argv[])
{
if (argc > 1 && strcmp(argv[1], "start") == 0) {
if (g_sim_task >= 0) {
PX4_WARN("Simulator already started");
return 0;
}
g_sim_task = px4_task_spawn_cmd("simulator",
SCHED_DEFAULT,
SCHED_PRIORITY_MAX,
1500,
Simulator::start,
argv);
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
// We want to prevent the rest of the startup script from running until time
// is initialized by the HIL_SENSOR messages from the simulator.
while (true) {
if (Simulator::getInstance() && Simulator::getInstance()->has_initialized()) {
break;
}
system_usleep(100);
}
#endif
} else if (argc == 2 && strcmp(argv[1], "stop") == 0) {
if (g_sim_task < 0) {
PX4_WARN("Simulator not running");
return 1;
} else {
px4_task_delete(g_sim_task);
g_sim_task = -1;
}
} else if (argc == 2 && strcmp(argv[1], "status") == 0) {
if (g_sim_task < 0) {
PX4_WARN("Simulator not running");
return 1;
} else {
PX4_INFO("running");
}
} else {
usage();
return 1;
}
return 0;
}
/****************************************************************************
*
* Copyright (c) 2015 Mark Charlebois. All rights reserved.
* Copyright (c) 2016-2019 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file simulator.h
*
* This module interfaces via MAVLink to a software in the loop simulator (SITL)
* such as jMAVSim or Gazebo.
*/
#pragma once
#include <drivers/drv_hrt.h>
#include <drivers/drv_rc_input.h>
#include <lib/drivers/accelerometer/PX4Accelerometer.hpp>
#include <lib/drivers/barometer/PX4Barometer.hpp>
#include <lib/drivers/gyroscope/PX4Gyroscope.hpp>
#include <lib/drivers/magnetometer/PX4Magnetometer.hpp>
#include <lib/ecl/geo/geo.h>
#include <lib/perf/perf_counter.h>
#include <px4_platform_common/atomic.h>
#include <px4_platform_common/bitmask.h>
#include <px4_platform_common/module_params.h>
#include <px4_platform_common/posix.h>
#include <uORB/Publication.hpp>
#include <uORB/Subscription.hpp>
#include <uORB/SubscriptionInterval.hpp>
#include <uORB/topics/actuator_outputs.h>
#include <uORB/topics/differential_pressure.h>
#include <uORB/topics/distance_sensor.h>
#include <uORB/topics/irlock_report.h>
#include <uORB/topics/manual_control_setpoint.h>
#include <uORB/topics/optical_flow.h>
#include <uORB/topics/parameter_update.h>
#include <uORB/topics/sensor_gps.h>
#include <uORB/topics/vehicle_angular_velocity.h>
#include <uORB/topics/vehicle_attitude.h>
#include <uORB/topics/vehicle_global_position.h>
#include <uORB/topics/vehicle_local_position.h>
#include <uORB/topics/vehicle_odometry.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_command_ack.h>
#include <random>
#include <v2.0/common/mavlink.h>
#include <v2.0/mavlink_types.h>
using namespace time_literals;
//! Enumeration to use on the bitmask in HIL_SENSOR
enum class SensorSource {
ACCEL = 0b111,
GYRO = 0b111000,
MAG = 0b111000000,
BARO = 0b1101000000000,
DIFF_PRESS = 0b10000000000
};
ENABLE_BIT_OPERATORS(SensorSource)
//! AND operation for the enumeration and unsigned types that returns the bitmask
template<typename A, typename B>
static inline SensorSource operator &(A lhs, B rhs)
{
// make it type safe
static_assert((std::is_same<A, uint32_t>::value || std::is_same<A, SensorSource>::value),
"first argument is not uint32_t or SensorSource enum type");
static_assert((std::is_same<B, uint32_t>::value || std::is_same<B, SensorSource>::value),
"second argument is not uint32_t or SensorSource enum type");
typedef typename std::underlying_type<SensorSource>::type underlying;
return static_cast<SensorSource>(
static_cast<underlying>(lhs) &
static_cast<underlying>(rhs)
);
}
class Simulator : public ModuleParams
{
public:
static Simulator *getInstance() { return _instance; }
enum class InternetProtocol {
TCP,
UDP
};
static int start(int argc, char *argv[]);
void set_ip(InternetProtocol ip) { _ip = ip; }
void set_port(unsigned port) { _port = port; }
void set_tcp_remote_ipaddr(char *tcp_remote_ipaddr) { _tcp_remote_ipaddr = tcp_remote_ipaddr; }
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
bool has_initialized() { return _has_initialized.load(); }
#endif
private:
Simulator() : ModuleParams(nullptr)
{
}
~Simulator()
{
// free perf counters
perf_free(_perf_sim_delay);
perf_free(_perf_sim_interval);
for (size_t i = 0; i < sizeof(_dist_pubs) / sizeof(_dist_pubs[0]); i++) {
delete _dist_pubs[i];
}
px4_lockstep_unregister_component(_lockstep_component);
for (size_t i = 0; i < sizeof(_sensor_gps_pubs) / sizeof(_sensor_gps_pubs[0]); i++) {
delete _sensor_gps_pubs[i];
}
_instance = nullptr;
}
void check_failure_injections();
int publish_flow_topic(const mavlink_hil_optical_flow_t *flow);
int publish_odometry_topic(const mavlink_message_t *odom_mavlink);
int publish_distance_topic(const mavlink_distance_sensor_t *dist);
static Simulator *_instance;
// simulated sensor instances
static constexpr uint8_t ACCEL_COUNT_MAX = 3;
PX4Accelerometer _px4_accel[ACCEL_COUNT_MAX] {
{1310988, ROTATION_NONE}, // 1310988: DRV_IMU_DEVTYPE_SIM, BUS: 1, ADDR: 1, TYPE: SIMULATION
{1310996, ROTATION_NONE}, // 1310996: DRV_IMU_DEVTYPE_SIM, BUS: 2, ADDR: 1, TYPE: SIMULATION
{1311004, ROTATION_NONE}, // 1311004: DRV_IMU_DEVTYPE_SIM, BUS: 3, ADDR: 1, TYPE: SIMULATION
};
static constexpr uint8_t GYRO_COUNT_MAX = 3;
PX4Gyroscope _px4_gyro[GYRO_COUNT_MAX] {
{1310988, ROTATION_NONE}, // 1310988: DRV_IMU_DEVTYPE_SIM, BUS: 1, ADDR: 1, TYPE: SIMULATION
{1310996, ROTATION_NONE}, // 1310996: DRV_IMU_DEVTYPE_SIM, BUS: 2, ADDR: 1, TYPE: SIMULATION
{1311004, ROTATION_NONE}, // 1311004: DRV_IMU_DEVTYPE_SIM, BUS: 3, ADDR: 1, TYPE: SIMULATION
};
PX4Magnetometer _px4_mag_0{197388, ROTATION_NONE}; // 197388: DRV_MAG_DEVTYPE_MAGSIM, BUS: 1, ADDR: 1, TYPE: SIMULATION
PX4Magnetometer _px4_mag_1{197644, ROTATION_NONE}; // 197644: DRV_MAG_DEVTYPE_MAGSIM, BUS: 2, ADDR: 1, TYPE: SIMULATION
PX4Barometer _px4_baro_0{6620172}; // 6620172: DRV_BARO_DEVTYPE_BAROSIM, BUS: 1, ADDR: 4, TYPE: SIMULATION
PX4Barometer _px4_baro_1{6620428}; // 6620428: DRV_BARO_DEVTYPE_BAROSIM, BUS: 2, ADDR: 4, TYPE: SIMULATION
float _sensors_temperature{0};
perf_counter_t _perf_sim_delay{perf_alloc(PC_ELAPSED, MODULE_NAME": network delay")};
perf_counter_t _perf_sim_interval{perf_alloc(PC_INTERVAL, MODULE_NAME": network interval")};
// uORB publisher handlers
uORB::Publication<differential_pressure_s> _differential_pressure_pub{ORB_ID(differential_pressure)};
uORB::PublicationMulti<optical_flow_s> _flow_pub{ORB_ID(optical_flow)};
uORB::Publication<irlock_report_s> _irlock_report_pub{ORB_ID(irlock_report)};
uORB::Publication<vehicle_odometry_s> _visual_odometry_pub{ORB_ID(vehicle_visual_odometry)};
uORB::Publication<vehicle_odometry_s> _mocap_odometry_pub{ORB_ID(vehicle_mocap_odometry)};
uORB::Publication<vehicle_command_ack_s> _command_ack_pub{ORB_ID(vehicle_command_ack)};
uORB::PublicationMulti<distance_sensor_s> *_dist_pubs[ORB_MULTI_MAX_INSTANCES] {};
uint32_t _dist_sensor_ids[ORB_MULTI_MAX_INSTANCES] {};
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
unsigned int _port{14560};
InternetProtocol _ip{InternetProtocol::UDP};
char *_tcp_remote_ipaddr{nullptr};
double _realtime_factor{1.0}; ///< How fast the simulation runs in comparison to real system time
hrt_abstime _last_sim_timestamp{0};
hrt_abstime _last_sitl_timestamp{0};
void run();
void handle_message(const mavlink_message_t *msg);
void handle_message_distance_sensor(const mavlink_message_t *msg);
void handle_message_hil_gps(const mavlink_message_t *msg);
void handle_message_hil_sensor(const mavlink_message_t *msg);
void handle_message_hil_state_quaternion(const mavlink_message_t *msg);
void handle_message_landing_target(const mavlink_message_t *msg);
void handle_message_odometry(const mavlink_message_t *msg);
void handle_message_optical_flow(const mavlink_message_t *msg);
void handle_message_rc_channels(const mavlink_message_t *msg);
void handle_message_vision_position_estimate(const mavlink_message_t *msg);
void parameters_update(bool force);
void poll_for_MAVLink_messages();
void request_hil_state_quaternion();
void send();
void send_controls();
void send_heartbeat();
void send_mavlink_message(const mavlink_message_t &aMsg);
void update_sensors(const hrt_abstime &time, const mavlink_hil_sensor_t &sensors);
static void *sending_trampoline(void *);
void actuator_controls_from_outputs(mavlink_hil_actuator_controls_t *msg);
// uORB publisher handlers
uORB::Publication<vehicle_angular_velocity_s> _vehicle_angular_velocity_ground_truth_pub{ORB_ID(vehicle_angular_velocity_groundtruth)};
uORB::Publication<vehicle_attitude_s> _attitude_ground_truth_pub{ORB_ID(vehicle_attitude_groundtruth)};
uORB::Publication<vehicle_global_position_s> _gpos_ground_truth_pub{ORB_ID(vehicle_global_position_groundtruth)};
uORB::Publication<vehicle_local_position_s> _lpos_ground_truth_pub{ORB_ID(vehicle_local_position_groundtruth)};
uORB::Publication<input_rc_s> _input_rc_pub{ORB_ID(input_rc)};
// HIL GPS
static constexpr int MAX_GPS = 3;
uORB::PublicationMulti<sensor_gps_s> *_sensor_gps_pubs[MAX_GPS] {};
uint8_t _gps_ids[MAX_GPS] {};
std::default_random_engine _gen{};
// uORB subscription handlers
int _actuator_outputs_sub{-1};
actuator_outputs_s _actuator_outputs{};
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)};
// hil map_ref data
map_projection_reference_s _global_local_proj_ref{};
float _global_local_alt0{NAN};
vehicle_status_s _vehicle_status{};
bool _accel_blocked[ACCEL_COUNT_MAX] {};
bool _accel_stuck[ACCEL_COUNT_MAX] {};
sensor_accel_fifo_s _last_accel_fifo{};
matrix::Vector3f _last_accel[GYRO_COUNT_MAX] {};
bool _gyro_blocked[GYRO_COUNT_MAX] {};
bool _gyro_stuck[GYRO_COUNT_MAX] {};
sensor_gyro_fifo_s _last_gyro_fifo{};
matrix::Vector3f _last_gyro[GYRO_COUNT_MAX] {};
bool _baro_blocked{false};
bool _baro_stuck{false};
bool _mag_blocked{false};
bool _mag_stuck{false};
bool _gps_blocked{false};
bool _airspeed_blocked{false};
float _last_magx{0.0f};
float _last_magy{0.0f};
float _last_magz{0.0f};
#if defined(ENABLE_LOCKSTEP_SCHEDULER)
px4::atomic<bool> _has_initialized {false};
#endif
int _lockstep_component{-1};
DEFINE_PARAMETERS(
(ParamInt<px4::params::MAV_TYPE>) _param_mav_type,
(ParamInt<px4::params::MAV_SYS_ID>) _param_mav_sys_id,
(ParamInt<px4::params::MAV_COMP_ID>) _param_mav_comp_id
)
};