• 嵌入式分享合集46


    一、基于STM32、ESP32 开发机械臂

    机械臂就淘宝上一个简单的啊 不是工业级那个啊 别想简单了

     

    硬件准备

        既然是要设计一台机械臂,那就需要从硬件开始准备,毕竟无论软件算法再重要,也需要一个优质的载体才能完美呈现。

    • 驱动方案

        硬件方面,首先需要确定的就是驱动方案,其中包括人们常说机器人的三大核心部件——电机、减速器和驱动器。

        一般真正的工业机器人使用的电机都是无刷伺服电机,其性能各方面都非常优秀,只是它的驱动系统较为复杂,并不适用于本次机械臂极其紧凑的结构当中。相比之下,选择了精度最高的步行电机,但它在高转速下力矩较小的缺点需要克服。

        为此,选择使用工业机械臂里面最常用的谐波减速以解决步行电机的力矩问题:其零背隙、高减速比、超小体积等优点简直是为这个项目量身打造。

        电机和减速器确定后,驱动器方面设计了一个步进电机的一体闭环驱动,以此保证驱动精度和体积最小化。 whaosoft aiot http://143ai.com

    • 结构设计

        驱动方案确定之后,紧接着就是结构设计,以下为设计图最终版本:

     从图中可以看到,这款机械臂一共使用了 6 个电机和 6 个谐波减速器,机身主体采用铝 CNC 加工,装饰组件则由 3D 打印制作,为了美观,控制电路上也都集成在本体上。

     

    • 电路设计

        整套机械臂的电路设计也非常复杂,其中涉及到了电源模块、电机驱动、计算模块、通信系统等很多方面,光各种型号的 MCU 就用了 12 个。此外,为了后续的扩展性够强,能在交互方面做一些独特创新,在机体上还搭载了 WiFi、蓝牙、2.4G 等多种无线能力。

        当然,这都是次要的,在电路方面最主要的还是主控制器和电机伺服驱动器。

        先说电机伺服驱动器吧,将其设计为电机一体式的驱动,支持 CAN 总线和功率机联,因此整套系统下来,仅需 4 根线即可将 6 个电机以及末端执行器全部连接起来。不仅如此,这款驱动器的性能也非常优秀,使用 FOC 加斩波恒流,并且添加了高精度的磁编码进行闭环控制,因此避免了像传统步进电机那样丢步的可能,在最高转速和效率方面也表现不俗。

        “如果说驱动器是心脏的话,那控制器就是机械臂的小脑了。”控制器方面,采用了他此前开发的机器人开发框架 REF,基于 Cortex-M4 内核的 MCU。这是因为 M4 内核自带 FPU 和 DSP,可大幅提升此后控制算法中涉及到的大量复杂计算的效率。另外,主控制器采用冗余设计,除了主控制器 REF 外,还搭载了一个 ESP32作为协处理器,用作 STM32 的安全备份并提供 WiFi、 蓝牙等无线能力。

        总体而言,为解决精度和性能问题,共进行了三个步骤:

    • 第一、使用步进电机加一体闭环驱动;

    • 第二、使用 0 背隙的谐波减速器;

    • 第三、在后续的算法实践中进行高精度补偿。

    软件走起

        硬件具备了,但这只是开始,更为核心的还是软件算法部分。对于机械臂来说,最核心的软件内容在于运动学正逆解的算法以及动力学模型的实现。

        运动学正逆解算法可以得知机械臂每个关节角度和最终末端位置之间的正逆解求解关系,而动力学模型则用于实现碰撞检测、柔性控制、力学反馈等多种功能,具体会涉及到大量十分复杂的矩阵和偏微分计算,这一点也是在项目实现中花费时间最多的部分:“请大家记住,这些项目表面上看起来是电子和机械,其实背后全是算法和数学。”

        除了核心算法外,软件部分还包括命令行和图形化的上位机、手机端的 APP 以及无线示教器固件等。另外,可能还有人注意到了机械臂底座上有一个又大又圆的灯环:

        看起来是不是很像......没错,就是鸿蒙的 Logo,这台机械臂主控制器里运行的是 LiteOS 内核的鸿蒙系统。

        不过由于视频时长有限,许多技术内容并没有详细讲述,所幸作者将这次的项目也开源了,因此感兴趣的小伙伴可以前往其 GitHub 查看项目详细代码:https://github.com/peng-zhihui/Dummy-Robot。

    交互方式

        软硬件兼备,那么接下来就是我们最喜闻乐见的演示环节啦!在这个部分,展示了很多常规和非常规的交互方式,一句话总结就是:你想要的交互方式,这里都有!

    • 利用串口

        这是一种最简单的交互方式,机械臂通过 USB 连上电脑会出现一个串口号,使用者能很方便地用串口命令来控制机械臂,还可以选择多种坐标方式,例如关节坐标系、世界坐标系、工具坐标系等,而所有的姿态结算均在机械臂内部完成。

    • 使用命令行

        通过设计的 REF 自带的 RPC 框架,可实现更大自由度的机械臂控制和各种参数设置。

    • 图形化上位机

        以上两种方式对于技术人没啥问题,但对于普通人来说就有些“阴间”了。因此还实现了对应的图形化上位机,可以在上位机中进行“傻瓜式”的拖拽交互。

        同时,这种交互还是双向的,即不仅可以把动作下发给机械臂,还可以在软件中实时同步机械臂的姿态:

    ,时长00:12

    • 手动协作示教

        理论上来说,以上三种交互方式已经可以满足绝大多数的使用需求了,但怎会止步于此:“更优雅的交互方式是什么?当然是连软件都不用打开,所见即所得。”

        基于此,可在硬件设计阶段通过合理设置减速器的减速比,使得机械臂可以在保持力矩和精度的同时进行反驱,以此获得手动协作示教的功能,即只需手动教它一遍运动流程,它就可以自动学习重复:

    ,时长00:20

        但很多协作机器都有手动示教功能,所以觉得这并不算炫酷,因此他设计了一个开启示教功能的特别方法:一个无线智能小终端。

        这个无线示教器名为 Peak,其功能非常多,可通过低功耗蓝牙和机械臂进行无感连接以实时显示机械臂的各种状态信息,还可以切换各种功能,其中就包括进入示教模式。

    • AR

        除此之外,还利用了较为前沿的 AR 技术作为交互方式。毕竟上位机无法展示真实环境,手动示教也比较累,而结合增强现实技术则可以真正实现“指哪打哪”的效果。

    • 终极交互形态:像自己的手臂一样

        相信在许多人看来,以上这些交互方式已经足够优秀了,但“还没有到理想状态”、“这一切都还不够自然和优雅”。为了追求极致的交互状态,思考了很久,最终想到了人类使用机械臂最符合直觉的方式:要跟使用自己的手臂一样。

        出于这种想法,设计了一套由双目相机、AHRS 系统、AI 算力平台、力传感和力反馈装置以及通信模组组成的装置,以此实现将人类手臂的动作直接同步到机械臂上,具体原理如下:

        首先由双目相机进行目标识别和跟踪定位以及AHRS 系统进行姿态解算来获取准确的手部位置和旋转姿态(由于此过程涉及到的 AI 算法需要高效计算平台来承载,因此选择了华为昇腾的 Atlas 边缘计算平台),然后实时的位姿信息会经过复杂的坐标换算通过无线的方式发送给机械臂,机械臂收到之后便能响应执行。

        不仅如此,考虑到机械臂的实用性价值,还为机械臂设计了一个带力反馈的微型夹爪,也就是说,使用者可随时得知夹爪正在抓取东西的力度。

        同时,结合空间定位系统,他还设计了一个手持控制器,集成了 AHRS 装置、红外 LED 以及 PS5 手柄中号称黑科技的扳机(其中安置了一个力反馈马达,可实现对于各种物理效果的真实模拟)。

        整套设备的最终效果堪称终极交互形态:使用者不仅可以把动作实时同步到机械臂,而且还可以在控制器这边实时感受到机械臂末端抓取东西的质感。

        为了展现这个效果有多惊人,用机械臂给葡萄做了一个缝合手术:

    ,时长00:31

        自然,这套动作让人们亲手完成也可以,不就是缝个葡萄,但你可以人在厕所缝着客厅的葡萄吗?没错,这台机械臂可以实现远程操作,除此之外,他还可以进行软件去抖、运动范围的重映射、力矩强增强等多种人手无法达到的效果。

    二、用BUCK电路简单实现一个可靠的负电源

    在对信号线性度放大要求非常高的应用需要使用双电源运放,比如高精度测量仪器、仪表等;那么就需要给双电源运放提供正负电源。

    我们常用的BUCK降压电路能得到正电压,如图1所示。

     

    图1:BUCK降压电路正电压输出

    其实BUCK降压电路在不改变元器件参数的情况下能变换得到与正电压相同输出能力的负电压,如图2所示;其工作原理和正电压输出是一样的,得到的电源质量也很高。

     

    图2:BUCK降压电路负电压输出

    以上两个电路图的元器件型号都是正确的,可以直接使用。

    另外由电容、二极管和振荡器组成的负压电荷泵也能实现负电压,由于二极管的存在会损失一部分压降,容易受负载影响且纹波较大,输出能力有限,对电源质量要求高的建议不要使用。

     

    图3:负压电荷泵

    ==== 最后还是要了解BUCK电路

    Buck电路原理图
     Buck电路,又称降压电路,其基本特征是DC-DC转换电路,输出电压低于输入电压。输入电流为脉动的,输出电流为连续的。

        Q1为三极管开关,PWM波控制。
    Buck电路工作原理
        当PWM波为高电平时,Q1导通,储能电感L1被充磁,流经电感的电流线性增加,同时给电容C1充电,给负载R1提供能量。等效电路如图

        当PWM波为低电平时,Q1关闭,储能电感L1通过续流二极管放电,电感电流线性减少,输出电压靠输出滤波电容C1放电以及减小的电感电流维持,等效电路如图。

    CCM及DCM定义

        CCM (Continuous Conduction Mode),连续导通模式:在一个开关周期内,电感电流从不会到0。或者说电感从不“复位”,意味着在开关周期内电感磁通从不回到0,功率管闭合时,线圈中还有电流流过。

        DCM,(Discontinuous Conduction Mode),断续导通模式:在开关周期内,电感电流总会到0,意味着电感被适当地“复位”,即功率开关闭合时,电感电流为零。

        BCM(Boundary Conduction Mode),临界导通模式:控制器监控电感电流,一旦检测到电流等于0,功率开关立即闭合。控制器总是等电感电流“复位”来激活开关。如果电感值电流高,而截至斜坡相当平,则开关周期延长,因此,BCM变化器是可变频率系统。

        电流斜坡的中点幅值等于直流输出电流Io的平均值,峰值电流Ip与谷值电流Iv之差为纹波电流。

    三、单片机的基本概念

    单片机执行指令

        我们来思考一个问题,当我们在编程器中把一条指令写进单片机内部,然后取下单片机,单片机就可以执行这条指令。

        那么这条指令一定保存在单片机的某个地方,并且这个地方在单片机掉电后依然可以保持这条指令不会丢失,这是个什么地方呢?

        这个地方就是单片机内部的只读存储器即ROM(READ ONLY MEMORY)。

        为什么称它为只读存储器呢?刚才我们不是明明把两个数字写进去了吗?原来在89C51中的ROM是一种电可擦除的ROM,称为FLASH ROM,刚才我们是用的编程器,在特殊的条件下由外部设备对ROM进行写的操作,在单片机正常工作条件下,只能从那面读,不能把数据写进去,所以我们还是把它称为ROM。

    单片机数的本质和物理现象

        我们知道,计算机可以进行数学运算,这令我们非常难以理解,它们只是一些电子元器件,怎么可以进行数学运算呢?

        我们人类做数学题如37+45是这样做的,先在纸上写37,然后在下面写45,然后大脑运算最后写出结果,运算的原材料是37和45,结果是82都是写在纸上的,计算机中又是放在什么地方呢?

        为了解决这个问题,先让我们做一个实验:这里有一盏灯,我们知道灯要么亮,要么不亮,就有两种状态,我们可以用‘0’和‘1’来代替这两种状态:规定亮为‘1’、不亮为‘0’。

        现在放上三盏灯,一共有几种状态呢?我们列表来看一下:000 / 001 / 010 / 011 / 100 / 101 / 110 / 111。我们来看,这个000 / 001 / 101 不就是我们学过的的二进制数吗?本来,灯的亮和灭只是一种物理现象,可当我们把它们按一定的顺序排好后,灯的亮和灭就代表了数字了。

        让我们再抽象一步,灯为什么会亮呢?是因为输出电路输出高电平,给灯通了电。因此,灯亮和灭就可以用电路的输出是高电平还是低电平来替代了。这样,数字就和电平的高、低联系上了。

    单片机数位的含义

        通过上面的实验我们已经知道:一盏灯亮或者说一根线的电平的高低,可以代表两种状态:0和1,实际上这就是一个二进制位。

        因此我们就把一根线称之为一“位”,用BIT表示。

    单片机字节的含义

        一根线可以表示0和1,两根线可以表达00 / 01 / 10 / 11四种状态,也就是可以表达0~3,而三根可以表达0~7,计算机中通常用8根线放在一起,同时计数,就可以表示0~255一共256种状态。

        这8根线或者8位就称之为一个字节(BYTE)。

    单片机存储器的构造

        存储器就是用来存放数据的地方。它是利用电平的高低来存放数据的,也就是说,它存放的实际上是电平的高、低,而不是我们所习惯认为的1234这样的数字,这样,我们的一个谜团就解开了。

        一个存储器就象一个个的小抽屉,一个小抽屉里有八个小格子,每个小格子就是用来存放“电荷”的,电荷通过与它相连的电线传进来或释放掉。至于电荷在小格子里是怎样存的,就不用我们操心了,你可以把电线想象成水管,小格子里的电荷就象是水,那就好理解了。存储器中的每个小抽屉就是一个放数据的地方,我们称之为一个“单元”。

        有了这么一个构造,我们就可以开始存放数据了,想要放进一个数据12,也就是00001100,我们只要把第二号和第三号小格子里存满电荷,而其它小格子里的电荷给放掉就行了。

        可是问题出来了,一个存储器有好多单元,线是并联的,在放入电荷的时候,会将电荷放入所有的单元中,而释放电荷的时候,会把每个单元中的电荷都放掉。这样的话,不管存储器有多少个单元,都只能放同一个数,这当然不是我们所希望的。因此,要在结构上稍作变化。

        需要在每个单元上有个控制线,想要把数据放进哪个单元,就把一个信号给这个单元的控制线,这个控制线就把开关打开,这样电荷就可以自由流动了。而其它单元控制线上没有信号,所以开关不打开,不会受到影响。

        这样,只要控制不同单元的控制线,就可以向各单元写入不同的数据了。同样,如果要从某个单元中取数据,也只要打开相应的控制开关就行了。

    单片机存储器的译码

        那么,我们怎样来控制各个单元的控制线呢?这个还不简单,把每个单元的控制线都引到集成电路的外面不就行了吗?

        事情可没那么简单,一片27512存储器中有65536个单元,把每根线都引出来,这个集成电路就得有6万多个脚?不行,怎么办?要想法减少线的数量。

        有一种方法称这为译码,简单介绍一下:一根线可以代表2种状态,2根线可以代表4种状态,3根线可以代表8种,256种状态又需要几根线代表?8根线,所以65536种状态我们只需要16根线就可以代表了。

    单片机存储器的选片概念

        至此,译码的问题解决了,让我们再来关注另外一个问题。送入每个单元的八根线是用从什么地方来的呢?它就是从计算机上接过来的,一般地,这八根线除了接一个存储器之外,还要接其它的器件。

        这样问题就出来了,这八根线既然不是存储器和计算机之间专用的,如果总是将某个单元接在这八根线上,就有问题出现了:比如这个存储器单元中的数值是0FFH另一个存储器的单元是00H,那么这根线到底是处于高电平,还是低电平?怎样分辩?

        办法很简单,当外面的线接到集成电路的引脚进来后,不直接接到各单元去,中间再加一组开关就行了。平时我们让开关打开着,如果确实是要向这个存储器中写入数据,或要从存储器中读出数据,再让开关接通就行了。

        这组开关由三根引线选择:读控制端、写控制端和片选端。要将数据写入片中,先选中该片,然后发出写信号,开关就合上了,并将传过来的数据(电荷)写入片中。如果要读,先选中该片,然后发出读信号,开关合上,数据就被送出去了。

        读和写信号同时还接入到另一个存储器,但是由于片选端不同,所以虽有读或写信号,但没有片选信号,所以另一个存储器不会“误会”而开门,造成冲突。那么会不同时选中两片芯片呢?

        只要是设计好的系统就不会,因为它是由计算控制的,而不是我们人来控制的,如果真的出现同时出现选中两片的情况,那就是电路出了故障了,这不在我们的讨论之列。

    单片机的总线概念

        从上面的介绍中我们已经看到,用来传递数据的八根线并不是专用的,而是很多器件大家共用的。

        所以我们称之为数据总线,总线英文名为BUS,总即公交车道,谁也可以走。而十六根地址线也是连在一起的,称之为地址总线。

  • 相关阅读:
    Docker自定义镜像
    Spark---核心概念(Spark,RDD,Spark的核心构成组件)详解
    基于python的图像识别
    一个计算行列坐标的应用
    Centos7.9部署snort-2.9.20
    2023年最佳键盘:打字和游戏的顶级键盘,总共十款,总有一款适合你
    Springboot——集成jodconverter做文档转换
    集美大学 - 2840 - 实验2-2
    VivadoAndTcl: namespace
    【每日一题】73. 矩阵置零
  • 原文地址:https://blog.csdn.net/qq_29788741/article/details/126609135