当前位置: 首页 > news >正文

ROS学习笔记1-幻宇机器人为模板

1.TF之间的管理建立:

<launch>
<!-- 建立base_foot与base(机器人)-gyro(陀螺仪)-laser(雷达)TF之间的关系 --><!--创建静态坐标转换广播器-rosrun tf2_ros static_transform_publisher x偏移量 y偏移量 z偏移量 z偏航角度 y俯仰角度 x翻滚角度 父级坐标系 子级坐标系--><node pkg="tf" type="static_transform_publisher" name="base_to_link" args="0.08 0 0 0 0 0 base_footprint base_link 100" /><node pkg="tf" type="static_transform_publisher" name="base_to_gyro" args="0.08 0 0 0 0 0 base_footprint gyro_link 100" /><node pkg="tf" type="static_transform_publisher" name="base_to_laser" args="0.14 0 0.11 3.14159 0 0 base_footprint laser 100" /><!-- 创造机器人模型 --><!-- <param name = "robot_description" textfile = "$(find huanyubot_description)/urdf/huanyubot.urdf"/> --><!-- 添加关节状态发布节点 --><!-- <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" /> --><!-- 添加机器人状态发布节点 --><!-- <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /> --><!-- 里程计相关设计 --><!--Start the robot's base control code and publish the odometer data--><!-- <node pkg="huanyu_robot_start" type="huanyu_robot_node" name="publish_odom" output="screen"><param name="usart_port"         type="string" value="/dev/huanyu_base"/>  <param name="baud_data"          type="int"    value="115200"/><param name="robot_frame_id"     type="string" value="base_footprint"/><param name="smoother_cmd_vel"   type="string" value="cmd_vel"/><param name="imu_velocity_z"     type="bool"   value="false"/><param name="filter_Vx_match"    type="double" value="1.0"/><param name="filter_Vth_match"   type="double" value="1.0"/></node> -->
<!-- 里程计 --><node pkg="huanyu_robot_start" type="huanyu_robot_node" name="publish_odom" output="screen"><!-- <param name="usart_port"         type="string" value="/dev/huanyu_base"/>   --><!-- <param name="baud_data"          type="int"    value="115200"/> --><param name="robot_frame_id"     type="string" value="base_footprint"/><param name="smoother_cmd_vel"   type="string" value="cmd_vel"/><param name="imu_velocity_z"     type="bool"   value="false"/><param name="filter_Vx_match"    type="double" value="1.0"/><param name="filter_Vth_match"   type="double" value="1.0"/></node><!-- 雷达1参数以及node启动 --><!-- <node name="rplidarNode"          pkg="rplidar_ros"  type="rplidarNode" output="screen"> <param name="serial_port"         type="string" value="/dev/huanyu_laser"/><param name="serial_baudrate"     type="int"    value="115200"/><param name="frame_id"            type="string" value="laser"/><param name="inverted"            type="bool"   value="false"/><param name="angle_compensate"    type="bool"   value="true"/></node> --><!-- Robot pose ekf --><!-- <node pkg="robot_pose_ekf" type="robot_pose_ekf" name="robot_pose_ekf" output="screen"><param name="freq" value="30.0"/><param name="sensor_timeout" value="1.0"/><param name="odom_used" value="true"/><param name="imu_used" value="true"/><param name="vo_used" value="false"/><remap from="/imu_data" to="/mobile_base/sensors/imu_data" /></node> --><!-- publish camera image --><!--node pkg="track_detection" type="imageRead_node" name="publish_image" output="screen"/>-->   <!-- 雷达2参数以及node启动 --><node pkg="hins_le_driver" type="hins_le_driver" name="hins_le_driver" output="screen" respawn="true"><param name="code_version" type="string" value="2.11.3"/>  <!-- 版本信息 请勿修改--><param name="laser_ip" type="string" value="192.168.1.88"/><param name="port" type="int" value="8080"/><param name="topic_name" type="string" value="scan"/><param name="frame_name" type="string" value="laser"/><param name="y_direction" type="bool" value="true"/>      <!-- 是否设置雷达的正前方为y轴正方向 false为x轴正方向--><param name="use_udp" type="bool" value="false"/>     <!-- 是否使用udp模式 是为true 否则为false--><!--雷达扫描参数--><param name="change_param" type="bool" value="false"/>      <!-- 是否改变雷达扫描参数 --><param name="measure_frequency_kHz" type="string" value="200"/>  <!-- 激光扫描频率(1s内输出点的数量) --><param name="spin_frequency_Hz" type="string" value="30"/> <!-- 电机转速(完整点云输出频率) --><param name="sampling_size_per_position" type="string" value="2"/> <!-- 单点采样次数(均值滤波窗口大小) --><param name="noise_filter_level" type="string" value="0"/> <!-- 噪声过滤等级(0~3) 值越小越接近原数据,越大点云越平滑 --><!--防拖尾过滤参数--><param name="shadows_filter_level" type="int" value="1"/><param name="shadows_filter_max_angle" value="175"/><param name="shadows_filter_min_angle" value="5"/><param name="shadows_filter_traverse_step" type="int" value="1"/><param name="shadows_filter_window" type="int" value="3"/><!--开始/结束角度 (角度值)  将开始角度~结束角度的值设为无效值(start_angle < end_angle)-->                                         <param name="start_angle" value="1.0"/><param name="end_angle" value="0.0"/><!--避障服务名--><param name="block_enable" type="bool" value="false"/>   <!--true为开启避障功能  false为关闭避障功能--><param name="service_name" type="string" value="hins_le_area_data"/></node></launch>

