STONE串口屏STM32 服务机器人运动状态监测

STONE串口屏STM32 服务机器人运动状态监测

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

服务机器人简介

服务机器人基础知识

作为一种半自主或完全自主的机器人,服务机器人能够为人类执行有用的服务工作,如搬运、清洁和救援。随着服务机器人逐渐融入人们的日常生活,它们现在被广泛应用于展览厅、餐厅、酒店等公共场所,对提升人类生活质量和服务行业产生了深远影响。

通常,服务机器人配备有高精度激光雷达、语音采集模块、运动模块、串口屏、无线连接模块等主要设备。机器人通过激光雷达构建高精度室内地图,利用语音模块接收语音指令,通过运动模块将机器人移动至目标位置,并借助无线模块接收控制器发出的远程指令,实现远程智能控制。

服务机器人的运动过程需经过地图构建、路径规划、速度规划及障碍物避让等功能,如图所示。

本文构建了一个移动机器人演示系统,采用全向移动底盘,使机器人能在小范围内完成转向、平移等动作。

远程监控模块:stm32F407 + Wi-Fi模块 + STONE STVC043WT-01串口屏

机器人主控中心:stm32F707扩展板(已移植至系统)

运动控制模块:STM32F407 + 电机驱动器

语音采集模块:Xunfei Six Pulse语音阵列

激光雷达:Silan Technology LPR激光雷达

移动底盘:ROTACASTER 125mm × 3

在此,我们以一栋高端办公楼的单层场景为例。机器人需定期为楼内办公人员提供服务,任务要求机器人通过内在或外在传感器感知环境及自身运动状态,并根据最优时间、最短路径或最低能耗原则,从当前位置规划并执行无碰撞运动至目标位置。

为成功完成该任务,首先通过激光雷达扫描楼层环境构建室内地图,并以坐标形式标记任务点位置:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

在机器人执行任务过程中,操作员无法实时掌握机器人状态并及时下达指令。

为使控制器能够远程访问机器人状态并从控制中心发送控制指令,本文采用STM32F407主板通过外部网络卡与机器人通信,并使用Stone STVC043WT-01串口屏进行UI设计,以提升操作员使用效率。设计原理图如下:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

本文将重点介绍如何使用Stone STVC043WT-01设计UI界面,以实时显示服务机器人的状态。在开始石串口屏的开发前,需先编写一个简单测试演示程序,确保远程控制模块能通过无线网络及时接收机器人当前状态(机器人ID、目的地、x/y/z电机速度、机器人当前位置坐标等)。

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

下图展示了机器人在原点旋转时生成的状态数据,从数据中可以看出,当机器人旋转时,x、y、z轴电机速度应保持一致:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

STVC043WT-01串口屏的开发流程

Stone提供了一套易于使用的显示设计工具,通过公司的STV系列串口屏,我们可以快速完成显示演示的开发。因此,选择了Stone STVC043WT-01串口屏用于实时监控远程机器的状态。串口屏的开发分为三个主要步骤:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

  1. 设计串口屏UI
  2. 开发对应的嵌入式主机程序,主要设计UART通信

调试串口屏与嵌入式主机。

UI设计

  1. 创建新项目

首先,从Stone官方网站下载最新版本的TOOL-2019工具。

根据串口屏参数创建对应项目,此处以STVC043WT-01(480*272)为例。

选择文件 -> 新建,将项目屏幕像素设置为 480*272:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

  1. 插入图片并设计 UI

右键点击项目文件 -> 添加,插入使用其他工具绘制的图片,注意图片大小必须与串口屏一致,本文中使用的图片大小均为 480×272。

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

在首页当前状态下设置跳转链接:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

然后使用石块工具在主页返回按钮处添加挑战链接:工具栏 -> 硬件参数配置0,在返回按钮处插入一个窗口,并修改名称定义和页面切换,使其通过返回按钮跳转至主页。

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

