亚博microros小车-原生ubuntu支持系列:1 键盘控制

背景:电脑配置不太行,我在ubuntu再运行vmware,里面运行亚博官方的虚拟机镜像ubuntu,系统很卡。基本上8G内存给打满了。还是想把亚博官方的代码迁移出来,之前售后就说除了官方镜像虚拟机,需要自己摸索迁移。

    先从键盘控制入手吧。这个模块就是发消息,类似于小海龟那个,比小海龟还要简化下,只是命令多一些,相对独立,依赖少,适合上手练习。

一 准备工作

启动代理:

docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4

可以参考之前的文章:亚博microROS 机器人配置与控制-CSDN博客

小车的配置:要与电脑IP保持一致,不是虚拟机的IP

还要关注一点:检查node

bohu@bohu-TM1701:~$ ros2 node list
/YB_Car_Node

 如果没有,请检查确认虚拟机/电脑上.bashrc文件的ROS DOMAIN ID与microROS控制板上配置的一致才可以搜索到节点信息。初次通常需要在.bashrc文件加一行:

export ROS_DOMAIN_ID=20

运行后小车开启电源效果如下:

bohu@bohu-TM1701:~$ docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:humble udp4 --port 8090 -v4
[1737378512.062782] info     | UDPv4AgentLinux.cpp | init                     | running...             | port: 8090
[1737378512.063437] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 4
[1737378512.532474] info     | Root.cpp           | create_client            | create                 | client_key: 0x2BEF9112, session_id: 0x81
[1737378512.532669] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x2BEF9112, address: 192.168.0.107:39455
[1737378512.677740] info     | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x2BEF9112, participant_id: 0x000(1)
[1737378512.690384] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x2BEF9112, topic_id: 0x000(2), participant_id: 0x000(1)
[1737378512.697153] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x2BEF9112, publisher_id: 0x000(3), participant_id: 0x000(1)
[1737378512.705426] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x2BEF9112, datawriter_id: 0x000(5), publisher_id: 0x000(3)
[1737378512.714186] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x2BEF9112, topic_id: 0x001(2), participant_id: 0x000(1)
[1737378512.725294] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x2BEF9112, publisher_id: 0x001(3), participant_id: 0x000(1)
[1737378512.800394] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x2BEF9112, datawriter_id: 0x001(5), publisher_id: 0x001(3)
[1737378512.813041] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x2BEF9112, topic_id: 0x002(2), participant_id: 0x000(1)
[1737378512.822137] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x2BEF9112, publisher_id: 0x002(3), participant_id: 0x000(1)
[1737378512.833437] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x2BEF9112, datawriter_id: 0x002(5), publisher_id: 0x002(3)

这是前提,否则没法控制小车

二 控制代码

在src/yahboomcar_ctrl/yahboomcar_ctrl/目录下新建文件yahboom_keyboard.py,

代码如下:

#!/usr/bin/env python
# encoding: utf-8
#import public lib
from geometry_msgs.msg import Twist # 消息
import sys, select, termios, tty #tty 设置终端模式。sys 系统模块,select  监听输入,termios 保存和恢复

#import ros lib
import rclpy
from rclpy.node import Node

msg = """
Control Your SLAM-Bot!
---------------------------
Moving around:
   u    i    o
   j    k    l
   m    ,    .

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%
t/T : x and y speed switch
s/S : stop keyboard control
space key, k : force stop
anything else : stop smoothly

CTRL-C to quit
"""

moveBindings = {
    'i': (1, 0),
    'o': (1, -1),
    'j': (0, 1),
    'l': (0, -1),
    'u': (1, 1),
    ',': (-1, 0),
    '.': (-1, 1),
    'm': (-1, -1),
    'I': (1, 0),
    'O': (1, -1),
    'J': (0, 1),
    'L': (0, -1),
    'U': (1, 1),
    'M': (-1, -1),
}

speedBindings = {
    'Q': (1.1, 1.1),
    'Z': (.9, .9),
    'W': (1.1, 1),
    'X': (.9, 1),
    'E': (1, 1.1),
    'C': (1, .9),
    'q': (1.1, 1.1),
    'z': (.9, .9),
    'w': (1.1, 1),
    'x': (.9, 1),
    'e': (1, 1.1),
    'c': (1, .9),
}



