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();
237#ifdef NPS_ACTUATOR_TIME_CONSTANTS
243#ifdef NPS_ACTUATOR_MAX_ANGULAR_MOMENTUM
274#if NPS_SIMULATE_VIDEO
277#if NPS_SIMULATE_LASER_RANGE_ARRAY
284 gazebo::runWorld(
model->GetWorld(), 1);
285 gazebo::sensors::run_once();
288#if NPS_SIMULATE_VIDEO
291#if NPS_SIMULATE_LASER_RANGE_ARRAY
340 string pprz_home(getenv(
"PAPARAZZI_HOME"));
344 if (getenv(
"ROS_MASTER_URI")) {
346 cout <<
"Add ROS plugins... ";
347 gazebo::addPlugin(
"libgazebo_ros_paths_plugin.so");
348 gazebo::addPlugin(
"libgazebo_ros_api_plugin.so");
352 if (!gazebo::setupServer(0,
NULL)) {
353 cout <<
"Failed to start Gazebo, exiting." <<
endl;
358 gazebo::common::SystemPaths::Instance()->AddModelPaths(
gazebodir +
"models/");
359 sdf::addURIPath(
"model://",
gazebodir +
"models/");
360 sdf::addURIPath(
"world://",
gazebodir +
"world/");
362 cout <<
"Add TU Delft paths: " <<
pprz_home +
"/sw/ext/tudelft_gazebo_models/" <<
endl;
363 gazebo::common::SystemPaths::Instance()->AddModelPaths(
pprz_home +
"/sw/ext/tudelft_gazebo_models/models/");
364 sdf::addURIPath(
"model://",
pprz_home +
"/sw/ext/tudelft_gazebo_models/models/");
365 sdf::addURIPath(
"world://",
pprz_home +
"/sw/ext/tudelft_gazebo_models/world/");
383#if NPS_SIMULATE_VIDEO
385 sdf::ElementPtr link =
vehicle_sdf->Root()->GetFirstElement()->GetElement(
"link");
387 if (link->Get<
string>(
"name") ==
"front_camera" && link->GetElement(
"sensor")->Get<
string>(
"name") ==
"mt9f002") {
389 int w = link->GetElement(
"sensor")->GetElement(
"camera")->GetElement(
"image")->GetElement(
"width")->Get<
int>();
390 int h = link->GetElement(
"sensor")->GetElement(
"camera")->GetElement(
"image")->GetElement(
"height")->Get<
int>();
391 int env = link->GetElement(
"sensor")->GetElement(
"camera")->GetElement(
"lens")->GetElement(
"env_texture_size")->Get<
int>();
397 int fps =
Min(
MT9F002_TARGET_FPS, link->GetElement(
"sensor")->GetElement(
"update_rate")->Get<
int>());
398 link->GetElement(
"sensor")->GetElement(
"update_rate")->Set(fps);
400 }
else if (link->Get<
string>(
"name") ==
"bottom_camera" && link->GetElement(
"sensor")->Get<
string>(
"name") ==
"mt9v117") {
402 int fps =
Min(
MT9V117_TARGET_FPS, link->GetElement(
"sensor")->GetElement(
"update_rate")->Get<
int>());
403 link->GetElement(
"sensor")->GetElement(
"update_rate")->Set(fps);
406 link = link->GetNextElement(
"link");
411#if NPS_SIMULATE_LASER_RANGE_ARRAY
412 vehicle_sdf->Root()->GetFirstElement()->AddElement(
"include")->GetElement(
"uri")->Set(
"model://range_sensors");
414 range_joint->GetAttribute(
"name")->Set(
"range_sensor_joint");
417 range_joint->GetElement(
"child")->Set(
"range_sensors::base");
440 gazebo::physics::WorldPtr
world = gazebo::loadWorld(
pprz_home +
"/var/gazebo.world");
442 cout <<
"Failed to open world, exiting." <<
endl;
455 gazebo::sensors::run_once(
true);
456 gazebo::sensors::run_threads();
457 gazebo::runWorld(
world, 1);
458 cout <<
"Sensors initialized..." <<
endl;
462 gazebo::sensors::SensorManager *
mgr = gazebo::sensors::SensorManager::Instance();
476 <<
"' should only contain 1 sensor!" <<
endl;
481 cout <<
"ERROR: Could not get pointer to '" << name <<
"'!" <<
endl;
484 sonar->SetActive(
true);
490#ifdef MOTOR_MIXING_YAW_COEF
498 cout <<
"Gazebo initialized successfully!" <<
endl;
511 static ignition::math::Vector3d
vel_prev;
514 gazebo::physics::WorldPtr
world =
model->GetWorld();
515 ignition::math::Pose3d
pose =
model->WorldPose();
516 ignition::math::Vector3d vel =
model->WorldLinearVel();
517 ignition::math::Vector3d ang_vel =
model->WorldAngularVel();
518 gazebo::common::SphericalCoordinatesPtr
sphere =
world->SphericalCoords();
529 ignition::math::Vector3d accel = (vel -
vel_prev) / dt;
546 for (
int i = 0; i < 3 * 3; i++) {
553 gazebo::common::SphericalCoordinates::GLOBAL));
565 double agl =
sonar->Range();
566 if (agl >
sonar->RangeMax()) agl = -1.0;
574 gazebo::common::SphericalCoordinates::GLOBAL));
581 gazebo::common::SphericalCoordinates::GLOBAL));
604 gazebo::common::SphericalCoordinates::GLOBAL));
606 gazebo::common::SphericalCoordinates::GLOBAL));
609#if GAZEBO_MAJOR_VERSION >= 8 && 0
658#ifdef NPS_ACTUATOR_TIME_CONSTANTS
667#ifdef NPS_ACTUATOR_MAX_ANGULAR_MOMENTUM
676 link->AddRelativeForce(ignition::math::Vector3d(0, 0, thrust));
677 link->AddRelativeTorque(ignition::math::Vector3d(0, 0,
torque));
681#if NPS_SIMULATE_VIDEO
698 gazebo::sensors::SensorManager *
mgr = gazebo::sensors::SensorManager::Instance();
700 cout <<
"Initializing cameras..." <<
endl;
705 gazebo::physics::LinkPtr link =
model->GetLink(
cameras[i]->dev_name);
713 if (link->GetSensorCount() != 1) {
714 cout <<
"ERROR: Link '" << link->GetName()
715 <<
"' should only contain 1 sensor!" <<
endl;
718 string name = link->GetSensorName(0);
720 < gazebo::sensors::CameraSensor > (
mgr->GetSensor(name));
722 cout <<
"ERROR: Could not get pointer to '" << name <<
"'!" <<
endl;
726 cam->SetActive(
true);
730 gazebo_cams[i].last_measurement_time =
cam->LastMeasurementTime();
746 if (
cam->Name() ==
"mt9f002") {
762 }
else if (
cam->Name() ==
"mt9v117") {
793 if ((
cam->LastMeasurementTime() -
gazebo_cams[i].last_measurement_time).Float() < 0.005
794 ||
cam->LastMeasurementTime() == 0) {
continue; }
802 cv::namedWindow(
cameras[i]->dev_name, cv::WINDOW_AUTOSIZE);
811 gazebo_cams[i].last_measurement_time =
cam->LastMeasurementTime();
828 if (
cam->Name() ==
"mt9f002") {
868 gazebo::common::Time
ts =
cam->LastMeasurementTime();
869 img->ts.tv_sec =
ts.sec;
870 img->ts.tv_usec =
ts.nsec / 1000.0;
871 img->pprz_ts =
ts.Double() * 1
e6;
876#if NPS_SIMULATE_LASER_RANGE_ARRAY
900 gazebo::sensors::RaySensorPtr
sensor;
908#define VL53L0_MAX_VAL 8.191f
912 gazebo::sensors::SensorManager *
mgr = gazebo::sensors::SensorManager::Instance();
913 gazebo::sensors::Sensor_V
sensors =
mgr->GetSensors();
926 if (
sensors.at(i)->Type() ==
"ray") {
930 cout <<
"ERROR: Could not get pointer to raysensor " << i <<
"!" <<
endl;
952 rays[
j].sensor->SetActive(
true);
954#if LASER_RANGE_ARRAY_SEND_AGL
969 "with the same orientation as in the airframe file " <<
endl;
972 cout <<
"Initialized laser range array" <<
endl;
981 if ((
rays[i].
sensor->LastMeasurementTime() -
rays[i].last_measurement_time).Float() < 0.005
982 ||
rays[i].sensor->LastMeasurementTime() == 0) {
continue; }
987 range =
rays[i].sensor->Range(0);
994 float agl =
rays[i].sensor->Range(0);
996 if (agl > 1e-5 && !
isinf(agl)) {
1000 rays[i].last_measurement_time =
rays[i].sensor->LastMeasurementTime();
1005#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 float update_first_order_low_pass(struct FirstOrderLowPass *filter, float value)
Update first order low pass filter state with a new value.
static void init_first_order_low_pass(struct FirstOrderLowPass *filter, float tau, float sample_time, float value)
Init first order low pass filter.
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)
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.