diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63ef85a --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# CMake generated files +CMakeFiles/ +CMakeCache.txt +cmake_install.cmake + +# Visual studio files +.vs/ +*.vc*proj* +*.sln +Release/ +Debug/ + +# Freeglut generated files +config.h +freeglut.* \ No newline at end of file diff --git a/3rdparty/.gitignore b/3rdparty/.gitignore new file mode 100644 index 0000000..a22e327 --- /dev/null +++ b/3rdparty/.gitignore @@ -0,0 +1,2 @@ +# Ignore all inside this folder +* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9bd328c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.0) + +project(HelicopterSimulation) + +################################################################################ +# Configuration section # +################################################################################ + +# Compile library only (WITH_SIM = 0) or the simulator also (WITH_SIM = 1) +set(WITH_SIM 1) + +# Compile the required dependencies "glut" (COMPILE_GLUT = 1) or use a system one (COMPILE_GLUT = 0) +# If using a system one the line +# target_link_libraries(HelicopterSimulationSim glut) +# must be updated accordingly (if the glut.lib name is different from "glut") +# Further, a copying a glut.dll file to the binary folder *may* be needed (if not installed in system path) +set(COMPILE_GLUT 1) + +# glut folder if COMPILE_GLUT is set to 1 +set(GLUT_FOLDER ${CMAKE_SOURCE_DIR}/3rdparty/freeglut/) + +################################################################################ +# Do NOT edit below this line (unless you know what you're doing) # +################################################################################ + +# Project output: +# * HelicopterSimulationLib: simulation static library +# * HelicopterSimulationSim: included test simulator executable +# The HelicopterSimulationSim is available only if WITH_SIM is set to 1 + +# Set the library source files +set(LIB_SRC + src/matlib.c + src/model.c + src/simlib.c +) + +# Create the static library +add_library(HelicopterSimulationLib STATIC ${LIB_SRC}) + +# If simulator is required +if(WITH_SIM) + + # Set the simulator source files + set(SIM_SRC + src/graphics.c + src/helisim.c + src/instruments.c + ) + + # If glut compilation is required + if(COMPILE_GLUT) + # Check glut folder exists, since the user should manually download it + if(NOT EXISTS ${GLUT_FOLDER}) + message(FATAL_ERROR + "Missing glut library." + "Please download glut (http://freeglut.sourceforge.net/) and extract it in '${GLUT_FOLDER}' without any intermediate folder (the '${GLUT_FOLDER}' folder must contain a CMakeLists.txt file)") + endif() + + # Add glut project + add_subdirectory(${GLUT_FOLDER}) + + # Add glut to include directories + include_directories(${GLUT_FOLDER}/include) + endif(COMPILE_GLUT) + + # Create the simulator executable... + add_executable(HelicopterSimulationSim ${SIM_SRC}) + # ... and link it: + # 1) with the simulation library + target_link_libraries(HelicopterSimulationSim HelicopterSimulationLib) + + if(COMPILE_GLUT) + # 2a) with compiled glut + target_link_libraries(HelicopterSimulationSim freeglut) + + # Deploy glut dll file to bin directory + add_custom_command(TARGET HelicopterSimulationSim POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$") + else(COMPILE_GLUT) + # 2b) with system glut + target_link_libraries(HelicopterSimulationSim glut) + endif(COMPILE_GLUT) + +endif(WITH_SIM) diff --git a/README.md b/README.md index 2dfcb95..0b19fdf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# Helicopter-Simulation +# Helicopter-Simulation # [![Codacy Badge](https://api.codacy.com/project/badge/Grade/dd8d6dd64aee43eda773c641c96de2d1)](https://www.codacy.com/app/DanIsraelMalta/Helicopter-Simulation?utm_source=github.com&utm_medium=referral&utm_content=DanIsraelMalta/Helicopter-Simulation&utm_campaign=Badge_Grade) +## Description ## + A complete rigid body six degrees of freedom helicopter simulation (ANSI-C) including: * Main rotor model (including a linear rotor flapping model accounting for coupled servo rotor dynamics and mechanical feedback by the gyroscopic effect of the @@ -20,3 +22,24 @@ A complete rigid body six degrees of freedom helicopter simulation (ANSI-C) incl * A place to write the flight control code... ![Alt text](https://cloud.githubusercontent.com/assets/5231886/6562224/f2eb1b14-c69f-11e4-8234-10785c2cbba2.png) + +## Project setup ## + +To compile the simulator *CMake* (https://www.cmake.org/) is required. +*CMake* is a tool to create a compiler-dependant project file and it is cross platform. + +Basic usage: +1. Open *CMakeLists.txt* file in the project folder with a text editor and tune the "Configuration section" based on your specific needing and configuration. +2. Download and install *CMake*. +3. Open a command prompt or a terminal and go to the project source directory. +4. Run "cmake ." without quotes. The *period* is important! +5. Check for any error message. +6. If no errors, a compiler-dependant project file will be available on project folder (e.g. .sln file for Visual Studio or Makefile for linux). +7. *Visual studio only*: Open HelicopterSimulation.sln and set "HelicopterSimulationSim" as startup project. If you disabled the "HelicopterSimulationSim" project from the CMakeLists.txt file skip this step. + +Alternatively you can use [CMake GUI](https://www.google.com/search?q=cmake+gui) to avoid using command prompt or the terminal. + +**Note:** Even if *CMake* is cross platform and can create a Makefile on linux, the source code for this project has not been tested on platforms different than Windows. Compilation errors may (and probably will) occurs. + +## Running the simulator ## +*Empty section* diff --git a/VC/HelicopterSimulation.sln b/VC/HelicopterSimulation.sln deleted file mode 100644 index 8017c70..0000000 --- a/VC/HelicopterSimulation.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "helisim", "helisim.vcproj", "{F3D3EC73-4985-4483-BD89-9A61AC6D1C72}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F3D3EC73-4985-4483-BD89-9A61AC6D1C72}.Debug|Win32.ActiveCfg = Debug|Win32 - {F3D3EC73-4985-4483-BD89-9A61AC6D1C72}.Debug|Win32.Build.0 = Debug|Win32 - {F3D3EC73-4985-4483-BD89-9A61AC6D1C72}.Release|Win32.ActiveCfg = Release|Win32 - {F3D3EC73-4985-4483-BD89-9A61AC6D1C72}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/VC/helisim.vcproj b/VC/helisim.vcproj deleted file mode 100644 index a2d74b5..0000000 --- a/VC/helisim.vcproj +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/graphics.c b/src/graphics.c index b1dfb22..0cf626b 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -656,7 +656,7 @@ void drawGUI(void) { void DrawCircle(float cx, float cy, float r, int num_segments) { // locals int i; - float theta = C_TWOPI / float(num_segments), + float theta = C_TWOPI / (float)num_segments, c = cos(theta), s = sin(theta), x = r, y = 0; diff --git a/src/matlib.c b/src/matlib.c index 8456e84..397311a 100644 --- a/src/matlib.c +++ b/src/matlib.c @@ -111,7 +111,7 @@ void F_QUATERNION_NORMALIZATION(double xio_quaternion[4]) { * @param {array} latitude [rad] * @param {array} longitude [rad] **/ -void F_GEODETIC_TO_ECEF(double xo_ecef[3], double xi_local[3], double xi_latitude, double xi_longitude) { +void F_GEODETIC_TO_ECEF_4args(double xo_ecef[3], double xi_local[3], double xi_latitude, double xi_longitude) { // locals double _transformationMatrix[3][3], _cosLat, _cosLon, _sinLat, _sinLon; @@ -186,7 +186,7 @@ void F_ECEF_TO_GEODETIC(double xi_ecef[3], double xo_llh[3]) * @param {array} 1x3 array {latitude [rad], longitude [rad], altitude [m]} * @return {array} 1x3 array holding ECEF XYZ coordinates [m] **/ -void F_GEODETIC_TO_ECEF(double xi_llh[3], double xo_ecef[3]) +void F_GEODETIC_TO_ECEF_2args(double xi_llh[3], double xo_ecef[3]) { // locals double temp = sin(xi_llh[_LAT]), N; diff --git a/src/matlib.h b/src/matlib.h index dd449ef..2d59cff 100644 --- a/src/matlib.h +++ b/src/matlib.h @@ -132,8 +132,8 @@ void F_EULER_TO_DCM(double tBL[3][3], double phi, double theta, double psi); void F_QUATERNION_TO_DCM(double tBL[3][3], double q[4]); void F_QUATERNION_NORMALIZATION(double q[4]); -void F_GEODETIC_TO_ECEF(double llh[3], double ECEF[3]); -void F_GEODETIC_TO_ECEF(double xo_ecef[3], double xi_local[3], double xi_latitude, double xi_longitude); +void F_GEODETIC_TO_ECEF_2args(double llh[3], double ECEF[3]); +void F_GEODETIC_TO_ECEF_4args(double xo_ecef[3], double xi_local[3], double xi_latitude, double xi_longitude); void F_ECEF_TO_GEODETIC(double llh[3], double ECEF[3]); void F_QUATERNION_TO_EULER(double q[4], double euler[3]); void F_EULER_TO_QUATERNION(double q[4], const double phi, const double theta, const double psi); diff --git a/src/simlib.c b/src/simlib.c index 5b7a731..4e03273 100644 --- a/src/simlib.c +++ b/src/simlib.c @@ -151,7 +151,7 @@ void F_IMU(struct imu_inputs_def *pIn, struct imu_outputs_def *pOut) { _vectorTemp1[_Z] = _body2earth[_Z][_X] * pIn->cg2imu[_X] + _body2earth[_Z][_Y] * pIn->cg2imu[_Y] + _body2earth[_Z][_Z] * pIn->cg2imu[_Z]; // transform position to ECEF coordinate system - F_GEODETIC_TO_ECEF(_VectorTemp2, _vectorTemp1, _lat, _lon); + F_GEODETIC_TO_ECEF_4args(_VectorTemp2, _vectorTemp1, _lat, _lon); // calculate IMU position in ECEF coordinate system pOut->ECEFpos[_X] = _VectorTemp2[_X] + pIn->cg_pos[_X]; @@ -1055,7 +1055,7 @@ void F_GRAVITY_MODEL(struct grav_inputs_def *pIn, struct grav_outputs_def *pOut) _LLH[_ALT] = pIn->altitude * C_FOOT_TO_METER; // calculate the position in ECEF coordinates - F_GEODETIC_TO_ECEF(_LLH, _ECEF); + F_GEODETIC_TO_ECEF_2args(_LLH, _ECEF); // calculate distance from earth center [m] _Recef = sqrt(_ECEF[_X] * _ECEF[_X] + _ECEF[_Y] * _ECEF[_Y] + _ECEF[_Z] * _ECEF[_Z]);