35#include <gazebo/gazebo.hh>
36#include <gazebo/physics/physics.hh>
37#include <gazebo/sensors/sensors.hh>
40#include <gazebo/gazebo_config.h>
41#if GAZEBO_MAJOR_VERSION < 8
42#error "Paparazzi only supports gazebo versions > 7, please upgrade to a more recent version of Gazebo"
49#include "generated/airframe.h"
50#include "generated/flight_plan.h"
66#if defined(NPS_DEBUG_VIDEO)
68#include <opencv2/core/core.hpp>
69#include <opencv2/highgui/highgui.hpp>
70#include <opencv2/imgproc/imgproc.hpp>
75#ifndef NPS_GAZEBO_WORLD
76#define NPS_GAZEBO_WORLD "empty.world"
78#ifndef NPS_GAZEBO_AC_NAME
79#define NPS_GAZEBO_AC_NAME "ardrone"
98 gazebo::sensors::CameraSensorPtr
cam);
100 gazebo::sensors::CameraSensorPtr
cam;
109#ifndef NPS_MT9F002_SENSOR_RES_DIVIDER
110#define NPS_MT9F002_SENSOR_RES_DIVIDER 1
125#if NPS_SIMULATE_LASER_RANGE_ARRAY
135std::shared_ptr<gazebo::sensors::SonarSensor>
sonar =
NULL;
145static gazebo::sensors::ContactSensorPtr
ct;
201 eulers.
psi = -quat.Yaw();
202 eulers.
theta = -quat.Pitch();
203 eulers.
phi = quat.Roll();
210 eulers.
psi = -quat.Yaw() -
M_PI / 2;
211 eulers.
theta = -quat.Pitch();
212 eulers.
phi = quat.Roll();
242#ifdef NPS_ACTUATOR_TIME_CONSTANTS
248#ifdef NPS_ACTUATOR_MAX_ANGULAR_MOMENTUM
279#if NPS_SIMULATE_VIDEO
282#if NPS_SIMULATE_LASER_RANGE_ARRAY
289 gazebo::runWorld(
model->GetWorld(), 1);
290 gazebo::sensors::run_once();
293#if NPS_SIMULATE_VIDEO
296#if NPS_SIMULATE_LASER_RANGE_ARRAY
345 string pprz_home(getenv(
"PAPARAZZI_HOME"));
349 if (getenv(
"ROS_MASTER_URI")) {
351 cout <<
"Add ROS plugins... ";
352 gazebo::addPlugin(
"libgazebo_ros_paths_plugin.so");
353 gazebo::addPlugin(
"libgazebo_ros_api_plugin.so");
357 if (!gazebo::setupServer(0,
NULL)) {
358 cout <<
"Failed to start Gazebo, exiting." <<
endl;
363 gazebo::common::SystemPaths::Instance()->AddModelPaths(
gazebodir +
"models/");
364 sdf::addURIPath(
"model://",
gazebodir +
"models/");
365 sdf::addURIPath(
"world://",
gazebodir +
"world/");
367 cout <<
"Add TU Delft paths: " <<
pprz_home +
"/sw/ext/tudelft_gazebo_models/" <<
endl;
368 gazebo::common::SystemPaths::Instance()->AddModelPaths(
pprz_home +
"/sw/ext/tudelft_gazebo_models/models/");
369 sdf::addURIPath(
"model://",
pprz_home +
"/sw/ext/tudelft_gazebo_models/models/");
370 sdf::addURIPath(
"world://",
pprz_home +
"/sw/ext/tudelft_gazebo_models/world/");
388#if NPS_SIMULATE_VIDEO
390 sdf::ElementPtr link =
vehicle_sdf->Root()->GetFirstElement()->GetElement(
"link");
392 if (link->Get<
string>(
"name") ==
"front_camera" && link->GetElement(
"sensor")->Get<
string>(
"name") ==
"mt9f002") {
394 int w = link->GetElement(
"sensor")->GetElement(
"camera")->GetElement(
"image")->GetElement(
"width")->Get<
int>();
395 int h = link->GetElement(
"sensor")->GetElement(
"camera")->GetElement(
"image")->GetElement(
"height")->Get<
int>();
396 int env = link->GetElement(
"sensor")->GetElement(
"camera")->GetElement(
"lens")->GetElement(
"env_texture_size")->Get<
int>();
402 int fps =
Min(
MT9F002_TARGET_FPS, link->GetElement(
"sensor")->GetElement(
"update_rate")->Get<
int>());
403 link->GetElement(
"sensor")->GetElement(
"update_rate")->Set(fps);
405 }
else if (link->Get<
string>(
"name") ==
"bottom_camera" && link->GetElement(
"sensor")->Get<
string>(
"name") ==
"mt9v117") {
407 int fps =
Min(
MT9V117_TARGET_FPS, link->GetElement(
"sensor")->GetElement(
"update_rate")->Get<
int>());
408 link->GetElement(
"sensor")->GetElement(
"update_rate")->Set(fps);
411 link = link->GetNextElement(
"link");
416#if NPS_SIMULATE_LASER_RANGE_ARRAY
417 vehicle_sdf->Root()->GetFirstElement()->AddElement(
"include")->GetElement(
"uri")->Set(
"model://range_sensors");
419 range_joint->GetAttribute(
"name")->Set(
"range_sensor_joint");
422 range_joint->GetElement(
"child")->Set(
"range_sensors::base");
445 gazebo::physics::WorldPtr world = gazebo::loadWorld(
pprz_home +
"/var/gazebo.world");
447 cout <<
"Failed to open world, exiting." <<
endl;
460 gazebo::sensors::run_once(
true);
461 gazebo::sensors::run_threads();
462 gazebo::runWorld(world, 1);
463 cout <<
"Sensors initialized..." <<
endl;
467 gazebo::sensors::SensorManager *
mgr = gazebo::sensors::SensorManager::Instance();
481 <<
"' should only contain 1 sensor!" <<
endl;
486 cout <<
"ERROR: Could not get pointer to '" << name <<
"'!" <<
endl;
489 sonar->SetActive(
true);
495#ifdef MOTOR_MIXING_YAW_COEF
503 cout <<
"Gazebo initialized successfully!" <<
endl;
516 static ignition::math::Vector3d
vel_prev;
519 gazebo::physics::WorldPtr world =
model->GetWorld();
520 ignition::math::Pose3d
pose =
model->WorldPose();
521 ignition::math::Vector3d vel =
model->WorldLinearVel();
522 ignition::math::Vector3d ang_vel =
model->WorldAngularVel();
523 gazebo::common::SphericalCoordinatesPtr
sphere = world->SphericalCoords();
527 fdm.
time = world->SimTime().Double();
534 ignition::math::Vector3d accel = (vel -
vel_prev) / dt;
551 for (
int i = 0; i < 3 * 3; i++) {
558 gazebo::common::SphericalCoordinates::GLOBAL));
570 double agl =
sonar->Range();
571 if (agl >
sonar->RangeMax()) agl = -1.0;
579 gazebo::common::SphericalCoordinates::GLOBAL));
586 gazebo::common::SphericalCoordinates::GLOBAL));
609 gazebo::common::SphericalCoordinates::GLOBAL));
611 gazebo::common::SphericalCoordinates::GLOBAL));
614#if GAZEBO_MAJOR_VERSION >= 8 && 0
663#ifdef NPS_ACTUATOR_TIME_CONSTANTS
672#ifdef NPS_ACTUATOR_MAX_ANGULAR_MOMENTUM
681 link->AddRelativeForce(ignition::math::Vector3d(0, 0, thrust));
682 link->AddRelativeTorque(ignition::math::Vector3d(0, 0,
torque));
686#if NPS_SIMULATE_VIDEO
703 gazebo::sensors::SensorManager *
mgr = gazebo::sensors::SensorManager::Instance();
705 cout <<
"Initializing cameras..." <<
endl;
710 gazebo::physics::LinkPtr link =
model->GetLink(
cameras[i]->dev_name);
718 if (link->GetSensorCount() != 1) {
719 cout <<
"ERROR: Link '" << link->GetName()
720 <<
"' should only contain 1 sensor!" <<
endl;
723 string name = link->GetSensorName(0);
725 < gazebo::sensors::CameraSensor > (
mgr->GetSensor(name));
727 cout <<
"ERROR: Could not get pointer to '" << name <<
"'!" <<
endl;
731 cam->SetActive(
true);
735 gazebo_cams[i].last_measurement_time =
cam->LastMeasurementTime();
751 if (
cam->Name() ==
"mt9f002") {
767 }
else if (
cam->Name() ==
"mt9v117") {
798 if ((
cam->LastMeasurementTime() -
gazebo_cams[i].last_measurement_time).Float() < 0.005
799 ||
cam->LastMeasurementTime() == 0) {
continue; }
807 cv::namedWindow(
cameras[i]->dev_name, cv::WINDOW_AUTOSIZE);
816 gazebo_cams[i].last_measurement_time =
cam->LastMeasurementTime();
833 if (
cam->Name() ==
"mt9f002") {
873 gazebo::common::Time
ts =
cam->LastMeasurementTime();
874 img->ts.tv_sec =
ts.sec;
875 img->ts.tv_usec =
ts.nsec / 1000.0;
876 img->pprz_ts =
ts.Double() * 1
e6;
881#if NPS_SIMULATE_LASER_RANGE_ARRAY
905 gazebo::sensors::RaySensorPtr
sensor;
913#define VL53L0_MAX_VAL 8.191f
917 gazebo::sensors::SensorManager *
mgr = gazebo::sensors::SensorManager::Instance();
918 gazebo::sensors::Sensor_V
sensors =
mgr->GetSensors();
931 if (
sensors.at(i)->Type() ==
"ray") {
935 cout <<
"ERROR: Could not get pointer to raysensor " << i <<
"!" <<
endl;
957 rays[
j].sensor->SetActive(
true);
959#if LASER_RANGE_ARRAY_SEND_AGL
974 "with the same orientation as in the airframe file " <<
endl;
977 cout <<
"Initialized laser range array" <<
endl;
986 if ((
rays[i].
sensor->LastMeasurementTime() -
rays[i].last_measurement_time).Float() < 0.005
987 ||
rays[i].sensor->LastMeasurementTime() == 0) {
continue; }
992 range =
rays[i].sensor->Range(0);
999 float agl =
rays[i].sensor->Range(0);
1001 if (agl > 1e-5 && !
isinf(agl)) {
1005 rays[i].last_measurement_time =
rays[i].sensor->LastMeasurementTime();
1010#pragma GCC diagnostic pop
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
Main include for ABI (AirBorneInterface).
#define OBS_DETECTION_RANGE_ARRAY_NPS_ID
#define AGL_RAY_SENSOR_GAZEBO_ID
struct pprz_autopilot autopilot
Global autopilot structure.
Core autopilot interface common to all firmwares.
bool motors_on
motor status
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
void cv_run_device(struct video_config_t *device, struct image_t *img)
Computer vision framework for onboard processing.
void double_quat_of_eulers(struct DoubleQuat *q, struct DoubleEulers *e)
#define QUAT_DOT_PRODUCT(_qa, _qb)
struct EcefCoor_d ecef
origin of local frame in ECEF
double gc_of_gd_lat_d(double gd_lat, double hmsl)
void ecef_of_ned_vect_d(struct EcefCoor_d *ecef, struct LtpDef_d *def, struct NedCoor_d *ned)
void lla_of_ecef_d(struct LlaCoor_d *lla, struct EcefCoor_d *ecef)
void ecef_of_ned_point_d(struct EcefCoor_d *ecef, struct LtpDef_d *def, struct NedCoor_d *ned)
vector in EarthCenteredEarthFixed coordinates
vector in Latitude, Longitude and Altitude
definition of the local (flat earth) coordinate system
vector in North East Down coordinates Units: meters
static float pprz_isa_pressure_of_height(float height, float ref_p)
Get pressure in Pa from height (using simplified equation).
struct LtpDef_f ned_origin_f
Definition of the local (flat earth) coordinate system.
Simple high pass filter with double precision.
static void init_first_order_high_pass(struct FirstOrderHighPass *filter, float tau, float sample_time, float value)
Init first order high pass filter.
static float update_first_order_high_pass(struct FirstOrderHighPass *filter, float value)
Update first order high pass filter state with a new value.
First order high pass filter structure.
void image_free(struct image_t *img)
Free the image.
void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
Create a new image.
Image helper functions like resizing, color filter, converters...
uint16_t h
height of the cropped area
struct timeval ts
The timestamp of creation.
uint16_t w
Width of the cropped area.
@ IMAGE_YUV422
UYVY format (uint16 per pixel)
Simple first order low pass filter with bilinear transform.
static void init_first_order_low_pass(struct FirstOrderLowPass *filter, float tau, const float sample_time, float value)
Init first order low pass filter.
static float update_first_order_low_pass(struct FirstOrderLowPass *filter, const float value)
Update first order low pass filter state with a new value.
First order low pass filter structure.
static const int32_t yaw_coef[MOTOR_MIXING_NB_MOTOR]
Common Motor Mixing configuration types.
#define MOTOR_MIXING_YAW_COEF
Initialization and configuration of the MT9F002 CMOS Chip.
uint16_t offset_x
Offset from left in pixels.
#define CFG_MT9F002_PIXEL_ARRAY_WIDTH
uint16_t offset_y
Offset from top in pixels.
#define MT9F002_OUTPUT_WIDTH
#define CFG_MT9F002_PIXEL_ARRAY_HEIGHT
#define MT9F002_TARGET_FPS
#define MT9F002_OUTPUT_HEIGHT
Initialization and configuration of the MT9V117 CMOS Chip.
#define MT9V117_TARGET_FPS
#define NPS_COMMANDS_NB
Number of commands sent to the FDM of NPS.
double aoa
angle of attack in rad
struct NedCoor_d ltpprz_ecef_vel
velocity in ltppprz frame, wrt ECEF frame
double pressure_sl
pressure at sea level in Pascal
struct DoubleQuat ltpprz_to_body_quat
struct EcefCoor_d ecef_pos
struct NedCoor_d ltpprz_pos
struct LlaCoor_d lla_pos_pprz
struct DoubleVect3 body_inertial_accel
acceleration in body frame, wrt ECI inertial frame
struct DoubleRates body_inertial_rotvel
double airspeed
equivalent airspeed in m/s
struct NedCoor_d ltp_ecef_vel
velocity in LTP frame, wrt ECEF frame
struct NedCoor_d ltpprz_ecef_accel
accel in ltppprz frame, wrt ECEF frame
struct DoubleVect3 body_ecef_vel
velocity in body frame, wrt ECEF frame
double dynamic_pressure
dynamic pressure in Pascal
struct DoubleEulers ltp_to_body_eulers
struct EcefCoor_d ecef_ecef_accel
acceleration in ECEF frame, wrt ECEF frame
double pressure
current (static) atmospheric pressure in Pascal
struct DoubleQuat ltp_to_body_quat
struct DoubleRates body_ecef_rotvel
struct EcefCoor_d ecef_ecef_vel
velocity in ECEF frame, wrt ECEF frame
struct DoubleVect3 body_ecef_accel
acceleration in body frame, wrt ECEF frame
double temperature
current temperature in degrees Celcius
struct DoubleEulers ltpprz_to_body_eulers
double sideslip
sideslip angle in rad
struct DoubleVect3 body_accel
acceleration in body frame as measured by an accelerometer (incl.
struct LlaCoor_d lla_pos_geoc
struct DoubleVect3 wind
velocity in m/s in NED
struct LlaCoor_d lla_pos_geod
struct NedCoor_d ltp_ecef_accel
acceleration in LTP frame, wrt ECEF frame
void nps_fdm_set_wind_ned(double wind_north, double wind_east, double wind_down)
struct FirstOrderLowPass lowpass[NPS_COMMANDS_NB]
void nps_fdm_init(double dt)
Initialize actuator dynamics, set unused fields in fdm.
struct gazebo_actuators_t gazebo_actuators
void nps_fdm_run_step(bool launch, double *act_commands, int commands_nb)
Update the simulation state.
struct DoubleEulers to_global_pprz_eulers(ignition::math::Quaterniond quat)
static void gazebo_write(double act_commands[], int commands_nb)
Write actuator commands to Gazebo.
struct DoubleRates to_pprz_rates(ignition::math::Vector3d body_g)
string names[NPS_COMMANDS_NB]
double max_ang_momentum[NPS_COMMANDS_NB]
void nps_fdm_set_temperature(double temp, double h)
Set temperature in degrees Celcius at given height h above MSL.
double torques[NPS_COMMANDS_NB]
struct NedCoor_d to_pprz_ned(ignition::math::Vector3d global)
struct LlaCoor_d to_pprz_lla(ignition::math::Vector3d lla_i)
double thrusts[NPS_COMMANDS_NB]
static void gazebo_read(void)
Read Gazebo's simulation state and store the results in the fdm struct used by NPS.
static gazebo::physics::ModelPtr model
static gazebo::sensors::ContactSensorPtr ct
std::shared_ptr< gazebo::sensors::SonarSensor > sonar
void nps_fdm_set_turbulence(double wind_speed, int turbulence_severity)
struct DoubleVect3 to_pprz_ltp(ignition::math::Vector3d xyz)
static void init_gazebo(void)
Set up a Gazebo server.
struct EcefCoor_d to_pprz_ecef(ignition::math::Vector3d ecef_i)
#define NPS_GAZEBO_AC_NAME
static bool gazebo_initialized
void nps_fdm_set_wind(double speed, double dir)
void nps_fdm_run_init_step(void)
struct NpsFdm fdm
Holds all necessary NPS FDM state information.
struct FirstOrderHighPass highpass[NPS_COMMANDS_NB]
struct DoubleVect3 to_pprz_body(ignition::math::Vector3d body_g)
struct DoubleEulers to_pprz_eulers(ignition::math::Quaterniond quat)
Paparazzi double precision floating point algebra.
Paparazzi double-precision floating point math for geodetic calculations.
Paparazzi floating point math for geodetic calculations.
float alt
in meters (normally above WGS84 reference ellipsoid)
float hmsl
Height above mean sea level in meters.
struct FloatRMat ltp_of_ecef
rotation from ECEF to local frame
struct EcefCoor_f ecef
origin of local frame in ECEF
struct LlaCoor_f lla
origin of local frame in LLA
Paparazzi atmospheric pressure conversion utilities.
API to get/set the generic vehicle states.
Architecture independent timing functions.
float focal_y
focal length in the y-direction in pixels
float center_x
center image coordinate in the x-direction
float focal_x
focal length in the x-direction in pixels
struct camera_intrinsics_t camera_intrinsics
Intrinsics of the camera; camera calibration parameters and distortion parameter(s)
float center_y
center image coordinate in the y-direction
struct crop_t crop
Cropped area definition.
struct img_size_t output_size
Output image size.
char * dev_name
path to device
struct img_size_t sensor_size
Original sensor size.
#define VIDEO_THREAD_MAX_CAMERAS
static struct video_config_t * cameras[VIDEO_THREAD_MAX_CAMERAS]
This header gives NPS access to the list of added cameras.
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.