使用python,通过串口ROS直接控制电机驱动器(4)

继续上节的工程,我给电机做了一个简单的建模后,就需要具体实现每一个功能了。

首先我们要在脑海里建立好一个模型,我们一方面向串口输入数据,一方面还要从串口里接收数据。在刚开始的时候,我定义了很多个函数,在发送完数据后立马就接收驱动器回复的数据,在后期想用多线程的时候很容易产生错误,导致驱动器不知道我发送的是什么指令需要使用线程锁来编写,又导致程序非常的复杂。在参考网上的的串口多线程编程的过程中,我转变了思想,为什么不定义一个线程向驱动器写数据,另一个线程接收驱动器数据并解析数据呢?这样很大的提高了程序的性能。

#!/usr/bin/env python

import serial
import time
import threading

motor_speed_mode = b'\x02\x00\xC4\xC6'
motor_status = b'\x80\x00\x80'
motor_start = b'\x00\x00\x01\x01'


class SpeedMotor:
    def __init__(self, device, acc, dcc):
        # 真实速度
        self.rel_speed = 0
        # 设置的速度
        self.set_speed = 0
        # 运行状态
        self.run = False
        # 故障状态
        self.fault = None
        # 电机电压
        self.voltage = 0
        # 电机电流
        self.current = 0
        # 设置串口通讯
        self.serial = serial.Serial(device, 57600)
        self.serial.timeout = 0
        # 开启读数据线程
        threads = []
        t1 = threading.Thread(target=self.read_motor)
        threads.append(t1)
        for t in threads:
            t.start()

通过初始函数的过程,定义一个读线程。

下面是读取线程的代码:

    def read_motor(self):
        while True:
            n = self.serial.inWaiting()  # 等待数据的到来,并得到数据的长度
            if n:   # 如果有数据
                n = self.serial.read(n)  # 读取n位数据
                s = [hex(x) for x in bytes(n)]
                for i in range(len(s)):
                    s[i] = int(s[i], 16)
                print(s)

通过不断的循环,从而不断的接收驱动器的数据。

要连接串口设备,需要使用Python的PySerial库。可以使用以下代码来连接富斯PL18: ```python import serial ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1) ``` 其中,`/dev/ttyUSB0`是串口设备的路径,`9600`是波特率,`timeout=1`是读取数据时的超时时间。 接下来,可以使用ROS2的Python API来发布遥控器数据。假设要发布的消息类型为`RemoteControl`,可以使用以下代码: ```python import rclpy from rclpy.node import Node from std_msgs.msg import String from your_package.msg import RemoteControl class RemoteControlPublisher(Node): def __init__(self): super().__init__('remote_control_publisher') self.publisher_ = self.create_publisher(RemoteControl, 'remote_control', 10) timer_period = 0.1 # seconds self.timer = self.create_timer(timer_period, self.publish_data) def publish_data(self): # Read data from serial port data = ser.readline().decode().strip().split(',') # Create message msg = RemoteControl() msg.steering = float(data[0]) msg.throttle = float(data[1]) msg.brake = float(data[2]) # Publish message self.publisher_.publish(msg) def main(args=None): rclpy.init(args=args) remote_control_publisher = RemoteControlPublisher() rclpy.spin(remote_control_publisher) remote_control_publisher.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` 在上面的代码中,`RemoteControlPublisher`类继承自`Node`类,并在初始化函数中创建了一个Publisher,用于发布遥控器数据。`publish_data`函数会在定时器周期内被调用,从串口读取数据并将其转换为消息类型,并将其发布到`remote_control`话题上。 最后,需要将上述代码保存为一个Python文件,并在终端中运行该文件,以启动遥控器数据发布节点。 ```bash $ python3 remote_control_publisher.py ```
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值