在rviz中使用键盘控制burger

2023-05-16

启动语句

roslaunch turtlebot3_fake turtlebot3_fake.launch //启动rviz、话题通信
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch //启动键盘控制节点

turtlebot3_fake.launch文件解读

<launch>
  <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
  <param name="tb3_model" value="$(arg model)"/>

  <include file="$(find turtlebot3_bringup)/launch/includes/description.launch.xml">
    <arg name="model" value="$(arg model)" />
  </include>  

  <node pkg="turtlebot3_fake" type="turtlebot3_fake_node" name="turtlebot3_fake_node" output="screen" />

  <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen">
    <param name="publish_frequency" type="double" value="50.0" />
  </node>

  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find turtlebot3_fake)/rviz/turtlebot3_fake.rviz"/>
</launch>

这个launch文件包含三部分:加载机器人模型、启动节点话题、启动rviz。

其中,turtlebot3_fake_node是自定义的一个节点。代码如下:

1. 主函数

int main(int argc, char* argv[])
{
  ros::init(argc, argv, "turtlebot3_fake_node");
  Turtlebot3Fake tb3fake;       
  ros::Rate loop_rate(30);

  while (ros::ok())
  {
    tb3fake.update();
    ros::spinOnce();
    loop_rate.sleep();
  }

  return 0;
}

定义turtlebot3_fake_node这个节点

2. Turtlebot3Fake::init()

发布burger的关节状态信息和里程计信息,订阅速度信息

// initialize publishers
  joint_states_pub_ = nh_.advertise<sensor_msgs::JointState>("joint_states", 100);
  odom_pub_         = nh_.advertise<nav_msgs::Odometry>("odom", 100);

  // initialize subscribers
  cmd_vel_sub_  = nh_.subscribe("cmd_vel", 100,  &Turtlebot3Fake::commandVelocityCallback, this);

//回调函数
  void Turtlebot3Fake::commandVelocityCallback(const geometry_msgs::TwistConstPtr cmd_vel_msg)  
{
  last_cmd_vel_time_ = ros::Time::now();

  goal_linear_velocity_  = cmd_vel_msg->linear.x;
  goal_angular_velocity_ = cmd_vel_msg->angular.z;

  wheel_speed_cmd_[LEFT]  = goal_linear_velocity_ - (goal_angular_velocity_ * wheel_seperation_ / 2);  //根据全局的速度和角速度得到左右轮的速度
  wheel_speed_cmd_[RIGHT] = goal_linear_velocity_ + (goal_angular_velocity_ * wheel_seperation_ / 2);
}

订阅得到的速度、角速度定义为全局速度、全局角速度。通过全局速度以及全局角速度得到左右轮的速度。

3. tb3fake.update()

bool Turtlebot3Fake::update()   
{
  ros::Time time_now = ros::Time::now();
  ros::Duration step_time = time_now - prev_update_time_;
  prev_update_time_ = time_now;

  // zero-ing after timeout
  if((time_now - last_cmd_vel_time_).toSec() > cmd_vel_timeout_)
  {
    wheel_speed_cmd_[LEFT]  = 0.0;
    wheel_speed_cmd_[RIGHT] = 0.0;
  }

  // odom
  updateOdometry(step_time);
  odom_.header.stamp = time_now;
  odom_pub_.publish(odom_);   //发布更新过的里程计信息  odom_pub是发布者的名称,odom_是定义的数据类型名称

  // joint_states
  updateJoint();
  joint_states_.header.stamp = time_now;
  joint_states_pub_.publish(joint_states_);   //发布更新过的关节状态

  // tf
  geometry_msgs::TransformStamped odom_tf;
  updateTF(odom_tf);
  tf_broadcaster_.sendTransform(odom_tf);

  return true;
}

4. Turtlebot3Fake::updateOdometry(ros::Duration diff_time)

通过订阅得到的速度信息,更新里程计信息,包括位置、速度、角速度。通过update()函数将更新过的里程计信息发布出去。

