7-Robot类大体框架

c++ 复制代码
#ifndef ELECTRONBOT_FW_ROBOT_H
#define ELECTRONBOT_FW_ROBOT_H

#include "stm32f4xx.h"
#include "screen.h"
#include "i2c.h"


#define ANY 0

class Robot
{
public:
    Robot(SPI_HandleTypeDef* _screenSpi, I2C_HandleTypeDef* _motorI2c) :
        screenSpi(_screenSpi), motorI2c(_motorI2c)
    {
        lcd = new Screen(screenSpi);

        /********* Need to adjust parameters for specific hardware *********/
        joint[ANY] = JointStatus_t{
            0,
            -180,
            180,
            90
        };

        joint[1] = JointStatus_t{ // Head
                2,
                70,
                95,
                0,
                -15,
                15,
                true
        };

        joint[2] = JointStatus_t{ // Left arm roll
                4,
                -10,
                10,
                0,
                0,
                30,
                false
        };

        joint[3] = JointStatus_t{ // Left arm pitch
                6,
                -16,
                117,
                0,
                -20,
                180,
                false
        };

        joint[4] = JointStatus_t{ // Right arm roll
                8,
                120,
                140,
                0,
                0,
                30,
                true
        };

        joint[5] = JointStatus_t{ // Right arm pitch
                10,
                15,
                150,
                0,
                -20,
                180,
                true
        };

        joint[6] = JointStatus_t{ // Body
                12,
                0,
                180,
                0,
                -90,
                90,
                false
        };

        /********* Need to adjust parameters for specific hardware *********/
    }


    struct UsbBuffer_t
    {
        uint8_t extraDataTx[32]; //32字节的发送缓冲区
        uint8_t rxData[2][60 * 240 * 3 + 32]; // 43232bytes, 43200 of which are lcd buffer,这是一个巨大的接收缓冲区,它有两条滑道。这就是经典的"乒乓缓冲 (Ping-Pong Buffer)"设计。240 * 240 是屏幕分辨率。* 3 代表每个像素是 RGB 三个字节。60 行,所以 60 * 240 * 3 正好是 1/4 屏的图像数据大小 (43200 字节)。+ 32 是用来存放伴随图像数据一起发来的指令数据(比如新的关节角度)。
/*业务逻辑:

滑道 0 正在被 USB 的 DMA("卸货机器人")写入新数据。

与此同时,CPU("仓库管理员")可以安全地从滑道 1 中读取上一批已经卸好的货物,而不用担心数据被中途修改。

当滑道 0 写满后,系统会切换,让 DMA 开始往滑道 1 写,CPU 则去处理滑道 0 的数据。

这种"一个在写,一个在读"的并行机制,极大地提高了数据处理的吞吐量和效率。*/
        volatile uint16_t receivedPacketLen = 0; // 记录当前收到的这一包数据,到底有多少个字节。
        volatile uint8_t pingPongIndex = 0; // 滑道切换开关
        volatile uint32_t rxDataOffset = 0; // 记录在当前这条滑道上,货物已经卸到了哪个位置。相当于货物是大于一个滑道的
    };
    UsbBuffer_t usbBuffer;