class Yahboom_Keybord(Node):
	def __init__(self,name):#初始化
		super().__init__(name)
		self.pub = self.create_publisher(Twist,'cmd_vel',1000)
		self.declare_parameter("linear_speed_limit",1.0) #声明参数-线速度
		self.declare_parameter("angular_speed_limit",5.0) #声明参数-角速度
		self.linenar_speed_limit = self.get_parameter("linear_speed_limit").get_parameter_value().double_value
		self.angular_speed_limit = self.get_parameter("angular_speed_limit").get_parameter_value().double_value
		self.settings = termios.tcgetattr(sys.stdin)
	def getKey(self):#读取键盘
		tty.setraw(sys.stdin.fileno())#原始模式,不用回车读取
		rlist, _, _ = select.select([sys.stdin], [], [], 0.1)# 监听输入,超时时间0.1秒
		if rlist: key = sys.stdin.read(1) #读取输入
		else: key = '' #没有输入设置为空串
		termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self.settings) #恢复终端属性
		return key
	def vels(self, speed, turn):#输出速度和朝向
		return "currently:\tspeed %s\tturn %s " % (speed,turn)		
	
def main():
	rclpy.init()
	yahboom_keyboard = Yahboom_Keybord("yahboom_keyboard_ctrl")
	xspeed_switch = True
	(speed, turn) = (0.2, 1.0)
	(x, th) = (0, 0)
	status = 0
	stop = False
	count = 0
	twist = Twist()
	try:
		print(msg)
		print(yahboom_keyboard.vels(speed, turn))
		while (1):
			key = yahboom_keyboard.getKey()
			if key=="t" or key == "T": xspeed_switch = not xspeed_switch
			elif key == "s" or key == "S":
				print ("stop keyboard control: {}".format(not stop))
				stop = not stop
			if key in moveBindings.keys(): #方向控制
				x = moveBindings[key][0]
				th = moveBindings[key][1]
				count = 0	
			elif key in speedBindings.keys(): #加速
				speed = speed * speedBindings[key][0]
				turn = turn * speedBindings[key][1]
				count = 0
				if speed > yahboom_keyboard.linenar_speed_limit: 
					speed = yahboom_keyboard.linenar_speed_limit
					print("Linear speed limit reached!")
				if turn > yahboom_keyboard.angular_speed_limit: 
					turn = yahboom_keyboard.angular_speed_limit
					print("Angular speed limit reached!")
				print(yahboom_keyboard.vels(speed, turn))
				if (status == 14): print(msg)
				status = (status + 1) % 15
			elif key == ' ': (x, th) = (0, 0)
			else:
				count = count + 1
				if count > 4: (x, th) = (0, 0)
				if (key == '\x03'): break
			if xspeed_switch: twist.linear.x = speed * x
			else: twist.linear.y = speed * x
			twist.angular.z = turn * th
			if not stop: yahboom_keyboard.pub.publish(twist) #发话题消息
			if stop:yahboom_keyboard.pub.publish(Twist())
	except Exception as e: print(e)
	finally: yahboom_keyboard.pub.publish(Twist())
	termios.tcsetattr(sys.stdin, termios.TCSADRAIN, yahboom_keyboard.settings) #恢复终端属性
	yahboom_keyboard.destroy_node()
	rclpy.shutdown()

代码我加了注释,从依赖上看,就是依赖了ros2基础的话题消息,剩下就是读取键盘的getKey()。

退出标识:\x03 就是ctrl+C 组合。

处理逻辑就是根据根据键盘输入调用话题发布。

三 测试:

重新构建下,再次运行节点

ros2 run yahboomcar_ctrl yahboom_keyboard

补充下相关信息

rqt看node:

