十一放假不停歇—学习ROS第三天

1.继承

第一步:

我们如果定义的类比较多,这里就会运用到子类继承父类的编程语言了,

我们首先在包(demo_python_pkg)下面创建一个新的文件命名为write_node这个节点,开始写里面的程序,我们发现确实比较简略,

from demo_python_pkg.person_node import PersonNode #从包的节点文件中导入这个文件的类函数
class WriteNode(PersonNode):     #新定义一个类,括号是父类,引用他里面所有的东西,省去很多步骤
    def __init__(self,book:str) -> None:  #类初始化,定义一些参数
        self.book=book                   #把属性值赋予它
        
    def eat( self,food_name:str):     #定义一个类方法
        print(f"{self.name},{self.age}岁,爱吃{food_name}")
def main():                           #定义一个函数
    node = WriteNode('王五')     #引用类里面的属性赋予一个实例
    node.eat('大蜂蜜')               # 引用类里面的方法赋予一个实例

这是程序代码以及我个人理解的标注

第二步:

写完这个程序,到setup中,把节点Node写入里面

第三步: colcon build下

运行结果如下图所示:

我们发现说找不到这个包,那么我们可以source一下,就可以了,

得添加环境变量。

所以运行结果如下  source install/setup.bash

对于父类来讲其实这是没有问题的,但是子类就会有问腿,让我们一次来解决这个问题。

按住Ctrl+这个文件直接就会跳转

在里面添加父类的属性,然后super.__init__(里面的属性)。就可以完成初始化。

 

是super().__init__(里面的属性)

总结一下在这个‘包里面→新建文件节点名字→在里面写程序→setup→节点名=包.节点:函数’,

→在终端里colcon build下→ros2 run 包名 节点名就可以实现你想要的功能了

子类里面要记住 初始化那里和super那里原来的属性

成功了,感觉是有个优先级之分的,所以把上面的那个删了剩图片中的就可以运行了 。

这个图片很关键,包括步骤,包括定义节点

这里再说下 继承的这段代码,super()这里的话,初始化的属性是父类的属性,即里面括号的属性

然后再def __init__(),括号里面也要写上父类的属性,子类的话再最后写上你的子类属性

要在src下弄!!

如何把这个person和write变成这个ros中的节点。

让你的类继承Node这个类

运行出错,错在哪里呢?看

就是节点这里要记住只能是(a-z),(A-Z)以及(0-9)。

修改后运行一遍

还有错误?

继续修改

好了,实现了!,加油同学们,

这里赋上一句这里的话,学习是可控的,我们要多做一些可控的事情,想要走万里路,走得更远,必须下一些苦功夫,必须在吃的苦头比别人多,这也是很多创业者的必备因素,人生中有很多需要学习的地方,人的出生是一无所知的,学习是为了填充智慧,限制你内心的狂妄感,任何事情都需要去学习要保持强烈的好奇心,持续自律的学习力,趁年轻给自己一片方土,踏踏实实一直学习,学到老,才能活到老!

好了,在这里我们ctrl+5看一下ROS2节点都有哪些?

看到了

import rclpy
from rclpy.node import Node

    def __init__(self,node_name:str,name:str,age:int) -> None:  #定义的属性
        super().__init__(node_name)

self.get_logger().info(f"{self.name},{self.age}岁,爱吃{food_name}")
def main():
    rclpy.init()

    rclpy.spin(node)
    rclpy.shutdown()

一共是添加了这些东西。

好的,那么这个父类成功了,子类变成节点应该怎么做呢?我们大概一想其实和父类基本一样,但你看到了我这个出现错误了,马虎了,告诉你,但你知道马虎在哪里吗?

修改之后程序与运行结果!成功

节点名字为readbook

2. 多线程与回调函数

import threading      导入多线程数据库
import requests     导入用于发送HTTP请求
class Download:   定义这个类 
    def download(self,url,callback_world_count):    参数有url callback_world_count
        print(f"线程:{threading.get_ident()} 开始下载:{url}")    
        response = requests.get(url)        获得请求
        response.encoding='utf-8'      文本编码
        callback_world_count(url,response.text)  
    def start_download(self,url,callback_world_count):
        thread = threading.Thread(target=self.download,args=(url,callback_world_count))
        thread.start()