bool Turtlebot3Fake::updateOdometry(ros::Duration diff_time)    //更新里程计信息,包括位置、速度、角速度
{
  double wheel_l, wheel_r; // rotation value of wheel [rad]
  double delta_s, delta_theta;
  double v[2], w[2];

  wheel_l = wheel_r     = 0.0;
  delta_s = delta_theta = 0.0;

  v[LEFT]  = wheel_speed_cmd_[LEFT];  //订阅得到的速度
  w[LEFT]  = v[LEFT] / WHEEL_RADIUS;  // w = v / r
  v[RIGHT] = wheel_speed_cmd_[RIGHT];
  w[RIGHT] = v[RIGHT] / WHEEL_RADIUS;

  last_velocity_[LEFT]  = w[LEFT];     //最新的角速度
  last_velocity_[RIGHT] = w[RIGHT];

  wheel_l = w[LEFT]  * diff_time.toSec();   //角度增量
  wheel_r = w[RIGHT] * diff_time.toSec();

  if(isnan(wheel_l))  //判断wheel_l是否为非数字值,若不是数字则条件为真
  {
    wheel_l = 0.0;
  }

  if(isnan(wheel_r))
  {
    wheel_r = 0.0;
  }

  last_position_[LEFT]  += wheel_l;   //一共转过的角度
  last_position_[RIGHT] += wheel_r;

  delta_s     = WHEEL_RADIUS * (wheel_r + wheel_l) / 2.0;   //位移增量
  delta_theta = WHEEL_RADIUS * (wheel_r - wheel_l) / wheel_seperation_;   //角度增量

  // compute odometric pose
  odom_pose_[0] += delta_s * cos(odom_pose_[2] + (delta_theta / 2.0));   //使用极坐标表示
  odom_pose_[1] += delta_s * sin(odom_pose_[2] + (delta_theta / 2.0));
  odom_pose_[2] += delta_theta;

  // compute odometric instantaneouse velocity    //计算瞬时速度
  odom_vel_[0] = delta_s / diff_time.toSec();     // v
  odom_vel_[1] = 0.0;
  odom_vel_[2] = delta_theta / diff_time.toSec(); // w

  odom_.pose.pose.position.x = odom_pose_[0];
  odom_.pose.pose.position.y = odom_pose_[1];
  odom_.pose.pose.position.z = 0;
  odom_.pose.pose.orientation = tf::createQuaternionMsgFromYaw(odom_pose_[2]);

  // We should update the twist of the odometry
  odom_.twist.twist.linear.x  = odom_vel_[0];
  odom_.twist.twist.angular.z = odom_vel_[2];

  return true;
}

启动rviz

首先打开一个空的rviz,Add需要的属性,save as 文件名为turtelbot3_fake.rviz。此时,会自动生成文件名为turtlebot3_fake.rviz的文件。

另一种turtlebot3_fake.launch写法

<launch>
  <arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
  <arg name="x_pos" default="0.0"/>
  <arg name="y_pos" default="0.0"/>
  <arg name="z_pos" default="0.0"/>

  <param name="robot_description" command="$(find xacro)/xacro --inorder $(find turtlebot3_description)/urdf/turtlebot3_$(arg model).urdf.xacro" />  

  <node pkg="turtlebot3_fake" type="turtlebot3_fake_node" name="turtlebot3_fake_node" output="screen" />

  <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen">
    <param name="publish_frequency" type="double" value="50.0" />
  </node>

  <node name="rviz" pkg="rviz" type="rviz" args="-d $(find turtlebot3_fake)/rviz/turtlebot3_fake.rviz"/>
</launch>

这种写法与开头的.launch文件的不同之处在于加载burger的方式不同。

键盘控制代码见下篇。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在rviz中使用键盘控制burger 的相关文章

