ROS学习——通过键盘控制机器人运动

ROS学习

通过键盘实现机器人的运动

C++ 代码

    1. 在软件包中创建节点
      代码及其解析如下
    #include <ros/ros.h>
    #include <geometry_msgs/Twist.h>
    #include <termios.h>
    #include <iostream>
    
    using namespace std;
    
    // 设定键位映射 (线速度, 角速度)
    map<char, pair<double, double>> key_mapping = 
    {
        {'w', {1.0, 0.0}},  // 前进
        {'s', {-1.0, 0.0}}, // 后退
        {'a', {0.0, 1.0}},  // 左转
        {'d', {0.0, -1.0}}, // 右转
        {'q', {0.0, 0.0}}   // 停止
    };
    
    void setTerminalMode()
    {
        struct termios new_settings;
        tcgetattr(0, &new_settings);
        new_settings.c_lflag &= ~ICANON; // 规定按键输入后不需要回车立即生效
        new_settings.c_lflag &= ~ECHO;   // 规定输入不显示在终端上
        new_settings.c_cc[VMIN] = 1;     // 规定按键必须输入一个字符 
        new_settings.c_cc[VTIME] = 0;    // 规定输入进行不等待,即立即响应
        tcsetattr(0, TCSANOW, &new_settings); // 进行设置
    }
    
    char getKey()
    {
        char c;
        if (read(0, &c, 1) < 0) return '\0';
        return c;
    }
    
    int main(int argc, char **argv)
    {
        ros::init(argc, argv, "keyboard_control"); // 初始化节点
        ros::NodeHandle nh;
        ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("/cmd_vel", 10); // 规定话题参数
        ros::Rate rate(10); // 控制发布话题频率
    
        setTerminalMode();
        cout << "控制小车移动:\n---------------------------\n   w    \n a  q  d\n   s    \n\nw/s: 前进/后退\na/d: 左转/右转\nq: 停止\nCTRL+C 退出\n";
        geometry_msgs::Twist twist;
        while (ros::ok()) 
        {
            char key = getKey();
            if (key_mapping.count(key) && key != 'q') //判断
            {
                twist.linear.x += key_mapping[key].first * 0.5;
                twist.angular.z += key_mapping[key].second * 0.5;
                pub.publish(twist);
            }
            if (key == 'q') 
            {
                twist.linear.x = 0;
                twist.angular.z = 0;
                pub.publish(twist);
            }
            rate.sleep(); // 设置频率
        }
        
        geometry_msgs::Twist empty_twist; 
        pub.publish(empty_twist); // 发布一个空话题,使小车停止移动
        return 0;
    }
    
    1. 在该节点的软件包中的CMakelist.txt文件添加节点声明如下
    add_executable(keyboard_control src/keyboard_control.cpp)
    target_link_libraries(keyboard_control
    ${catkin_LIBRARIES}
    )
    add_dependencies(keyboard_control ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
    
    1. catkin_make编译工作空间

Python 代码

  • 软件包中新建节点,编写代码
    #!/usr/bin/env python3
    #coding = utf-8
    import rospy
    import sys
    import termios
    import tty
    from geometry_msgs.msg import Twist
    
    # 设定键位映射 (线速度, 角速度)
    key_mapping = {
        'w': (0.1, 0.0),  # 前进
        's': (-0.1, 0.0),  # 后退
        'a': (0.0, 0.1),   # 左转
        'd': (0.0, -0.1),  # 右转
        'q': (0.0, 0.0)    # 停止
    }
    
    """ 获取键盘输入 """
    def get_key():
        fd = sys.stdin.fileno() 
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())  # 设置终端不回显和缓冲输入
            key = sys.stdin.read(1)  # 读取一个字符
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)  # 还原终端设置
        return key
    
    def main():
        rospy.init_node("keyboard_control")  # 初始化 ROS 节点
        pub = rospy.Publisher("/cmd_vel", Twist, queue_size=10)  # 发布 /cmd_vel 话题
        rate = rospy.Rate(10)  # 设置发布话题频率
    
        twist = Twist()
        print("控制小车移动:\n---------------------------\n   w    \n a  q  d\n   s    \n\nw/s: 前进/后退\na/d: 左转/右转\nq: 停止\nCTRL+C 退出\n")
    
        while not rospy.is_shutdown():
            key = get_key()
            if key in key_mapping:
                twist.linear.x += key_mapping[key][0] 
                twist.angular.z += key_mapping[key][1]
    
            if key == 'q':  # 按 'q' 停止
                twist.linear.x = 0
                twist.angular.z = 0
            
            pub.publish(twist)
            rate.sleep()
    
        empty_twist = Twist()
        pub.publish(empty_twist)
    
    if __name__ == "__main__":
        main()
    
    1. 打开文件路径下的终端,通过chmod +x keyboard_control给予节点可执行权限

通过仿真环境观察代码现象

  • 确保已经下载wpr_simulation软件包,没下载的可以看我的上一篇文章
    1. 打开终端执行roslaunch wpr_simulation wpb_simple.launch
    1. 打开一个新的终端执行rosrun vel_pkg keyboard_control节点

代码现象如下

键盘控制机器人运动

### Gazebo 中控制小车移动 在 Gazebo 仿真环境中,可以通过多种方式来控制小车的移动。一种常见的方式是利用 ROS (Robot Operating System) 和其配套工具包来进行操作。 #### 使用 `teleop_twist_keyboard` 控制小车 为了方便测试和开发,在命令行下有一个名为 `teleop_twist_keyboard` 的节点可以帮助用户通过键盘输入指令给机器人发送速度命令[^2]。这通常适用于差动驱动的小车型号。具体步骤如下: 1. 启动 Gazebo 并加载带有机器人的世界文件: ```bash roslaunch gazebo_ros house_2_with_robot.launch ``` 2. 打开新的终端窗口并运行 teleop 工具: ```bash rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/robot/cmd_vel ``` 3. 此时可以根据屏幕提示按相应键位使能前进、后退、左转或右转等功能。 对于某些特定情况下遇到的问题比如小车不响应控制信号的情况,可能是由于所使用的 world 文件存在问题或是模型本身配置不当所致[^3]。建议尝试更换不同的 world 文件或者检查 SDF/URDF 定义是否正确设置了关节控制器参数等信息。 另外值得注意的是,如果希望实现更复杂的路径规划或者是自动避障功能,则可能还需要引入其他算法库如 move_base 或者自定义行为逻辑。 ```python import rospy from geometry_msgs.msg import Twist def publish_velocity(): pub = rospy.Publisher('/robot/cmd_vel', Twist, queue_size=10) rospy.init_node('velocity_publisher') rate = rospy.Rate(10) while not rospy.is_shutdown(): twist_msg = Twist() # 设置线性和角速度值 twist_msg.linear.x = 0.5 # 前进速度 m/s twist_msg.angular.z = 0.2 # 转弯角度 rad/s pub.publish(twist_msg) rate.sleep() if __name__ == '__main__': try: publish_velocity() except rospy.ROSInterruptException: pass ``` 此 Python 程序展示了如何向 `/robot/cmd_vel` 主题发布消息以改变小车的速度方向;实际应用中可根据需求调整这些数值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值