def world_count(url,result):
    print(f"{url}:{len(result)}->{result[:5]}")
def main():
    download = Download()
    download.start_download('http://0.0.0.0:8000/novel1.txt',world_count)
    download.start_download('http://0.0.0.0:8000/novel2.txt',world_count)
    download.start_download('http://0.0.0.0:8000/novel3.txt',world_count)

以下是这段代码的下详细解释:
import threading
import requests

- `threading`:这是Python的标准库模块,用于提供线程相关的操作。
- `requests`:这是一个非常流行的第三方库,用于发送HTTP请求。它允许你轻松地发送HTTP/1.1请求而无需手动添加查询字符串或编码。

def download(self, url, callback_world_count):
    print(f"线程:{threading.get_ident()} 开始下载:{url}")
    response = requests.get(url)
    response.encoding = 'utf-8'
    callback_world_count(url, response.text)

- `download`方法接受三个参数:`url`是要下载的网页地址,`callback_world_count`是一个回调函数,用于处理下载后的数据。
threading.get_ident()`返回当前线程的唯一标识符。
 requests.get(url)`发送一个HTTP GET请求到指定的URL。
- `response.encoding = 'utf-8'`设置响应内容的编码为UTF-8,以确保正确地处理文本。
- `callback_world_count(url, response.text)`调用回调函数,并将URL和响应的文本内容作为参数传递。


def start_download(self, url, callback_world_count):
    thread = threading.Thread(target=self.download, args=(url, callback_world_count))
    thread.start()
```

`start_download`方法接受两个参数:`url`和`callback_world_count`。
`threading.Thread`创建了一个新的线程对象。`target=self.download`指定新线程将执行`Download`类的`download`方法。`args=(url, callback_world_count)`是一个元组,包含了传递给`download`方法的参数。
`thread.start()`启动新创建的线程。

### 定义`world_count`函数
def world_count(url, result):
    print(f"{url} 字符数:{len(result)} -> 开头内容:{result[:5]}")

- `world_count`是一个回调函数,它接受两个参数:`url`和`result`。
- `len(result)`计算结果字符串的长度。
- `result[:5]`获取结果字符串的前5个字符。
- 函数打印出URL、结果字符串的长度和结果字符串的前5个字符。


def main():
    download = Download()
    download.start_download('', world_count)
    download.start_download('', world_count)
    download.start_download('', world_count)
```

- `main`函数是程序的入口点。
- 创建`Download`类的实例。
- 调用`start_download`方法三次,每次都会创建一个新的线程来下载数据,并在下载完成后调用`world_count`函数。


if __name__ == '__main__':
    main()

### 注意事项

以上就是这段代码的详细解释。

自建库,生成网站

3.1 话题通信介绍

这里以运行小海龟的示例做解释

查看列表都有哪些 ros2 node list 

查看这个节点的信息: ros2 node info +节点名  例如ros2 node info /turtlesim 

这里的 turtle1/cmd_vel: (订阅话题的名字)geometry_msgs/msg/Twist (订阅话题的类型)

发布的话题名字和类型  使用ros2 topic --help 查看话题信息先查看都有哪些

那就使用ros2 topic echo +话题名字


把那个:去掉

这里对于话题的信息进行分析,x与y是指xy的坐标值

theta:脑袋朝向的弧度不是角度哦,最大值到Πpai,linear_velocity是指线速度,angular_velocity是指角速度。直线和旋转的角速度。逆时针大于0,顺时针小于0

查看这个话题的基本信息,查看话题哦的接口(是什么类型的),几个发布者,几个订阅者。

ros2 interface show  geometry_msgs/msg/Twist
查看这个接口的定义,发现由linear和angular组成的

ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1,y: 0.3},angular: {z: 0.1}}"
意思是ros2 话题 发布 话题名称 话题接口 “{数据信息}”

注意:只要是有等级的就用{},然后冒号后面注意空格 

那么就会自动动起来,就像我们之前用的键盘命令差不多。

ros2 run turtlesim turtle_teleop_key

后退加个负号 改变发布者的频率 可以用这个命令 ros2 topic pub --help

默认是1.

明天早点来,中午还是睡吧 然后把效率提高下,很多东西还没学完,但慢慢来,效率要高

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值