随机推荐

  • centos 64bit安装arm-none-linux-gnueabi交叉编译工具链

    xfeff xfeff yum install glibc i686在centos中安装arm none Linux gnueabi有两种方法 xff0c 一种是apt get 安装容易但是不易成功 xff0c 一种是下载压缩包或安装程序
  • 旋转矩阵和欧拉角

    欧拉角介绍 旋转可以参考两种坐标系 内部坐标系 XYZ 角度 外部坐标系 xyz 角度 不考虑参考坐标系情况下 按照旋转方式可以分为两种 Proper Euler angles z x z x y x y z y z y z x z x y
  • SIP 鉴权 & HTTP 认证

    sip 鉴权是基于摘要签名认证的 具体来说 每一个用户都有一个用户名和密码 用户名和密码在客户端和SIP 服务器的数据库中都有保存 在认证的过程中 客户端将自己的信息 用户名 密码 url 等信息 做一些复杂的MD5 或者SHA256 SH
  • ROS——TF坐标变换

    TF功能包 创建功能包 cd catkin ws src catkin creat pkg learning tf roscpp rospy tf turtlesim 如果此时依赖包已有tf xff0c 后文中CMakeLists文件中的f
  • Gazebo——仿真平台搭建(基于Ubuntu20.04)

    目录 Gazebo安装配置 创建仿真环境 仿真使用 Rviz查看摄像头采集的信息 Kinect仿真 问题解决 xff1a 1 gazebo SpawnModel Failure model name mrobot already exist
  • 单片机要学多久可以找到工作?能找到哪类的工作

    单片机学多久能工作 单片机学好了能应聘什么工作 xff1f 从事单片机开发10年 xff0c 我见证了这个行业的成长 xff0c 最明显的就是这几年的工资涨幅 大家好 xff0c 我是小哥 xff0c 10年前我还是个对前景充满憧憬的小屌丝
  • 互联网企业部分面试笔试真题以及考察知识点总结(一)

    1 static的作用 1 1用static关键字修饰的静态变量 静态变量属于类 xff0c 在内存中只有一个复制 xff0c 只要静态变量所在的类被加 载 xff0c 这个静态变量就会被分配空间 1 2 static成员方法 Java中提
  • 史上最全网址导航大全,让世上没有找不到的好东西

    收录的导航网址大全 好用和常用的网址几乎都在里面 个人喜欢往浏览器书签收藏夹里塞喜欢的干货和网站 xff0c 以至于收藏夹里有着几千条网址 xff0c 所以比较喜欢导航 xff0c 但是浏览器原生自带的导航又太low 所以一般自己设置打开浏
  • HTTP的认证方式之DIGEST 认证(摘要认证)

    核心步骤 xff1a 步骤 1 xff1a 请求需认证的资源时 xff0c 服务器会随着状态码 401Authorization Required xff0c 返回带WWW Authenticate 首部字段的响应 该字段内包含质问响应方式
  • 相机标定评价标准

    相机标定的实验一般根据图像数据的类型分为两种 xff1a 1 仿真实验 2 实际场景的操作性实验 目前为止 xff0c 还没有形成一套完善的用于评价相机标定方法的标准体系 xff0c 通常采用的评价准则如下 xff1a 1 标定方法是否具有
  • ubuntu下串口工具的安装与使用

    1 概述 作为一个嵌入式开发人员 xff0c 串口是开发过程中不可或缺的工具之一 xff0c window下有各种各样的串口工具 xff0c 使用起来很方便 xff0c 这里不再做过多陈述 xff0c 这里主要介绍Ubuntu 16 04
  • Ubuntu查看文件大小或文件夹大小

    Ubuntu查看文件大小或文件夹大小 一 查看文件大小 查看文件大小的命令 xff1a ls l filename 会在终端输出 xff1a rw r r 1 root root 2147483648 Mar 5 09 39 filetem
  • 结构体数据对齐

    结构体数据对齐 结构体数据对齐 xff0c 是指结构体内的各个数据对齐 在结构体中的第一个成员的首地址等于整个结构体的变量的首地址 xff0c 而后的成员的地址随着它声明的顺序和实际占用的字节数递增 为了总的结构体大小对齐 xff0c 会在
  • 2016你配得上更好地自己

    传统里我一直觉得过完春节才是一年结束的时候 xff0c 但是现在慢慢习惯阳历的计算 xff0c 2017年1月1日 xff0c 看着空间里面新年祝福和期待 xff0c 突然觉得这才是过年 2016年就这样走了 xff0c 以后我再也回不到2
  • 树莓派镜像备份与恢复文章

    在做完下属步骤以后 xff0c 需要考虑分区表 xff0c 将分区表复制到镜像里 xff0c 否则系统无法启动 xff0c 而且还要回利用gparted dev loop0以及fdisk l dev loop0等命令 xff0c 查看分区类
  • 在树莓派上将现有系统复制到新存储卡(转载 )

    在树莓派上将现有系统复制到新存储卡 xff08 转载 xff09 http www eeboard com bbs thread 39663 1 1 html 最初 xff0c 使用树莓派的时候 xff0c 也许也只是为了新鲜 xff0c
  • 【c/c++】单链表、头指针、头结点、首元节点

    链表中第一个结点的存储位置叫做头指针 xff0c 那么整个链表的存取就必须是从头指针开始进行了 之后的每一个结点 xff0c 其实就是上一个的后继指针指向的位置 这里有个地方要注意 xff0c 就是对头指针概念的理解 xff0c 这个很重要
  • VINS-mono学习总结

    Vins mono是一个后端基于非线性优化的 单目与IMU紧耦合的融合定位算法 整体 xff1a 1 预处理模块 视觉 xff1a 特征点提取与追踪 IMU xff1a 惯性解算与误差状态分析 计算预积分量 2 初始化模块 xff08 旋转
  • Fast-lio个人总结

    Lidar第一帧作为基坐标 1 lidar原始数据预处理默认不提取特征 xff0c 对原始数据间隔式 xff08 间隔3个点 xff09 降采样提取 2 imu初始化 惯性解算 误差分析 状态 协方差预测 3 Lidar与imu时间状态对齐
  • 在rviz中使用键盘控制burger

    启动语句 roslaunch turtlebot3 fake turtlebot3 fake launch 启动rviz 话题通信 roslaunch turtlebot3 teleop turtlebot3 teleop key laun