Qt智能机器人控制系统

最近一直为机器人做一个控制系统,需要同时搭载Tensorflow和海康网络摄像头,当然python是最好的开发工具,搭载tensorflow比较容易,但是搭载海康摄像头,一直找不到如何去做。后来又想到java,海康摄像头解决了,调用tensorflow训练模型又有很多的坑。暂时先用Qt做了,后面再想办法。只能用tenssorflow的ssd_mobilenet模型。opencv官方也没有更新其他的模型。

Qt智能机器人控制系统_第1张图片


这是完成后的Qt控制系统界面。

关于海康摄像头的配置,完全看的海康的官方文档。

INCLUDEPATH+= D:\OpenCV\include\
 D:\OpenCV\include\opencv\
 D:\OpenCV\include\opencv2\
 D:\CH-HCNetSDK_32\includes\
 D:\CH-HCNetSDK_32\libs\
 D:\CH-HCNetSDK_32\libs\HCNetSDKCom\
 D:\CH-HCNetSDK_32\libs\ClientDemoDll\

LIBS +=  D:\OpenCV\x86\mingw\lib\libopencv_*.a\
D:\CH-HCNetSDK_32\libs\HCNetSDK.lib\
D:\CH-HCNetSDK_32\libs\PlayCtrl.lib\
D:\CH-HCNetSDK_32\libs\HCCore.lib\


