键盘控制ROS车运动

键盘控制ROS车运动

上位机

使用pyseria库与stm32单片机进行通信控制

#!/usr/bin/env python
# -*- coding: utf-8 -*


import sys, select, termios, tty
import serial

msg = """
---------------------------
        w     
   a    x    d
        s     

w : +x    a : +y
s : -x    d : -y 
x : stop

其他按键 : stop


q/z : 线性速度增加/减少1RPM
e/c : 只增加/减少角速度1RPM

CTRL-C 退出
---------------------------
"""

moveBindings = {
'w':'w',
's':'s',
'a':'a',
'd':'d',
'x':'x',
'q':'q',
'z':'z',
'e':'e',
'c':'c'
      }



def getKey():
    tty.setraw(sys.stdin.fileno())
    select.select([sys.stdin], [], [], 0)
    key = sys.stdin.read(1)
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    return key



if __name__=="__main__":
    settings = termios.tcgetattr(sys.stdin)
    port = '/dev/ttyUSB1'  # 串口号
    baud = 115200  # 波特率
    ser = serial.Serial(port, baud, timeout=0.5)
    flag = ser.isOpen()
    try:
        print(msg)
        print(port, "串口打开成功")
        if flag:
            while(1):
                key = getKey()
                if key in moveBindings.keys():
                    data = moveBindings[key]
                    ser.write(data.encode("gbk"))
                    # print('串口发送数据:  ', data)
                else:
                    if (key == '\x03'):
                        break
                
    except Exception as e:
        print(e)
        print("串口打开异常")

下位机

下位机采用USART1进行通信,轮毂电机的控制参考上篇文章STM32HAL库RS485-ModBus协议控制伺服电机

uint16_t data[2] = {0, 0};
uint16_t data1[2] = {-16, 16};
uint16_t data2[2] = {6, 6};
uint16_t data3[2] = {0, 0};
uint8_t RxData;

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint16_t speed_flag, turn_flag;
  uint16_t speed = 10;
  uint16_t turn = 10;
  speed_flag = turn_flag = 1;
  /* USER CODE END 1 */

  //....初始化省略.....
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1, &RxData,1);
  //RS485发送模式
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET);
  //电机初始化指令
  MBRTUMasterWriteSingleRegister(&MBRTUHandle, 1, 0X200D, 0x0003, 100);
  HAL_Delay(10);
  MBRTUMasterWriteSingleRegister(&MBRTUHandle, 1, 0X200E, 0x0008, 100);
  HAL_Delay(10);
  MBRTUMasterWriteSingleRegister(&MBRTUHandle, 1, 0X200E, 0x0010, 100);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET);
        if(RxData == 'w'||RxData == 's'||RxData == 'a'||RxData == 'd'||RxData == 'x'||RxData == 'e'||RxData == 'c'||RxData == 'q'||RxData == 'z')
        {
            if(RxData == 'w' || RxData == 's'||RxData == 'q'||RxData == 'z')
            {
                if(RxData == 'w') speed_flag = 1;
                if(RxData == 's') speed_flag = -1;
                if(RxData == 'q') speed+=10;
                if(RxData == 'z') speed-=10;
                data[0] = speed_flag * speed;
                data[1] = -speed_flag * speed;
            }
            if(RxData == 'a'||RxData == 'd'||RxData == 'e'||RxData == 'c')
            {
                if (RxData == 'a') turn_flag = 1;
                if (RxData == 'd') turn_flag = -1;
                if(RxData == 'e') turn+=10;
                if(RxData == 'c') turn-=10;
                data[0] = turn_flag * turn;
                data[1] = turn_flag * turn;
            }
            if(RxData == 'x')
            {
                data[0] = 0;
                data[1] = 0;
            }
            //0x10指令便于给多寄存器发送指令,电机同时启动
            MBRTUMasterWriteMultipleRegisters(&MBRTUHandle, 1, 0X2088, 0X0002, data, 100);
        }
        RxData = ' ';
  }

