Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 390 → Rev 391

/QMK-Groundstation/branches/own_com_lib/Forms/mktool.cpp
0,0 → 1,1854
/***************************************************************************
* Copyright (C) 2008 by Manuel Schrape *
* manuel.schrape@gmx.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
 
// TODO: Wiederholungssenden wieder einbauen
 
#include <QtGui>
 
#include <QLineEdit>
#include <QString>
#include <QTimer>
#include <QIcon>
#include <QToolButton>
#include <QSpinBox>
#include <QAction>
#include <QPalette>
 
#include "mktool.h"
#include "dlg_Config.h"
#include "dlg_Motortest.h"
#include "dlg_Preferences.h"
#include "../global.h"
#include "../Classes/ToolBox.h"
#include "../com/Parser.h"
 
#include <stdlib.h>
 
MKTool::MKTool()
{
setupUi(this);
 
Settings = new cSettings;
 
init_Arrays();
init_GUI();
init_Cockpit();
 
init_Objects();
init_Connections();
 
init_Plot();
}
 
void MKTool::init_GUI()
{
setWindowTitle(QA_NAME + " v" + QA_VERSION);
 
// Tab mit Debug-Elementen verbergen
tab_Main->removeTab(6);
// Develop - Nicht gebrauchte sachen abschalten.
pb_SettingsReset->hide();
pb_Flash->hide();
rb_NC->hide();
 
// Beta-Sachen einschalten.
#ifdef _BETA_
ac_QMKServer->setEnabled(true);
#endif
 
// Settings-Tab hinzufügen.
f_Settings = new wdg_Settings( this );
f_Settings->set_Config(Settings);
tab_Main->insertTab ( 2, f_Settings, ac_View2->icon(), tr("FC-Settings"));
tab_Main->widget(2)->setObjectName("Tab_2");
 
// Zusätzliche Widgets in die Toolbar.
tb_TTY->addWidget(lb_Port);
tb_TTY->addWidget(le_Port);
 
tb_Hardware->addWidget(rb_SelFC);
tb_Hardware->addWidget(rb_SelNC);
tb_Hardware->addWidget(rb_SelMag);
 
tb_Allgemein->setVisible(Settings->GUI.ToolViews[0]);
tb_Werkzeuge->setVisible(Settings->GUI.ToolViews[1]);
tb_Debug->setVisible(Settings->GUI.ToolViews[2]);
tb_TTY->setVisible(Settings->GUI.ToolViews[3]);
tb_Hardware->setVisible(Settings->GUI.ToolViews[4]);
 
#ifdef _EEEPC_
lb_Status->hide();
#endif
 
lb_Status->setText(tr("Hallo bei QMK-Groundstation...!!!"));
 
resize(Settings->GUI.Size);
move(Settings->GUI.Point);
 
if (Settings->GUI.isMax)
{
showMaximized();
}
 
// Analoglabels anzeigen
for (int a = 0; a < MaxAnalog; a++)
{
lb_Analog[a]->setText(Settings->Analog1.Label[a]);
}
 
// Kopie der Tabs anlegen
for (int b = 0; b < 7; b++)
{
TabWidgets[b] = tab_Main->widget(b);
}
 
// Ausgeblendete Tabs ausblenden
for (int c = 0; c < 7; c++)
{
if (Settings->GUI.TabViews[c] == false)
{
QString TabName = QString("Tab_%1").arg(c);
 
for (int d = 0; d < tab_Main->count(); d++)
{
if (tab_Main->widget(d)->objectName() == TabName)
{
tab_Main->removeTab(d);
}
}
}
}
 
ac_View0->setChecked(Settings->GUI.TabViews[0]);
ac_View1->setChecked(Settings->GUI.TabViews[1]);
ac_View2->setChecked(Settings->GUI.TabViews[2]);
ac_View3->setChecked(Settings->GUI.TabViews[3]);
ac_View4->setChecked(Settings->GUI.TabViews[4]);
ac_View5->setChecked(Settings->GUI.TabViews[5]);
ac_View6->setChecked(Settings->GUI.TabViews[6]);
 
le_Port->setText(Settings->TTY.Port);
 
cb_ShowMSG->setChecked(Settings->GUI.Term_Info);
cb_ShowData->setChecked(Settings->GUI.Term_Data);
cb_ShowAlways->setChecked(Settings->GUI.Term_Always);
}
 
void MKTool::init_Cockpit()
{
// Cockpit-Elemente
QPalette newPalette;
 
newPalette.setColor(QPalette::Base, Qt::darkBlue);
newPalette.setColor(QPalette::Foreground, QColor(Qt::darkBlue).dark(120));
newPalette.setColor(QPalette::Text, Qt::white);
 
Compass->setScaleOptions(QwtDial::ScaleTicks | QwtDial::ScaleLabel);
Compass->setScaleTicks(0, 0, 3);
Compass->setScale(36, 5, 0);
 
Compass->setNeedle(new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, true, Qt::red, QColor(Qt::gray).light(130)));
Compass->setPalette(newPalette);
Compass->setMaximumSize(QSize(MeterSize, MeterSize));
Compass->setMinimumSize(QSize(MeterSize, MeterSize));
 
QPalette newPalette1;
 
newPalette1.setColor(QPalette::Base, Qt::darkBlue);
newPalette1.setColor(QPalette::Foreground, QColor(255,128,0).dark(120));
newPalette1.setColor(QPalette::Text, Qt::white);
 
Attitude = new AttitudeIndicator(this);
Attitude->setMaximumSize(QSize(MeterSize, MeterSize));
Attitude->setMinimumSize(QSize(MeterSize, MeterSize));
Attitude->setPalette(newPalette1);
 
verticalLayout->addWidget(Attitude);
 
qwt_Rate->setRange(-10.0, 10.0, 0.1, 0);
 
newPalette1.setColor(QPalette::Foreground, QColor(Qt::darkBlue).dark(120));
 
SpeedMeter = new cSpeedMeter(this);
SpeedMeter->setMaximumSize(QSize(MeterSize, MeterSize));
SpeedMeter->setMinimumSize(QSize(MeterSize, MeterSize));
SpeedMeter->setPalette(newPalette1);
SpeedMeter->setRange(0.0, 5.0);
SpeedMeter->setScale(1, 2, 0.5);
SpeedMeter->setProperty("END", 5);
 
LayOut_Speed->addWidget(SpeedMeter);
}
 
void MKTool::init_Objects()
{
// QTimer-Instanzen
Ticker = new QTimer(this);
 
// Verbindungsobject
o_Connection = new cConnection();
 
// neuer Logger
logger = new Logger(Settings, &Mode);
 
// LCD-Dialog
f_LCD = new dlg_LCD(this);
 
// LCD-Dialog
f_MotorMixer = new dlg_MotorMixer(this);
 
// LCD-Dialog
f_Map = new dlg_Map(this);
f_Map->create_Map(Settings);
 
KML_Server = new cKML_Server();
 
QMK_Server = new cQMK_Server();
QMK_Server->setProperty("Connect", false);
 
if (Settings->Server.StartServer)
{
ac_StartServer->setChecked(true);
KML_Server->start_Server(Settings->Server.Port.toInt(), Settings);
}
}
 
void MKTool::init_Connections()
{
connect(Dec, SIGNAL(clicked()), this, SLOT(slot_Test()));
 
// Waypoints übergeben
connect(f_Map, SIGNAL(set_Target(sWayPoint)), this , SLOT(slot_MAP_SetTarget(sWayPoint)));
connect(f_Map, SIGNAL(set_WayPoints(QList<sWayPoint>)), this , SLOT(slot_MAP_SetWayPoints(QList<sWayPoint>)));
 
// Daten Senden / Empfangen
connect(o_Connection, SIGNAL(newData(sRxData)), this, SLOT(slot_newData(sRxData)));
connect(o_Connection, SIGNAL(showTerminal(int, QString)), this, SLOT(slot_showTerminal(int, QString)));
 
// Serielle Verbundung öffnen / schließen
connect(ac_ConnectTTY, SIGNAL(triggered()), this, SLOT(slot_OpenPort()));
 
// TCP-Connection verbinden / trennen
connect(ac_QMKServer, SIGNAL(triggered()), this, SLOT(slot_QMKS_Connect()));
 
// Buttons Settings lesen / schreiben
connect(f_Settings->pb_Read, SIGNAL(clicked()), this, SLOT(slot_GetFCSettings()));
connect(f_Settings->pb_Write, SIGNAL(clicked()), this, SLOT(slot_SetFCSettings()));
 
// Actions
connect(ac_Config, SIGNAL(triggered()), this, SLOT(slot_ac_Config()));
connect(ac_Preferences, SIGNAL(triggered()), this, SLOT(slot_ac_Preferences()));
connect(ac_Motortest, SIGNAL(triggered()), this, SLOT(slot_ac_Motortest()));
connect(ac_MotorMixer, SIGNAL(triggered()), this, SLOT(slot_ac_MotorMixer()));
connect(ac_LCD, SIGNAL(triggered()), this, SLOT(slot_ac_LCD()));
connect(ac_Map, SIGNAL(triggered()), this, SLOT(slot_ac_Map()));
connect(ac_FastDebug, SIGNAL(triggered()), this, SLOT(slot_ac_FastDebug()));
connect(ac_NoDebug, SIGNAL(triggered()), this, SLOT(slot_ac_NoDebug()));
connect(ac_FastNavi, SIGNAL(triggered()), this, SLOT(slot_ac_FastNavi()));
connect(ac_NoNavi, SIGNAL(triggered()), this, SLOT(slot_ac_NoNavi()));
connect(ac_GetLabels, SIGNAL(triggered()), this, SLOT(slot_ac_GetLabels()));
 
// Plotter starten / scrollen
connect(scroll_plot, SIGNAL(valueChanged(int)), this, SLOT(slot_ScrollPlot(int)));
connect(ac_StartPlotter, SIGNAL(triggered()), this, SLOT(slot_ac_StartPlotter()));
connect(ac_StartServer, SIGNAL(triggered()), this, SLOT(slot_ac_StartServer()));
 
// Tabs ein & ausblenden
connect(ac_View0, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
connect(ac_View1, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
connect(ac_View2, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
connect(ac_View3, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
connect(ac_View4, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
connect(ac_View5, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
connect(ac_View6, SIGNAL(triggered()), this, SLOT(slot_ac_View()));
 
connect(ac_SelNC, SIGNAL(triggered()), this, SLOT(slot_ac_Hardware()));
connect(ac_SelFC, SIGNAL(triggered()), this, SLOT(slot_ac_Hardware()));
connect(ac_SelMag, SIGNAL(triggered()), this, SLOT(slot_ac_Hardware()));
 
connect(rb_SelNC, SIGNAL(clicked()), this, SLOT(slot_rb_Hardware()));
connect(rb_SelFC, SIGNAL(clicked()), this, SLOT(slot_rb_Hardware()));
connect(rb_SelMag, SIGNAL(clicked()), this, SLOT(slot_rb_Hardware()));
 
// firmeware Updateen / flashen
connect(pb_Update, SIGNAL(clicked()), this, SLOT(slot_pb_Update()));
connect(pb_HexFile, SIGNAL(clicked()), this, SLOT(slot_pb_HexFile()));
 
// Wegpunkt-Befehl
connect(pb_FlyTo, SIGNAL(clicked()), this, SLOT(slot_pb_SendTarget()));
 
// CVS-Record starten / stoppen
connect(ac_RecordCSV, SIGNAL(triggered()), this, SLOT(slot_RecordLog()));
 
// Timer-Events
connect(Ticker, SIGNAL(timeout()), SLOT(slot_Ticker()));
 
// Seitenwechsel
connect(tab_Main, SIGNAL(currentChanged(int)), this, SLOT(slot_TabChanged(int)));
// connect(f_Settings->tab_Par, SIGNAL(currentChanged(int)), this, SLOT(slot_TabChanged(int)));
connect(f_Settings->listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(slot_TabChanged(int)));
 
// About QMK & About-QT Dialog einfügen
connect(ac_About, SIGNAL(triggered()), this, SLOT(slot_ac_About()));
menu_Help->addAction(trUtf8("Über &Qt"), qApp, SLOT(aboutQt()));
}
 
void MKTool::init_Arrays()
{
lb_Analog[0] = lb_A_0;
lb_Analog[1] = lb_A_1;
lb_Analog[2] = lb_A_2;
lb_Analog[3] = lb_A_3;
lb_Analog[4] = lb_A_4;
lb_Analog[5] = lb_A_5;
lb_Analog[6] = lb_A_6;
lb_Analog[7] = lb_A_7;
lb_Analog[8] = lb_A_8;
lb_Analog[9] = lb_A_9;
lb_Analog[10] = lb_A_10;
lb_Analog[11] = lb_A_11;
lb_Analog[12] = lb_A_12;
lb_Analog[13] = lb_A_13;
lb_Analog[14] = lb_A_14;
lb_Analog[15] = lb_A_15;
lb_Analog[16] = lb_A_16;
lb_Analog[17] = lb_A_17;
lb_Analog[18] = lb_A_18;
lb_Analog[19] = lb_A_19;
lb_Analog[20] = lb_A_20;
lb_Analog[21] = lb_A_21;
lb_Analog[22] = lb_A_22;
lb_Analog[23] = lb_A_23;
lb_Analog[24] = lb_A_24;
lb_Analog[25] = lb_A_25;
lb_Analog[26] = lb_A_26;
lb_Analog[27] = lb_A_27;
lb_Analog[28] = lb_A_28;
lb_Analog[29] = lb_A_29;
lb_Analog[30] = lb_A_30;
lb_Analog[31] = lb_A_31;
}
 
void MKTool::init_Plot()
{
NextPlot = 0;
 
qwtPlot->setCanvasBackground(QColor(QRgb(0x00000000)));
 
qwtPlot->insertLegend(new QwtLegend(), QwtPlot::RightLegend);
 
QwtPlotGrid *Grid = new QwtPlotGrid();
Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
 
Grid->attach(qwtPlot);
 
qwtPlot->setAxisScale(QwtPlot::xBottom,0,Settings->Data.Plotter_Count,0);
 
for (int a = 0; a < MaxAnalog; a++)
{
Plot[a] = new QwtPlotCurve(Settings->Analog1.Label[a]);
Plot[a]->setPen(QPen(QColor(Def_Colors[a])));
// Plot[a]->setRenderHint(QwtPlotItem::RenderAntialiased);
 
if (Settings->Analog1.PlotView[a])
Plot[a]->attach(qwtPlot);
}
qwtPlot->replot();
}
 
void MKTool::slot_set_Settings(cSettings *t_Settings)
{
Settings = t_Settings;
}
 
void MKTool::slot_Test()
{
sRxData RX;
 
RX.str = IN->text().toLatin1().data();
 
RX.input = (char *)RX.str.c_str();
 
slot_newData(RX);
}
 
// KML-Datei nach Wegpunkt parsen
// TODO: Richtigen KML-Parser bauen
void MKTool::parse_TargetKML()
{
QString Tmp = te_KML->toPlainText().simplified();
QStringList List;
 
if ((Tmp.contains("<kml xmlns=\"http://earth.google.com/kml/2.2\">")) && (Tmp.contains("<coordinates>")))
{
List = Tmp.split("<coordinates>");
List = List[1].split(",");
 
le_TarLong->setText(ToolBox::get_Float((List[0].toDouble() * 10000000), 7));
le_TarLat->setText(ToolBox::get_Float((List[1].toDouble() * 10000000), 7));
}
}
 
// Waypoint zur NC Senden.
void MKTool::slot_pb_SendTarget()
{
if ((Navi.Current.Longitude == 0) && (Navi.Current.Latitude == 0))
{
QMessageBox msgB;
QString msg;
msgB.setText(tr("Fehler: Es konnten keine GPS-Daten vom Mikrokopter empfangen werden"));
msgB.exec();
return;
}
 
//erstelle einen Wegpunkt, den die NaviCtrl auswerten kann
Waypoint_t desired_pos;
bool ok_lat, ok_lon;
 
//eingegebene Daten holen
double desired_long, desired_lat;
 
desired_long = le_TarLong->text().toDouble(&ok_lon);
desired_lat = le_TarLat->text().toDouble(&ok_lat);
 
if (ok_lon && desired_long < 100)
desired_long *= 10000000+0.5;
 
if (ok_lat && desired_lat < 100)
desired_lat *= 10000000+0.5;
 
//fülle Wegpunkt-Daten
desired_pos.Position.Altitude = 0;
desired_pos.Position.Longitude = int32_t(desired_long);
desired_pos.Position.Latitude = int32_t(desired_lat);
desired_pos.Position.Status = NEWDATA;
desired_pos.Heading = -1;
desired_pos.ToleranceRadius = 5;
desired_pos.HoldTime = sb_TarTime->value();
desired_pos.Event_Flag = 0;
desired_pos.reserve[0] = 0; // reserve
desired_pos.reserve[1] = 0; // reserve
desired_pos.reserve[2] = 0; // reserve
desired_pos.reserve[3] = 0; // reserve
 
//...und sende ihn an die NaviCtrl
int max_radius = 10000;
if (ok_lat && ok_lon &&
abs((double)(Navi.Current.Longitude - desired_pos.Position.Longitude)) < max_radius &&
abs((double)(Navi.Current.Latitude - desired_pos.Position.Latitude)) < max_radius)
{
o_Connection->send_Cmd('s', ADDRESS_NC, (char *)&desired_pos, sizeof(desired_pos), false);
}
else
{
QMessageBox msgB;
QString msg;
msg += tr("Bitte die Eingabe ueberpruefen!\n");
msg += tr("Die Werte muessen sich in der Naehe der aktuellen Koordinaten befinden\n");
msg += "(Lon: ";
msg += ToolBox::get_Float(Navi.Current.Longitude,7);
msg += ", ";
msg += "Lat: ";
msg += ToolBox::get_Float(Navi.Current.Latitude,7);
msg += ")";
msgB.setText(msg);
msgB.exec();
}
}
 
// Hardware-Auswahl im Menp
void MKTool::slot_ac_Hardware()
{
QAction *Action = (QAction*)sender();
 
if (Action->isChecked() == false)
{
Action->setChecked(true);
}
 
slot_rb_Hardware();
}
 
// Hardware Auswahl und umschalten
void MKTool::slot_rb_Hardware()
{
if ((rb_SelNC->isChecked() == false) && (Mode.ID != ADDRESS_NC))
{
lb_Status->setText(tr("Schalte um auf NaviCtrl."));
TX_Data[0] = 0x1B;
TX_Data[1] = 0x1B;
TX_Data[2] = 0x55;
TX_Data[3] = 0xAA;
TX_Data[4] = 0x00;
TX_Data[5] = '\r';
o_Connection->send_Cmd('#', ADDRESS_NC, TX_Data, 6, false);
ToolBox::wait(SLEEP);
}
 
if (rb_SelFC->isChecked())
{
lb_Status->setText(tr("Schalte um auf FlightCtrl."));
TX_Data[0] = 0;
o_Connection->send_Cmd('u', ADDRESS_NC, TX_Data, 1, false);
}
else
if (rb_SelMag->isChecked())
{
lb_Status->setText(tr("Schalte um auf MK3MAG."));
TX_Data[0] = 1;
o_Connection->send_Cmd('u', ADDRESS_NC, TX_Data, 1, false);
}
else
if (rb_SelNC->isChecked())
{
lb_Status->setText(tr("Schalte um auf NaviCtrl."));
TX_Data[0] = 0x1B;
TX_Data[1] = 0x1B;
TX_Data[2] = 0x55;
TX_Data[3] = 0xAA;
TX_Data[4] = 0x00;
TX_Data[5] = '\r';
o_Connection->send_Cmd('#', ADDRESS_NC, TX_Data, 6, false);
}
ToolBox::wait(SLEEP);
 
// qDebug("Select RB Hardware");
o_Connection->send_Cmd('v', ADDRESS_ALL, TX_Data, 0, true);
}
 
// Ticker-Event
///////////////
void MKTool::slot_Ticker()
{
if (TickerDiv)
TickerDiv = false;
else
TickerDiv = true;
/*
if (cb_ClipBoard->isChecked())
{
QString s_OLD = te_KML->toPlainText();
te_KML->clear();
te_KML->paste();
if (s_OLD != te_KML->toPlainText())
{
parse_TargetKML();
}
}
*/
for (int a = 0; a < MaxTickerEvents; a++)
{
if (TickerEvent[a] == true)
{
switch(a)
{
case 0 :
{
}
break;
case 1 :
TX_Data[0] = 0;
o_Connection->send_Cmd('p', ADDRESS_FC, TX_Data, 0, false);
break;
case 2 :
if (f_LCD->cb_LCD->isChecked())
{
if (!f_LCD->isVisible())
{
Ticker->setInterval(2000);
TickerEvent[2] = false;
}
TX_Data[0] = LCD_Page;
TX_Data[1] = 0;
o_Connection->send_Cmd('l', ADDRESS_ALL, TX_Data, 1, true);
}
break;
case 3 :
if (ac_FastDebug->isChecked())
{
TX_Data[0] = Settings->Data.Debug_Fast / 10;
o_Connection->send_Cmd('d', ADDRESS_ALL, TX_Data, 1, false);
}
else
{
TX_Data[0] = Settings->Data.Debug_Slow / 10;
o_Connection->send_Cmd('d', ADDRESS_ALL, TX_Data, 1, false);
}
break;
case 4 :
{
for (int z = 0; z<12; z++)
{
TX_Data[z] = Motor.Speed[z];
}
o_Connection->send_Cmd('t', ADDRESS_FC, TX_Data, 12, false);
}
 
}
}
}
}
 