bohu@bohu-TM1701:~$ ros2 node info /YB_Car_Node 
/YB_Car_Node
  Subscribers:
    /beep: std_msgs/msg/UInt16
    /cmd_vel: geometry_msgs/msg/Twist
    /servo_s1: std_msgs/msg/Int32
    /servo_s2: std_msgs/msg/Int32
  Publishers:
    /battery: std_msgs/msg/UInt16
    /imu: sensor_msgs/msg/Imu
    /odom_raw: nav_msgs/msg/Odometry
    /scan: sensor_msgs/msg/LaserScan
  Service Servers:

  Service Clients:

  Action Servers:

  Action Clients:

从节点信息来看,/YB_Car_Node

订阅了话题:包含刚才的cmd_vel,用于接受指令。消息接口:

geometry_msgs/msg/Twist

发布的话题:battery 电池、imu 惯性测量数据,odom:里程计数据、scan:激光雷达的数据。

控制话题具体信息

---
linear:
  x: 0.26620000000000005
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
---

真的很感谢之前小鱼老师那本《ros2机器人开发》那本书,要是没有这本书作为入门指导,直接看亚博的源码会很吃力。这是第一步,期待后面能逐步学习完亚博的完整功能,把小车玩起来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/957462.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

总结5..

#include<stdio.h> struct nb {//结构体列队 int x, y;//x为横坐标&#xff0c;y为纵坐标 int s, f;//s为步数&#xff0c;//f为方向 }link[850100]; int n, m, x, y, p, q, f; int hard 1, tail 1; int a[52][52], b[52][52], book[52][52][91]; int main() { …

鸿蒙系统 将工程HarmonyOS变成OpenHarmony

DevEco Studio软件创建工程后需要修改两个地方&#xff1a; 修改第二个build-profile.json5文件 将原先内容&#xff1a; {"app": {"signingConfigs": [],"products": [{"name": "default","signingConfig": &q…

什么样的问题适合用递归

递归是一种通过函数调用自身来解决问题的方法。递归适用于那些可以被分解为相似子问题的问题&#xff0c;即原问题可以通过解决一个或多个更小规模的同类问题来解决。递归通常需要满足以下两个条件&#xff1a; 递归基&#xff08;Base Case&#xff09;&#xff1a;问题的最简…

C# 网络协议第三方库Protobuf的使用

为什么要使用二进制数据 通常我们写一个简单的网络通讯软件可能使用的最多的是字符串类型&#xff0c;比较简单&#xff0c;例如发送格式为(head)19|Msg:Heart|100,x,y,z…&#xff0c;在接收端会解析收到的socket数据。 这样通常是完全可行的&#xff0c;但是随着数据量变大&…

认识BOM

BOM 弹出层 可视窗口尺寸 屏幕宽高 浏览器内核和其操作系统的版本 剪贴板 是否允许使用cookie 语言 是否在线

国产编辑器EverEdit - 大纲视图

1 大纲视图 1.1 应用场景 在编辑较长代码文件时&#xff0c;使用大纲视图可以方便的检视当前文件的变量、函数等信息&#xff0c;方便在不同函数间跳转&#xff0c;对整个文档的全貌了然于胸。   在编辑XML文档时&#xff0c;通过展示XML文件的层次结构、节点布局&#xff0…

(2)STM32 USB设备开发-USB虚拟串口

例程&#xff1a;STM32USBdevice: 基于STM32的USB设备例子程序 - Gitee.com 本篇为USB虚拟串口教程&#xff0c;没有知识&#xff0c;全是实操&#xff0c;按照步骤就能获得一个STM32的USB虚拟串口。本例子是在野火F103MINI开发板上验证的&#xff0c;如果代码中出现一些外设的…

68,[8] BUUCTF WEB [RoarCTF 2019]Simple Upload(未写完)

<?php // 声明命名空间&#xff0c;遵循 PSR-4 自动加载规范&#xff0c;命名空间为 Home\Controller namespace Home\Controller;// 导入 Think\Controller 类&#xff0c;以便扩展该类 use Think\Controller;// 定义 IndexController 类&#xff0c;继承自 Think\Control…

AutoGen入门——快速实现多角色、多用户、多智能体对话系统

1.前言 如https://github.com/microsoft/autogen所述&#xff0c;autogen是一多智能体的框架&#xff0c;属于微软旗下的产品。 依靠AutoGen我们可以快速构建出一个多智能体应用&#xff0c;以满足我们各种业务场景。 本文将以几个示例场景&#xff0c;使用AutoGen快速构建出…

