void GazeboMavlinkInterface::ImuCallback(ImuPtr& imu_message) { math::Pose T_W_I = model_->GetWorldPose(); math::Vector3 pos_W_I = T_W_I.pos; // Use the models'world position for GPS and pressure alt. math::Quaternion C_W_I; C_W_I.w = imu_message->orientation().w(); C_W_I.x = imu_message->orientation().x(); C_W_I.y = imu_message->orientation().y(); C_W_I.z = imu_message->orientation().z(); math::Vector3 mag_I = C_W_I.RotateVectorReverse(mag_W_); // TODO: Add noise based on bais and variance like for imu and gyro math::Vector3 body_vel = C_W_I.RotateVectorReverse(model_->GetWorldLinearVel()); standard_normal_distribution_ = std::normal_distribution<float>(0, 0.01f); float mag_noise = standard_normal_distribution_(random_generator_); if(use_mavlink_udp){ mavlink_hil_sensor_t sensor_msg; sensor_msg.time_usec = world_->GetSimTime().nsec*1000; sensor_msg.xacc = imu_message->linear_acceleration().x(); sensor_msg.yacc = imu_message->linear_acceleration().y(); sensor_msg.zacc = imu_message->linear_acceleration().z(); sensor_msg.xgyro = imu_message->angular_velocity().x(); sensor_msg.ygyro = imu_message->angular_velocity().y(); sensor_msg.zgyro = imu_message->angular_velocity().z(); sensor_msg.xmag = mag_I.x + mag_noise; sensor_msg.ymag = mag_I.y + mag_noise; sensor_msg.zmag = mag_I.z + mag_noise; sensor_msg.abs_pressure = 0.0; sensor_msg.diff_pressure = 0.5*1.2754*body_vel.x*body_vel.x; sensor_msg.pressure_alt = pos_W_I.z; sensor_msg.temperature = 0.0; sensor_msg.fields_updated = 4095; send_mavlink_message(MAVLINK_MSG_ID_HIL_SENSOR, &sensor_msg, 200); } else{ hil_sensor_msg_.set_time_usec(world_->GetSimTime().nsec*1000); hil_sensor_msg_.set_xacc(imu_message->linear_acceleration().x()); hil_sensor_msg_.set_yacc(imu_message->linear_acceleration().y()); hil_sensor_msg_.set_zacc(imu_message->linear_acceleration().z()); hil_sensor_msg_.set_xgyro(imu_message->angular_velocity().x()); hil_sensor_msg_.set_ygyro(imu_message->angular_velocity().y()); hil_sensor_msg_.set_zgyro(imu_message->angular_velocity().z()); hil_sensor_msg_.set_xmag(mag_I.x); hil_sensor_msg_.set_ymag(mag_I.y); hil_sensor_msg_.set_zmag(mag_I.z); hil_sensor_msg_.set_abs_pressure(0.0); hil_sensor_msg_.set_diff_pressure(0.5*1.2754*body_vel.x*body_vel.x); hil_sensor_msg_.set_pressure_alt(pos_W_I.z); hil_sensor_msg_.set_temperature(0.0); hil_sensor_msg_.set_fields_updated(4095); // 0b1111111111111 (All updated since new data with new noise added always) hil_sensor_pub_->Publish(hil_sensor_msg_); } }
void GazeboMavlinkInterface::ImuCallback(ImuPtr& imu_message) { math::Pose T_W_I = model_->GetWorldPose(); math::Vector3 pos_W_I = T_W_I.pos; // Use the models'world position for GPS and pressure alt. math::Quaternion C_W_I; C_W_I.w = imu_message->orientation().w(); C_W_I.x = imu_message->orientation().x(); C_W_I.y = imu_message->orientation().y(); C_W_I.z = imu_message->orientation().z(); // gzerr << "got imu: " << C_W_I << "\n"; float declination = get_mag_declination(lat_rad, lon_rad); math::Quaternion C_D_I(0.0, 0.0, declination); math::Vector3 mag_decl = C_D_I.RotateVectorReverse(mag_W_); // TODO replace mag_W_ in the line below with mag_decl math::Vector3 mag_I = C_W_I.RotateVectorReverse(mag_decl); // TODO: Add noise based on bais and variance like for imu and gyro math::Vector3 body_vel = C_W_I.RotateVectorReverse(model_->GetWorldLinearVel()); standard_normal_distribution_ = std::normal_distribution<float>(0, 0.01f); float mag_noise = standard_normal_distribution_(random_generator_); mavlink_hil_sensor_t sensor_msg; sensor_msg.time_usec = world_->GetSimTime().nsec*1000; sensor_msg.xacc = imu_message->linear_acceleration().x(); sensor_msg.yacc = imu_message->linear_acceleration().y(); sensor_msg.zacc = imu_message->linear_acceleration().z(); sensor_msg.xgyro = imu_message->angular_velocity().x(); sensor_msg.ygyro = imu_message->angular_velocity().y(); sensor_msg.zgyro = imu_message->angular_velocity().z(); sensor_msg.xmag = mag_I.x + mag_noise; sensor_msg.ymag = mag_I.y + mag_noise; sensor_msg.zmag = mag_I.z + mag_noise; sensor_msg.abs_pressure = 0.0; sensor_msg.diff_pressure = 0.5*1.2754*(body_vel.z + body_vel.x)*(body_vel.z + body_vel.x) / 100; sensor_msg.pressure_alt = pos_W_I.z; sensor_msg.temperature = 0.0; sensor_msg.fields_updated = 4095; //gyro needed for optical flow message optflow_xgyro = imu_message->angular_velocity().x(); optflow_ygyro = imu_message->angular_velocity().y(); optflow_zgyro = imu_message->angular_velocity().z(); send_mavlink_message(MAVLINK_MSG_ID_HIL_SENSOR, &sensor_msg, 200); }
void GazeboMavlinkInterface::OpticalFlowCallback(OpticalFlowPtr& opticalFlow_message) { mavlink_hil_optical_flow_t sensor_msg; sensor_msg.time_usec = opticalFlow_message->time_usec(); sensor_msg.sensor_id = opticalFlow_message->sensor_id(); sensor_msg.integration_time_us = opticalFlow_message->integration_time_us(); sensor_msg.integrated_x = opticalFlow_message->integrated_x(); sensor_msg.integrated_y = opticalFlow_message->integrated_y(); sensor_msg.integrated_xgyro = optflow_ygyro * opticalFlow_message->integration_time_us() / 1000000.0; //xy switched sensor_msg.integrated_ygyro = optflow_xgyro * opticalFlow_message->integration_time_us() / 1000000.0; //xy switched sensor_msg.integrated_zgyro = -optflow_zgyro * opticalFlow_message->integration_time_us() / 1000000.0; //change direction sensor_msg.temperature = opticalFlow_message->temperature(); sensor_msg.quality = opticalFlow_message->quality(); sensor_msg.time_delta_distance_us = opticalFlow_message->time_delta_distance_us(); sensor_msg.distance = optflow_distance; send_mavlink_message(MAVLINK_MSG_ID_HIL_OPTICAL_FLOW, &sensor_msg, 200); }
void GazeboMavlinkInterface::LidarCallback(LidarPtr& lidar_message) { mavlink_distance_sensor_t sensor_msg; sensor_msg.time_boot_ms = lidar_message->time_msec(); sensor_msg.min_distance = lidar_message->min_distance() * 100.0; sensor_msg.max_distance = lidar_message->max_distance() * 100.0; sensor_msg.current_distance = lidar_message->current_distance() * 100.0; sensor_msg.type = 0; sensor_msg.id = 0; sensor_msg.orientation = 0; sensor_msg.covariance = 0; //distance needed for optical flow message optflow_distance = lidar_message->current_distance(); //[m] send_mavlink_message(MAVLINK_MSG_ID_DISTANCE_SENSOR, &sensor_msg, 200); }
// This gets called by the world update start event. void GazeboMavlinkInterface::OnUpdate(const common::UpdateInfo& /*_info*/) { pollForMAVLinkMessages(); common::Time now = world_->GetSimTime(); if(received_first_referenc_) { mav_msgs::msgs::CommandMotorSpeed turning_velocities_msg; for (int i = 0; i < input_reference_.size(); i++){ if (last_actuator_time_ == 0 || (now - last_actuator_time_).Double() > 0.2) { turning_velocities_msg.add_motor_speed(0); } else { turning_velocities_msg.add_motor_speed(input_reference_[i]); } } // TODO Add timestamp and Header // turning_velocities_msg->header.stamp.sec = now.sec; // turning_velocities_msg->header.stamp.nsec = now.nsec; // gzerr << turning_velocities_msg.motor_speed(0) << "\n"; motor_velocity_reference_pub_->Publish(turning_velocities_msg); } //send gps common::Time current_time = now; double dt = (current_time - last_time_).Double(); last_time_ = current_time; double t = current_time.Double(); math::Pose T_W_I = model_->GetWorldPose(); //TODO(burrimi): Check tf. math::Vector3 pos_W_I = T_W_I.pos; // Use the models' world position for GPS and pressure alt. math::Vector3 velocity_current_W = model_->GetWorldLinearVel(); // Use the models' world position for GPS velocity. math::Vector3 velocity_current_W_xy = velocity_current_W; velocity_current_W_xy.z = 0; // Set global reference point // Zurich Irchel Park: 47.397742, 8.545594, 488m // Seattle downtown (15 deg declination): 47.592182, -122.316031, 86m // Moscow downtown: 55.753395, 37.625427, 155m // TODO: Remove GPS message from IMU plugin. Added gazebo GPS plugin. This is temp here. // Zurich Irchel Park const double lat_zurich = 47.397742 * M_PI / 180; // rad const double lon_zurich = 8.545594 * M_PI / 180; // rad const double alt_zurich = 488.0; // meters // Seattle downtown (15 deg declination): 47.592182, -122.316031 // const double lat_zurich = 47.592182 * M_PI / 180; // rad // const double lon_zurich = -122.316031 * M_PI / 180; // rad // const double alt_zurich = 86.0; // meters const float earth_radius = 6353000; // m // reproject local position to gps coordinates double x_rad = pos_W_I.x / earth_radius; double y_rad = -pos_W_I.y / earth_radius; double c = sqrt(x_rad * x_rad + y_rad * y_rad); double sin_c = sin(c); double cos_c = cos(c); if (c != 0.0) { lat_rad = asin(cos_c * sin(lat_zurich) + (x_rad * sin_c * cos(lat_zurich)) / c); lon_rad = (lon_zurich + atan2(y_rad * sin_c, c * cos(lat_zurich) * cos_c - x_rad * sin(lat_zurich) * sin_c)); } else { lat_rad = lat_zurich; lon_rad = lon_zurich; } if(current_time.Double() - last_gps_time_.Double() > gps_update_interval_){ // 5Hz if(use_mavlink_udp){ // Raw UDP mavlink mavlink_hil_gps_t hil_gps_msg; hil_gps_msg.time_usec = current_time.nsec*1000; hil_gps_msg.fix_type = 3; hil_gps_msg.lat = lat_rad * 180 / M_PI * 1e7; hil_gps_msg.lon = lon_rad * 180 / M_PI * 1e7; hil_gps_msg.alt = (pos_W_I.z + alt_zurich) * 1000; hil_gps_msg.eph = 100; hil_gps_msg.epv = 100; hil_gps_msg.vel = velocity_current_W_xy.GetLength() * 100; hil_gps_msg.vn = velocity_current_W.x * 100; hil_gps_msg.ve = -velocity_current_W.y * 100; hil_gps_msg.vd = -velocity_current_W.z * 100; hil_gps_msg.cog = atan2(hil_gps_msg.ve, hil_gps_msg.vn) * 180.0/3.1416 * 100.0; hil_gps_msg.satellites_visible = 10; send_mavlink_message(MAVLINK_MSG_ID_HIL_GPS, &hil_gps_msg, 200); } else{ // Send via protobuf hil_gps_msg_.set_time_usec(current_time.nsec*1000); hil_gps_msg_.set_fix_type(3); hil_gps_msg_.set_lat(lat_rad * 180 / M_PI * 1e7); hil_gps_msg_.set_lon(lon_rad * 180 / M_PI * 1e7); hil_gps_msg_.set_alt((pos_W_I.z + alt_zurich) * 1000); hil_gps_msg_.set_eph(100); hil_gps_msg_.set_epv(100); hil_gps_msg_.set_vel(velocity_current_W_xy.GetLength() * 100); hil_gps_msg_.set_vn(velocity_current_W.x * 100); hil_gps_msg_.set_ve(-velocity_current_W.y * 100); hil_gps_msg_.set_vd(-velocity_current_W.z * 100); hil_gps_msg_.set_cog(atan2(-velocity_current_W.y * 100, velocity_current_W.x * 100) * 180.0/3.1416 * 100.0); hil_gps_msg_.set_satellites_visible(10); hil_gps_pub_->Publish(hil_gps_msg_); } last_gps_time_ = current_time; } }
// This gets called by the world update start event. void GazeboMavlinkInterface::OnUpdate(const common::UpdateInfo& /*_info*/) { pollForMAVLinkMessages(); common::Time now = world_->GetSimTime(); if(received_first_referenc_) { mav_msgs::msgs::CommandMotorSpeed turning_velocities_msg; for (int i = 0; i < input_reference_.size(); i++){ turning_velocities_msg.add_motor_speed(input_reference_[i]); } // TODO Add timestamp and Header // turning_velocities_msg->header.stamp.sec = now.sec; // turning_velocities_msg->header.stamp.nsec = now.nsec; motor_velocity_reference_pub_->Publish(turning_velocities_msg); } //send gps common::Time current_time = now; double dt = (current_time - last_time_).Double(); last_time_ = current_time; double t = current_time.Double(); math::Pose T_W_I = model_->GetWorldPose(); //TODO(burrimi): Check tf. math::Vector3 pos_W_I = T_W_I.pos; // Use the models' world position for GPS and pressure alt. math::Vector3 velocity_current_W = model_->GetWorldLinearVel(); // Use the models' world position for GPS velocity. math::Vector3 velocity_current_W_xy = velocity_current_W; velocity_current_W_xy.z = 0; // Set default global reference point // Zurich Irchel Park: 47.397742, 8.545594, 488m const double lat_default = 47.397742 * M_PI / 180; // rad const double lon_default = 8.545594 * M_PI / 180; // rad const double alt_default = 488.0; // meters const float radius_default = 6353000; // m double lat_world = lat_default; double lon_world = lon_default; double alt_world = alt_default; double radius_world = radius_default; common::SphericalCoordinatesPtr spherical_coordinates = world_->GetSphericalCoordinates(); if (spherical_coordinates) { lat_world = spherical_coordinates->LatitudeReference().Radian(); // rad lon_world = spherical_coordinates->LongitudeReference().Radian(); // rad alt_world = spherical_coordinates->GetElevationReference(); // m switch (spherical_coordinates->GetSurfaceType()) { case (common::SphericalCoordinates::EARTH_WGS84): { radius_world = 6353000; // m break; } } } // reproject local position to gps coordinates double x_rad = pos_W_I.x / radius_world; double y_rad = -pos_W_I.y / radius_world; double c = sqrt(x_rad * x_rad + y_rad * y_rad); double sin_c = sin(c); double cos_c = cos(c); if (c != 0.0) { lat_rad = asin(cos_c * sin(lat_world) + (x_rad * sin_c * cos(lat_world)) / c); lon_rad = (lon_world + atan2(y_rad * sin_c, c * cos(lat_world) * cos_c - x_rad * sin(lat_world) * sin_c)); } else { lat_rad = lat_world; lon_rad = lon_world; } if(current_time.Double() - last_gps_time_.Double() > gps_update_interval_){ // 5Hz if(use_mavlink_udp){ // Raw UDP mavlink mavlink_hil_gps_t hil_gps_msg; hil_gps_msg.time_usec = current_time.nsec*1000; hil_gps_msg.fix_type = 3; hil_gps_msg.lat = lat_rad * 180 / M_PI * 1e7; hil_gps_msg.lon = lon_rad * 180 / M_PI * 1e7; hil_gps_msg.alt = (pos_W_I.z + alt_world) * 1000; hil_gps_msg.eph = 100; hil_gps_msg.epv = 100; hil_gps_msg.vel = velocity_current_W_xy.GetLength() * 100; hil_gps_msg.vn = velocity_current_W.x * 100; hil_gps_msg.ve = -velocity_current_W.y * 100; hil_gps_msg.vd = -velocity_current_W.z * 100; hil_gps_msg.cog = atan2(hil_gps_msg.ve, hil_gps_msg.vn) * 180.0/3.1416 * 100.0; hil_gps_msg.satellites_visible = 10; send_mavlink_message(MAVLINK_MSG_ID_HIL_GPS, &hil_gps_msg, 200); } else{ // Send via protobuf hil_gps_msg_.set_time_usec(current_time.nsec*1000); hil_gps_msg_.set_fix_type(3); hil_gps_msg_.set_lat(lat_rad * 180 / M_PI * 1e7); hil_gps_msg_.set_lon(lon_rad * 180 / M_PI * 1e7); hil_gps_msg_.set_alt((pos_W_I.z + alt_world) * 1000); hil_gps_msg_.set_eph(100); hil_gps_msg_.set_epv(100); hil_gps_msg_.set_vel(velocity_current_W_xy.GetLength() * 100); hil_gps_msg_.set_vn(velocity_current_W.x * 100); hil_gps_msg_.set_ve(-velocity_current_W.y * 100); hil_gps_msg_.set_vd(-velocity_current_W.z * 100); hil_gps_msg_.set_cog(atan2(-velocity_current_W.y * 100, velocity_current_W.x * 100) * 180.0/3.1416 * 100.0); hil_gps_msg_.set_satellites_visible(10); hil_gps_pub_->Publish(hil_gps_msg_); } last_gps_time_ = current_time; } }
// This gets called by the world update start event. void GazeboMavlinkInterface::OnUpdate(const common::UpdateInfo& /*_info*/) { pollForMAVLinkMessages(); if(!received_first_referenc_) return; common::Time now = world_->GetSimTime(); mav_msgs::msgs::CommandMotorSpeed turning_velocities_msg; for (int i = 0; i < input_reference_.size(); i++){ turning_velocities_msg.add_motor_speed(input_reference_[i]); } // TODO Add timestamp and Header // turning_velocities_msg->header.stamp.sec = now.sec; // turning_velocities_msg->header.stamp.nsec = now.nsec; motor_velocity_reference_pub_->Publish(turning_velocities_msg); //send gps common::Time current_time = now; double dt = (current_time - last_time_).Double(); last_time_ = current_time; double t = current_time.Double(); math::Pose T_W_I = model_->GetWorldPose(); //TODO(burrimi): Check tf. math::Vector3 pos_W_I = T_W_I.pos; // Use the models' world position for GPS and pressure alt. math::Vector3 velocity_current_W = model_->GetWorldLinearVel(); // Use the models' world position for GPS velocity. math::Vector3 velocity_current_W_xy = velocity_current_W; velocity_current_W_xy.z = 0.0; // TODO: Remove GPS message from IMU plugin. Added gazebo GPS plugin. This is temp here. double lat_zurich = 47.3667 * M_PI / 180 ; // rad double lon_zurich = 8.5500 * M_PI / 180; // rad float earth_radius = 6353000; // m // reproject local position to gps coordinates double x_rad = pos_W_I.x / earth_radius; double y_rad = -pos_W_I.y / earth_radius; double c = sqrt(x_rad * x_rad + y_rad * y_rad); double sin_c = sin(c); double cos_c = cos(c); double lat_rad; double lon_rad; if (c != 0.0) { lat_rad = asin(cos_c * sin(lat_zurich) + (x_rad * sin_c * cos(lat_zurich)) / c); lon_rad = (lon_zurich + atan2(y_rad * sin_c, c * cos(lat_zurich) * cos_c - x_rad * sin(lat_zurich) * sin_c)); } else { lat_rad = lat_zurich; lon_rad = lon_zurich; } common::Time gps_update(gps_update_interval_); if(current_time - last_gps_time_ > gps_update){ // 5Hz if(use_mavlink_udp){ // Raw UDP mavlink mavlink_hil_gps_t hil_gps_msg; hil_gps_msg.time_usec = current_time.nsec*1000; hil_gps_msg.fix_type = 3; hil_gps_msg.lat = lat_rad * 180 / M_PI * 1e7; hil_gps_msg.lon = lon_rad * 180 / M_PI * 1e7; hil_gps_msg.alt = pos_W_I.z * 1000; hil_gps_msg.eph = 100; hil_gps_msg.epv = 100; hil_gps_msg.vel = velocity_current_W_xy.GetLength() * 100; hil_gps_msg.vn = velocity_current_W.x * 100; hil_gps_msg.ve = -velocity_current_W.y * 100; hil_gps_msg.vd = -velocity_current_W.z * 100; hil_gps_msg.cog = atan2(hil_gps_msg.ve, hil_gps_msg.vn) * 180.0/3.1416 * 100.0; hil_gps_msg.satellites_visible = 10; send_mavlink_message(MAVLINK_MSG_ID_HIL_GPS, &hil_gps_msg, 200); } else{ // Send via protobuf hil_gps_msg_.set_time_usec(current_time.nsec*1000); hil_gps_msg_.set_fix_type(3); hil_gps_msg_.set_lat(lat_rad * 180 / M_PI * 1e7); hil_gps_msg_.set_lon(lon_rad * 180 / M_PI * 1e7); hil_gps_msg_.set_alt(pos_W_I.z * 1000); hil_gps_msg_.set_eph(100); hil_gps_msg_.set_epv(100); hil_gps_msg_.set_vel(velocity_current_W_xy.GetLength() * 100); hil_gps_msg_.set_vn(velocity_current_W.x * 100); hil_gps_msg_.set_ve(-velocity_current_W.y * 100); hil_gps_msg_.set_vd(-velocity_current_W.z * 100); hil_gps_msg_.set_cog(atan2(-velocity_current_W.y * 100, velocity_current_W.x * 100) * 180.0/3.1416 * 100.0); hil_gps_msg_.set_satellites_visible(10); hil_gps_pub_->Publish(hil_gps_msg_); } last_gps_time_ = current_time; } }