// Zum QMK-Datenserver verbinden
void MKTool::slot_QMKS_Connect()
{
if (ac_QMKServer->isChecked())
{
lb_Status->setText(tr("Verbinde zum QMK-Datenserver."));
 
QMK_Server->Connect(Settings->Server.QMKS_Host, Settings->Server.QMKS_Port.toInt(), Settings->Server.QMKS_Login, Settings->Server.QMKS_Password);
 
connect(QMK_Server, SIGNAL(sig_Connected()), this, SLOT(slot_QMKS_Connected()));
connect(QMK_Server, SIGNAL(sig_Disconnected(int)), this, SLOT(slot_QMKS_Disconnected(int)));
}
else
{
if ((QMK_Server->property("Connect")) == true)
{
disconnect(QMK_Server, SIGNAL(sig_Disconnected(int)), 0, 0);
lb_Status->setText(tr("Trenne vom QMK-Datenserver."));
 
QMK_Server->Disconnect();
QMK_Server->setProperty("Connect", false);
ac_QMKServer->setText(tr("QMK-Server Verbinden"));
}
}
}
 
// Verbindung zum QMK-Server hergestellt.
void MKTool::slot_QMKS_Connected()
{
QMK_Server->setProperty("Connect", true);
ac_QMKServer->setText(tr("QMK-Server Trennnen"));
lb_Status->setText(tr("Verbunden mit QMK-Datenserver."));
}
 