void Robot::convexImage()
{
    LONG lRealHandle=0;
    NET_DVR_Init();
    //设置连接时间与重连时间
    NET_DVR_SetConnectTime(2000, 1);
    NET_DVR_SetReconnect(10000, true);

    if(bPlaying)
    {
        NET_DVR_StopRealPlay(lRealHandle);
        NET_DVR_Logout_V30(lUserID);
        lRealHandle=0;
        lUserID=0;
        bPlaying=false;
    }
    else
    {
        //注册设备
        NET_DVR_DEVICEINFO_V30 struDeviceInfo;
        //memset(&struDeviceInfo, 0, sizeof(NET_DVR_DEVICEINFO_V30));
        lUserID = NET_DVR_Login_V30("10.20.15.96", 8000, "admin", "admin12345", &struDeviceInfo);

        if(lUserID < 0)
        {
            qDebug()<<"login Err="<label_5->winId();
        struPlayInfo.lChannel = 1;                //预览通道
        struPlayInfo.dwStreamType = 0;      //主码流
        struPlayInfo.dwLinkMode = 0;        //TCP方式

        lRealHandle = NET_DVR_RealPlay_V40(lUserID, &struPlayInfo, NULL, NULL);
        if (lRealHandle < 0)
        {
            QMessageBox::information(this, tr("NET_DVR_RealPlay error"), tr("SDK_LASTERROR=%1").arg(NET_DVR_GetLastError()));
            NET_DVR_Logout_V30(lUserID);
            ui->textEdit->append("高清摄像头显示异常!\t");

        }
        if(lRealHandle > 0)
        {
            bPlaying = true;

        }
    }

}


然后把海康给的dll和头文件都放在Qt中,防止出现打不开预览组件。

 

关于控制系统的变成,比较麻烦,

operateCommand.h

#define    BGN_READ_MSG                        0xff       //起始符0xff
#define    PROTOCOL_BASIC_SIZE              0x07     //protocal长度
#define    MSG_EMPTY_MODEL                 0x00     //默认设备号
#define    MSG_EMPTY_MODEL_CMD        0x00     //默认设备命令
#define    DATA_LEN                                 0x02     //数据长度
#define    MSG_EMPTY_DATA                    0x00         //空数据

enum enum_instruction
{
    go=0x01,
    back=0x02,
    left_top=0x03,
    right_top=0x04,
    stop=0x05,
    left_bottom=0x09,
    right_bottom=0x0A,
    deceleration=0x0B,
    accelerate=0x0C,
};
enum enum_mode
{
    zero=0x00,//指令
    one=0x01,//环境温度
    two=0x02,//红外测温
    three=0x03,//接受
    four=0x04,//错误
    five=0x05,//初始化
    six=0x06,//浓度
    seven=0x07,//环境湿度
};

struct Settings
{
    enum_instruction instructing;
    enum_mode mode;

};


robot.h

#ifndef ROBOT_H
#define ROBOT_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class QTcpSocket;

namespace Ui {
class Robot;
}

class Robot : public QMainWindow
{
    Q_OBJECT

public:
    explicit Robot(QWidget *parent = 0);
    ~Robot();

    void execCmd(QByteArray buff);                                       //解析读取的指令

signals:
    void signalReceiveData(QByteArray buff);                         //接受数据
    void signalInfraredTemperature(quint16,quint16);             //红外温度
    void signalEnvironmentTemperature(quint16,quint16);     //环境温度
    void signalEnvironmentHumidity(quint16,quint16);          //湿度
    void signalEnvironmentGasCon(quint16,quint16);            //气体浓度

    //电机控制
    void signalMachineryControl(quint16 ,quint16 );


private slots:
    void on_open_pushButton_clicked();

    void on_close_pushButton_clicked();

    void on_forward_pushButton_clicked();
    void convexImage();
    void slotReadData();         //读取数据槽函数
    //接收电机信息,向下位机发送
    void slotReceiveMachineryValue(quint16 ,quint16);

    void on_back_pushButton_clicked();

    void on_stop_pushButton_clicked();

private:
    Ui::Robot *ui;
    QTcpSocket *tcpSocket;
    QString currentForture;
    quint16 blockSuze;
    QSerialPort *my_serialport;
    QImage img;
    QTimer *time_clock;
private:
    void senddata();
    void packSendData(quint16 drive, quint16 drive_cmd,
                      quint16 data_len, quint16 data1,quint16 data2);   //发送整包数据
    void initData();                                              //清空数据
    void initConnect();                                        //连接信号与槽
    void execData();                                            //
    void exec_InfTemData(QByteArray buff);        //红外测温
    void exec_TemData(QByteArray buff);           //环境温度temperature
    void exec_HumData(QByteArray buff);         //环境湿度humidity
    void exec_GasData(QByteArray buff);           //可燃气气体浓度Gas

    //控制电机
    void sendMachineryCmd(quint16 data1,quint16 data2);
    void sendForwardCmd(quint16 drive,const QString &);             //前进指令
    void sendBackCmd(quint16 drive,const QString &);                  //后退指令
    void sendForwardLeftCmd(quint16 drive,const QString &);      //左前行走
    void sendForwardRightCmd(quint16 drive,const QString &);    //右前行走
    void sendBackLeftCmd(quint16 drive,const QString &);            //左退行走
    void sendBackRightCmd(quint16 drive,const QString &);         //右退行走
    void sendAccelerateCmd(quint16 drive,const QString &);        //加速行走
    void sendDeaccelerateCmd(quint16 drive,const QString &);    //减速行走
    void sendStopCmd(quint16 drive,const QString &);                 //停止

private:
    quint16  m_sendBegin;       //起始标志
    quint16  m_potocolLen;      //信息长度
    quint16  m_device;             //设备名
    quint16 m_deviceCmd;      //设备命令
    quint16 m_dataLen;           //数据长度
    quint16  m_data_1;              //数据1
    quint16  m_data_2;              //数据2
    quint16 checkcode;            //校验位

    quint16 getProtocolLen();     //获取信息长度
    quint16 getDevice();             //获取设备名
    quint16 getDeviceCmd();      //设备使能
    quint16 getDataLen();          //数据长度
    quint16 getData1();               //获取数据1
    quint16 getData2();               //获取数据2
    quint16 getCheckCode();     //获取校验码

};

#endif // ROBOT_H

StrToHex.h


#ifndef STRTOHEX_H
#define STRTOHEX_H

#include 
#include 
#include 
#include "robot.h"

class STRTOHEX:public QObject
{
public:
    //16进制字符串转字符数组
    static QByteArray HexstrToByteArray(QString str)
    {
        QByteArray senddata;
        int hexdata,lowhexdata;
        int hexdatalen=0;
        int len=str.length();
        senddata.resize(len/2);
        char lstr,hstr;
        for(int i=0;i=len)
                break;
            lstr=str[i].toLatin1();
            hexdata=ConvertHexChar(hstr);
            lowhexdata=ConvertHexChar(lstr);
            if((hexdata==16)||(lowhexdata==16))
                break;
            else
                hexdata=hexdata*16+lowhexdata;
            i++;
            senddata[hexdatalen]=(char)hexdata;
            hexdatalen++;
        }
        senddata.resize(hexdatalen);
        return senddata;
    }
    //转字符型
    static char ConvertHexChar(char ch)
    {
        if((ch>='0')&&(ch<='9'))
            return ch-0x30;
        else if((ch>='A')&&(ch<='F'))
            return ch-'A'+10;
        else if((ch>='a')&&(ch<='f'))
            return ch-'a'+10;
        else return (-1);
    }
    //字节数组转16进制字符串
    static QString ByteArrayToHexStr(QByteArray data)
    {
        QString temp=" ";
        QString hex=data.toHex();
        for(int i=0;i127)
        {
            temp=data+256;
        }
        else
        {
            temp=data;
        }
        return temp;
    }
    //延时
    static void Sleep(int sec)
    {
        QTime dieTime = QTime::currentTime().addMSecs(sec);
        while( QTime::currentTime() < dieTime )
            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
};
#endif // STRTOHEX_H

开发模式就是这种模式。

向下位机发送数据:

//发送数据
void Robot::senddata()
{
    QByteArray str;
    str.append(m_sendBegin);
    str.append(getProtocolLen());
    str.append(getDevice());
    str.append(getDeviceCmd());
    str.append(getDataLen());
    str.append(getData1());
    str.append(getData2());
    //str.append(getCheckCode());
    checkcode=STRTOHEX::GetCheckCode(str,7);
    str.append(checkcode);
    QString outData;
    outData=STRTOHEX::ByteArrayToHexStr(str);
    ui->textEdit->append("开始发送数据\t");
    ui->textEdit->append(outData);
    ui->textEdit->append("\t");
    tcpSocket->write(str);
    STRTOHEX::Sleep(50);
    tcpSocket->write(str);

}



你可能感兴趣的:(Qt)