添加遥控器功能

This commit is contained in:
hm
2021-04-29 09:54:21 +08:00
parent a98244d7ff
commit bc8040e2e6
13 changed files with 743 additions and 63 deletions
+12 -1
View File
@@ -27,7 +27,18 @@ void JoyStick::setValue(uint16_t ch, uint16_t value)//
if((value > m_max[ch])||(value < m_min[ch]))
{
emit error(Rate_Error);
return;
//return;
if(value > m_max[ch])
{
value = m_max[ch];
}
if(value < m_min[ch])
{
value = m_min[ch];
}
}
m_channel[ch] = value;
@@ -11,10 +11,16 @@ RemoteControl::RemoteControl(QWidget *parent) :
AUX8Switch(new Switch(this))
{
this->setTop(true);
resize(600,400);
setMinimumSize(600,400);
timer = new QTimer();
timer->setInterval(100);
connect(timer,&QTimer::timeout,
this,&RemoteControl::timerout);
joystick_left->setGeometry(0,
this->height()/2 - joystick_left->height()/2,
joystick_left->width(),
@@ -198,6 +204,13 @@ RemoteControl::~RemoteControl()
{
delete joystick_left;
delete joystick_right;
if(timer)
{
timer->stop();
delete timer;
timer = nullptr;
}
}
@@ -260,16 +273,23 @@ void RemoteControl::PowerSwitchUpdate(uint16_t value)
if(value <= 1300)
{
isActive = 0;
isActive = 2;
timer->start();
}
else if(value <= 1600)
{
isActive = 1;
timer->stop();
}
else
{
isActive = 2;
isActive = 0;
timer->stop();
}
//qDebug() << isActive << value;
update();
emit RemoteActive(isActive);
}
@@ -289,6 +309,15 @@ void RemoteControl::stateChanged(void)
rc.append(channel[7]);
rc.append(channel[8]);
rc.append(channel[9]);
rc.append(channel[10]);
rc.append(channel[11]);
rc.append(channel[12]);
rc.append(channel[13]);
rc.append(channel[14]);
rc.append(channel[15]);
rc.append(channel[16]);
rc.append(channel[17]);
rc.append(channel[18]);
if(isActive == 2)
@@ -361,6 +390,11 @@ void RemoteControl::setChannelOveride(QList<uint16_t> rc)
{
if(isActive == 1)
{
for(int i = 1;i <= 18;i++)
{
channel[i] = rc.at(i);
}
if(mode == RightHand)//右手油门
{
joystick_right->setValue(0,rc.at(1));
@@ -386,7 +420,12 @@ void RemoteControl::setChannelOveride(QList<uint16_t> rc)
.arg(rc[0],5).arg(rc[1],4).arg(rc[2],4)\
.arg(rc[3],4).arg(rc[4],4).arg(rc[5],4)\
.arg(rc[6],4).arg(rc[7],4).arg(rc[8],4).arg(rc[9],4));
update();
}
}
void RemoteControl::timerout(void)
{
stateChanged();
}
+12
View File
@@ -7,6 +7,8 @@
#include "QLabel"
#include "ToolsUI/ToolsWidget.h"
#include "QTimer"
class RemoteControl : public ToolsWidget
{
Q_OBJECT
@@ -31,6 +33,8 @@ public:
signals:
void RemoteActive(uint32_t);
void RemoteControlUpdate(QList<uint16_t>);
@@ -56,6 +60,11 @@ protected:
void stateChanged(void);
private slots:
void timerout(void);
private:
QLabel *remotelabel;
@@ -88,6 +97,9 @@ private:
//开关
uint32_t isActive= 0;
QTimer *timer = nullptr;
};
#endif // REMOTECONTROL_H
+16
View File
@@ -315,12 +315,16 @@ MainWindow::MainWindow(QWidget *parent)
toolsui->index2,SLOT(ReplayComplete()),Qt::DirectConnection);
connect(toolsui->index2,SIGNAL(CreateCSV()),
dlink->mavlinknode,SLOT(CreateCSV()),Qt::DirectConnection);
/*
connect(dlink->mavlinknode,SIGNAL(new_remote_ctrl(QList<uint16_t>)),
toolsui->remotecontrol,SLOT(setChannelOveride(QList<uint16_t>)));
*/
//dlink --- toolui-index3
connect(dlink->mavlinknode->Terminal,SIGNAL(Recieve(QString)),
@@ -330,6 +334,18 @@ MainWindow::MainWindow(QWidget *parent)
dlink->mavlinknode->Terminal,SLOT(Transmit(QString)),Qt::DirectConnection);
//dlink ---- rc
qRegisterMetaType<QList<uint16_t>>("QList<uint16_t>");
qRegisterMetaType<uint32_t>("uint32_t");
connect(dlink->mavlinknode->RC,SIGNAL(new_remote_ctrl(QList<uint16_t>)),
toolsui->remotecontrol,SLOT(setChannelOveride(QList<uint16_t>)));
connect(toolsui->remotecontrol,SIGNAL(RemoteControlUpdate(QList<uint16_t>)),
dlink->mavlinknode->RC,SLOT(SoftRCUpdate(QList<uint16_t>)),Qt::DirectConnection);
connect(toolsui->remotecontrol,SIGNAL(RemoteActive(uint32_t)),
dlink->mavlinknode->RC,SLOT(setRCActive(uint32_t)),Qt::DirectConnection);
//setting ----- map
+4
View File
@@ -53,21 +53,25 @@ DEFINES += QtMavlinkNode
HEADERS += \
Terminal.h \
ThreadTemplet.h \
commandprocess.h \
mavlinknode.h \
parameterprocess.h \
missionprocess.h \
mavlinknodeglobal.h \
rcprocess.h \
replay.h \
sbusparser.h \
statusprocess.h
SOURCES += \
Terminal.cpp \
ThreadTemplet.cpp \
commandprocess.cpp \
mavlinknode.cpp \
parameterprocess.cpp \
missionprocess.cpp \
rcprocess.cpp \
replay.cpp \
sbusparser.cpp \
statusprocess.cpp
+72
View File
@@ -0,0 +1,72 @@
#include "ThreadTemplet.h"
ThreadTemplet::ThreadTemplet(QObject *parent) : QObject(parent)
{
running_flag = false;
thread = new QThread();
this->moveToThread(thread);
connect(thread, &QThread::started, this, &ThreadTemplet::process);
setRunFrq(50);//default frq = 50
}
ThreadTemplet::~ThreadTemplet()
{
stop();
}
void ThreadTemplet::setRunFrq(uint32_t frq)
{
if((frq != 0)||(frq <= 1000))
{
running_frq = frq;
qDebug() << "set Mavlink Node running frquency:" <<frq <<"Hz";
}
}
void ThreadTemplet::start()
{
if(!thread->isRunning())
{
running_flag = true;
thread->start();
qDebug() << "thread start" << running_flag;
}
else
{
qDebug() << "thread has started";
}
}
void ThreadTemplet::stop()
{
if(thread->isRunning())
{
running_flag = false;
disconnect(thread, nullptr, nullptr, nullptr);
thread->quit();
thread->deleteLater();
thread = nullptr;
}
else
{
qDebug() << "thread is not running";
}
}
void ThreadTemplet::process()//线程函数
{
uint8_t count = 0;
while (running_flag)
{
count ++;
QThread::msleep(1000/running_frq);
}
}
+68
View File
@@ -0,0 +1,68 @@
#ifndef THREADTEMPLET_H
#define THREADTEMPLET_H
#include <QObject>
#include "QThread"
#include "QFile"
#include "QDebug"
#ifdef QtMavlinkNode
#include <mavlinknodeglobal.h>
class MAVLINKNODESHARED_EXPORT ThreadTemplet : public QObject {
#else
class ThreadTemplet : public QObject
{
#endif
Q_OBJECT
public:
typedef struct {
qint32 max_size;
quint8 select;
QByteArray buff[2];
}_buffdef;
explicit ThreadTemplet(QObject *parent = nullptr);
~ThreadTemplet();
signals:
public slots:
//线程对外接口
void setRunFrq(uint32_t frq);
void start();
void stop();
bool isActive(void)
{
return running_flag;
}
//缓存对外接口
private slots:
//线程私有接口
void process();
//缓存私有接口
//解析
protected:
bool running_flag = false;
quint32 running_frq = 200;//200Hz
QThread *thread;
};
#endif // THREADTEMPLET_H
+26 -48
View File
@@ -130,8 +130,18 @@ MavLinkNode::MavLinkNode(QObject *parent) : QObject(parent)
connect(Terminal,SIGNAL(showMessage(QString,int)),
this,SIGNAL(showMessage(QString,int)),Qt::DirectConnection);
RC = new rcprocess();
RC->setGCSID(Current_sysID,Current_CompID);
connect(RC,SIGNAL(SendMessageTo(quint8,quint8*,quint16)),
this,SIGNAL(SendMessageTo(quint8,quint8*,quint16)),Qt::DirectConnection);
connect(this,SIGNAL(setCurrentID(int,int)),
RC,SLOT(setID(int,int)),Qt::DirectConnection);
connect(RC,SIGNAL(showMessage(QString,int)),
this,SIGNAL(showMessage(QString,int)),Qt::DirectConnection);
isCommunicationLost = false;
}
@@ -276,6 +286,12 @@ void MavLinkNode::start()
{
Terminal->start();
}
if(RC)
{
RC->start();
}
}
else
{
@@ -364,6 +380,16 @@ void MavLinkNode::stop()
}
}
if(RC)
{
if(RC->isActive())
{
RC->stop();
delete RC;
RC = nullptr;
}
}
CreateCSV();
@@ -1429,37 +1455,6 @@ void MavLinkNode::update15Hz(void)
rtkrawdata = rtkrawdata.mid(180);
}
else if (rcin_update)
{
if (!remote_enabled || rcin_cnt > 0)
{
rcin_cnt--;
mavlink_rc_channels_override_t command;
command.chan1_raw = rcin[0];
command.chan2_raw = rcin[1];
command.chan3_raw = rcin[2];
command.chan4_raw = rcin[3];
command.chan5_raw = rcin[4];
command.chan6_raw = rcin[5];
command.chan7_raw = rcin[6];
command.chan8_raw = rcin[7];
command.chan9_raw = rcin[8];
command.chan10_raw = rcin[9];
command.chan11_raw = rcin[10];
command.chan12_raw = rcin[11];
command.chan13_raw = rcin[12];
command.chan14_raw = rcin[13];
command.chan15_raw = rcin[14];
command.chan16_raw = rcin[15];
command.chan17_raw = rcin[16];
command.chan18_raw = rcin[17];
command.target_component = 2;
command.target_system = 0;
mavlink_msg_rc_channels_override_encode(0,0,&msg,&command);
//Send(msg);
}
}
}
void MavLinkNode::readRTK(QByteArray datagram)
@@ -1486,24 +1481,7 @@ void MavLinkNode::readRemote(QByteArray datagram)
{
for (QByteArray::const_iterator i = datagram.cbegin(); i != datagram.cend(); ++i)
{
if (sbus.parse_char(*i))
{
/*
for (int i=0; i<18; ++i)
{
rcin[i] = sbus.Channel[i+1];
}
rcin_cnt = 10;
*/
QList<uint16_t> list;
for (int i=0; i<13; ++i)
{
list.append(sbus.Channel[i]);
}
emit new_remote_ctrl(list);
}
}
}
}
+4 -7
View File
@@ -16,6 +16,7 @@
#include "sbusparser.h"
//#include "QAxObject"
#include "rcprocess.h"
#ifdef QtMavlinkNode
#include <mavlinknodeglobal.h>
@@ -83,7 +84,7 @@ public:
commandprocess *Commander = nullptr;
statusprocess *Status = nullptr;
terminal *Terminal = nullptr;
rcprocess *RC = nullptr;
bool isCommunicationLost = false;
@@ -106,11 +107,7 @@ public:
float rssi = 100;
uint16_t rcin[20];
int rcin_cnt = 0;
bool rcin_update = true;
bool remote_enabled;
QByteArray rtkrawdata;
@@ -178,7 +175,7 @@ signals:
void signal_servo_output_raw(mavlink_servo_output_raw_t *servo);
void new_remote_ctrl(QList<uint16_t>);
void updateDlink(float rssi,uint64_t in,uint64_t out);
void CommuniationLost(bool);
@@ -279,7 +276,7 @@ protected:
QThread *Parameterthread;
SBusParser sbus;
QTimer *gdt_timer = nullptr;
QTimer *timer = nullptr;
+336
View File
@@ -0,0 +1,336 @@
#include "rcprocess.h"
rcprocess::rcprocess(QObject *parent) : QObject(parent)
{
//初始化ID
running_flag = false;
thread = new QThread();
this->moveToThread(thread);
connect(thread, &QThread::started, this, &rcprocess::process);
setRunFrq(50);//50
//初始化buff
initbuff();
rcin[0] = 1500;
rcin[1] = 1500;
rcin[2] = 1100;
rcin[3] = 1500;
rcin[4] = 1100;
rcin[5] = 1100;
rcin[6] = 1100;
rcin[7] = 1100;
rcin[8] = 1100;
rcin[9] = 1100;
rcin[10] = 1500;
rcin[11] = 1100;
rcin[12] = 1100;
for (int i=13; i<20; ++i)
{
rcin[i] = 1100;
}
isRCActive = 0;
}
rcprocess::~rcprocess()
{
stop();
}
void rcprocess::setID(int m_sysid,int m_compid)
{
sysid = (uint8_t)m_sysid;
compid = (uint8_t)m_compid;
}
void rcprocess::Send(mavlink_message_t msg)
{
uint8_t buff[MAVLINK_MAX_PACKET_LEN+sizeof(quint64)];
//quint64 currentTimestamp = ((quint64)QDateTime::currentMSecsSinceEpoch()) * 1000;
//qToBigEndian(currentTimestamp, buff);
//uint16_t len = mavlink_msg_to_send_buffer(buff + sizeof(quint64), &msg);
uint16_t len = mavlink_msg_to_send_buffer(buff, &msg);
emit SendMessageTo(0,buff, len);//使用信号和槽
}
void rcprocess::setRunFrq(uint32_t frq)
{
if((frq != 0)||(frq <= 1000))
{
running_frq = frq;
qDebug() << "set running frquency:" <<frq <<"Hz";
}
}
void rcprocess::start()
{
if(!thread->isRunning())
{
//初始化buff
initbuff();
timer = new QTimer();
timer->setInterval(66);
// connect(timer, &QTimer::timeout,
// this, &rcprocess::update15Hz,Qt::DirectConnection);
timer->start();
running_flag = true;
thread->start();
qDebug() << "rc thread start" << running_flag;
}
else
{
qDebug() << "thread has started";
}
}
void rcprocess::stop()
{
if(thread->isRunning())
{
running_flag = false;
disconnect(thread, nullptr, nullptr, nullptr);
thread->quit();
thread->deleteLater();
thread = nullptr;
}
else
{
qDebug() << "thread is not running";
}
}
//这里一直在解码,一直检查双缓冲里面是否有数据,有就解码,没有就休息
uint64_t lastTime = 0;
void rcprocess::process()//线程函数
{
uint8_t count = 0;
QByteArray datagram = nullptr;
while (running_flag)
{
count ++;
QThread::msleep(1000/running_frq);
//解码从串口来的
datagram.clear();
datagram = readbuff(SourceType::s_port);//每次全部读取
//qDebug() << "serial port parse";
if(datagram.size() > 0)
{
/*
QString s;
for(int i = 0;i < datagram.size();i++)
{
s.append(QString::number((uint8_t)datagram.data()[i],16).toUpper());
s.append(' ');
}
qDebug() << s;
*/
parse(SourceType::s_port,datagram);
}
quint64 currentTimestamp = (quint64)QDateTime::currentMSecsSinceEpoch();
if((currentTimestamp - lastTime) > 66)
{
lastTime = currentTimestamp;
update15Hz();
}
}
}
void rcprocess::initbuff(void)
{
client_buff.max_size = 10 * 1024 *1024;//10M
client_buff.buff[0].clear();
client_buff.buff[1].clear();
client_buff.select = 0;
serial_buff.max_size = 10 * 1024 *1024;
serial_buff.buff[0].clear();
serial_buff.buff[1].clear();
serial_buff.select = 0;
}
void rcprocess::setbuff(quint32 src,QByteArray data)
{
switch (src) {
default:
case SourceType::c_sock:
//当前的buff超过10M字节之后就清除,防爆机制,不然buff太大后容易卡死
if(client_buff.buff[client_buff.select].size() >= client_buff.max_size)
{
client_buff.buff[client_buff.select].clear();
qDebug() << "client_buff.buff " << client_buff.select <<" OVERFLOW";
}
client_buff.buff[client_buff.select].append(data);
break;
case SourceType::s_port:
//当前的buff超过10M字节之后就清除,防爆机制,不然buff太大后容易卡死
if(serial_buff.buff[serial_buff.select].size() >= serial_buff.max_size)
{
serial_buff.buff[serial_buff.select].clear();
qDebug() << "serial_buff.buff " << serial_buff.select <<" OVERFLOW";
}
serial_buff.buff[serial_buff.select].append(data);
break;
}
}
QByteArray rcprocess::readbuff(quint32 src)
{
QByteArray datagram;
switch (src) {
default:
case SourceType::c_sock:
if(client_buff.select == 0)
{
datagram.clear();
datagram.append(client_buff.buff[1]);
//清除这个未选择的buff
client_buff.buff[1].clear();
//读取完成,可以往这个内存里面写数了
client_buff.select = 1;
}
else if(client_buff.select == 1)
{
datagram.clear();
datagram.append(client_buff.buff[0]);
//清除这个未选择的buff
client_buff.buff[0].clear();
//读取完成,可以往这个内存里面写数了
client_buff.select = 0;
}
break;
case SourceType::s_port:
if(serial_buff.select == 0)
{
datagram.clear();
datagram.append(serial_buff.buff[1]);
//读取完成,可以往这个内存里面写数了
serial_buff.buff[1].clear();
serial_buff.select = 1;
}
else if(serial_buff.select == 1)
{
datagram.clear();
datagram.append(serial_buff.buff[0]);
//读取完成,可以往这个内存里面写数了
serial_buff.buff[0].clear();
serial_buff.select = 0;
}
break;
}
return datagram;
}
void rcprocess::parse(quint32 src,QByteArray datagram)
{
for (QByteArray::const_iterator i = datagram.cbegin(); i != datagram.cend(); ++i)
{
if(sbus.parse_char((uint8_t)*i))
{
rcin_update = true;
if(isRCActive == 1)
{
for (int i=0; i<18; ++i)
{
rcin[i] = sbus.Channel[i+1];
}
rcin_cnt = 13;
}
sbuslist.clear();
for (int i=0; i<13; ++i)
{
sbuslist.append(sbus.Channel[i]);
}
emit new_remote_ctrl(sbuslist);
}
}
}
void rcprocess::update15Hz(void)
{
uint8_t buff[MAVLINK_MAX_PACKET_LEN+sizeof(quint64)];
quint64 currentTimestamp = ((quint64)QDateTime::currentMSecsSinceEpoch()) * 1000;
qToBigEndian(currentTimestamp, buff);
mavlink_message_t msg;
if (rcin_update)
{
if ((isRCActive != 0) || rcin_cnt > 0)
{
rcin_cnt--;
mavlink_rc_channels_override_t command;
command.chan1_raw = rcin[0];
command.chan2_raw = rcin[1];
command.chan3_raw = rcin[2];
command.chan4_raw = rcin[3];
command.chan5_raw = rcin[4];
command.chan6_raw = rcin[5];
command.chan7_raw = rcin[6];
command.chan8_raw = rcin[7];
command.chan9_raw = rcin[8];
command.chan10_raw = rcin[9];
command.chan11_raw = rcin[10];
command.chan12_raw = rcin[11];
command.chan13_raw = rcin[12];
command.chan14_raw = rcin[13];
command.chan15_raw = rcin[14];
command.chan16_raw = rcin[15];
command.chan17_raw = rcin[16];
command.chan18_raw = rcin[17];
command.target_component = (uint8_t)isRCActive;
command.target_system = sysid;
mavlink_msg_rc_channels_override_encode(Current_sysID,Current_CompID,&msg,&command);
Send(msg);
rcin_update = false;
}
}
}
void rcprocess::SoftRCUpdate(QList<uint16_t> rc)
{
if(isRCActive == 2)
{
rcin_update = true;
for (int i=0; i<18; ++i)
{
rcin[i] = rc.at(i+1);
}
rcin_cnt = 10;
}
}
+146
View File
@@ -0,0 +1,146 @@
#ifndef RCPROCESS_H
#define RCPROCESS_H
#include <QObject>
#include "QThread"
#include "QFile"
#include "QDebug"
#include "QtEndian"
#include "QDateTime"
#include "QTimer"
#include "mavlink.h"
#include "sbusparser.h"
#ifdef QtMavlinkNode
#include <mavlinknodeglobal.h>
class MAVLINKNODESHARED_EXPORT rcprocess : public QObject {
#else
class rcprocess : public QObject
{
#endif
Q_OBJECT
public:
typedef struct {
qint32 max_size;
quint8 select;
QByteArray buff[2];
}_buffdef;
explicit rcprocess(QObject *parent = nullptr);
~rcprocess();
void setGCSID(int m_sysid, int m_compid)
{
Current_sysID = m_sysid;
Current_CompID = m_compid;
}
signals:
void SendMessageTo(quint8 ch, quint8 *data,quint16 len);
void new_remote_ctrl(QList<uint16_t>);
void showMessage(const QString &message,int TimeOut = 0);
public slots:
//线程对外接口
void setRunFrq(uint32_t frq);
void start();
void stop();
bool isActive(void)
{
return running_flag;
}
//缓存对外接口
void setID(int m_sysid, int m_compid);
void setbuff(quint32 src, QByteArray data);
void SoftRCUpdate(QList<uint16_t> rc);
void setRCActive(uint32_t value)
{
isRCActive = value;
qDebug() << "set ch" << isRCActive;
}
private slots:
//线程私有接口
void Send(mavlink_message_t msg);
void process();
//缓存私有接口
void initbuff(void);
QByteArray readbuff(quint32 src);
void update15Hz(void);
//解析
void parse(quint32 src,QByteArray datagram);
protected:
int Current_sysID = 0xF1;
int Current_CompID = MAV_COMP_ID_MISSIONPLANNER;
//目标id
uint8_t sysid;
uint8_t compid;
enum SourceType{
c_sock = 0,
s_port = 1
};
bool hasConneted = false;
int32_t CommucationOverCount = 5;
uint64_t CommucationOverTimer = 5000;
uint8_t GCS_System_ID = 0xFF;
bool running_flag = false;
quint32 running_frq = 200;//200Hz
QThread *thread;
QByteArray databuff;
_buffdef serial_buff;
_buffdef client_buff;
uint16_t rcin[20];
int rcin_cnt = 0;
bool rcin_update = true;
uint32_t isRCActive = 0;
SBusParser sbus;
QList<uint16_t> sbuslist;
QTimer *timer = nullptr;
};
#endif // RCPROCESS_H
+6 -4
View File
@@ -25,11 +25,13 @@ DLink::DLink(QObject *parent) : QObject(parent)
connect(this,SIGNAL(recieveMessage(quint32,QByteArray)),
mavlinknode,SLOT(setbuff(quint32,QByteArray)),Qt::DirectConnection);
/*
connect(this,SIGNAL(getRTK(QByteArray)),
mavlinknode,SLOT(readRTK(QByteArray)),Qt::DirectConnection);
*/
connect(this,SIGNAL(getRemote(QByteArray)),
mavlinknode,SLOT(readRemote(QByteArray)),Qt::DirectConnection);
connect(this,SIGNAL(getRemote(quint32,QByteArray)),
mavlinknode->RC,SLOT(setbuff(quint32,QByteArray)),Qt::DirectConnection);
@@ -571,7 +573,7 @@ void DLink::readRTKPendingDatagrams(void)
if(datagram.size() > 0)
{
emit getRTK(datagram);
emit getRTK(SourceType::s_port,datagram);
}
}
}
@@ -587,7 +589,7 @@ void DLink::readRemotePendingDatagrams(void)
if(datagram.size() > 0)
{
emit getRemote(datagram);
emit getRemote(SourceType::s_port,datagram);
}
}
+2 -3
View File
@@ -8,7 +8,6 @@
#include "QDebug"
#include "mavlinknode.h"
QT_BEGIN_NAMESPACE
@@ -70,8 +69,8 @@ signals:
QVariant m_Param3,QVariant m_Param4,
QVariant m_Param5);
void getRemote(QByteArray);
void getRTK(QByteArray);
void getRemote(quint32,QByteArray);
void getRTK(quint32,QByteArray);
void info(double rssi,double in,double out);