上传了彩页,更新了图编号

pull/16/head
liuyunhua 1 year ago
parent 75627b97ec
commit 204e6acd48

@ -0,0 +1,694 @@
#include "uav_estimator.h"
UAV_estimator::UAV_estimator(ros::NodeHandle &nh)
{
// 【参数】编号
nh.param<int>("uav_id", uav_id, 1);
// 【参数】定位源, 定义见UAVState.msg
nh.param<int>("control/location_source", location_source, prometheus_msgs::UAVState::GPS);
// 【参数】最大安全速度
nh.param<float>("control/maximum_safe_vel_xy", maximum_safe_vel_xy, 4.0f);
nh.param<float>("control/maximum_safe_vel_z", maximum_safe_vel_z, 3.0f);
// 【参数】最大vision/px4速度误差
nh.param<float>("control/maximum_vel_error_for_vision", maximum_vel_error_for_vision, 1.0f);
// 【变量】无人机名字
uav_name = "/uav" + std::to_string(uav_id);
// 【变量】节点名字
node_name = "[uav_estimator_uav" + std::to_string(uav_id) + "]";
// 【订阅】无人机当前状态 - 来自飞控
px4_state_sub = nh.subscribe<mavros_msgs::State>(uav_name + "/mavros/state", 1, &UAV_estimator::px4_state_cb, this);
// 【订阅】无人机电池状态 - 来自飞控
px4_battery_sub = nh.subscribe<sensor_msgs::BatteryState>(uav_name + "/mavros/battery", 1, &UAV_estimator::px4_battery_cb, this);
// 【订阅】无人机当前位置 坐标系:ENU系 - 来自飞控
// 【备注】所有状态量在飞控中均为NED系但在ros中mavros将其转换为ENU系处理。所以在ROS中所有和mavros交互的量都为ENU系
px4_position_sub = nh.subscribe<geometry_msgs::PoseStamped>(uav_name + "/mavros/local_position/pose", 1, &UAV_estimator::px4_pos_cb, this);
// 【订阅】无人机当前速度 坐标系:ENU系 - 来自飞控
px4_velocity_sub = nh.subscribe<geometry_msgs::TwistStamped>(uav_name + "/mavros/local_position/velocity_local", 1, &UAV_estimator::px4_vel_cb, this);
// 【订阅】无人机当前欧拉角 坐标系:ENU系 - 来自飞控
px4_attitude_sub = nh.subscribe<sensor_msgs::Imu>(uav_name + "/mavros/imu/data", 1, &UAV_estimator::px4_att_cb, this);
// 根据设定的定位来源订阅不同的定位数据
if (location_source == prometheus_msgs::UAVState::MOCAP)
{
// 【订阅】mocap估计位置
mocap_sub = nh.subscribe<geometry_msgs::PoseStamped>("/vrpn_client_node" + uav_name + "/pose", 1, &UAV_estimator::mocap_cb, this);
}
else if (location_source == prometheus_msgs::UAVState::T265)
{
// 【订阅】T265估计位置
}
else if (location_source == prometheus_msgs::UAVState::GAZEBO)
{
// 【订阅】gazebo仿真真值
gazebo_sub = nh.subscribe<nav_msgs::Odometry>(uav_name + "/prometheus/ground_truth", 1, &UAV_estimator::gazebo_cb, this);
}
else if (location_source == prometheus_msgs::UAVState::FAKE_ODOM)
{
// 【订阅】fake odom
fake_odom_sub = nh.subscribe<nav_msgs::Odometry>(uav_name + "/prometheus/fake_odom", 10, &UAV_estimator::fake_odom_cb, this);
}
else if (location_source == prometheus_msgs::UAVState::GPS || location_source == prometheus_msgs::UAVState::RTK)
{
// 【订阅】GPS状态来自飞控
gps_status_sub = nh.subscribe<mavros_msgs::GPSRAW>(uav_name + "/mavros/gpsstatus/gps1/raw", 10, &UAV_estimator::gps_status_cb, this);
// 【订阅】无人机当前经纬度,来自飞控
px4_global_position_sub = nh.subscribe<sensor_msgs::NavSatFix>(uav_name + "/mavros/global_position/global", 1, &UAV_estimator::px4_global_pos_cb, this);
// 【订阅】设置ENU坐标系下无人机的位置偏移量 坐标系:ENU系 - 来自地面站/终端窗口
set_local_pose_offset_sub = nh.subscribe<prometheus_msgs::GPSData>(uav_name + "/prometheus/set_local_offset_pose", 1, &UAV_estimator::set_local_pose_offset_cb, this);
// 【发布】ENU坐标系下的位置偏移量
local_pose_offset_pub = nh.advertise<prometheus_msgs::OffsetPose>(uav_name + "/prometheus/offset_pose", 1);
}
else if (location_source == prometheus_msgs::UAVState::UWB)
{
// uwb todo
}
else
{
cout << YELLOW << node_name << ": wrong location_source param, no external location information input!" << TAIL << endl;
}
// 【发布】无人机状态合集,包括位置\速度\姿态\模式等,供上层节点使用
uav_state_pub = nh.advertise<prometheus_msgs::UAVState>(uav_name + "/prometheus/state", 1);
// 【发布】无人机位置和偏航角传输至PX4_EKF2模块用于位置姿态估计 坐标系 ENU系
px4_vision_pose_pub = nh.advertise<geometry_msgs::PoseStamped>(uav_name + "/mavros/vision_pose/pose", 1);
// 【发布】无人机里程计,主要用于RVIZ显示
uav_odom_pub = nh.advertise<nav_msgs::Odometry>(uav_name + "/prometheus/odom", 1);
// 【发布】无人机运动轨迹,主要用于RVIZ显示
uav_trajectory_pub = nh.advertise<nav_msgs::Path>(uav_name + "/prometheus/trajectory", 1);
// 【发布】无人机位置(带图标),用于RVIZ显示
uav_mesh_pub = nh.advertise<visualization_msgs::Marker>(uav_name + "/prometheus/uav_mesh", 1);
// 【发布】运行状态信息(-> 通信节点 -> 地面站)
ground_station_info_pub = nh.advertise<prometheus_msgs::TextInfo>("/uav" + std::to_string(uav_id) + "/prometheus/text_info", 1);
if (location_source == prometheus_msgs::UAVState::MOCAP || location_source == prometheus_msgs::UAVState::T265 || location_source == prometheus_msgs::UAVState::GAZEBO)
{
// 【定时器】当需要使用外部定位设备时需要定时发送vision信息至飞控,并保证一定频率
timer_px4_vision_pub = nh.createTimer(ros::Duration(0.02), &UAV_estimator::timercb_pub_vision_pose, this);
}
// 【定时器】定时发布 uav_state, uav_odom 保证50Hz以上
timer_uav_state_pub = nh.createTimer(ros::Duration(0.02), &UAV_estimator::timercb_pub_uav_state, this);
// 【定时器】定时发布 rviz显示,保证1Hz以上
timer_rviz_pub = nh.createTimer(ros::Duration(0.05), &UAV_estimator::timercb_rviz, this);
// 变量初始化
uav_state.uav_id = uav_id;
uav_state.connected = false;
uav_state.armed = false;
uav_state.mode = "";
uav_state.location_source = location_source;
uav_state.odom_valid = false;
uav_state.gps_status = prometheus_msgs::UAVState::GPS_FIX_TYPE_NO_GPS;
uav_state.position[0] = 0.0;
uav_state.position[1] = 0.0;
uav_state.position[2] = 0.0;
//该经纬度为阿木实验室测试场地(小花园)的经纬度
uav_state.latitude = 30.7852600;
uav_state.longitude = 103.8610300;
uav_state.altitude = 100.0;
uav_state.velocity[0] = 0.0;
uav_state.velocity[1] = 0.0;
uav_state.velocity[2] = 0.0;
uav_state.attitude_q.w = 1.0;
uav_state.attitude_q.x = 0.0;
uav_state.attitude_q.y = 0.0;
uav_state.attitude_q.z = 0.0;
uav_state.attitude[0] = 0.0;
uav_state.attitude[1] = 0.0;
uav_state.attitude[2] = 0.0;
uav_state.attitude_rate[0] = 0.0;
uav_state.attitude_rate[1] = 0.0;
uav_state.attitude_rate[2] = 0.0;
uav_state.battery_state = 0.0;
uav_state.battery_percetage = 0.0;
offset_pose.x = 0.0;
offset_pose.y = 0.0;
// 【函数】打印参数
printf_param();
cout << GREEN << node_name << " init! " << TAIL << endl;
// 地面站消息打印
text_info.header.stamp = ros::Time::now();
text_info.MessageType = prometheus_msgs::TextInfo::INFO;
text_info.Message = node_name + " init.";
ground_station_info_pub.publish(text_info);
}
void UAV_estimator::timercb_pub_uav_state(const ros::TimerEvent &e)
{
if (!uav_state_update)
{
return;
}
// 无人机状态检查:
// 1检查odom状态
// 2待补充
check_uav_state();
// 发布uav_state
uav_state.header.stamp = ros::Time::now();
uav_state_pub.publish(uav_state);
// 发布无人机当前odometry(有些节点需要Odometry这个数据类型)
uav_odom.header.stamp = ros::Time::now();
uav_odom.header.frame_id = "world";
uav_odom.child_frame_id = "base_link";
uav_odom.pose.pose.position.x = uav_state.position[0];
uav_odom.pose.pose.position.y = uav_state.position[1];
uav_odom.pose.pose.position.z = uav_state.position[2];
// 导航算法规定 高度不能小于0
if (uav_odom.pose.pose.position.z <= 0)
{
uav_odom.pose.pose.position.z = 0.01;
}
uav_odom.pose.pose.orientation = uav_state.attitude_q;
uav_odom.twist.twist.linear.x = uav_state.velocity[0];
uav_odom.twist.twist.linear.y = uav_state.velocity[1];
uav_odom.twist.twist.linear.z = uav_state.velocity[2];
uav_odom_pub.publish(uav_odom);
}
void UAV_estimator::timercb_pub_vision_pose(const ros::TimerEvent &e)
{
if (location_source == prometheus_msgs::UAVState::GAZEBO)
{
vision_pose = gazebo_pose;
}
else if (location_source == prometheus_msgs::UAVState::MOCAP)
{
vision_pose = mocap_pose;
}
else if (location_source == prometheus_msgs::UAVState::T265)
{
vision_pose = t265_pose;
}
else
{
vision_pose_error = true;
return;
}
Eigen::Vector3d pos_vision = Eigen::Vector3d(vision_pose.pose.position.x, vision_pose.pose.position.y, vision_pose.pose.position.z);
Eigen::Vector3d pos_px4 = Eigen::Vector3d(uav_state.position[0], uav_state.position[1], uav_state.position[2]);
// vision位置和px4回传位置相差较多一般是PX4中EKF2参数设置错误导致PX4没有收到vision定位数据导致
// 无人机发生剧烈位移,也会出现本错误,这个需要根据实际测试结果来确定
if ((pos_vision - pos_px4).norm() > maximum_vel_error_for_vision)
{
vision_pose_error = true;
}
else
{
vision_pose_error = false;
}
px4_vision_pose_pub.publish(vision_pose);
}
void UAV_estimator::timercb_rviz(const ros::TimerEvent &e)
{
// 发布无人机运动轨迹用于rviz显示
geometry_msgs::PoseStamped uav_pos;
uav_pos.header.stamp = ros::Time::now();
uav_pos.header.frame_id = "world";
uav_pos.pose.position.x = uav_state.position[0];
uav_pos.pose.position.y = uav_state.position[1];
uav_pos.pose.position.z = uav_state.position[2];
uav_pos.pose.orientation = uav_state.attitude_q;
pos_vector.insert(pos_vector.begin(), uav_pos);
if (pos_vector.size() > TRA_WINDOW)
{
pos_vector.pop_back();
}
nav_msgs::Path uav_trajectory;
uav_trajectory.header.stamp = ros::Time::now();
uav_trajectory.header.frame_id = "world";
uav_trajectory.poses = pos_vector;
uav_trajectory_pub.publish(uav_trajectory);
// 发布无人机marker
visualization_msgs::Marker meshROS;
meshROS.header.frame_id = "world";
meshROS.header.stamp = ros::Time::now();
meshROS.ns = "mesh";
meshROS.id = 0;
meshROS.type = visualization_msgs::Marker::MESH_RESOURCE;
meshROS.action = visualization_msgs::Marker::ADD;
meshROS.pose.position.x = uav_state.position[0];
meshROS.pose.position.y = uav_state.position[1];
meshROS.pose.position.z = uav_state.position[2];
meshROS.pose.orientation.w = uav_state.attitude_q.w;
meshROS.pose.orientation.x = uav_state.attitude_q.x;
meshROS.pose.orientation.y = uav_state.attitude_q.y;
meshROS.pose.orientation.z = uav_state.attitude_q.z;
meshROS.scale.x = 1.0;
meshROS.scale.y = 1.0;
meshROS.scale.z = 1.0;
meshROS.color.a = 1.0;
meshROS.color.r = 0.0;
meshROS.color.g = 0.0;
meshROS.color.b = 1.0;
meshROS.mesh_resource = std::string("package://prometheus_uav_control/meshes/hummingbird.mesh");
uav_mesh_pub.publish(meshROS);
// 发布TF用于RVIZ显示用于lidar
static tf2_ros::TransformBroadcaster broadcaster;
geometry_msgs::TransformStamped tfs;
// |----头设置
tfs.header.frame_id = "world"; //相对于世界坐标系
tfs.header.stamp = ros::Time::now(); //时间戳
// |----坐标系 ID
tfs.child_frame_id = uav_name + "/lidar_link"; //子坐标系,无人机的坐标系
// |----坐标系相对信息设置 偏移量 无人机相对于世界坐标系的坐标
tfs.transform.translation.x = uav_state.position[0];
tfs.transform.translation.y = uav_state.position[1];
tfs.transform.translation.z = uav_state.position[2];
// |--------- 四元数设置
tfs.transform.rotation = uav_state.attitude_q;
// |--------- 广播器发布数据
broadcaster.sendTransform(tfs);
}
void UAV_estimator::px4_state_cb(const mavros_msgs::State::ConstPtr &msg)
{
uav_state.connected = msg->connected;
uav_state.armed = msg->armed;
uav_state.mode = msg->mode;
uav_state_update = true;
}
void UAV_estimator::px4_pos_cb(const geometry_msgs::PoseStamped::ConstPtr &msg)
{
// 统一坐标系RTK情况下可以设置offset_pose其他情况offset_pose为零
uav_state.position[0] = msg->pose.position.x + offset_pose.x;
uav_state.position[1] = msg->pose.position.y + offset_pose.y;
uav_state.position[2] = msg->pose.position.z;
}
void UAV_estimator::px4_global_pos_cb(const sensor_msgs::NavSatFix::ConstPtr &msg)
{
uav_state.latitude = msg->latitude;
uav_state.longitude = msg->longitude;
uav_state.altitude = msg->altitude;
}
void UAV_estimator::px4_vel_cb(const geometry_msgs::TwistStamped::ConstPtr &msg)
{
uav_state.velocity[0] = msg->twist.linear.x;
uav_state.velocity[1] = msg->twist.linear.y;
uav_state.velocity[2] = msg->twist.linear.z;
}
void UAV_estimator::px4_att_cb(const sensor_msgs::Imu::ConstPtr &msg)
{
Eigen::Quaterniond q_fcu = Eigen::Quaterniond(msg->orientation.w, msg->orientation.x, msg->orientation.y, msg->orientation.z);
Eigen::Vector3d euler_fcu = quaternion_to_euler(q_fcu);
uav_state.attitude_q = msg->orientation;
uav_state.attitude[0] = euler_fcu[0];
uav_state.attitude[1] = euler_fcu[1];
uav_state.attitude[2] = euler_fcu[2];
uav_state.attitude_rate[0] = msg->angular_velocity.x;
uav_state.attitude_rate[1] = msg->angular_velocity.y;
uav_state.attitude_rate[2] = msg->angular_velocity.z;
}
void UAV_estimator::px4_battery_cb(const sensor_msgs::BatteryState::ConstPtr &msg)
{
uav_state.battery_state = msg->voltage;
uav_state.battery_percetage = msg->percentage;
}
void UAV_estimator::gps_status_cb(const mavros_msgs::GPSRAW::ConstPtr &msg)
{
uav_state.gps_status = msg->fix_type;
}
void UAV_estimator::mocap_cb(const geometry_msgs::PoseStamped::ConstPtr &msg)
{
mocap_pose = *msg;
get_mocap_stamp = ros::Time::now(); // 记录时间戳,防止超时
}
void UAV_estimator::gazebo_cb(const nav_msgs::Odometry::ConstPtr &msg)
{
gazebo_pose.header = msg->header;
gazebo_pose.pose = msg->pose.pose;
get_gazebo_stamp = ros::Time::now(); // 记录时间戳,防止超时
}
void UAV_estimator::t265_cb(const nav_msgs::Odometry::ConstPtr &msg)
{
t265_pose.header = msg->header;
t265_pose.pose = msg->pose.pose;
get_t265_stamp = ros::Time::now(); // 记录时间戳,防止超时
}
void UAV_estimator::fake_odom_cb(const nav_msgs::Odometry::ConstPtr &msg)
{
// uav_state 直接赋值
uav_state.connected = true;
uav_state.armed = true;
uav_state.odom_valid = true;
uav_state.mode = "OFFBOARD";
uav_state.position[0] = msg->pose.pose.position.x;
uav_state.position[1] = msg->pose.pose.position.y;
uav_state.position[2] = msg->pose.pose.position.z;
uav_state.velocity[0] = msg->twist.twist.linear.x;
uav_state.velocity[1] = msg->twist.twist.linear.y;
uav_state.velocity[2] = msg->twist.twist.linear.z;
uav_state.attitude_q = msg->pose.pose.orientation;
Eigen::Quaterniond q = Eigen::Quaterniond(msg->pose.pose.orientation.w, msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z);
Eigen::Vector3d euler = quaternion_to_euler(q);
uav_state.attitude[0] = euler[0];
uav_state.attitude[1] = euler[1];
uav_state.attitude[2] = euler[2];
uav_state.attitude_rate[0] = 0.0;
uav_state.attitude_rate[1] = 0.0;
uav_state.attitude_rate[2] = 0.0;
uav_state_update = true;
}
void UAV_estimator::check_uav_state()
{
// 检查odom状态
odom_state = check_uav_odom();
if (odom_state == 1 && last_odom_state != 1)
{
cout << RED << node_name << "---> Odom invalid: Get Vision Pose Timeout! " << TAIL << endl;
}
else if (odom_state == 2 && last_odom_state != 2)
{
cout << RED << node_name << "---> Odom invalid: Velocity too large! " << TAIL << endl;
}
else if (odom_state == 3 && last_odom_state != 3)
{
cout << RED << node_name << "---> Odom invalid: vision_pose_error! " << TAIL << endl;
}
else if (odom_state == 4 && last_odom_state != 4)
{
cout << RED << node_name << "---> Odom invalid: GPS/RTK location error! " << TAIL << endl;
}
else if (odom_state == 5 && last_odom_state != 5)
{
cout << YELLOW << node_name << "---> Odom invalid: RTK not fixed! " << TAIL << endl;
}
if (odom_state == 9 || odom_state == 5)
{
uav_state.odom_valid = true;
}
else
{
uav_state.odom_valid = false;
}
last_odom_state = odom_state;
}
int UAV_estimator::check_uav_odom()
{
ros::Time time_now = ros::Time::now();
// odom失效可能原因1外部定位数据接收超时
if (location_source == prometheus_msgs::UAVState::GAZEBO && (time_now - get_gazebo_stamp).toSec() > GAZEBO_TIMEOUT)
{
return 1;
}
else if (location_source == prometheus_msgs::UAVState::MOCAP && (time_now - get_mocap_stamp).toSec() > MOCAP_TIMEOUT)
{
return 1;
}
else if (location_source == prometheus_msgs::UAVState::T265 && (time_now - get_t265_stamp).toSec() > T265_TIMEOUT)
{
return 1;
}
// odom失效可能原因2无人机合速度过大认为定位模块失效
Eigen::Vector2d uav_vel_xy = Eigen::Vector2d(uav_state.velocity[0], uav_state.velocity[1]);
if (uav_vel_xy.norm() > maximum_safe_vel_xy || uav_state.velocity[2] > maximum_safe_vel_z)
{
return 2;
}
// odom失效可能原因3无人机位置与外部定位设备原始值相差过多
if (vision_pose_error)
{
return 3;
}
// odom失效可能原因4:GPS定位模块数据异常,无法获取定位数据
if (location_source == prometheus_msgs::UAVState::GPS)
{
if (uav_state.gps_status != prometheus_msgs::UAVState::GPS_FIX_TYPE_3D_FIX)
{
return 4;
}
}
if (location_source == prometheus_msgs::UAVState::RTK)
{
if (uav_state.gps_status < prometheus_msgs::UAVState::GPS_FIX_TYPE_3D_FIX)
{
return 4;
}
// odom数据可信度降低可能原因5:RTK定位精度未达到FIXED状态(非odom失效状态)
else if (uav_state.gps_status <= prometheus_msgs::UAVState::GPS_FIX_TYPE_RTK_FLOATR)
{
return 5;
}
}
//UWB todo
return 9;
}
void UAV_estimator::printf_uav_state()
{
cout << GREEN << ">>>>>>>>>>>>>>>>>>>> UAV [" << uav_id << "] State <<<<<<<<<<<<<<<<<<<<" << TAIL << endl;
//固定的浮点显示
cout.setf(ios::fixed);
// setprecision(n) 设显示小数精度为n位
cout << setprecision(NUM_POINT);
//左对齐
cout.setf(ios::left);
// 强制显示小数点
cout.setf(ios::showpoint);
// 强制显示符号
cout.setf(ios::showpos);
// 打印 无人机状态
if (uav_state.connected == true)
{
cout << GREEN << "PX4 Status: [ Connected ] ";
}
else
{
cout << RED << "PX4 Status:[ Unconnected ] ";
}
//是否上锁
if (uav_state.armed == true)
{
cout << GREEN << "[ Armed ] ";
}
else
{
cout << RED << "[ DisArmed ] ";
}
cout << "[ " << uav_state.mode << " ] " << TAIL << endl;
switch (location_source)
{
case prometheus_msgs::UAVState::MOCAP:
cout << GREEN << "Location: [ MOCAP ] " << TAIL << endl;
cout << GREEN << "MOCAP_pos [X Y Z] : " << mocap_pose.pose.position.x << " [ m ] " << mocap_pose.pose.position.y << " [ m ] " << mocap_pose.pose.position.z << " [ m ] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::T265:
cout << GREEN << "Location: [ T265 ] " << TAIL << endl;
cout << GREEN << "T265_pos [X Y Z] : " << t265_pose.pose.position.x << " [ m ] " << t265_pose.pose.position.y << " [ m ] " << t265_pose.pose.position.z << " [ m ] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GAZEBO:
cout << GREEN << "Location: [ GAZEBO ] " << TAIL << endl;
cout << GREEN << "GAZEBO_pos [X Y Z] : " << gazebo_pose.pose.position.x << " [ m ] " << gazebo_pose.pose.position.y << " [ m ] " << gazebo_pose.pose.position.z << " [ m ] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::FAKE_ODOM:
cout << GREEN << "Location: [ FAKE_ODOM ] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS:
cout << GREEN << "Location: [ GPS ] " << TAIL;
printf_gps_status();
break;
case prometheus_msgs::UAVState::RTK:
cout << GREEN << "Location: [ RTK ] " << TAIL;
printf_gps_status();
case prometheus_msgs::UAVState::UWB:
cout << GREEN << "Location: [ UWB ] " << TAIL;
// todo
break;
}
if (uav_state.odom_valid)
{
cout << GREEN << "Odom Status : [ Valid ] " << TAIL << endl;
}
else
{
cout << RED << "Odom Status : [ Invalid ] " << TAIL << endl;
}
cout << GREEN << "UAV_pos [X Y Z] : " << uav_state.position[0] << " [ m ] " << uav_state.position[1] << " [ m ] " << uav_state.position[2] << " [ m ] " << TAIL << endl;
cout << GREEN << "UAV_vel [X Y Z] : " << uav_state.velocity[0] << " [m/s] " << uav_state.velocity[1] << " [m/s] " << uav_state.velocity[2] << " [m/s] " << TAIL << endl;
cout << GREEN << "UAV_att [R P Y] : " << uav_state.attitude[0] * 180 / M_PI << " [deg] " << uav_state.attitude[1] * 180 / M_PI << " [deg] " << uav_state.attitude[2] * 180 / M_PI << " [deg] " << TAIL << endl;
cout << GREEN << "Battery Voltage : " << uav_state.battery_state << " [V] "
<< " Battery Percent : " << uav_state.battery_percetage << TAIL << endl;
}
void UAV_estimator::printf_gps_status()
{
// 确认一下哪些是红色哪些是绿色todo...
if (location_source == prometheus_msgs::UAVState::GPS)
{
switch (uav_state.gps_status)
{
case prometheus_msgs::UAVState::GPS_FIX_TYPE_NO_GPS:
cout << RED << " [GPS_FIX_TYPE_NO_GPS] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_NO_FIX:
cout << RED << " [GPS_FIX_TYPE_NO_FIX] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_2D_FIX:
cout << YELLOW << " [GPS_FIX_TYPE_2D_FIX] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_3D_FIX:
cout << GREEN << " [GPS_FIX_TYPE_3D_FIX] " << TAIL << endl;
break;
}
}
if (location_source == prometheus_msgs::UAVState::RTK)
{
switch (uav_state.gps_status)
{
case prometheus_msgs::UAVState::GPS_FIX_TYPE_NO_GPS:
cout << RED << " [GPS_FIX_TYPE_NO_GPS] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_NO_FIX:
cout << RED << " [GPS_FIX_TYPE_NO_FIX] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_2D_FIX:
cout << RED << " [GPS_FIX_TYPE_2D_FIX] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_3D_FIX:
cout << YELLOW << " [GPS_FIX_TYPE_3D_FIX] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_DGPS:
cout << YELLOW << " [GPS_FIX_TYPE_DGPS] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_RTK_FLOATR:
cout << YELLOW << " [GPS_FIX_TYPE_RTK_FLOATR] " << TAIL << endl;
break;
case prometheus_msgs::UAVState::GPS_FIX_TYPE_RTK_FIXEDR:
cout << GREEN << " [GPS_FIX_TYPE_RTK_FIXEDR] " << TAIL << endl;
break;
}
// offset_pose
cout << GREEN << "offset_pose [X Y] : " << offset_pose.x << " [ m ] " << offset_pose.y << " [ m ] " << TAIL << endl;
}
// 确定下单位todo
cout << GREEN << "GPS [lat lon alt] : " << uav_state.latitude << " [ deg ] " << uav_state.longitude << " [ deg ] " << uav_state.altitude << " [ m ] " << TAIL << endl;
}
void UAV_estimator::printf_param()
{
cout << GREEN << ">>>>>>>>>>>>>>>> UAV estimator Param <<<<<<<<<<<<<<<<" << TAIL << endl;
cout << GREEN << "uav_id : " << uav_id << " " << TAIL << endl;
cout << GREEN << "maximum_safe_vel_xy : " << maximum_safe_vel_xy << " [m/s] " << TAIL << endl;
cout << GREEN << "maximum_safe_vel_z : " << maximum_safe_vel_z << " [m/s] " << TAIL << endl;
cout << GREEN << "maximum_vel_error_for_vision : " << maximum_vel_error_for_vision << " [m/s] " << TAIL << endl;
if (location_source == prometheus_msgs::UAVState::GAZEBO)
{
cout << GREEN << "location_source: [GAZEBO] " << TAIL << endl;
}
else if (location_source == prometheus_msgs::UAVState::MOCAP)
{
cout << GREEN << "location_source: [MOCAP] " << TAIL << endl;
}
else if (location_source == prometheus_msgs::UAVState::T265)
{
cout << GREEN << "location_source: [T265] " << TAIL << endl;
}
else if (location_source == prometheus_msgs::UAVState::FAKE_ODOM)
{
cout << GREEN << "location_source: [FAKE_ODOM] " << TAIL << endl;
}
else if (location_source == prometheus_msgs::UAVState::GPS)
{
cout << GREEN << "location_source: [GPS] " << TAIL << endl;
}
else if (location_source == prometheus_msgs::UAVState::RTK)
{
cout << GREEN << "location_source: [GPS] " << TAIL << endl;
}
else if (location_source == prometheus_msgs::UAVState::UWB)
{
cout << GREEN << "location_source: [GPS] " << TAIL << endl;
}
else
{
cout << GREEN << "location_source: [UNKNOW] " << endl;
}
}
void UAV_estimator::set_local_pose_offset_cb(const prometheus_msgs::GPSData::ConstPtr &msg)
{
GeographicLib::Geocentric earth(GeographicLib::Constants::WGS84_a(), GeographicLib::Constants::WGS84_f());
Eigen::Vector3d origin_gps;
Eigen::Vector3d origin_ecef;
Eigen::Vector3d current_uav_gps;
Eigen::Vector3d current_uav_ecef;
Eigen::Vector3d ecef_offset;
Eigen::Vector3d enu_offset;
origin_gps[0] = msg->latitude;
origin_gps[1] = msg->longitude;
origin_gps[2] = msg->altitude;
current_uav_gps[0] = uav_state.latitude;
current_uav_gps[1] = uav_state.longitude;
current_uav_gps[2] = uav_state.altitude;
earth.Forward(origin_gps[0], origin_gps[1], origin_gps[2], origin_ecef[0], origin_ecef[1], origin_ecef[2]);
earth.Forward(current_uav_gps[0], current_uav_gps[1], current_uav_gps[2], current_uav_ecef[0], current_uav_ecef[1], current_uav_ecef[2]);
ecef_offset = current_uav_ecef - origin_ecef;
enu_offset = mavros::ftf::transform_frame_ecef_enu(ecef_offset, origin_gps);
// estimator节点根据GPS初始位置解算得到初始偏差只发布一次
// 发布出来的uav_state在uav1的坐标系下
// 每个飞机的local_position还是在起飞坐标系
// 所以发布控制指令也要加上偏差
offset_pose.uav_id = uav_id;
offset_pose.x = enu_offset[0];
offset_pose.y = enu_offset[1];
local_pose_offset_pub.publish(offset_pose);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

Loading…
Cancel
Save