内部由TF实现了:

建立base_foot与base(机器人)-gyro(陀螺仪)-laser(雷达)TF之间联系;

base(机器人)内部联系由urdf实现:

odom与basefoot之间海未建立链接,因为gmapping与odom之间建立链接,但是没找道odom与basefoot如何建立连接的。

查阅可知:

odom与basefoot之间属于动态tf转换方式,不在launch里,launch实现静态TF转换,因此再程序内部实现。

map与odom再

void Huanyu_start_object::PublisherOdom()
{geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(th);std_msgs::Float32 power_msgs;power_msgs.data = this->Power_valtage;power_pub.publish(power_msgs);//first, we'll publish the transform over tf// geometry_msgs::TransformStamped odom_trans;// odom_trans.header.stamp = ros::Time::now();;// odom_trans.header.frame_id = "odom";// odom_trans.child_frame_id = this->robot_frame_id;// odom_trans.transform.translation.x = x;// odom_trans.transform.translation.y = y;// odom_trans.transform.translation.z = 0.0;// odom_trans.transform.rotation = odom_quat;// //send the transform// odom_broadcaster.sendTransform(odom_trans);//next, we'll publish the odometry message over ROSnav_msgs::Odometry odom;odom.header.stamp = ros::Time::now();;odom.header.frame_id = "odom";//set the positionodom.pose.pose.position.x = x;odom.pose.pose.position.y = y;odom.pose.pose.position.z = 0.0;odom.pose.pose.orientation = odom_quat;//set the velocityodom.child_frame_id = this->robot_frame_id;odom.twist.twist.linear.x =  this->vx;odom.twist.twist.linear.y =  this->vy;odom.twist.twist.angular.z = this->vth;		if(this->vx == 0){memcpy(&odom.pose.covariance, odom_pose_covariance2, sizeof(odom_pose_covariance2));memcpy(&odom.twist.covariance, odom_twist_covariance2, sizeof(odom_twist_covariance2));}else{memcpy(&odom.pose.covariance, odom_pose_covariance, sizeof(odom_pose_covariance));memcpy(&odom.twist.covariance, odom_twist_covariance, sizeof(odom_twist_covariance));}				//publish the messageodom_pub.publish(odom);
}

里面的:

 odom.header.frame_id = "odom";

    //set the position
odom.pose.pose.position.x = x;
odom.pose.pose.position.y = y;
odom.pose.pose.position.z = 0.0;
odom.pose.pose.orientation = odom_quat;

    //set the velocity