// QMK-Serververbindung getrennt
void MKTool::slot_QMKS_Disconnected(int Error)
{
QMK_Server->setProperty("Connect", false);
ac_QMKServer->setText(tr("QMK-Server Verbinden"));
ac_QMKServer->setChecked(false);
 
disconnect(QMK_Server, SIGNAL(sig_Disconnected(int)), 0, 0);
 
switch (Error)
{
case 1 :
{
lb_Status->setText(tr("Verbindung vom Server beendet."));
QMessageBox::warning(this, QA_NAME,tr("QMK-Datenserver: Verbindung wurde vom Server beendet."), QMessageBox::Ok);
}
break;
case 2 :
{
lb_Status->setText(tr("Server nicht gefunden."));
QMessageBox::warning(this, QA_NAME,tr("QMK-Datenserver: Kann nicht zum Server verbinden."), QMessageBox::Ok);
}
break;
case 3 :
{
lb_Status->setText(tr("Serververbindung getrennt. Logindaten falsch."));
QMessageBox::warning(this, QA_NAME,tr("QMK-Datenserver: Loginname oder Password falsch."), QMessageBox::Ok);
}
break;
default :
{
lb_Status->setText(tr("Getrennt vom QMK-Datenserver."));
}
break;
}
}
 
// Slots der Actions (Menüpunkte, Buttons)
//////////////////////////////////////////
void MKTool::slot_ac_Motortest()
{
dlg_Motortest *f_Motortest = new dlg_Motortest(this);
 
// connect(f_Motortest, SIGNAL(updateMotor(int, int, int, int)), this, SLOT(slot_Motortest(int, int, int, int)));
connect(f_Motortest, SIGNAL(updateMotor(sMotor)), this, SLOT(slot_Motortest(sMotor)));
 
 
Ticker->setInterval(500);
TickerEvent[4] = true;
 
if (f_Motortest->exec()==QDialog::Accepted)
{
}
 
disconnect(f_Motortest, 0,0,0);
 
for (int z = 0; z<12; z++)
{
Motor.Speed[z] = 0;
}
 
slot_Motortest(Motor);
 
Ticker->setInterval(2000);
TickerEvent[4] = false;
}
 