阿九的python 爬虫进阶课18.3 学习笔记

文章目录 前言1. 爬取大标题2. 爬取小标题3. 证券栏下的标题4. 某篇文章里的具体内容 前言 网课链接&#xff1a;https://www.bilibili.com/video/BV1kV4y1576b/新浪财经网址&#xff1a;https://finance.sina.com.cn/需先下载库&#xff1a; conda install lxml布置爬取的一…

WGCAT工单系统部署教程

第一步、安装JDK WGCAT部署所在主机需要JDK环境&#xff08;JDK1.8、JDK11都可以&#xff09;&#xff0c;OpenJDK也可以&#xff0c;更高版本JDK也支持&#xff0c;一般推荐使用JDK1.8或JDK11 参考&#xff1a;linux CentOS系统安装jdk教程_centos安装jdk-CSDN博客 第二步、…

自动化01

测试用例的万能公式&#xff1a;功能测试界面测试性能测试易用性测试安全性测试兼容性测试 自动化的主要目的就是用来进行回归测试 新产品--第一个版本 (具备丰富的功能)&#xff0c;将产品的整体进行测试&#xff0c;人工创造一个自动化测试用例&#xff0c;在n个版本的时候…

Mysql触发器(学习自用)

一、介绍 二、触发器语法 注意&#xff1a;拿取新的数据时用new&#xff0c;旧数据用old。

python-leetcode-简化路径

71. 简化路径 - 力扣&#xff08;LeetCode&#xff09; class Solution:def simplifyPath(self, path: str) -> str:# 使用栈来处理路径stack []# 分割路径&#xff0c;以 / 为分隔符parts path.split(/)for part in parts:if part or part .:# 空字符串或 .&#xff0…

STMCubeMX配置STM32F103ZET6

1 配置时钟 配置RCC。 配置 SYS。将Timebase Source配置为TIM1, SysTick留给FreeRTOS用。 注意: 由于第一次配置的时候忘记配置这个步骤,导致工程第一次烧录成功后,后面一直无法烧录,报以下错误: keil no target connect Error: Flash Download failed - Target DLL h…

Yearning开源MySQL SQL审核平台

一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用. 本地部署&#xff0c;注重隐私&#xff0c;简单高效的MYSQL审计平台。 它可以通过流程审批&#xff0c;实现真实线上环境sql的审核和执行&#xff0c;还可以回滚执行&#xff0c;能够确保线上SQL更新的可靠性…

【TCP】rfc文档

tcp协议相关rfc有哪些 TCP&#xff08;传输控制协议&#xff09;是一个复杂的协议&#xff0c;其设计和实现涉及多个RFC文档。以下是一些与TCP协议密切相关的RFC文档列表&#xff0c;按照时间顺序排列&#xff0c;涵盖了从基础定义到高级特性和优化的各个方面&#xff1a; 基…

python进程池、线程池

Python广为使用的并发处理库futures使用入门与内部原理_concurrent.futures-CSDN博客 ThreadPoolExecutor(max_workers1) 池中至多创建max_workers个线程的池来同时异步执行&#xff0c;返回Executor实例、支持上下文&#xff0c;进入时返回自己&#xff0c;退出时调用 submit(…

人工智能之深度学习_[5]-神经网络优化学习率衰减优化正则化方法

文章目录 神经网络入门二3 神经网络优化方法3.1 梯度下降算法回顾3.2 反向传播&#xff08;BP算法&#xff09;3.2.1 反向传播概念3.2.2 反向传播详解 3.3 梯度下降优化方法3.3.1 指数加权平均3.3.2 动量算法Momentum3.3.3 AdaGrad3.3.4 RMSProp3.3.5 Adam3.3.6 小结 4 学习率衰…

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置 1.Prometheus部署1.2.Prometheus修改默认端口 2.grafana可视化页面部署3.alertmanager部署4.监控配置4.1.主机监控node-exporter4.2.监控mysql数据库mysqld_exporter4.3.监控mongod数据库mongodb_expo…