    struct JointStatus_t
    {
        uint8_t id;
        float angleMin;
        float angleMax;
        float angle; // 当前角度,这个角度作者设计的是当前模型的角度
        float modelAngelMin;
        float modelAngelMax;
        bool inverted = false; //反不反转
    };
    JointStatus_t joint[7];

//SwitchPingPongBuffer 和 GetPingPongBufferPtr 是 CDC_Receive_HS 回调函数使用的底层接口,负责"切换"和"准备"。
    uint8_t* GetPingPongBufferPtr();// 获取当前空闲滑道的地址,返回当前应该用于接收数据的那个空闲缓冲区的内存地址
    uint8_t* GetLcdBufferPtr();// 返回刚刚接收完成的那块、包含屏幕动画数据的缓冲区的内存地址。
    uint8_t* GetExtraDataRxPtr();// 获取附加指令数据,返回刚刚接收完成的那块、包含关节角度等指令的缓冲区的内存地址。
    void SwitchPingPongBuffer(); // 切换当前正在被 DMA 使用的接收缓冲区
    void SendUsbPacket(uint8_t* _data, uint32_t _len); //这是一个封装,用来向上位机发送数据。
    bool ReceiveUsbPacketUntilSizeIs(uint32_t _count); //等到指定的快递
    void SetJointId(JointStatus_t &_joint, uint8_t _id);
    void SetJointKp(JointStatus_t &_joint, float _value);
    void SetJointKi(JointStatus_t &_joint, float _value);
    void SetJointKv(JointStatus_t &_joint, float _value);
    void SetJointKd(JointStatus_t &_joint, float _value);
    void SetJointEnable(JointStatus_t &_joint, bool _enable);
    void SetJointInitAngle(JointStatus_t &_joint, float _angle);
    void SetJointTorqueLimit(JointStatus_t &_joint, float _percent);

    //物理角度,直接和舵机进行通信
    void UpdateServoAngle(JointStatus_t &_joint);
    void UpdateServoAngle(JointStatus_t &_joint, float _angleSetPoint);
    //模型角度,和上位机进行通信
    void UpdateJointAngle(JointStatus_t &_joint);
    void UpdateJointAngle(JointStatus_t &_joint, float _angleSetPoint);

    void JointADCValueRead(JointStatus_t &_joint, uint8_t _id); // 就是远程命令舵机,让它把此刻测量到的、来自电位器的原始 ADC 数字值,报告上来。提供一个底层的硬件诊断接口,允许开发者远程查询并获取指定舵机内部、位置反馈电位器的原始 ADC 读数及其对应的电压值
    //下面三个是测试舵机的函数
    void JointPWMChnel1Test(JointStatus_t &_joint, uint8_t _id);
    void JointPWMChnel2Test(JointStatus_t &_joint, uint8_t _id);
    void JointPWMChnelTestClose(JointStatus_t &_joint, uint8_t _id);
    //查询舵机版本
    char* JointFamerWareVersionRead(JointStatus_t &_joint, uint8_t _id);
    char* JointIdRead(Robot::JointStatus_t &_joint, uint8_t _id);
    void JointSystemReset(JointStatus_t &_joint, uint8_t _id);

    Screen* lcd;

private:
    SPI_HandleTypeDef* screenSpi;
    I2C_HandleTypeDef* motorI2c;

    uint8_t i2cRxData[8];
    uint8_t i2cTxData[8];
    uint8_t usbExtraData[32];

    bool TransmitAndReceiveI2cPacket(uint8_t _id);
};

#endif //ELECTRONBOT_FW_ROBOT_H

在这个robot类里面定义了一个结构体数组来表示机器人六个舵机的参数

相关推荐
jerryinwuhan2 小时前
linux_shell_1226_1
linux
纸带2 小时前
MCU 错误中断HardFault_Handler KEIL 仿真分析
单片机·嵌入式硬件
羽飞2 小时前
GCC ABI炸弹
linux·c++·python
先知后行。2 小时前
电子元器件2
单片机·学习
程序猿编码2 小时前
手动清理 TCP TIME-WAIT 套接字:Linux 内核模块的实现与原理
linux·网络·tcp/ip·linux内核·套接字
DIY机器人工房2 小时前
解决方法:用新唐 NuMicro M483这款单片机遇到的一些问题
单片机·嵌入式硬件·嵌入式·diy机器人工房·新唐m483
pwn蒸鱼2 小时前
buuctf中的ciscn_2019_es_2(栈迁移)
linux·安全
牛奶咖啡132 小时前
Linux的实用技巧——终端安全会话、命令提示工具安装使用、端口连通性测试与rm命令无法使用解决方案
linux·tmux·linux实现后台安全运行会话·linux的端口连通性测试·linux的命令提示工具·rm命令无法使用解决方法·tldr
fufu03112 小时前
Linux环境下的C语言编程(五十二)
java·linux·c语言