123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- /*
- rmui — an UI for RM (a breaking machine by AMGlatsin <sanddevil@ut.mephi.ru>)
- Copyright (C) 2016 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
- 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 3 of the License, or
- (at your option) any later version.
- 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, see <http://www.gnu.org/licenses/>.
- */
- #include <QResizeEvent>
- #include <QDateTime>
- #include <QtSerialPort/QtSerialPort>
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- this->xMax = 60;
- this->ui->setupUi(this);
- this->setWindowTitle("RM control interface");
- this->ui->centralWidget->installEventFilter(this);
- this->ui->toolsWidget->installEventFilter(this);
- this->ui->ADC1Plot->setAxisScale(QwtPlot::yLeft, 0, 4095);
- this->ui->ADC2Plot->setAxisScale(QwtPlot::yLeft, 0, 4095);
- this->ui->ADC1Plot->setAxisScale(QwtPlot::xBottom, 0, this->xMax);
- this->ui->ADC2Plot->setAxisScale(QwtPlot::xBottom, 0, this->xMax);
- this->remote = new QSerialPort(this);
- connect(this->remote, SIGNAL(readyRead()), this, SLOT(recvData()));
- connect(this->ui->ttyReconnectButton, SIGNAL(released()),this, SLOT(reopenRemote()));
- {
- memset(&this->curState, 0, sizeof(this->curState));
- memset(&this->ADCData, 0xff, sizeof(this->ADCData));
- memset(&this->ADCCurPoint, 0, sizeof(this->ADCCurPoint));
- int adcId = 0;
- while (adcId < ADCS) {
- QwtPlot *p = this->getPlotByAdcId(adcId);
- p->installEventFilter(this);
- int i = 0;
- //this->ui->ADC1Plot->setAutoReplot(true);
- while (i < 2) {
- QwtPlotCurve *c;
- c = &this->ADCCurve[adcId][i];
- c->setStyle( QwtPlotCurve::Lines );
- c->setPen( QColor(0, 0, 0, 255 / ((2-i)*(2-i))) );
- c->setRenderHint( QwtPlotItem::RenderAntialiased, true );
- c->setPaintAttribute( QwtPlotCurve::ClipPolygons, false );
- c->attach(p);
- i++;
- }
- p->show();
- adcId++;
- }
- }
- this->showCurState();
- this->redrawGraphics();
- this->on_stopM0Radio_toggled(true);
- this->on_stopM1Radio_toggled(true);
- this->openRemote();
- }
- MainWindow::~MainWindow()
- {
- this->closeRemote();
- delete ui;
- }
- void MainWindow::openRemote()
- {
- qDebug("openRemote(): %s", this->ui->ttyPathEdit->toPlainText().toStdString().c_str());
- //SettingsDialog::Settings p = settings->settings();
- this->remote->setPortName(this->ui->ttyPathEdit->toPlainText());
- this->remote->setBaudRate(9600);
- this->remote->setDataBits(QSerialPort::Data8);
- this->remote->setParity(QSerialPort::NoParity);
- this->remote->setStopBits(QSerialPort::OneStop);
- this->remote->setFlowControl(QSerialPort::NoFlowControl);
- if (remote->open(QIODevice::ReadWrite)) {
- this->ui->statusBar->showMessage("Connected");
- } else {
- this->ui->statusBar->showMessage("Error: cannot connect!");
- }
- }
- void MainWindow::closeRemote()
- {
- qDebug("closeRemote()");
- if (remote->isOpen())
- remote->close();
- this->ui->statusBar->showMessage("Disconnected");
- }
- void MainWindow::reopenRemote()
- {
- this->closeRemote();
- this->openRemote();
- return;
- }
- QwtPlot *MainWindow::getPlotByAdcId(int adcId)
- {
- switch (adcId) {
- case 0:
- return this->ui->ADC1Plot;
- case 1:
- return this->ui->ADC2Plot;
- default:
- qFatal("Invalid adcId == %i", adcId);
- }
- return NULL;
- }
- void MainWindow::showCurState()
- {
- this->ui->ADC1Value->setText("ADC1: "+QString::number(this->curState.adc[0].value));
- this->ui->ADC2Value->setText("ADC2: "+QString::number(this->curState.adc[1].value));
- this->ui->statusBar->showMessage(QString("Connected: " + QString(this->curState.m[0].direction) +" "+ QString::number(this->curState.m[0].speed) +" "+ QString(this->curState.m[1].direction) +" "+ QString::number(this->curState.m[1].speed) +" "+ QString::number(this->curState.adc[0].value) +" "+ QString::number(this->curState.adc[1].value)));
- return;
- }
- void MainWindow::pushAdcValue(u_int8_t adcId, qint64 ts, u_int16_t value)
- {
- //static int i = 0;
- qint64 ts_local_int = ts;
- double ts_local;
- ts_local_int %= this->xMax*1000;
- ts_local = (double)ts_local_int/1000;
- curpoint_t *c = &this->ADCCurPoint[adcId];
- //qDebug("pushAdcValue(): %i %lf (%lu) %i", adcId, ts_local, (u_int64_t)ts, value);
- if (c->ts != ts_local*POINTSPERSEC) {
- point_t *p = &this->ADCData[adcId][c->pointId++];
- p->x = ts_local;
- p->y = c->avg;
- //qDebug("pushAdcValue(): new point: %lu: %f %u", (u_int64_t)c->pointId, p->x, p->y);
- if (c->pointId > ADCDATALEN) c->pointId = 0;
- c->times = 0;
- c->avg = 65535;
- c->ts = ts_local*POINTSPERSEC;
- }
- c->avg = (c->avg * c->times + value) / (c->times+1);
- c->times++;
- return;
- }
- int MainWindow::fillPoints(QPolygonF &points, point_t *data, int startPointId, int endPointId, int skipBeforeTs)
- {
- int i = startPointId;
- float skipBeforeTsFloat = (float)skipBeforeTs / POINTSPERSEC;
- float oldX = -1;
- while (i < endPointId) {
- float x = data[i].x;
- u_int16_t y = data[i].y;
- i++;
- if (y > 4096)
- continue;
- if (x < oldX)
- break;
- if (x <= skipBeforeTsFloat) {
- //qDebug("x <= skipBeforeTsFloat: %f %f", x, skipBeforeTsFloat);
- continue;
- }
- oldX=x;
- points << QPointF(x, y);
- }
- return i;
- }
- qint64 MainWindow::drawOldCurve(int adcId)
- {
- QPolygonF points;
- int i = this->fillPoints(points, this->ADCData[adcId], (int)this->ADCCurPoint[adcId].pointId, ADCDATALEN, (int)this->ADCCurPoint[adcId].ts);
- if (i >= ADCDATALEN)
- i = this->fillPoints(points, this->ADCData[adcId], 0, (int)this->ADCCurPoint[adcId].pointId, (int)this->ADCCurPoint[adcId].ts);
- if (i != this->ADCCurPoint[adcId].pointId) {
- this->ADCCurve[adcId][0].setSamples(points);
- this->getPlotByAdcId(adcId)->replot();
- } else i = 0;
- //qDebug("drawOldCurve(%i): pointId == %lu; i == %i", adcId, (u_int64_t)this->ADCCurPoint[adcId].pointId, i);
- return i;
- }
- void MainWindow::drawNewCurve(int adcId, qint64 startPointId)
- {
- QPolygonF points;
- //qDebug("drawNewCurve(%i, %lu)", adcId, (u_int64_t)startPointId);
- if (this->ADCCurPoint[adcId].pointId < startPointId)
- this->fillPoints(points, this->ADCData[adcId], startPointId, ADCDATALEN, 0);
- this->fillPoints(points, this->ADCData[adcId], startPointId, (int)this->ADCCurPoint[adcId].pointId, 0);
- this->ADCCurve[adcId][1].setSamples(points);
- this->getPlotByAdcId(adcId)->replot();
- }
- void MainWindow::redrawGraphics()
- {
- //qDebug("redrawGraphics()");
- int i = 0;
- while (i < ADCS) {
- this->drawNewCurve(i, this->drawOldCurve(i));
- i++;
- }
- return;
- }
- void MainWindow::recvData()
- {
- if (!remote->canReadLine())
- return;
- QByteArray data = remote->readLine();
- QString string = QTextCodec::codecForMib(106)->toUnicode(data);
- QRegExp rx("[ ]+");
- QStringList arguments = string.split(rx);
- qDebug("received data (%i: %s): %s", arguments.size(), arguments.at(0).toStdString().c_str(), string.toStdString().c_str());
- if(arguments.size() < 6)
- return;
- this->curState.m[0].direction = arguments.at(0).at(0).toLatin1();
- this->curState.m[0].speed = arguments.at(1).toInt();
- this->curState.m[1].direction = arguments.at(2).at(0).toLatin1();
- this->curState.m[1].speed = arguments.at(3).toInt();
- this->curState.adc[0].value = arguments.at(4).toInt();
- this->curState.adc[1].value = arguments.at(5).toInt();
- int i = 0;
- while (i < MOTORS) {
- if (memcmp(&this->curState.m[i], &this->desiredState.m[i], sizeof(this->curState.m[i]))) {
- //qDebug("motor %i differs: %c ? %c; %i ? %i", i, this->curState.m[i].direction, this->desiredState.m[i].direction, this->curState.m[i].speed, this->desiredState.m[i].speed);
- this->sendDesiredState(i);
- }
- i++;
- }
- QDateTime curDateTime = QDateTime::currentDateTime();
- qint64 ts = curDateTime.currentMSecsSinceEpoch();
- this->pushAdcValue(0, ts, this->curState.adc[0].value);
- this->pushAdcValue(1, ts, this->curState.adc[1].value);
- this->showCurState();
- this->redrawGraphics();
- return;
- }
- void MainWindow::on_resize_centralWidget(QResizeEvent *event) {
- qDebug("centralWidget Resized (New Size) - Width: %d Height: %d (was: %d x %d)",
- event->size().width(),
- event->size().height(),
- event->oldSize().width(),
- event->oldSize().height()
- );
- this->ui->graphicsLayout->setGeometry(QRect(0, 0, event->size().width()-105, event->size().height()-20));
- this->ui->infoLayout->setGeometry(QRect(event->size().width()-100, 0, 100, event->size().height()-20));
- //this->ui->statusBar->setGeometry(0, event->size().height()-20, event->size().width(), 20);
- this->redrawGraphics();
- return;
- }
- void MainWindow::on_resize_toolsWidget(QResizeEvent *event) {
- qDebug("toolsWidget Resized (New Size) - Width: %d Height: %d (was: %d x %d)",
- event->size().width(),
- event->size().height(),
- event->oldSize().width(),
- event->oldSize().height()
- );
- this->ui->toolsLayout->setGeometry(QRect(0, 0, event->size().width()-40, event->size().height()));
- return;
- }
- void MainWindow::on_resize_plot(QResizeEvent *event, int adcId, QwtPlot *p)
- {
- QSize centerWidgetSize = this->ui->centralWidget->size();
- /*qDebug("plot %i Resized (New Size) - Width: %d Height: %d (was: %d x %d); newY: %u", adcId,
- event->size().width(),
- event->size().height(),
- event->oldSize().width(),
- event->oldSize().height(),
- (centerWidgetSize.height() * (adcId))/ADCS
- );*/
- this->ui->graphicsLayout->setGeometry(QRect(0, 0, centerWidgetSize.width()-105, centerWidgetSize.height()-20));
- p->setGeometry(0, (centerWidgetSize.height() * (adcId))/ADCS, centerWidgetSize.width()-105, centerWidgetSize.height()/ADCS);
- return;
- }
- bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
- if (event->type() == QEvent::Resize) {
- Ui::MainWindow *ui = this->ui;
- if (obj == ui->centralWidget)
- this->on_resize_centralWidget(static_cast<QResizeEvent*>(event));
- else
- if (obj == ui->toolsWidget)
- this->on_resize_toolsWidget (static_cast<QResizeEvent*>(event));
- else {
- int adcId = 0;
- while (adcId < ADCS) {
- QwtPlot *p = this->getPlotByAdcId(adcId);
- if (obj == p) {
- this->on_resize_plot(static_cast<QResizeEvent*>(event), adcId, p);
- break;
- }
- adcId++;
- }
- }
- }
- return QWidget::eventFilter(obj, event);
- }
- void MainWindow::sendDesiredState(int motorId)
- {
- motor_t *m = &this->desiredState.m[motorId];
- QString sendStr = "H"+QString::number(motorId+1)+ m->direction +" "+QString::number(m->speed)+"\r\n";
- this->remote->write(sendStr.toUtf8());
- //qDebug("sending: %s", sendStr.toStdString().c_str());
- }
- void MainWindow::on_speedM0Slider_valueChanged(int value)
- {
- this->desiredState.m[0].speed = sqrt(209-value+0.1);
- this->sendDesiredState(0);
- }
- void MainWindow::on_speedM1Slider_valueChanged(int value)
- {
- this->desiredState.m[1].speed = sqrt(209-value+0.1);
- this->sendDesiredState(0);
- }
- void MainWindow::on_downM0Radio_toggled(bool checked)
- {
- if (checked)
- this->desiredState.m[0].direction = M_DOWN;
- this->sendDesiredState(0);
- }
- void MainWindow::on_stopM0Radio_toggled(bool checked)
- {
- if (checked)
- this->desiredState.m[0].direction = M_STOP;
- this->sendDesiredState(0);
- }
- void MainWindow::on_upM0Radio_toggled(bool checked)
- {
- if (checked)
- this->desiredState.m[0].direction = M_UP;
- this->sendDesiredState(1);
- }
- void MainWindow::on_downM1Radio_toggled(bool checked)
- {
- if (checked)
- this->desiredState.m[1].direction = M_DOWN;
- this->sendDesiredState(1);
- }
- void MainWindow::on_stopM1Radio_toggled(bool checked)
- {
- if (checked)
- this->desiredState.m[1].direction = M_STOP;
- this->sendDesiredState(1);
- }
- void MainWindow::on_upM1Radio_toggled(bool checked)
- {
- if (checked)
- this->desiredState.m[1].direction = M_UP;
- this->sendDesiredState(1);
- }
|