加入按键外部中断控制,进行测试或急停

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin==WK_UP_EXTI_Pin)
    {
        HAL_Delay(10);
        if(HAL_GPIO_ReadPin(WK_UP_EXTI_GPIO_Port, WK_UP_EXTI_Pin) == 1)
        {
            MBRTUMasterWriteMultipleRegisters(&MBRTUHandle, 1, 0X2088, 0X0002, data3, 100);
        }
    }
    else if(GPIO_Pin==KEY0_EXTI_Pin)
    {
        HAL_Delay(10);
        if(HAL_GPIO_ReadPin(KEY0_EXTI_GPIO_Port, KEY0_EXTI_Pin) == 0)
        {
//            MBRTUMasterWriteMultipleRegisters(&MBRTUHandle, 1, 0X2088, 0X0002, data1, 100);
            HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_RESET);
            MBRTUMasterReadHoldingRegisters(&MBRTUHandle, 0x01, 0x20AB, 0x0002, 100);
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
        }
    }
    else if(GPIO_Pin==KEY1_EXTI_Pin)
    {
        HAL_Delay(10);
        if(HAL_GPIO_ReadPin(KEY1_EXTI_GPIO_Port, KEY1_EXTI_Pin) == 0)
        {
            MBRTUMasterWriteMultipleRegisters(&MBRTUHandle, 1, 0X2088, 0X0002, data2, 100);
        }
    }
}

运行结果

赋予串口权限

sudo chmod 777 /dev/ttyUSB*
python3 keyboard_control.py 

image-20231120164116548

演示视频
键盘控制节点编写

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

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

相关文章

基于JavaWeb的智慧停车管理系统设计与实现

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题,今天给大家介绍…

右键菜单和弹出菜单的区别

接触windows开发10年了,一直以为"右键菜单"和"弹出菜单"是不同的。 最近刚刚发现,这两种菜单在定义的时候和消息循环处理程序中并没有什么不同,区别只是在于windows底层显示方式。 如下是右键菜单的显示方式&#xff1…

42、element表格内容溢出自动往上滚动,鼠标移入停止滚动,溢出继续滚动

vue模块&#xff0c;添加ref属性 <v-table ref"rollTable" style"margin: 0!important;" :loading"TBloading" :isIndex"true" :tableData"tableData":tableHead"tableHead":paginationShow"false"…

海康威视综合安防管理平台任意文件上传

系统介绍 HIKVISION iSecure Center综合安防管理平台是一套“集成化”、“智能化”的平台&#xff0c;通过接入视频监控、一卡通、停车场、报警检测等系统的设备&#xff0c;获取边缘节点数据&#xff0c;实现安防信息化集成与联动&#xff0c;公众号&#xff1a;web安全工具库…

【LeetCode刷题-字符串】--6.N字形变换

6.N字形变换 方法&#xff1a;使用二维矩阵模拟 根据题意&#xff0c;当在矩阵中填写字符时&#xff0c;会向下填写r个字符&#xff0c;然后向右继续填写r - 2个字符&#xff0c;最后回到第一行&#xff0c;因此Z字形变换的周期是t r r - 2 2r - 2&#xff0c;是|/,每个周期…

Django 入门学习总结2 创建一个投票系统

通过学习&#xff0c;我们可以实现一个简单的投票系统。这个投票系统有两部分组成。 公共部分&#xff0c;公众可以查看和进行投票。管理员可以进行增加、删除、修改投票信息。 这里投票系统Python语言版本为3.10.13&#xff0c;Django Web框架版本为4.2.7。 投票系统的实现…

单链表相关面试题--1.删除链表中等于给定值 val 的所有节点