void MKTool::slot_Motortest(sMotor p_Motor)
{
Motor = p_Motor;
 
for (int z = 0; z<12; z++)
{
TX_Data[z] = Motor.Speed[z];
}
o_Connection->send_Cmd('t', ADDRESS_FC, TX_Data, 12, false);
}
 
// Motormixer-Einstellungen anzeigen
void MKTool::slot_ac_MotorMixer()
{
f_MotorMixer->set_Objects(o_Connection, Settings);
f_MotorMixer->read_Mixer();
 
if (f_MotorMixer->exec()==QDialog::Accepted)
{
}
}
 
// LCD Anzeigen
void MKTool::slot_ac_LCD()
{
if (!f_LCD->isVisible())
{
delete f_LCD;
f_LCD = new dlg_LCD(this);
 
// LCD auf / ab
connect(f_LCD->pb_LCDup, SIGNAL(clicked()), this, SLOT(slot_LCD_UP()));
connect(f_LCD->pb_LCDdown, SIGNAL(clicked()), this, SLOT(slot_LCD_DOWN()));
 
f_LCD->show();
TX_Data[0] = 0;
TX_Data[1] = 0;
o_Connection->send_Cmd('l', ADDRESS_ALL, TX_Data, 1, true);
 
Ticker->setInterval(500);
TickerEvent[2] = true;
}
}
 
// Map-Fenster anzeigen
void MKTool::slot_ac_Map()
{
if (!f_Map->isVisible())
{
f_Map->show();
}
}
 
void MKTool::slot_MAP_SetWayPoints(QList<sWayPoint> l_WayPoints)
{
Waypoint_t WayPoint;
double Longitude, Latitude;
 
// Waypoint-Liste löschen
WayPoint.Position.Status = INVALID;
o_Connection->send_Cmd('w', ADDRESS_NC, (char *)&WayPoint, sizeof(WayPoint), false);
ToolBox::wait(SLEEP);
 
for (int z = 0; z < l_WayPoints.count(); z++)
{
Longitude = l_WayPoints[z].Longitude;
Latitude = l_WayPoints[z].Latitude;
 
if (Longitude < 100)
Longitude *= 10000000+0.5;
 
if (Latitude < 100)
Latitude *= 10000000+0.5;
 
//fülle Wegpunkt-Daten
WayPoint.Position.Altitude = 0;
WayPoint.Position.Longitude = int32_t(Longitude);
WayPoint.Position.Latitude = int32_t(Latitude);
WayPoint.Position.Status = NEWDATA;
WayPoint.Heading = -1;
WayPoint.ToleranceRadius = 5;
WayPoint.HoldTime = l_WayPoints[z].Time;
WayPoint.Event_Flag = 0;
WayPoint.reserve[0] = 0; // reserve
WayPoint.reserve[1] = 0; // reserve
WayPoint.reserve[2] = 0; // reserve
WayPoint.reserve[3] = 0; // reserve
 
o_Connection->send_Cmd('w', ADDRESS_NC, (char *)&WayPoint, sizeof(WayPoint), false);
// ToolBox::Wait(SLEEP);
}
 
}
 
void MKTool::slot_MAP_SetTarget(sWayPoint Target)
{
 
QString s_Lon, s_Lat;
QTextStream t_Lon(&s_Lon);
QTextStream t_Lat(&s_Lat);
 
t_Lon.setRealNumberPrecision(9);
t_Lat.setRealNumberPrecision(9);
t_Lon << Target.Longitude;
t_Lat << Target.Latitude;
 
le_TarLong->setText(s_Lon);
le_TarLat->setText(s_Lat);
sb_TarTime->setValue(Target.Time);
 
slot_pb_SendTarget();
}
 
void MKTool::slot_ac_Config()
{
set_Analog Old_Analog1;
 
Old_Analog1 = Settings->Analog1;
 
dlg_Config *f_Config = new dlg_Config(this);
f_Config->set_Settings(Settings, Mode.ID);
 
if (f_Config->exec()==QDialog::Accepted)
{
Settings = f_Config->get_Settings();
Settings->write_Settings_Analog(Mode.ID);
 
// Plotter neu einrichten
if (Old_Analog1.PlotView != Settings->Analog1.PlotView)
{
config_Plot();
}
 
// CVS-Datei neu anlegen.
if ((logger->is_active()) && (Old_Analog1.LogView != Settings->Analog1.LogView))
{
logger->close();
logger->start_Log();
}
 
}
}
 
//aktualisiere Logging-Status
void MKTool::update_Log()
{
if (logger->is_active())
{
 
ac_RecordCSV->setText(tr("Log Stop"));
lb_Status->setText(tr("Log-Record gestartet."));
}
else
{
ac_RecordCSV->setText(tr("Log Aufzeichnen"));
lb_Status->setText(tr("Log-Record gestopt."));
}
}
 
//starte/stoppe Logging, wenn auf den entsprechenden Button gedrückt wurde
void MKTool::slot_RecordLog()
{
if (!logger->is_active())
logger->start_Log();
else
logger->close();
 
update_Log();
}
 
void MKTool::slot_ac_Preferences()
{
dlg_Preferences *f_Preferences = new dlg_Preferences(this);
 
Settings->TTY.Port = le_Port->text();
f_Preferences->set_Settings(Settings);
 
if (f_Preferences->exec()==QDialog::Accepted)
{
Settings = f_Preferences->get_Settings();
Settings->write_Settings();
le_Port->setText(Settings->TTY.Port);
config_Plot();
}
}
 
void MKTool::slot_ac_StartPlotter()
{
if (ac_StartPlotter->isChecked())
{
lb_Status->setText(tr("Datenplotter gestartet."));
ac_StartPlotter->setText(tr("Stop Plotter"));
pb_StartPlotter->setText(tr("Stop Plotter"));
}
else
{
lb_Status->setText(tr("Datenplotter gestopt."));
ac_StartPlotter->setText(tr("Start Plotter"));
pb_StartPlotter->setText(tr("Start Plotter"));
}
}
 
