Ros小车应用篇(一)——Ros小车wifiQT上位机

Ros小车多功能QT上位机

  • 代码仓库:https://github.com/zhuchen99899/RosCar/tree/master/Ros_car_pid_test

  • 小车嵌入式控制可以查看我的博客:https://blog.csdn.net/zhuchen88988/article/details/118612242?spm=1001.2014.3001.5501

  • 小车通讯协议可以参看我的博客:https://blog.csdn.net/zhuchen88988/article/details/118637714?spm=1001.2014.3001.5501

  • QT上位机界面如下(MPU6050数据暂时未加入):
    在这里插入图片描述

  • 此上位机功能:
    ①修改电机方向
    ②修改电机速度
    ③修改小车PID参数
    ④控制小车行进方向
    ⑤接收小车速度,并在图表上显示,图表指针移动上去有X,Y位置指示,下方勾选栏可以屏蔽,显示电机1/2曲线,按钮可以暂停接收/继续接收速度数据。数据图表可以使用滚轮放大缩小曲线刻度,方便查看,右键复位原先尺寸,方便于PID调参。
    ⑥可以使用Xbox手柄控制小车,或者使用北通之类的。只要在驱动中显示为xbox360的手柄均可。

  • 小车北通手柄WIFI控制:
    在这里插入图片描述

功能①~④均为协议的基础实现,使用QT基本控件以及实现qttcp客户端。通过QT信号槽即可完成。

  • 使用网络需要在.pro文件中加入network
  • 协议类已经在protocol.cpp中实现

class protocol
{
public: union float_trans_forM1_rec_speed{

        float f;
        unsigned char uch[4];
    };

       union float_trans_forM1_PID{
       float f;
       unsigned char uch[4];
    };
       union float_trans_forM1_ctrl_speed{
       float f;
       unsigned char uch[4];
    };

public:
    protocol();
    ~protocol();

    /*方向控制报文方法*/
    QByteArray Control_direction(QByteArray block,uchar motor,uchar dir);
    /*pwm控制报文方法*/
    QByteArray Control_PWM(QByteArray block,uchar motor,int PWM_percentage);
    QByteArray Control_set_PID(QByteArray block,uchar motor,PID PID_data);
    QByteArray Control_Speed(QByteArray block,uchar motor,float speed_data[]);
    QByteArray Control_SpeedAndDir(QByteArray block,uchar motor,float speed_data[],uchar dir[]);
    /*接收一帧数据,筛选数据类型,并进行CRC校验和长度校验*/
    uchar Receive_data(QByteArray block,qint64 tcp_readsize);
    /*校验后,按照数据包头类型,选择解帧方法*/
    /*解速度帧数据*/
    void Receive_Data_Speed(float speed_data[],QByteArray block);

private:
    /*CRC16——MODBUS 校验计算*/
    ushort CRC16_calculate(QByteArray block);
     /*CRC16校验结果转换 ushort 型 ->转为两个字节 uchar*/
    void CRC16_trans(uchar *CRC_out_uchar,ushort CRC16_res);
    /*取字节流最后两位组成CRC校验值*/
    ushort CRC16_comb(QByteArray block,qint64 tcp_buffsize);
};

#endif // PROTOCOL_H

  • 注意协议的CRC校验计算是使用C语言完成,QT中可以使用 extern 引用头文件方式使用C写的库。
extern "C"{
#include "crc16.h"

}

功能⑤为重写qchart功能实现。可参照网上代码完成

  • 使用qchart功能需要在.pro中加入 charts
class ChartView : public QChartView
{
Q_OBJECT


public:
    ChartView(QChart *chart, QWidget *parent = nullptr);
    ~ChartView();
    // 保存坐标区域,用于复位
    void saveAxisRange();
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void keyReleaseEvent(QKeyEvent *event);

private:
    QPoint m_lastPoint;
    bool m_isPress;
    bool m_ctrlPress;
    bool m_alreadySaveRange;
    double m_xMin, m_xMax, m_yMin, m_yMax;
    QGraphicsSimpleTextItem* m_coordItem;

};

功能⑥为qgamepad功能实现。

  • 使用qgamepad功能需要在.pro中加入gamepad
  • qgamepad在qt官方也有例子 可在欢迎界面搜索例程学习。不过官方例子是基于qml实现,在经过网上搜索后也找到了C++的例子。
  • 通过信号槽来连接手柄的按键,可以从名字上清楚看出每个信号的作用


          m_gamepad = new QGamepad(0, this);

          connect(m_gamepad, &QGamepad::buttonR1Changed, this, [=](double value){
              GamePAD_getBtnVaule(1, value);
          });
          connect(m_gamepad, &QGamepad::buttonR2Changed, this, [=](double value){
              GamePAD_getBtnVaule(2, value);
          });

          connect(m_gamepad, &QGamepad::buttonL1Changed, this, [=](double value){
              GamePAD_getBtnVaule(3, value);
          });
          connect(m_gamepad,&QGamepad::buttonL2Changed, this, [=](double value){
              GamePAD_getBtnVaule(4, value);
          });
          connect(m_gamepad, &QGamepad::buttonUpChanged, this, [=](double value){
              GamePAD_getBtnVaule(5, value);
          });
          connect(m_gamepad, &QGamepad::buttonDownChanged, this, [=](double value){
              GamePAD_getBtnVaule(6, value);
          });
          connect(m_gamepad, &QGamepad::buttonRightChanged, this, [=](double value){
              GamePAD_getBtnVaule(7, value);
          });
          connect(m_gamepad, &QGamepad::buttonLeftChanged, this, [=](double value){
              GamePAD_getBtnVaule(8, value);
          });

          connect(m_gamepad, &QGamepad::axisRightXChanged, this, [=](double value){
                  GamePAD_getBtnVaule(9, value);
          });
          connect(m_gamepad, &QGamepad::axisRightYChanged, this, [=](double value){
              GamePAD_getBtnVaule(10, value);
          });
          connect(m_gamepad, &QGamepad::axisLeftXChanged, this, [=](double value){
              GamePAD_getBtnVaule(11, value);
          });
          connect(m_gamepad, &QGamepad::axisLeftYChanged, this, [=](double value){
              GamePAD_getBtnVaule(12, value);
          });
  • 在对应的槽函数GamePAD_getBtnVaule中判断btName数值来判断哪个按键被按下并做响应处理。
  • 普通按键value为1即为按下,摇杆按下需要判断value 正负,从上述信号可以看出,摇杆有X轴和Y轴,正负即为轴的不同方向的数值,以此判断摇杆状态。value为0时摇杆回0,给小车下发停止的协议。
  • 使用过程中代码中加入判断机制,当有按键变动时再发送TCP信息给Ros小车,降低小车通讯压力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值