/* 解题思路&#xff1a;从头节点开始进行元素删除&#xff0c;每删除一个元素&#xff0c;需要重新链接节点 */ struct ListNode* removeElements(struct ListNode* head, int val) {if(head NULL)return NULL;struct ListNode* cur head;struct ListNode* prev NULL;while…

nvm的下载与使用

1.如果已经安装nodejs , 先卸载nodejs; 从控制面板中 卸载程序 卸载nodejs win r打开cmd ,管理员运行 where node 查看是否删除干净nodejs 2.下载nvm 从github 下载nvm , 下载nvm 3.nvm 和node安装路径最好写在同一个路径下 &#xff0c;如D盘 ,D\a\nvm , D\a\nodejs 4.…

什么是美颜SDK?直播美颜SDK技术深度剖析

在实现实时美颜的过程中&#xff0c;美颜SDK扮演着关键的角色&#xff0c;它为开发者提供了一套强大的工具&#xff0c;使得实时美颜效果能够轻松应用于直播平台。 一、美颜SDK的基本概念 美颜SDK是一种软件工具包&#xff0c;通过集成了丰富的图像处理算法和实时计算技术&a…

2024年测试工程师必看系列之fiddler设置手机端抓包全套教程

fiddler设置手机端抓包 安卓手机抓包 第一步&#xff1a;配置电脑和安卓的相关设置 1、手机和fiddler位于同一个局域网内&#xff1b;首先从fiddler处获取到ip地址和端口号&#xff1a; &#xff0c;点击online&#xff0c;最后一行就是ip地址 2、路径&#xff1a;Tools》Op…

国际物流社交销售玩法拆解(三):打造社交电商式分销增长

这一篇&#xff0c;是国际物流行业社交销售玩法最后一篇&#xff0c;也是国际物流企业实现业务经营新增长、打造分销增长体系的新模式。以下&#xff0c;我们一起来拆解这一模式具体内容吧。 #01 国际物流第二曲线&#xff1a;社交电商 经营增长是企业的永恒话题。在客户成本…

【前端学java】Java中的异常处理(15)完结

往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类的使用 &#xff08;…

分享职业技术培训类型

职业技术培训类型包括&#xff1a;Python技术应用、人工智能应机器学习、大数据分析、机器学习。 一、“Python技术应用工程师” “Python技术应用工程师”职业技术认证是由工业和信息化部教育与考试中心推出一套专业化、科学化、系统化的人才考核标准&#xff0c;涉及在互…

单链表相关面试题--2.反转一个单链表

/* 解题思路&#xff1a; 此题一般常用的方法有两种&#xff0c;三指针翻转法和头插法 1. 三指针翻转法记录连续的三个节点&#xff0c;原地修改节点指向 2. 头插法每一个节点都进行头插 */ // 三个指针翻转的思想完成逆置 struct ListNode* reverseList(struct ListNode* head…

数据防泄密软件都有哪些丨十大数据防泄密软件盘点

随着信息化的不断发展&#xff0c;数据防泄密软件的需求越来越大。企业和个人应该根据自身的需求和实际情况选择适合自己的数据防泄密软件来保护数据资产的安全。 数据防泄密&#xff08;Data Loss Prevention&#xff0c;简称DLP&#xff09;&#xff1a;这是一款对敏感数据进…

mysqlbinlog使用记录

首先要确认mysql启用了binlog功能。一般默认启用。 mysql> select log_bin; ----------- | log_bin | ----------- | 1 | ----------- 然后确认binlog目录 mysql> select log_bin_basename; ---------------------------- | log_bin_basename | -----…

关于漏洞:检测到目标SSL证书已过期【原理扫描】

这个漏洞是监听443端口的&#xff0c;如果我们是正式的网站且使用了https那么更新证书即可。 但是我的服务器上面几乎是个空服务器&#xff0c;谁会用443呢&#xff1f; 找不到谁用了那我就部署一个nginx&#xff0c;用nginx代理443&#xff0c;找个证书配一下呗。 然而当我…

进程管理(四)

管程概念及实现要旨 管程引入了条件变量condition。 wait操作,把当前进程挂到条件变量对应的阻塞队列上去,signal把条件队列上的对手进程唤醒。 注意:条件变量的signal操作和信号量的signal是有区别的。条件变量的signal可能啥都不干,如果有阻塞的进程唤醒,没有啥事都不做…

使用Python实现3D曲线拟合

曲线拟合是数据分析和数学建模领域中广泛使用的技术。它涉及到寻找最接近一组数据点的数学函数的过程。在3D曲线拟合中&#xff0c;该过程被扩展到三维空间&#xff0c;其中的目标是找到最好地表示一组3D数据点的函数。 Python是一种用于科学计算的流行编程语言&#xff0c;它…

口袋参谋:如何通过布局“问大家”,快速提高宝贝转化!

问大家对于中小卖家来说&#xff0c;是非常适合的&#xff0c;因为我们完全可以靠对问大家的布局&#xff0c;提高宝贝的转化率。 问大家的作用 问大家主要是方便买家在购买前&#xff0c;了解商品的一些问题&#xff0c;而作为该不该购买的参考。对于卖家来说&#xff0c;是…
最新文章