#include "mainwindow.h" #include "./ui_mainwindow.h" #include #include #include #include "gcodetovhf.h" MainWindow::MainWindow(VhfMill* mill, QWidget *parent) : mill_(mill), QMainWindow(parent), ui(new Ui::MainWindow), viewTopAction(QKeySequence(Qt::Key_7), this, 0, 0, Qt::ApplicationShortcut), viewFrontAction(QKeySequence(Qt::Key_1), this, 0, 0, Qt::ApplicationShortcut), viewLeftAction(QKeySequence(Qt::Key_9), this, 0, 0, Qt::ApplicationShortcut), viewRightAction(QKeySequence(Qt::Key_3), this, 0, 0, Qt::ApplicationShortcut) { installEventFilter(this); ui->setupUi(this); checkBlocks(); int splitHight = ui->splitter->size().height(); ui->splitter->setSizes({3*splitHight/4, splitHight/4}); ui->horizontalSlider->setTracking(false); ui->plainTextEdit_compiled->setVisible(false); ui->plainTextEdit_compiled->setWordWrapMode(QTextOption::NoWrap); ui->plainTextEdit->setWordWrapMode(QTextOption::NoWrap); connect(mill_, &VhfMill::raiseError, this, &MainWindow::raiseError); connect(mill_, &VhfMill::positionUpdate, this, &MainWindow::positionUpdate); connect(mill_, &VhfMill::gotToolNum, ui->lcd_tool, QOverload::of(&QLCDNumber::display)); connect(mill_, &VhfMill::gotOutputs, this, &MainWindow::gotOutputs); connect(mill_, &VhfMill::gotSindleSpeed, this, &MainWindow::gotSpindleSpeed); connect(mill_, &VhfMill::gotProbeState, ui->led_probe, &Led::setLit); connect(mill_, &VhfMill::gotPressureState, this, &MainWindow::gotPressureState); connect(mill_, &VhfMill::initDone, this, &MainWindow::checkBlocks); connect(mill_, &VhfMill::isHomed, this, &MainWindow::isHomed); connect(mill_, &VhfMill::toolChangeDone, this, &MainWindow::toolChangeDone); connect(mill_, &VhfMill::touchoffChanged, this, &MainWindow::touchoffChanged); connect(mill_, &VhfMill::positionUpdate, ui->backPlot, &BackPlotWidget::positionUpdate); connect(ui->checkBox_oe1, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 1), Q_ARG(bool, checked)); }); connect(ui->checkBox_oe2, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 2), Q_ARG(bool, checked)); }); connect(ui->checkBox_oe3, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 3), Q_ARG(bool, checked)); }); connect(ui->checkBox_oe4, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 4), Q_ARG(bool, checked)); }); connect(ui->checkBox_oe5, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 5), Q_ARG(bool, checked)); }); connect(ui->checkBox_oe6, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 6), Q_ARG(bool, checked)); }); connect(ui->checkBox_oe7, &QCheckBox::toggled, mill_, [this](bool checked) { QMetaObject::invokeMethod(mill_, "setOutput", Qt::QueuedConnection, Q_ARG(int, 7), Q_ARG(bool, checked)); }); connect(ui->pushButton_home, &QPushButton::clicked, this, &MainWindow::home); connect(ui->pushButton_homeAll, &QPushButton::clicked, this, [this](){QMetaObject::invokeMethod(mill_, [this]() {mill_->home(VhfMill::AXIS_ALL);}, Qt::QueuedConnection);}); connect(ui->pushButton_stopSpindle, &QPushButton::clicked, this, &MainWindow::stopSpindle); connect(ui->horizontalSlider, &QSlider::valueChanged, mill_, &VhfMill::setSpindleSpeed); connect(ui->pushButton_init, &QPushButton::clicked, mill_, &VhfMill::init); connect(ui->pushButton_run, &QPushButton::clicked, this, &MainWindow::run); connect(ui->pushButton_toolUnload, &QPushButton::clicked, this, &MainWindow::toolUnload); connect(ui->pushButton_toolSwitch, &QPushButton::clicked, this, &MainWindow::toolSwitch); connect(ui->pushButton_touchoff, &QPushButton::clicked, this, &MainWindow::touchoff); connect(ui->pushButton_touchoffAll, &QPushButton::clicked, this, &MainWindow::touchoffAll); connect(ui->pushButton_touchoffRst, &QPushButton::clicked, this, &MainWindow::touchoffRst); connect(ui->pushButton_stop, &QPushButton::released, mill_, &VhfMill::stop); connect(ui->actionOpen_Gcode, &QAction::triggered, this, &MainWindow::openGcode); connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::openVhfCode); connect(ui->plainTextEdit, &QPlainTextEdit::textChanged, this, &MainWindow::textChanged); connect(ui->radioButton_gcode, &QRadioButton::toggled, ui->plainTextEdit_compiled, &QPlainTextEdit::setVisible); connect(ui->radioButton_gcode, &QRadioButton::toggled, this, &MainWindow::textChanged); connect(ui->comboBox_jogStep, &QComboBox::currentIndexChanged, this, &MainWindow::selectedJogStepChanged); connect(ui->pushButton_jogXp, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_X, 1);}); connect(ui->pushButton_jogXn, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_X, -1);}); connect(ui->pushButton_jogYp, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_Y, -1);}); connect(ui->pushButton_jogYn, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_Y, 1);}); connect(ui->pushButton_jogUp, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_Z, 1);}); connect(ui->pushButton_jogDown, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_Z, -1);}); connect(ui->pushButton_jogAp, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_A, 1);}); connect(ui->pushButton_jogAn, &QPushButton::pressed, this, [this](){jog(VhfMill::AXIS_A, -1);}); connect(ui->pushButton_jogXp, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_X, 0);}); connect(ui->pushButton_jogXn, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_X, 0);}); connect(ui->pushButton_jogYp, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_Y, 0);}); connect(ui->pushButton_jogYn, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_Y, 0);}); connect(ui->pushButton_jogUp, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_Z, 0);}); connect(ui->pushButton_jogDown, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_Z, 0);}); connect(ui->pushButton_jogAp, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_A, 0);}); connect(ui->pushButton_jogAn, &QPushButton::released, this, [this](){jog(VhfMill::AXIS_A, 0);}); BackPlotWidget* backplot = ui->backPlot; connect(&viewTopAction, &QShortcut::activated, backplot, [backplot](){backplot->showView(BackPlotWidget::VIEW_TOP);}); connect(&viewFrontAction, &QShortcut::activated, backplot, [backplot](){backplot->showView(BackPlotWidget::VIEW_FRONT);}); connect(&viewLeftAction, &QShortcut::activated, backplot, [backplot](){backplot->showView(BackPlotWidget::VIEW_LEFT);}); connect(&viewRightAction, &QShortcut::activated, backplot, [backplot](){backplot->showView(BackPlotWidget::VIEW_RIGHT);}); } MainWindow::~MainWindow() { delete ui; } void MainWindow::selectedJogStepChanged(int index) { switch(index) { case 0: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(-1);}, Qt::QueuedConnection); break; case 1: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(5000);}, Qt::QueuedConnection); break; case 2: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(1000);}, Qt::QueuedConnection); break; case 3: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(250);}, Qt::QueuedConnection); break; case 4: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(100);}, Qt::QueuedConnection); break; case 5: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(50);}, Qt::QueuedConnection); break; default: QMetaObject::invokeMethod(mill_, [this](){mill_->setjogStep(0);}, Qt::QueuedConnection); break; } } void MainWindow::jog(VhfMill::Axis axis, int jogDirection) { QMetaObject::invokeMethod(mill_, [this, axis, jogDirection](){mill_->jog(axis, jogDirection);}, Qt::QueuedConnection); } bool MainWindow::eventFilter(QObject *object, QEvent *event) { if(jogEnabled) { if(event->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(event); switch(ke->key()) { case Qt::Key_Up: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Y, -1); event->setAccepted(true); return true; case Qt::Key_Left: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_X, -1); event->setAccepted(true); return true; case Qt::Key_Right: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_X, 1); event->setAccepted(true); return true; case Qt::Key_Down: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Y, 1); event->setAccepted(true); return true; case Qt::Key_PageUp: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Z, 1); event->setAccepted(true); return true; case Qt::Key_PageDown: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Z, -1); event->setAccepted(true); return true; default: break; } } else if(event->type() == QEvent::KeyRelease) { QKeyEvent *ke = static_cast(event); switch(ke->key()) { case Qt::Key_Up: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Y, 0); event->setAccepted(true); return true; case Qt::Key_Left: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_X, 0); event->setAccepted(true); return true; case Qt::Key_Right: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_X, 0); event->setAccepted(true); return true; case Qt::Key_Down: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Y, 0); event->setAccepted(true); return true; case Qt::Key_PageUp: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Z, 0); event->setAccepted(true); return true; case Qt::Key_PageDown: if(!ke->isAutoRepeat()) jog(VhfMill::AXIS_Z, 0); event->setAccepted(true); return true; default: break; } } } return false; } void MainWindow::textChanged() { bool ok = true; QByteArray programm = ui->plainTextEdit->toPlainText().toLatin1(); if(ui->radioButton_gcode->isChecked()) { QList errors; programm = gcodeToVhf(programm, &ok, &errors); if(!ok) ui->statusbar->showMessage(errors.back()); ui->plainTextEdit_compiled->setPlainText(programm); } ui->backPlot->programChanged(programm); } void MainWindow::home() { VhfMill::Axis axis = comboBoxToAxis(*ui->comboBox_homeAxis); qDebug()<<__func__<home(axis);}, Qt::QueuedConnection); } void MainWindow::toolUnload() { QMetaObject::invokeMethod(mill_, [this](){mill_->setTool(0);}, Qt::QueuedConnection); } void MainWindow::gotSpindleSpeed(int speed) { ui->lcd_spindle->display(speed); } void MainWindow::stopSpindle() { QMetaObject::invokeMethod(mill_, [this](){mill_->setSpindleSpeed(0);}, Qt::QueuedConnection); ui->horizontalSlider->setValue(0); } void MainWindow::isHomed(VhfMill::Axis axis) { ui->led_homeX->setLit(axis & VhfMill::AXIS_X); ui->led_homeY->setLit(axis & VhfMill::AXIS_Y); ui->led_homeZ->setLit(axis & VhfMill::AXIS_Z); ui->led_homeA->setLit(axis & VhfMill::AXIS_A); checkBlocks(); } VhfMill::Axis MainWindow::comboBoxToAxis(const QComboBox& box) { switch(box.currentIndex()) { case 0: return VhfMill::AXIS_X; case 1: return VhfMill::AXIS_Y; case 2: return VhfMill::AXIS_Z; case 3: return VhfMill::AXIS_A; case 4: return VhfMill::AXIS_B; default: return VhfMill::AXIS_NONE; } } void MainWindow::run() { QByteArray programm = ui->plainTextEdit->toPlainText().toLatin1(); if(ui->radioButton_gcode->isChecked()) { bool ok; programm = gcodeToVhf(programm, &ok); if(!ok) { QMessageBox::critical(this, "Error", "failed to parse gcode"); return; } } QMetaObject::invokeMethod(mill_, [programm, this](){mill_->send(programm);}, Qt::QueuedConnection); } void MainWindow::toolSwitch() { QMetaObject::invokeMethod(mill_, [this](){mill_->setTool(ui->comboBox_tool->currentIndex()+1);}, Qt::QueuedConnection); } void MainWindow::touchoff() { bool ok; double offset = QInputDialog::getDouble(this, "Offset", "offset in mm", 0, -1000, 1000, 2, &ok); if(ok) QMetaObject::invokeMethod(mill_, [this, offset](){mill_->touchOff(comboBoxToAxis(*ui->comboBox_TouchoffAxis), offset*1000);}, Qt::QueuedConnection); } void MainWindow::touchoffAll() { QMetaObject::invokeMethod(mill_, [this](){mill_->touchOff(VhfMill::AXIS_ALL, 0);}, Qt::QueuedConnection); } void MainWindow::touchoffRst() { QMetaObject::invokeMethod(mill_, [this](){mill_->touchOffAbsolute({0,0,0,0});}, Qt::QueuedConnection); } void MainWindow::toolChangeDone() { QMetaObject::invokeMethod(mill_, &VhfMill::reqTool, Qt::QueuedConnection); setToolchangeBlocked(false); } void MainWindow::raiseError(int errorNum) { QMessageBox::critical(this, "Error", VhfMill::textForErrno(errorNum)); checkBlocks(); } void MainWindow::positionUpdate(std::vector position) { if(position.size() < 4) return; std::vector touchoff; if(ui->radioButton->isChecked()) touchoff.assign(position.size(), 0); else touchoff = mill_->getLastTouchoffPosition(); size_t xIndex = VhfMill::axisToIndex(VhfMill::AXIS_X); size_t yIndex = VhfMill::axisToIndex(VhfMill::AXIS_Y); size_t zIndex = VhfMill::axisToIndex(VhfMill::AXIS_Z); size_t aIndex = VhfMill::axisToIndex(VhfMill::AXIS_A); double xDpl = position[xIndex] - touchoff[xIndex]; double yDpl = position[yIndex] - touchoff[yIndex]; double zDpl = position[zIndex] - touchoff[zIndex]; double aDpl = position[aIndex] - touchoff[aIndex]; ui->lcd_x->display(xDpl/1000.0); ui->lcd_y->display(yDpl/1000.0); ui->lcd_z->display(zDpl/1000.0); ui->lcd_a->display(aDpl/1000.0); } void MainWindow::openVhfCode() { QString fileName = QFileDialog::getOpenFileName(this, "Open File", "~", "VhfCode (*.vhf)"); if(!fileName.isEmpty()) { QFile gcodeFile(fileName); if(!gcodeFile.open(QIODeviceBase::ReadOnly)) { QMessageBox::critical(this, "Error", "Could not open " + fileName + " for reading"); return; } QByteArray vhfCode = gcodeFile.readAll(); ui->radioButton_vhfCode->setChecked(true); ui->plainTextEdit->setPlainText(vhfCode); } } void MainWindow::openGcode() { QString fileName = QFileDialog::getOpenFileName(this, "Open File", "~", "Gcode (*.ngc *.nc)"); if(!fileName.isEmpty()) { QFile gcodeFile(fileName); if(!gcodeFile.open(QIODeviceBase::ReadOnly)) { QMessageBox::critical(this, "Error", "Could not open " + fileName + " for reading"); return; } bool ok; QByteArray gcode = gcodeFile.readAll(); gcodeToVhf(gcode, &ok); if(!ok) { QMessageBox::critical(this, "Error", "failed to parse gcode"); return; } ui->radioButton_gcode->setChecked(true); ui->radioButton_vhfCode->setChecked(false); ui->plainTextEdit->setPlainText(gcode); } } void MainWindow::touchoffChanged(std::vector position) { if(position.size() < 4) return; ui->lcd_touchX->display(static_cast(position[VhfMill::axisToIndex(VhfMill::AXIS_X)])/1000.0); ui->lcd_touchY->display(static_cast(position[VhfMill::axisToIndex(VhfMill::AXIS_Y)])/1000.0); ui->lcd_touchZ->display(static_cast(position[VhfMill::axisToIndex(VhfMill::AXIS_Z)])/1000.0); ui->lcd_touchA->display(static_cast(position[VhfMill::axisToIndex(VhfMill::AXIS_A)])/1000.0); positionUpdate(mill_->getLastKnownPosition()); ui->backPlot->touchoffUpdate(position); textChanged(); } void MainWindow::checkBlocks() { setAllBlocked(true); if(mill_->isInitDone()) { qDebug()<<__func__<<"unblocking home and spindle"; setSpindleBlocked(false); setHomeingBlocked(false); setOutputsBlocked(false); if(mill_->allHomed()) { qDebug()<<__func__<<"unblocking jog"; setJogBlocked(false); ui->pushButton_run->setEnabled(true); if(mill_->presureReady()) { qDebug()<<__func__<<"unblocking tool change"; setToolchangeBlocked(false); } } } } void MainWindow::gotOutputs(uint8_t outputs) { ui->checkBox_oe1->setChecked(outputs & 1<<0); ui->checkBox_oe2->setChecked(outputs & 1<<1); ui->checkBox_oe3->setChecked(outputs & 1<<2); ui->checkBox_oe4->setChecked(outputs & 1<<3); ui->checkBox_oe5->setChecked(outputs & 1<<4); ui->checkBox_oe6->setChecked(outputs & 1<<5); ui->checkBox_oe7->setChecked(outputs & 1<<6); } void MainWindow::gotPressureState(bool state) { ui->led_pressure->setLit(!state); checkBlocks(); } void MainWindow::setAllBlocked(bool blocked) { setOutputsBlocked(blocked); setJogBlocked(blocked); setToolchangeBlocked(blocked); setSpindleBlocked(blocked); setHomeingBlocked(blocked); ui->pushButton_run->setEnabled(!blocked); } void MainWindow::setOutputsBlocked(bool block) { ui->checkBox_oe1->setEnabled(!block); ui->checkBox_oe2->setEnabled(!block); ui->checkBox_oe3->setEnabled(!block); ui->checkBox_oe4->setEnabled(!block); ui->checkBox_oe5->setEnabled(!block); ui->checkBox_oe6->setEnabled(!block); ui->checkBox_oe7->setEnabled(!block); } void MainWindow::setJogBlocked(bool block) { jogEnabled = !block; ui->pushButton_jogDown->setEnabled(!block); ui->pushButton_jogUp->setEnabled(!block); ui->pushButton_jogXp->setEnabled(!block); ui->pushButton_jogXn->setEnabled(!block); ui->pushButton_jogYp->setEnabled(!block); ui->pushButton_jogYn->setEnabled(!block); ui->pushButton_jogAp->setEnabled(!block); ui->pushButton_jogAn->setEnabled(!block); ui->comboBox_jogStep->setEnabled(!block); } void MainWindow::setToolchangeBlocked(bool block) { ui->pushButton_toolSwitch->setEnabled(!block); ui->pushButton_toolUnload->setEnabled(!block); ui->comboBox_tool->setEnabled(!block); } void MainWindow::setSpindleBlocked(bool block) { ui->pushButton_stopSpindle->setEnabled(!block); ui->horizontalSlider->setEnabled(!block); } void MainWindow::setHomeingBlocked(bool block) { ui->pushButton_home->setEnabled(!block); ui->pushButton_homeAll->setEnabled(!block); ui->comboBox_homeAxis->setEnabled(!block); } void MainWindow::setTouchoffBlocked(bool block) { ui->comboBox_TouchoffAxis->setEnabled(!block); ui->pushButton_touchoff->setEnabled(!block); ui->pushButton_touchoffAll->setEnabled(!block); }