又是哭瞎的调试过程,不是码农,不做很深入地追究,只想实现想要的效果,随便记录下。期待有更好的想法。

设计目标:方便小车调试,能用键盘控制小车急停与移动。

  刚开始是为了调试的时候防止小车出现不可控制的意外要能通过键盘急停,想用Ctrl+c退出的时候小车可以停下,于是添加了signal函数,在节点退出的时候发布速度为0的信息给base_controller,但是发现有时候可以有时候又不可以。由于通过.launch文件启动的节点,在Ctrl+c退出的时候各节点退出时间不固定,这时候发布速度话题很不稳定,这个方法不可取。

  以前在MFC中也用过键盘控制很简单,直接检测键盘事件即可。在ROS下也有键盘控制移动机器人的源码,但是由于自己设计的控制部分是不断地发布速度话题的,如果采用控制一个节点键盘控制一个节点,发布的速度话题就很混乱,小车应该停不下来。暂时没有很深入地考虑一定采用这种方式的解决方案。由于本来的键盘控制源码里面是采用了线程的方式,所以考虑直接在控制程序中开一个专门用来处理键盘事件的线程。

  大部分直接copy源码就可以了,线程部分需要小改一下。键盘控制源码中是:

SmartCarKeyboardTeleopNode tbk;
boost::thread t = boost::thread(boost::bind(&SmartCarKeyboardTeleopNode::keyboardLoop,&tbk));
ros::spin();
t.interrupt();
t.join();
tcsetattr(kfd, TCSANOW, &cooked);
return(0);

我的控制部分是:

int main(int argc, char** argv)
{ros::init(argc, argv, "tracking");ros::NodeHandle n_;ros::Subscriber odom_sub_ = n_.subscribe("odom", 10, odom_message);cmdvel_pub_ = n_.advertise<geometry_msgs::Twist>("cmd_vel", 10);......while(ros::ok()){......ros::spinOnce();loop_rate.sleep();}return 0;
}

将键盘控制加入主控制中:

#include <ros/ros.h>
#include <nav_msgs/Odometry.h>
#include <boost/thread.hpp>
#include <csignal>
#include <termios.h>boost::thread t;
int kfd=0;
struct termios cooked, raw;
void signalHandler(int signum)
{tcsetattr(kfd, TCSANOW, &cooked);...
}
void callbackThread()
{...(键盘的监听与发布控制命令)
}
int main(int argc, char** argv)
{ros::init(argc, argv, "tracking");ros::NodeHandle n_;ros::Subscriber odom_sub_ = n_.subscribe("odom", 10, odom_message);cmdvel_pub_ = n_.advertise<geometry_msgs::Twist>("cmd_vel", 10);...t = boost::thread(callbackThread);signal(SIGINT, signalHandler);while(ros::ok()){......ros::spinOnce();loop_rate.sleep();}(t.interrupt();)(t.join();)return 0;
}

  下面介绍一下我的想法与试验结果:

//线程中断
t.interrupt();
//用来指定当前主线程等待其他线程执行完毕后,再来继续执行t.join()后面的代码
t.join();

  看了wiki介绍的自定义消息队列 + 处理线程部分就是直接把这个放在while循环外的,也可以看看这个博客写的,很全了http://blog.chinaunix.net/uid-27875-id-5817906.html。从实质功能上,我的while循环里是主要控制算法部分,所以不可能让主线程阻塞等待子线程,所以也只能把这两句放到循环外。但其实放到while循环外也不可能会执行到,没有什么意义,所以我是直接把这两句删了。
  线程可以正常工作,能实现键盘控制,原来的回调函数也没有受到影响。但是!但是!但是!

//在程序结束时在恢复原来的配置
tcsetattr(kfd, TCSANOW, &cooked);

这句没有放到正常的位置,导致一直出现很奇怪的现象。Ctrl+C结束程序后,终端不显示键盘打的字符了,但其实盲打再按回车是执行程序的。刚开始怀疑是不是没有退出线程,还是主线程没有退出只是被挂起了。。。(走了很多弯路,因为一开始程序还不是上面的这个版本,根本不知道线程的部分应该怎么插入,搜了很多博客也没找到啊,心累。)后面通过查看进程和线程,确定是都退出了的。然后怀疑是键盘控制没有释放,再一步步调键盘里面的源码,最终确定上面这一句是关键。(以前看过代码解释的,都怪我忘了。)由于要在关闭节点之前才能恢复键盘原来的配置,不能放在while循环外也不能放在循环内,循环外不起作用,循环内则线程失效,所以添加signal函数,在退出节点之前恢复键盘控制。经过测试,一切OK。

