31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
39 #include <gazebo/gazebo.hh>
40 #include <gazebo/common/common.hh>
41 #include <gazebo/physics/physics.hh>
42 #include <gazebo/sensors/sensors.hh>
43 #include <gazebo/gazebo_config.h>
51 #include "generated/airframe.h"
54 #ifdef NPS_SIMULATE_VIDEO
64 #ifndef NPS_GAZEBO_WORLD
65 #define NPS_GAZEBO_WORLD "ardrone.world"
67 #ifndef NPS_GAZEBO_AC_NAME
68 #define NPS_GAZEBO_AC_NAME "paparazzi_uav"
72 #ifdef NPS_SIMULATE_VIDEO
73 static void init_gazebo_video(
void);
74 static void gazebo_read_video(
void);
75 static void read_image(
77 gazebo::sensors::CameraSensorPtr cam);
79 gazebo::sensors::CameraSensorPtr cam;
80 gazebo::common::Time last_measurement_time;
91 static gazebo::physics::ModelPtr
model = NULL;
102 ecef_p.
x = ecef_i.X();
103 ecef_p.
y = ecef_i.Y();
104 ecef_p.
z = ecef_i.Z();
120 lla_p.
lat = lla_i.X();
121 lla_p.
lon = lla_i.Y();
122 lla_p.
alt = lla_i.Z();
130 body_p.
y = -body_g.y;
131 body_p.
z = -body_g.z;
139 body_p.
q = -body_g.y;
140 body_p.
r = -body_g.z;
147 eulers.
psi = -quat.GetYaw() - M_PI / 2;
148 eulers.
theta = -quat.GetPitch();
149 eulers.
phi = quat.GetRoll();
182 bool launch __attribute__((unused)),
195 #ifdef NPS_SIMULATE_VIDEO
202 gazebo::runWorld(
model->GetWorld(), 1);
203 gazebo::sensors::run_once();
206 #ifdef NPS_SIMULATE_VIDEO
214 double speed __attribute__((unused)),
215 double dir __attribute__((unused)))
220 double wind_north __attribute__((unused)),
221 double wind_east __attribute__((unused)),
222 double wind_down __attribute__((unused)))
227 double wind_speed __attribute__((unused)),
228 int turbulence_severity __attribute__((unused)))
234 double temp __attribute__((unused)),
235 double h __attribute__((unused)))
253 string gazebo_home =
"/conf/simulator/gazebo/";
254 string pprz_home(getenv(
"PAPARAZZI_HOME"));
255 string gazebodir = pprz_home + gazebo_home;
256 cout <<
"Gazebo directory: " << gazebodir << endl;
258 if (!gazebo::setupServer(0, NULL)) {
259 cout <<
"Failed to start Gazebo, exiting." << endl;
263 cout <<
"Add Paparazzi model path: " << gazebodir +
"models/" << endl;
264 gazebo::common::SystemPaths::Instance()->AddModelPaths(
265 gazebodir +
"models/");
268 gazebo::physics::WorldPtr world = gazebo::loadWorld(
271 cout <<
"Failed to open world, exiting." << endl;
284 gazebo::sensors::run_once(
true);
285 gazebo::sensors::run_threads();
286 gazebo::runWorld(world, 1);
287 cout <<
"Sensors initialized..." << endl;
289 cout <<
"Gazebo initialized successfully!" << endl;
302 gazebo::physics::WorldPtr world =
model->GetWorld();
303 gazebo::math::Pose pose =
model->GetWorldPose();
304 gazebo::math::Vector3 vel =
model->GetWorldLinearVel();
305 gazebo::math::Vector3 accel =
model->GetWorldLinearAccel();
306 gazebo::math::Vector3 ang_vel =
model->GetWorldAngularVel();
307 gazebo::common::SphericalCoordinatesPtr sphere =
308 world->GetSphericalCoordinates();
309 gazebo::math::Quaternion local_to_global_quat(0, 0,
310 -sphere->HeadingOffset().Radian());
313 fdm.
time = world->GetSimTime().Double();
322 sphere->PositionTransform(pose.pos.Ign(),
323 gazebo::common::SphericalCoordinates::LOCAL,
324 gazebo::common::SphericalCoordinates::ECEF));
326 sphere->PositionTransform(pose.pos.Ign(),
327 gazebo::common::SphericalCoordinates::LOCAL,
328 gazebo::common::SphericalCoordinates::GLOBAL));
330 sphere->PositionTransform(pose.pos.Ign(),
331 gazebo::common::SphericalCoordinates::LOCAL,
332 gazebo::common::SphericalCoordinates::SPHERICAL));
342 sphere->VelocityTransform(vel.Ign(),
343 gazebo::common::SphericalCoordinates::LOCAL,
344 gazebo::common::SphericalCoordinates::ECEF));
347 sphere->VelocityTransform(vel.Ign(),
348 gazebo::common::SphericalCoordinates::LOCAL,
349 gazebo::common::SphericalCoordinates::GLOBAL));
354 sphere->VelocityTransform(accel.Ign(),
355 gazebo::common::SphericalCoordinates::LOCAL,
356 gazebo::common::SphericalCoordinates::ECEF));
359 sphere->VelocityTransform(accel.Ign(),
360 gazebo::common::SphericalCoordinates::LOCAL,
361 gazebo::common::SphericalCoordinates::GLOBAL));
365 pose.rot.RotateVectorReverse(accel.Ign() - world->Gravity()));
383 sphere->VelocityTransform(-1 * world->Gravity(),
384 gazebo::common::SphericalCoordinates::LOCAL,
385 gazebo::common::SphericalCoordinates::GLOBAL));
387 sphere->VelocityTransform(world->MagneticField(),
388 gazebo::common::SphericalCoordinates::LOCAL,
389 gazebo::common::SphericalCoordinates::GLOBAL));
392 #if GAZEBO_MAJOR_VERSION >= 8 && 0 // TODO implement
397 fdm.
wind = {.
x = 0, .y = 0, .z = 0};
436 const string names[] = NPS_ACTUATOR_NAMES;
437 const double thrusts[] = { NPS_ACTUATOR_THRUSTS };
438 const double torques[] = { NPS_ACTUATOR_TORQUES };
440 for (
int i = 0; i < commands_nb; ++i) {
443 gazebo::physics::LinkPtr link =
model->GetLink(names[i]);
444 link->AddRelativeForce(gazebo::math::Vector3(0, 0, thrust));
445 link->AddRelativeTorque(gazebo::math::Vector3(0, 0, torque));
451 #ifdef NPS_SIMULATE_VIDEO
466 static void init_gazebo_video(
void)
468 gazebo::sensors::SensorManager *mgr =
469 gazebo::sensors::SensorManager::Instance();
471 cout <<
"Initializing cameras..." << endl;
476 gazebo::physics::LinkPtr link =
model->GetLink(
cameras[i]->dev_name);
484 if (link->GetSensorCount() != 1) {
485 cout <<
"ERROR: Link '" << link->GetName()
486 <<
"' should only contain 1 sensor!" << endl;
489 string name = link->GetSensorName(0);
490 gazebo::sensors::CameraSensorPtr cam = static_pointer_cast
491 < gazebo::sensors::CameraSensor > (mgr->GetSensor(name));
493 cout <<
"ERROR: Could not get pointer to '" << name <<
"'!" << endl;
497 cam->SetActive(
true);
499 gazebo_cams[i].cam = cam;
500 gazebo_cams[i].last_measurement_time = cam->LastMeasurementTime();
509 cout <<
"ok" << endl;
521 static void gazebo_read_video(
void)
524 gazebo::sensors::CameraSensorPtr &cam = gazebo_cams[i].cam;
526 if (cam == NULL) {
continue; }
529 if (cam->LastMeasurementTime() == gazebo_cams[i].last_measurement_time
530 || cam->LastMeasurementTime() == 0) {
continue; }
533 read_image(&img, cam);
538 gazebo_cams[i].last_measurement_time = cam->LastMeasurementTime();
552 static void read_image(
554 gazebo::sensors::CameraSensorPtr cam)
558 const uint8_t *data_rgb = cam->ImageData();
560 for (
int x = 0; x < img->
w; ++x) {
561 for (
int y = 0; y < img->
h; ++y) {
562 int idx_rgb = 3 * (img->
w * y + x);
563 int idx_yuv = 2 * (img->
w * y + x);
564 int idx_px = img->
w * y + x;
565 if (idx_px % 2 == 0) {
566 data_yuv[idx_yuv] = -0.148 * data_rgb[idx_rgb]
567 - 0.291 * data_rgb[idx_rgb + 1]
568 + 0.439 * data_rgb[idx_rgb + 2] + 128;
570 data_yuv[idx_yuv] = 0.439 * data_rgb[idx_rgb]
571 - 0.368 * data_rgb[idx_rgb + 1]
572 - 0.071 * data_rgb[idx_rgb + 2] + 128;
574 data_yuv[idx_yuv + 1] = 0.257 * data_rgb[idx_rgb]
575 + 0.504 * data_rgb[idx_rgb + 1]
576 + 0.098 * data_rgb[idx_rgb + 2] + 16;
580 gazebo::common::Time
ts = cam->LastMeasurementTime();
581 img->
ts.tv_sec = ts.sec;
582 img->
ts.tv_usec = ts.nsec / 1000.0;
583 img->
pprz_ts = ts.Double() * 1e6;
588 #pragma GCC diagnostic pop // Ignore -Wdeprecated-declarations
struct NedCoor_d to_pprz_ned(ignition::math::Vector3d global)
vector in North East Down coordinates Units: meters
struct NedCoor_d ltpprz_ecef_accel
accel in ltppprz frame, wrt ECEF frame
struct LlaCoor_d lla_pos_geoc
void nps_fdm_set_temperature(double temp, double h)
Set temperature in degrees Celcius at given height h above MSL.
struct DoubleVect3 body_inertial_accel
acceleration in body frame, wrt ECI inertial frame
struct crop_t crop
Cropped area definition.
struct DoubleRates body_ecef_rotvel
void nps_fdm_run_step(bool launch, double *commands, int commands_nb)
Update the simulation state.
uint16_t h
height of the cropped area
struct img_size_t output_size
Output image size.
static gazebo::physics::ModelPtr model
struct EcefCoor_d to_pprz_ecef(ignition::math::Vector3d ecef_i)
void image_free(struct image_t *img)
Free the image.
struct NedCoor_d ltp_ecef_accel
acceleration in LTP frame, wrt ECEF frame
double alt
in meters above WGS84 reference ellipsoid
struct NpsFdm fdm
Holds all necessary NPS FDM state information.
static struct video_config_t * cameras[VIDEO_THREAD_MAX_CAMERAS]
void image_create(struct image_t *img, uint16_t width, uint16_t height, enum image_type type)
Create a new image.
struct LlaCoor_d lla_pos_pprz
vector in Latitude, Longitude and Altitude
char * dev_name
path to device
struct DoubleRates body_inertial_rotvel
void nps_fdm_init(double dt)
Set JSBsim specific fields that are not used for Gazebo.
void nps_fdm_set_wind_ned(double wind_north, double wind_east, double wind_down)
uint32_t pprz_ts
The timestamp in us since system startup.
struct DoubleEulers ltp_to_body_eulers
struct NedCoor_d ltp_ecef_vel
velocity in LTP frame, wrt ECEF frame
struct DoubleEulers to_pprz_eulers(gazebo::math::Quaternion quat)
struct pprz_autopilot autopilot
Global autopilot structure.
double pressure_sl
pressure at sea level in Pascal
struct NedCoor_d ltpprz_pos
uint16_t w
Width of the cropped area.
struct DoubleRates to_pprz_rates(gazebo::math::Vector3 body_g)
struct LlaCoor_d to_pprz_lla(ignition::math::Vector3d lla_i)
struct DoubleVect3 to_pprz_body(gazebo::math::Vector3 body_g)
struct EcefCoor_d ecef_ecef_vel
velocity in ECEF frame, wrt ECEF frame
uint8_t buf_idx
Buffer index for V4L2 freeing.
double airspeed
equivalent airspeed in m/s
Image helper functions like resizing, color filter, converters...
struct DoubleVect3 body_accel
acceleration in body frame as measured by an accelerometer (incl.
double pressure
current (static) atmospheric pressure in Pascal
static void gazebo_write(double commands[], int commands_nb)
Write actuator commands to Gazebo.
void nps_fdm_set_turbulence(double wind_speed, int turbulence_severity)
Architecture independent timing functions.
void double_quat_of_eulers(struct DoubleQuat *q, struct DoubleEulers *e)
struct img_size_t sensor_size
Original sensor size.
Computer vision framework for onboard processing.
struct DoubleVect3 wind
velocity in m/s in NED
void * buf
Image buffer (depending on the image_type)
struct LlaCoor_d lla_pos_geod
double dynamic_pressure
dynamic pressure in Pascal
vector in EarthCenteredEarthFixed coordinates
This header gives NPS access to the list of added cameras.
#define NPS_GAZEBO_AC_NAME
Core autopilot interface common to all firmwares.
struct DoubleVect3 body_ecef_vel
velocity in body frame, wrt ECEF frame
static void init_gazebo(void)
Set up a Gazebo server.
void cv_run_device(struct video_config_t *device, struct image_t *img)
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
double temperature
current temperature in degrees Celcius
bool motors_on
motor status
pprz_t commands[COMMANDS_NB]
Storage of intermediate command values.
struct timeval ts
The timestamp of creation.
struct DoubleQuat ltpprz_to_body_quat
struct EcefCoor_d ecef_pos
UYVY format (uint16 per pixel)
struct DoubleVect3 body_ecef_accel
acceleration in body frame, wrt ECEF frame
#define VIDEO_THREAD_MAX_CAMERAS
void nps_fdm_set_wind(double speed, double dir)
static void gazebo_read(void)
Read Gazebo's simulation state and store the results in the fdm struct used by NPS.
Paparazzi double precision floating point algebra.
struct NedCoor_d ltpprz_ecef_vel
velocity in ltppprz frame, wrt ECEF frame
struct DoubleVect3 to_pprz_ltp(gazebo::math::Vector3 xyz)
static bool gazebo_initialized
struct DoubleQuat ltp_to_body_quat
double sideslip
sideslip angle in rad
struct EcefCoor_d ecef_ecef_accel
acceleration in ECEF frame, wrt ECEF frame
struct DoubleEulers ltpprz_to_body_eulers
double aoa
angle of attack in rad