odom.child_frame_id = this->robot_frame_id;

//<param name="robot_frame_id"     type="string" value="base_footprint"/>已经对应成base_footprint了。

因此实现odom与base_footprint之间的TF转换。

未连接:

map与odom之间连理TF转换是由程序内部实现:如下:

gmapping中map->odom的转换
gmapping 通过“粒子滤波"实现定位。具体通过粒子与已经产生的地图进行scanMatch,矫正里程计误差实现。 在定位的同时,每次经过map_update_interval_时间,进行地图更新updateMap(*scan)。

//gmapping/src/slam_gmapping.cpp
void SlamGMapping::startLiveSlam()
{...  // 订阅激光数据scan_filter_->registerCallback(boost::bind(&SlamGMapping::laserCallback, this, _1));
}void SlamGMapping::laserCallback(const sensor_msgsList item::LaserScan::ConstPtr& scan)
{// We can't initialize the mapper until we've got the first scanif(!got_first_scan_){if(!initMapper(*scan))return;}GMapping::OrientedPoint odom_pose;if(addScan(*scan, odom_pose))// addscan:对新激光,结合里程计数据进行粒子滤波矫正得出最新位置{ // 以下通过getBestParticle的位置(即,当前激光位置)和里程计最终,算出map-to-odom,发布出去GMapping::OrientedPoint mpose = gsp_->getBestParticleIndex().pose;tf::Transform laser_to_map = tf::Transform(mpose...);tf::Transform odom_to_laser = tf::Transform(odom_pose...);map_to_odom_ = (odom_to_laser * laser_to_map).inverse();// 当满足 一定时间间隔 更新地图if(!got_map_ || (scan->header.stamp - last_map_update) > map_update_interval_){updateMap(*scan);last_map_update = scan->header.stamp;}}

 tf::Transform laser_to_map = tf::Transform(mpose...);
tf::Transform odom_to_laser = tf::Transform(odom_pose...);
map_to_odom_ = (odom_to_laser * laser_to_map).inverse();

进行实现。

TF正确链接:

话题topic链接:

http://www.dtcms.com/a/344981.html

相关文章:

  • Windows11 家庭版永久解密BitLocker加密移动硬盘
  • 【Java并发编程】Java多线程深度解析:状态、通信与停止线程的全面指南
  • RK3506-PWM计数功能
  • c#实现鼠标mousemove事件抽稀,避免大数据阻塞网络
  • 【COMSOL】Comsol学习案例时的心得记录分享(三)
  • 罗技鼠标驱动下载教程 多种方法详细说明
  • 排序---插入排序
  • CS 创世 SD NAND 助力 T-BOX:破解智能汽车数字中枢的存储密码
  • 110、【OS】【Nuttx】【周边】效果呈现方案解析:查找最新构建件
  • C++/QT 开发技能树详解
  • 钉钉 Stream 模式SpringBoot接入配置与事件监听
  • Maxscript如何清理3dMax场景?
  • react样式问题
  • git旧仓库迁移到新仓库
  • [系统架构设计师]安全架构设计理论与实践(十八)
  • Web3与AI语境下的审美积累:HAQQ品牌识别解析
  • 多人编程新方式:cpolar 让 OpenHands 远程开发更轻松
  • 区块链技术原理(17)-以太坊网络
  • SpringBoot中的条件注解
  • 常用三角函数公式推导体系
  • LLM应用场景能力边界趋势全览
  • 从系统修复到硬件检测的技术实测
  • [antv-x6] 文档链接
  • 08高级语言逻辑结构到汇编语言之逻辑结构转换 continue break 完结汇编按逻辑结构
  • RCE的CTF题目环境和做题复现第4集
  • 驱动(二)系统移植
  • 根据webpack设计原理手写一个简版webpack
  • 亚马逊广告优化新逻辑:从人工苦力到AI智能的进化之路
  • K8S的部署与常用管理
  • http请求有哪些?