在机器人ID和目标位置插入文本变量,在电机速度和当前位置插入数据变量,如图所示。 需注意,变量内存地址表示数据或文本的存储位置,字长表示可显示字节的最大长度。

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

编译3.并下载

完成上述步骤后,检查屏幕配置,确保波特率为115200且命令处理程序为0xA5 0x5A。检查完成后,点击编译选项并将文件下载到串口屏。

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

  1. 调试

系统启动后,串口屏显示主页面,包含六个选项。点击“连接”选项时,系统将建立远程控制台与机器人之间的无线连接;反之,点击“断开”将断开无线连接。“显示地图”选项将显示机器人创建的室内环境地图;“清除状态”选项将初始化系统并发送命令中断机器人的任务执行,使其返回起点;“当前状态”选项显示并更改机器人的当前状态;“返回起点”选项将提示机器人返回起点。

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

选择“当前状态”以查看机器人当前状态。当机器人处于起点时,串口屏将显示机器人状态的初始值:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

设置机器人目标后,机器人开始执行任务,此时串口屏将实时显示机器人的ID、目的地、速度和坐标,如图所示,其中机器人在坐标(174,269)处旋转:

STONE-TFT-LCD-Module-STM32-Service-Robot-Motion-Status-Monitoring

选择返回选项,串口屏将返回主页面。

检查远程控制台发送至串口屏的UART数据是否与屏幕显示一致:

A5 5A 0b 82 01 20 53 48 2D 4B 4C 2D 30 31 //Robot ID: SH-KL_01
A5 5A 09 82 01 9B 6F 66 66 69 63 65      //Destination: office
A5 5A 05 82 01 14 0f 09  //motor x speed 3849 r/min
A5 5A 05 82 01 18 0f 09  //motor y speed 3849 r/min
A5 5A 05 82 01 1a 0f 09  //motor z speed 3849 r/min
A5 5A 05 82 01 1c 00 ae  //coordinate-axis X :174
A5 5A 05 82 01 1e 01 0d  //coordinate-axis X :269

  1. 代码共享部分

Serial_debug.CPP:

#include
#include "serial_debug.h"
using namespace std;
int debug_wait() {
#if DEBUG
cout << "press any key to contine" << endl;
getchar();
#endif
return 0;
}
bool creat_serial(HANDLE &hComm,string strPort) {
//Second, for the serial port number greater than 9 (for example, COM12), the serial port name in the CreateFile() function should be written "\. \COM12"。
// hComm = CreateFile(TEXT("com6"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
hComm = CreateFile(strPort.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hComm == INVALID_HANDLE_VALUE) {
cout << "Fail to open Serial Port.!!!" << endl;
debug_wait();
return FALSE;
}
else {
cout << "Success to open Serial Port. " << endl;
debug_wait();
return TRUE;
}
}
bool close_serial(HANDLE &hComm) {
CloseHandle(hComm);
return TRUE;
}
bool set_serial(HANDLE &hComm)
{
DCB dcb;
GetCommState(hComm, &dcb);
dcb.BaudRate = CBR_115200;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
SetCommState(hComm, &dcb);
return TRUE;
}
bool WriteSerial(char* btData, ULONG ulSize, HANDLE hSerial)
{
DWORD dwNumBytes, dwRet;
dwRet = WriteFile(hSerial, //Handle
btData, //Data buffer
ulSize, //Buffer size
&dwNumBytes, //written bytes
NULL); //don't support
return (dwRet != 0);
};
int serial_process()
{
HANDLE hComm;
string portname = "com6";
bool ret = FALSE;
string buff = "serial opened";
char c[20]="";//A5 5A 03 81 00 01
// strcpy_s(c, buff.c_str());
ret=creat_serial(hComm, portname);
if (!ret)
return 0;
set_serial(hComm);
if (!WriteSerial(c, 7, hComm))//Send data hello to com1
printf("ERROR!!");
wait_for_end();// pending until uart is not need.
close_serial(hComm);
return 0;
}

    滚动至顶部