void MKTool::slot_ac_View()
{
int Aktive = -1;
 
QAction *Action = (QAction*)sender();
 
if (Action->objectName() == QString("ac_View0"))
Aktive = 0;
if (Action->objectName() == QString("ac_View1"))
Aktive = 1;
if (Action->objectName() == QString("ac_View2"))
Aktive = 2;
if (Action->objectName() == QString("ac_View3"))
Aktive = 3;
if (Action->objectName() == QString("ac_View4"))
Aktive = 4;
if (Action->objectName() == QString("ac_View5"))
Aktive = 5;
if (Action->objectName() == QString("ac_View6"))
Aktive = 6;
 
QString TabName = QString("Tab_%1").arg(Aktive);
 
if (!Action->isChecked())
{
for (int a = 0; a < tab_Main->count(); a++)
{
if (tab_Main->widget(a)->objectName() == TabName)
{
tab_Main->removeTab(a);
}
}
}
else
{
tab_Main->insertTab(Aktive, TabWidgets[Aktive], Action->icon(), Action->text());
}
}
 
void MKTool::slot_ac_FastNavi() // DONE NC 0.12i
{
if (!ac_NoNavi->isChecked())
{
if (ac_FastNavi->isChecked())
{
lb_Status->setText(tr("Fordere schnelle NaviDaten an."));
TX_Data[0] = Settings->Data.Navi_Fast / 10;
}
else
{
lb_Status->setText(tr("Fordere langsame NaviDaten an."));
TX_Data[0] = Settings->Data.Navi_Slow / 10;
}
o_Connection->send_Cmd('o', ADDRESS_NC, TX_Data, 1, false);
}
}
 
void MKTool::slot_ac_NoNavi() // DONE NC 0.12i
{
if (ac_NoNavi->isChecked())
{
lb_Status->setText(tr("NaviDaten abstellen."));
TX_Data[0] = 0;
}
else
{
if (ac_FastNavi->isChecked())
{
lb_Status->setText(tr("Fordere schnelle NaviDaten an."));
TX_Data[0] = Settings->Data.Navi_Fast / 10;
}
else
{
lb_Status->setText(tr("Fordere langsame NaviDaten an."));
TX_Data[0] = Settings->Data.Navi_Slow / 10;
}
}
o_Connection->send_Cmd('o', ADDRESS_NC, TX_Data, 1, false);
}
 
void MKTool::slot_ac_FastDebug() // DONE 0.71g
{
if (!ac_NoDebug->isChecked())
{
if (ac_FastDebug->isChecked())
{
lb_Status->setText(tr("Fordere schnelle DebugDaten an."));
TX_Data[0] = Settings->Data.Debug_Fast / 10;
}
else
{
lb_Status->setText(tr("Fordere langsame DebugDaten an."));
TX_Data[0] = Settings->Data.Debug_Slow / 10;
}
o_Connection->send_Cmd('d', ADDRESS_ALL, TX_Data, 1, false);
}
}
 
void MKTool::slot_ac_NoDebug() // DONE 0.71g
{
if (ac_NoDebug->isChecked())
{
lb_Status->setText(tr("DebugDaten abstellen."));
TickerEvent[3] = false;
TX_Data[0] = 0;
}
else
{
// Wenn MK3MAG dann andauernd Daten neu anfragen.
if (Mode.ID == ADDRESS_MK3MAG)
TickerEvent[3] = true;
 
if (ac_FastDebug->isChecked())
{
lb_Status->setText(tr("Fordere schnelle DebugDaten an."));
TX_Data[0] = Settings->Data.Debug_Fast / 10;
}
else
{
lb_Status->setText(tr("Fordere langsame DebugDaten an."));
TX_Data[0] = Settings->Data.Debug_Slow / 10;
}
}
o_Connection->send_Cmd('d', ADDRESS_ALL, TX_Data, 1, false);
}
 
void MKTool::slot_ac_About()
{
QMessageBox::about(this, trUtf8(("Über ")) + QA_NAME, QA_ABOUT);
}
 
void MKTool::slot_ac_GetLabels() // DONE 0.71g
{
lb_Status->setText(tr("Analoglabels auslesen."));
TX_Data[0] = 0;
o_Connection->send_Cmd('a', ADDRESS_ALL, TX_Data, 1, true);
}
 
void MKTool::slot_ac_StartServer()
{
if (ac_StartServer->isChecked())
{
lb_Status->setText(tr("KML-Server gestartet."));
KML_Server->start_Server(Settings->Server.Port.toInt(), Settings);
}
else
{
lb_Status->setText(tr("KML-Server gestopt."));
KML_Server->stop_Server();
}
}
 
 
// Daten-Plotter
/////////////////
void MKTool::update_Plot()
{
for (int a = 0; a < MaxAnalog; a++)
{
Plot[a]->setData(aID,aData[a],NextPlot - 1);
}
 
if ((NextPlot > Settings->Data.Plotter_Count))
{
scroll_plot->setMaximum(NextPlot - Settings->Data.Plotter_Count);
}
 
if ((scroll_plot->value() == NextPlot - (Settings->Data.Plotter_Count + 1)))
{
qwtPlot->setAxisScale(QwtPlot::xBottom,NextPlot - Settings->Data.Plotter_Count,NextPlot,0);
scroll_plot->setValue(NextPlot - Settings->Data.Plotter_Count);
}
 
qwtPlot->replot();
}
 
void MKTool::config_Plot()
{
// qDebug("Plotter rekonfiguriert..!!");
qwtPlot->setAxisScale(QwtPlot::xBottom,0,Settings->Data.Plotter_Count,0);
 
for (int a = 0; a < MaxAnalog; a++)
{
Plot[a]->detach();
Plot[a]->setPen(QPen(QColor(Def_Colors[a])));
 
if (Settings->Analog1.PlotView[a])
{
Plot[a]->setTitle(Settings->Analog1.Label[a]);
Plot[a]->attach(qwtPlot);
}
}
qwtPlot->replot();
}
 
