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

最近在一个公司实习,公司需要我用ROS搭建一个机器车地盘,因此我开始学习关于ROS方面的东西。通常传统的方法大家搭建机器车地盘的时候会想到用一个stm32开发板作为中间层次,对上层上位机通过ros-stm32串口的方式通讯,对下层电机驱动器通过pwm的模拟电压来控制电机。但是公司给我的驱动器的通讯方式不仅仅是模拟量的输出,还可以通过can或者串口的形式来控制驱动器。

我之前的学习基本是在上位机上进行开发,因此不是很熟悉stm32,在捣鼓一两天后我便有点放弃stm32通过pwm控制电机。电机的厂家虽然提供了can通讯的stm32工程文件。但是我测试很久后还是无法驱动电机。因此我产生了一个新的想法。为什么我们有一个这么智能的驱动器,却还需要和传统有刷电机那样用pwm的形式来控制电机呢?白白浪费驱动器的性能。因此我想到了一个新方法:

我能否能通过Python,通过调用串口或者can通讯的形式来驱动电机。于是我查了一下可行性。串口可以很方便的通过pyserial模块来通讯,而can通讯的资料就十分少了。因此我选择用串口来完成这个项目。

相对于传统的电机控制结构,上位机直接控制有以下几个优点:

  1. 通过直接驱动的方式,大大降低了stm32的开发工作量。减少学习成本和开发时间成本
  2. 如果后期要新加入电机时,只需要增加串口就可以直接控制电机,而不用修改底层代码

通过与公司其他做嵌入式开发的交流,我意识到我的这种方案可能会有以下几点问题:

  1. 串口通讯的稳定性不是很好,因此要是有电磁辐射会造成丢包问题。但是我认为传统的上位机与stm32也是以串口的形式通讯,也是存在同样问题
  2. 如果上位机死机后,传统的形式stm32可以关闭电机,而新方案无法实现这个功能。针对这个问题,驱动器需要上位机不停的查询驱动器当前状态,否则会锁死电机
  3. 传统的方案可以做二次pid,新方案只能使用驱动器的pid,因此控制精度没有太高。

在阅读本教程之前,我先交代一下我开发环境以及需要提前掌握的内容:

    1. 本项目使用的电机为中菱机器人轮毂电机,控制器为中菱ZLAC706。如果你有自己的带串口的电机驱动器,可以参考本教程。
    2. 本项目首先是在windows系统下用anaconda进行测试,然后使用pycharm进行开发。最后移植到ubuntu 16.04下的ROS Kinetic。
    3. 懂Python语言以及编程能力(建议学习廖雪峰的Python,会运用到多线程等比较难的功能)
    4. 知道ROS(Kinetic)系统的基本工作原理
    5.  

 

 

  • 16
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要连接串口设备,需要使用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 ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值