控制程序中加入键盘控制相关推荐

  1. TIANBOT MINI机器人在gazebo中使用键盘控制运动

    在上一节,我们配置好了xacro文件,那么这一节我们实现小车在gazebo环境中通过键盘控制节点动起来,并且使用rviz可视化工具. 01 配置各个文件 第一步首先是要修改描述文件,修改的目的是增加c ...

  2. mfc键盘控制移动鼠标光标_如何在Windows中使用键盘控制鼠标光标

    mfc键盘控制移动鼠标光标 If you're stuck without a mouse temporarily, don't worry-you can still use your PC. Yo ...

  3. JavaScript或jQuery中使用键盘控制对象运动

    <div id="monkey"><img src="img/monkey.png" ></div> 在JavaScript ...

  4. UE4(unreal Engine)中使用蓝图类Actor创建开关门,并使用鼠标和键盘控制开关门

    UE4系列文章目录 文章目录 UE4系列文章目录 前言 一.具体步骤 (一)自动开关门 (二)使用键盘开关门 (三)使用鼠标开关门 总结 前言 上一节中我们讨论了用蓝图来控制开关门,虽然可以实现效果, ...

  5. 51单片机按键扫描程序汇编程序(独立按键与矩阵按键)(使用定时器)(可移植的汇编程序)矩阵键盘控制两个led数码管(汇编语言)与UART通信总结(上)

    一,按键控制数码管 1四按键控制程序(汇编) (您的关注点赞是作者创作的最大动力哦) //******************************************************* ...

  6. EAI Dashgo D1环境搭建/键盘控制/rplidar a1 a2建图导航详细教程

    昨天同学让我帮他看一下EAI Dashgo D1怎么用,因为好像按官方教程还是有一些问题,甚至连键盘控制都不能,查看了一下官方说明,再安装发现的确有一些地方需要注意,尤其对于小白来说这个教程还是有点不 ...

  7. 键盘控制事件应用教程大全

    获取键盘控制事件是实现交互性最有力的方法之一.          首先需要了解的是如何初始化该事件,基本语句如下:          document.onkeydown = keyDown      ...

  8. ROS探索总结(七)(八)(九)——smartcar源码上传 键盘控制 操作杆控制

    ROS探索总结(七)--smartcar源码上传 看到前面写的博客还是帮助了很多ROS的学习者,我感到非常荣幸.其实我也是一名ROS的新手,ROS的相关资料少,上手难度大,我现在也在摸索着学习,还希望 ...

  9. [转]基于ROS平台的移动机器人-4-通过ROS利用键盘控制小车移动

    原文出处: https://blog.csdn.net/Forrest_Z/article/details/55002484 准备工作 1.下载串口通信的ROS包 (1)cd ~/catkin_ws/ ...

最新文章

  1. 搞定一个C++项目最快需要多久?
  2. C Primer Plus 第6章 C控制语句:循环 6.3 关系运算符和表达式
  3. 【C++ 语言】面向对象 ( 模板编程 | 函数模板 | 类模板 )
  4. nginx、apach、php、mysql编译参数
  5. [深度学习] 自然语言处理 --- Huggingface-Pytorch中文语言Bert模型预训练
  6. 剑指Offer - 面试题33. 二叉搜索树的后序遍历序列(递归)
  7. iis 日志 post数据_云原生日志的趋势(1):logscape和logiq
  8. Duplicated Numbers (10分)
  9. [转载] Numpy_索引操作
  10. 软中断和tasklet
  11. 运动会管理系统的需求调研会纪要
  12. 微软.NET设计上的一个错误(从.NET1.1--4.0),不知道以后.NET会不会修复这个错误...
  13. 油猴/暴力猴工具换cook脚本
  14. 不懂PS怎么修改图片尺寸?
  15. 注册表Windows桌面设置
  16. 云原生Docker搭建为知笔记
  17. Debezium的基本使用(以MySQL为例)
  18. 女神异闻录5(p5)系统拆解
  19. GITLAB email不发送腾讯企业邮箱解决方案
  20. RGB值和RGBA值

热门文章

  1. 【excel小技巧】对多个sheet页的相同列进行计数
  2. 计算机图形学——实验一 VS+OpenGL绘图环境及基本图形绘制
  3. python夺命系列-列表
  4. 解决Outlook新建 回复和转发邮件时字体变大的问题
  5. 找不到Windows SDK版本 10.0.18362.0.请安装所需版本的 Windows SDK,或者在项目属性页中或通过右键单击解决
  6. vim复制粘贴常用命令
  7. Agisoft Metashape 空三导入inpho(带连接点和控制点)
  8. 32个动作教你看懂微表情读心术
  9. chatGPT接入微信攻略
  10. 适配android P