void MKTool::slot_ScrollPlot(int Pos)
{
qwtPlot->setAxisScale(QwtPlot::xBottom,Pos,Pos + Settings->Data.Plotter_Count,0);
qwtPlot->replot();
}
 
 
// Firmeware-Update
///////////////////
void MKTool::slot_pb_Update()
{
QString Device;
QString Hardware;
 
if (rb_FC->isChecked())
{
Device = "m644";
Hardware = "FlightCtrl";
}
else if (rb_MK3MAG->isChecked())
{
Device = "m168";
Hardware = "MK3MAG";
}
else if (rb_BL->isChecked())
{
Device = "m8";
Hardware = "BL-Ctrl";
}
 
QString Message = trUtf8("Firmeware-Datei \n\n");
Message = Message + le_HexFile->text() + "\n\n";
Message = Message + trUtf8("an ") + Hardware + trUtf8(" mit AVRDUDE - Seriel & Bootloader über ") + le_Port->text() + trUtf8(" übertragen?\n");
 
if (le_HexFile->text() == "")
{
QMessageBox::warning(this, QA_NAME, trUtf8("Bitte Firmeware-Datei wählen."), QMessageBox::Ok);
}
else if (QMessageBox::warning(this, QA_NAME, Message, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
{
QString Programm = Settings->DIR.AVRDUDE;
 
QStringList Argumente;
 
Update = new QProcess();
 
if (o_Connection->isOpen())
{
slot_OpenPort();
}
 
Argumente << "-P";
Argumente << le_Port->text();
Argumente << "-p";
Argumente << Device;
Argumente << "-c";
Argumente << "butterfly";
Argumente << "-b";
Argumente << "57600";
Argumente << "-U";
Argumente << "flash:w:" + le_HexFile->text();
 
// QString Programm = "/home/Manuel/bin/avrdude -p m644 -P /dev/ttyS0 -c butterfly -b 57600 -U flash:w:/home/Manuel/Documents/Mikrokopter/Firmeware/FlightCtrl/Flight-Ctrl_MEGA644_V0_71h.hex";
 
te_Shell->setText(""); // Ausgabefenster säubern
 
connect(Update, SIGNAL(readyReadStandardOutput()), this, SLOT(slot_UpdateShell()) );
connect(Update, SIGNAL(readyReadStandardError()), this, SLOT(slot_UpdateShell()) );
 
Update->start(Programm, Argumente); // Programmaufruf
}
}
 
void MKTool::slot_UpdateShell()
{
QByteArray Output;
 
Output = Update->readAllStandardError(); // Shellausgabe an Variable
te_Shell->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
te_Shell->insertPlainText(QString::fromUtf8(Output));
 
Output = Update->readAll();
te_Shell->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
te_Shell->insertPlainText(QString::fromUtf8(Output));
}
 
void MKTool::slot_pb_HexFile()
{
QString FileName = QFileDialog::getOpenFileName(this,trUtf8(("Firmeware-Datei wählen")),"",
tr("Intel Hex(*.hex);;Alle Dateien (*)"));
if (!FileName.isEmpty())
{
le_HexFile->setText(FileName);
}
}
 
 
// Wechsel der Tabs erkennen
void MKTool::slot_TabChanged(int Tab) // DONE 0.71g
{
Tab = Tab;
if (tab_Main->count() != 0)
{
if ((tab_Main->currentWidget()->objectName() == QString("Tab_2")) && (f_Settings->listWidget->currentRow() == 1))
{
TX_Data[0] = 0;
o_Connection->send_Cmd('p', ADDRESS_FC, TX_Data, 0, false);
 
Ticker->setInterval(500);
TickerEvent[1] = true;
}
else
{
Ticker->setInterval(2000);
TickerEvent[1] = false;
}
}
}
 
// LCD-Seiten weiterschalten
void MKTool::slot_LCD_UP() // DONE 0.71g
{
if (LCD_Page == LCD_MAX_Page)
TX_Data[0] = 0;
else
TX_Data[0] = LCD_Page + 1;
 
TX_Data[1] = 0;
o_Connection->send_Cmd('l', ADDRESS_ALL, TX_Data, 1, true);
}
 
void MKTool::slot_LCD_DOWN() // DONE 0.71g
{
if (LCD_Page == 0)
TX_Data[0] = LCD_MAX_Page;
else
TX_Data[0] = LCD_Page - 1;
 
TX_Data[1] = 0;
o_Connection->send_Cmd('l', ADDRESS_ALL, TX_Data, 1, true);
}
 
// Settings aus MK lesen / in MK schreiben
void MKTool::slot_GetFCSettings() // DONE 0.71g
{
lb_Status->setText(tr("Lese FlightCtrl-Settings aus."));
TX_Data[0] = f_Settings->sb_Set->value();
TX_Data[1] = 0;
o_Connection->send_Cmd('q', ADDRESS_FC, TX_Data, 1, true);
}
 
void MKTool::slot_SetFCSettings() // DONE 0.71g
{
char *TX_Data2 = f_Settings->GetFCSettings();
 
lb_Status->setText(tr("Schreibe FlightCtrl-Settings."));
 
o_Connection->send_Cmd('s', ADDRESS_FC, TX_Data2, MaxParameter + 2, true);
}
 
 
// Save GUI-Preferences
///////////////////////
void MKTool::set_Preferences()
{
Settings->GUI.TabViews.setBit(0, ac_View0->isChecked());
Settings->GUI.TabViews.setBit(1, ac_View1->isChecked());
Settings->GUI.TabViews.setBit(2, ac_View2->isChecked());
Settings->GUI.TabViews.setBit(3, ac_View3->isChecked());
Settings->GUI.TabViews.setBit(4, ac_View4->isChecked());
Settings->GUI.TabViews.setBit(5, ac_View5->isChecked());
Settings->GUI.TabViews.setBit(6, ac_View6->isChecked());
 
Settings->GUI.ToolViews.setBit(0, tb_Allgemein->isVisibleTo(this));
Settings->GUI.ToolViews.setBit(1, tb_Werkzeuge->isVisibleTo(this));
Settings->GUI.ToolViews.setBit(2, tb_Debug->isVisibleTo(this));
Settings->GUI.ToolViews.setBit(3, tb_TTY->isVisibleTo(this));
Settings->GUI.ToolViews.setBit(4, tb_Hardware->isVisibleTo(this));
 
Settings->GUI.Term_Info = cb_ShowMSG->isChecked();
Settings->GUI.Term_Data = cb_ShowData->isChecked();
Settings->GUI.Term_Always = cb_ShowAlways->isChecked();
Settings->GUI.Term_Send = cb_ShowSend->isChecked();
Settings->GUI.isMax = isMaximized();
Settings->GUI.Size = size();
Settings->GUI.Point = pos();
 
Settings->TTY.Port = le_Port->text();
}
 
void MKTool::show_DebugData()
{
if (logger->is_active())
logger->write(AnalogData);
 
if (ac_StartPlotter->isChecked())
{
aID[NextPlot] = NextPlot;
 
for (int a = 0; a < MaxAnalog; a++)
{
aData[a][NextPlot] = AnalogData[a];
}
NextPlot++;
 
if ((tab_Main->currentWidget()->objectName() == QString("Tab_1")))
update_Plot();
}
 
le_A_0->setText(QString("%1").arg(AnalogData[0]));
le_A_1->setText(QString("%1").arg(AnalogData[1]));
le_A_2->setText(QString("%1").arg(AnalogData[2]));
le_A_3->setText(QString("%1").arg(AnalogData[3]));
le_A_4->setText(QString("%1").arg(AnalogData[4]));
le_A_5->setText(QString("%1").arg(AnalogData[5]));
le_A_6->setText(QString("%1").arg(AnalogData[6]));
le_A_7->setText(QString("%1").arg(AnalogData[7]));
le_A_8->setText(QString("%1").arg(AnalogData[8]));
le_A_9->setText(QString("%1").arg(AnalogData[9]));
le_A_10->setText(QString("%1").arg(AnalogData[10]));
le_A_11->setText(QString("%1").arg(AnalogData[11]));
le_A_12->setText(QString("%1").arg(AnalogData[12]));
le_A_13->setText(QString("%1").arg(AnalogData[13]));
le_A_14->setText(QString("%1").arg(AnalogData[14]));
le_A_15->setText(QString("%1").arg(AnalogData[15]));
le_A_16->setText(QString("%1").arg(AnalogData[16]));
le_A_17->setText(QString("%1").arg(AnalogData[17]));
le_A_18->setText(QString("%1").arg(AnalogData[18]));
le_A_19->setText(QString("%1").arg(AnalogData[19]));
le_A_20->setText(QString("%1").arg(AnalogData[20]));
le_A_21->setText(QString("%1").arg(AnalogData[21]));
le_A_22->setText(QString("%1").arg(AnalogData[22]));
le_A_23->setText(QString("%1").arg(AnalogData[23]));
le_A_24->setText(QString("%1").arg(AnalogData[24]));
le_A_25->setText(QString("%1").arg(AnalogData[25]));
le_A_26->setText(QString("%1").arg(AnalogData[26]));
le_A_27->setText(QString("%1").arg(AnalogData[27]));
le_A_28->setText(QString("%1").arg(AnalogData[28]));
le_A_29->setText(QString("%1").arg(AnalogData[29]));
le_A_30->setText(QString("%1").arg(AnalogData[30]));
le_A_31->setText(QString("%1").arg(AnalogData[31]));
 
if ((Mode.ID == ADDRESS_FC) && (FCSettings[P_GYRO_ACC_FAKTOR] > 0))
{
bar_UBAT->setValue(AnalogData[9]);
bar_RX->setValue(AnalogData[10]);
 
Compass->setValue(AnalogData[8]);
 
int Roll = (AnalogData[1] * FCSettings[P_GYRO_ACC_FAKTOR]) / 1024;
int Nick = (AnalogData[0] * FCSettings[P_GYRO_ACC_FAKTOR]) / 1024;
 
if (Roll > 128)
Roll = Roll - 255;
 
if (Nick > 128)
Nick = Nick - 255;
 
Attitude->setAngle(Roll);
Attitude->setGradient(double(double(Nick) / 100.0));
}
}
 
void MKTool::new_NaviData(sRxData RX)
{
// qDebug("Navi-Data");
 
switch(RX.decode[N_NC_FLAGS])
{
case 0x01 : lb_Mode->setText(tr("Free")); break;
case 0x02 : lb_Mode->setText(tr("Position Hold")); break;
case 0x04 : lb_Mode->setText(tr("Coming Home")); break;
case 0x08 : lb_Mode->setText(tr("Range Limit")); break;
case 0x10 : lb_Mode->setText(tr("Serial Error")); break;
case 0x20 : lb_Mode->setText(tr("Target reached")); break;
case 0x40 : lb_Mode->setText(tr("Manual Control")); break;
}
 
Navi.Current.Longitude = Parser::dataToLong(RX.decode, N_CUR_LONGITUDE, true);
Navi.Current.Latitude = Parser::dataToLong(RX.decode, N_CUR_LATITUDE, true);
Navi.Current.Altitude = Parser::dataToLong(RX.decode, N_CUR_ALTITUDE, true);
Navi.Target.Longitude = Parser::dataToLong(RX.decode, N_TAR_LONGITUDE, true);
Navi.Target.Latitude = Parser::dataToLong(RX.decode, N_TAR_LATITUDE, true);
Navi.Target.Altitude = Parser::dataToLong(RX.decode, N_TAR_ALTITUDE, true);
 
le_CDistance->setText(QString("%1 cm").arg(Parser::dataToInt(RX.decode, N_HOME_DISTANCE)));
le_CWPA->setText(QString("%1").arg(RX.decode[N_WP_INDEX]));
le_CWPT->setText(QString("%1").arg(RX.decode[N_WP_NUMBER]));
le_CSats->setText(QString("%1").arg(RX.decode[N_SATS_IN_USER]));
 
qwt_Rate->setValue(double(Parser::dataToInt(RX.decode, N_VARIOMETER, true)));
 
le_CTime->setText(QString("%1 sec.").arg(Parser::dataToInt(RX.decode, N_FLYING_TIME)));
 
bar_UBAT->setValue(RX.decode[N_UBAT]);
 
double Speed = double((Parser::dataToLong(RX.decode, N_GROUND_SPEED)) / 10.0);
 
if ((Speed > 4.5) && SpeedMeter->property("END") == 5)
{
SpeedMeter->setRange(0.0, 10.0);
SpeedMeter->setScale(1, 2, 1);
SpeedMeter->setProperty("END", 10);
}
 
if ((Speed > 9) && SpeedMeter->property("END") == 10)
{
SpeedMeter->setRange(0.0, 20.0);
SpeedMeter->setScale(1, 2, 2);
SpeedMeter->setProperty("END", 20);
}
 
SpeedMeter->setValue(Speed);
 
Compass->setValue(Parser::dataToInt(RX.decode, N_COMAPSS_HEADING)); //(68)
 
bar_RX->setValue(RX.decode[N_RC_QUALITY]);
 
int Nick = RX.decode[N_ANGLE_NICK];
int Roll = RX.decode[N_ANGLE_ROLL];
 
if (Roll > 128)
Roll = Roll - 255;
 
if (Nick > 128)
Nick = Nick - 255;
 
Attitude->setAngle(Roll);
Attitude->setGradient(double(0.0 - (double(Nick) / 100.0)));
 
sNaviString NaviString;
 
NaviString.Longitude = Parser::getFloat(Navi.Current.Longitude,7);
NaviString.Latitude = Parser::getFloat(Navi.Current.Latitude,7);
NaviString.Altitude = Parser::getFloat(Navi.Current.Altitude,3);
 
le_CurLong->setText(QString::number(NaviString.Longitude));
le_CurLat->setText(QString::number(NaviString.Latitude));
 
KML_Server->store_NaviString(NaviString);
 
f_Map->add_Position(NaviString.Longitude, NaviString.Latitude);
 
if ((QMK_Server->property("Connect")) == true)
{
// qDebug("Send Data to Server..!!");
QMK_Server->NewPosition(NaviString);
}
}
 
// Kopter-Kommunikations-Bereich, Befehle senden und Daten empfangen
////////////////////////////////////////////////////////////////////
 
// Neues Datenpacket empfangen -> Verarbeiten
void MKTool::slot_newData(sRxData RX) // DONE 0.71g
{
if (LastSend.length() > 2)
{
}
int HardwareID = RX.input[1] - 'a';
 
switch(HardwareID)
{
case ADDRESS_FC :
switch(RX.input[2])
{
// Motor-Mixer
case 'N' :
if (Parser::decode64(RX))
{
o_Connection->stop_ReSend();
 
if (RX.decode[0] == VERSION_MIXER)
{
f_MotorMixer->set_MotorConfig(RX);
}
}
break;
// Motor-Mixer Schreib-Bestätigung
case 'M' :
if (Parser::decode64(RX))
{
o_Connection->stop_ReSend();
 
if (RX.decode[0] == 1)
{
lb_Status->setText(tr("MotorMixer-Daten in FC geschrieben."));
}
}
break;
 
// Stick-Belegung der Fernsteuerung
case 'P' : // DONE 0.71g
if (Parser::decode64(RX))
{
f_Settings->pb_K1->setValue(Parser::dataToInt(RX.decode, 2,true));
f_Settings->pb_K2->setValue(Parser::dataToInt(RX.decode, 4,true));
f_Settings->pb_K3->setValue(Parser::dataToInt(RX.decode, 6,true));
f_Settings->pb_K4->setValue(Parser::dataToInt(RX.decode, 8,true));
f_Settings->pb_K5->setValue(Parser::dataToInt(RX.decode, 10 ,true));
f_Settings->pb_K6->setValue(Parser::dataToInt(RX.decode, 12,true));
f_Settings->pb_K7->setValue(Parser::dataToInt(RX.decode, 14,true));
f_Settings->pb_K8->setValue(Parser::dataToInt(RX.decode, 16,true));
}
break;
// Settings lesen
case 'Q' : // DONE 0.71g
if (Parser::decode64(RX))
{
o_Connection->stop_ReSend();
 
if (RX.decode[1] == VERSION_SETTINGS)
{
int Settings_ID = RX.decode[0];
for (int a = 0; a < MaxParameter; a++)
{
FCSettings[a] = RX.decode[a + 2];
}
f_Settings->show_FCSettings(Settings_ID, FCSettings);
f_Settings->pb_Read->setEnabled(true);
f_Settings->pb_Write->setEnabled(true);
}
else
{
f_Settings->pb_Read->setDisabled(true);
f_Settings->pb_Write->setDisabled(true);
 
QString name = QString("Versionen inkompatibel.\n") +
QString("Version von GroundStation benoetigt: ") +
QString(VERSION_SETTINGS) +
QString("\nVersion auf der FlightCtrl: ") +
QString(RX.decode[1]) +
QString("\nParameterbearbeitung nicht moeglich.");
QMessageBox::warning(this, QA_NAME,
name, QMessageBox::Ok);
}
}
break;
// Settings geschrieben
case 'S' : // DONE 0.71g
o_Connection->stop_ReSend();
break;
}
 
case ADDRESS_NC :
switch(RX.input[2])
{
// Navigationsdaten
case 'O' : // NOT DONE 0.12h
if (Parser::decode64(RX))
{
new_NaviData(RX);
}
break;
}
// case ADDRESS_MK3MAG :
 
default :
switch(RX.input[2])
{
// LCD-Anzeige
case 'L' : // DONE 0.71g
if (Parser::decode64(RX))
{
o_Connection->stop_ReSend();
 
int LCD[150];
memcpy(LCD,RX.decode, sizeof(RX.decode));
 
f_LCD->show_Data(LCD);
 
LCD_Page = RX.decode[0];
LCD_MAX_Page = RX.decode[1];
}
break;
// Analoglabels
case 'A' : // DONE 0.71g
if (Parser::decode64(RX))
{
o_Connection->stop_ReSend();
 
int Position = RX.decode[0];
if (Position != 31)
{
Settings->Analog1.Label[Position] = ToolBox::dataToQString(RX.decode,1,17).trimmed();
if (Settings->Analog1.Label[Position] == "")
{
Settings->Analog1.Label[Position] = "A-" + QString("%1").arg(Position);
}
Position ++;
TX_Data[0] = Position;
o_Connection->send_Cmd('a', ADDRESS_ALL, TX_Data, 1, true);
}
if (Position == 31)
{
for (int a = 0; a < MaxAnalog; a++)
{
lb_Analog[a]->setText(Settings->Analog1.Label[a]);
}
Settings->Analog1.Version = Mode.Version;
Settings->write_Settings_AnalogLabels(HardwareID);
config_Plot();
}
}
break;
// Debug-Daten
case 'D' : // DONE 0.71g
if (Parser::decode64(RX))
{
for (int i = 0; i < MaxAnalog; i++)
{
AnalogData[i] = Parser::dataToInt(RX.decode, (i * 2) + 2);
}
show_DebugData();
}
break;
// Version
case 'V' : // DONE 0.71h
if (Parser::decode64(RX))
{
o_Connection->stop_ReSend();
 
Mode.ID = HardwareID;
Mode.VERSION_MAJOR = RX.decode[0];
Mode.VERSION_MINOR = RX.decode[1];
Mode.VERSION_PATCH = RX.decode[4];
Mode.VERSION_SERIAL_MAJOR = RX.decode[2];
Mode.VERSION_SERIAL_MINOR = RX.decode[3];
 
Mode.Hardware = HardwareType[Mode.ID];
//TODO: Funktion im Handler get_version() oder sowas
QString version = QString("%1").arg(RX.decode[0]) + "." +
QString("%1").arg(RX.decode[1]) +
QString(RX.decode[4] + 'a');
Mode.Version = version.toLatin1();
setWindowTitle(QA_NAME + " v" + QA_VERSION + " - " +
QString(Mode.Hardware) + " " + Mode.Version);
 
if (Mode.VERSION_SERIAL_MAJOR != VERSION_SERIAL_MAJOR)
{
// AllowSend = false;
QMessageBox::warning(this, QA_NAME,
tr("Serielles Protokoll Inkompatibel. \nBitte neue Programmversion installieren,"), QMessageBox::Ok);
}
 
if (ac_NoDebug->isChecked())
{
TX_Data[0] = 0;
}
else
if (ac_FastDebug->isChecked())
{
TX_Data[0] = Settings->Data.Debug_Fast / 10;
}
else
{
TX_Data[0] = Settings->Data.Debug_Slow / 10;
}
 
o_Connection->send_Cmd('d', ADDRESS_ALL, TX_Data, 1, false);
 
// Wenn MK3MAG dann andauernd Daten neu anfragen.
if (Mode.ID == ADDRESS_MK3MAG)
{
TickerEvent[3] = true;
rb_SelMag->setChecked(true);
}
 
// Wenn NaviCtrl dann hier.
if (Mode.ID == ADDRESS_NC)
{
rb_SelNC->setChecked(true);
 
if (ac_NoNavi->isChecked())
{
TX_Data[0] = 0;
}
else
if (ac_FastNavi->isChecked())
{
TX_Data[0] = Settings->Data.Navi_Fast / 10;
}
else
{
TX_Data[0] = Settings->Data.Navi_Slow / 10;
}
 
o_Connection->send_Cmd('o', ADDRESS_NC, TX_Data, 1, false);
}
 
 
// Wenn FlightCtrl dann Settings abfragen.
if (Mode.ID == ADDRESS_FC)
{
rb_SelFC->setChecked(true);
{
TX_Data[0] = 0xff;
TX_Data[1] = 0;
 
// DEP: Raus wenn Resend implementiert.
// ToolBox::Wait(SLEEP);
o_Connection->send_Cmd('q', ADDRESS_FC, TX_Data, 1, true);
qDebug("FC - Get Settings");
}
}
// Wenn nicht Lesen und Schreiben der Settings deaktivieren.
else
{
f_Settings->pb_Read->setDisabled(true);
f_Settings->pb_Write->setDisabled(true);
}
 
Settings->read_Settings_Analog(HardwareID);
Settings->read_Settings_AnalogLabels(HardwareID);
 
if (Settings->Analog1.Version != Mode.Version)
{
lb_Status->setText(tr("Analoglabel-Version unterschiedlich. Lese Analoglabels neu aus."));
slot_ac_GetLabels();
}
else
for (int a = 0; a < MaxAnalog; a++)
{
lb_Analog[a]->setText(Settings->Analog1.Label[a]);
}
config_Plot();
}
break;
}
}
 
// TODO: Roh-Daten senden zum QMK-Server dazu Sendebuffer bauen.
if ((QMK_Server->property("Connect")) == true)
{
// QMK_Server->send_RawData(RX.String);
}
 
slot_showTerminal(1, RX.str);
}
 
void MKTool::slot_showTerminal(int Typ, QString Text)
{
switch(Typ)
{
case 1 :
{
if ((cb_ShowData->isChecked()) && ((tab_Main->currentWidget()->objectName() == QString("Tab_3")) || (cb_ShowAlways->isChecked())))
{
te_RX->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
te_RX->insertHtml("<span style=\"color:#00008b;\">" + Text + "<br /></span>");
}
}
break;
case 2 :
{
if ((cb_ShowMSG->isChecked()) && ((tab_Main->currentWidget()->objectName() == QString("Tab_3")) || (cb_ShowAlways->isChecked())))
{
if (Text.length() > 0)
{
te_RX->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
te_RX->insertHtml("<span style=\"color:#008b00;\">" + Text + "</span><br />");
}
}
}
break;
case 3 :
{
if (cb_ShowSend->isChecked())
{
te_RX->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
te_RX->insertHtml("<span style='color:#8b0000;'>" + Text + "<br /></span>");
}
}
break;
}
}
 
// Verbindung zum Kopter herstellen / Trennen
void MKTool::slot_OpenPort()
{
if (o_Connection->isOpen())
{
TX_Data[0] = Settings->Data.Debug_Off / 10;
o_Connection->send_Cmd('d', ADDRESS_ALL, TX_Data, 1, false);
ToolBox::wait(SLEEP);
 
if (Mode.ID == ADDRESS_NC)
{
TX_Data[0] = Settings->Data.Navi_Off / 10;
o_Connection->send_Cmd('o', ADDRESS_NC, TX_Data, 1, false);
ToolBox::wait(SLEEP);
}
 
if (Mode.ID == ADDRESS_FC)
{
TX_Data[0] = 0;
TX_Data[1] = 0;
TX_Data[2] = 0;
TX_Data[3] = 0;
o_Connection->send_Cmd('t', ADDRESS_FC, TX_Data, 4, false);
ToolBox::wait(SLEEP);
}
 
o_Connection->Close();
 
ac_ConnectTTY->setText(tr("Kopter Verbinden"));
le_Port->setEnabled(true);
 
Ticker->stop();
}
else
{
int i_Type;
if (le_Port->text().contains(QString("IP:")))
{
i_Type = C_IP;
}
else
{
i_Type = C_TTY;
}
 
if (o_Connection->Open(i_Type, le_Port->text()))
{
ac_ConnectTTY->setText(tr("Kopter Trennen"));
le_Port->setEnabled(false);
 
o_Connection->send_Cmd('v', ADDRESS_ALL, TX_Data, 0, true);
 
Ticker->start(2000);
}
}
}
 
// Programm beenden
///////////////////
 
MKTool::~MKTool()
{
if (o_Connection->isOpen())
{
o_Connection->Close();
}
 
set_Preferences();
Settings->write_Settings();
 
logger->close();
}