inital commit
This commit is contained in:
		
						commit
						f91c9f1a6f
					
				
					 19 changed files with 3763 additions and 0 deletions
				
			
		
							
								
								
									
										43
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | |||
| cmake_minimum_required(VERSION 3.5) | ||||
| 
 | ||||
| project(VHFMill VERSION 0.1 LANGUAGES CXX) | ||||
| 
 | ||||
| set(CMAKE_AUTOUIC ON) | ||||
| set(CMAKE_AUTOMOC ON) | ||||
| set(CMAKE_AUTORCC ON) | ||||
| 
 | ||||
| set(CMAKE_CXX_STANDARD 17) | ||||
| set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||||
| 
 | ||||
| find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets) | ||||
| find_package(Qt6 REQUIRED COMPONENTS Widgets SerialPort Network 3DCore 3DRender 3DInput 3DExtras) | ||||
| 
 | ||||
| set(PROJECT_SOURCES | ||||
| 	    main.cpp | ||||
| 		mainwindow.cpp | ||||
| 		vhfmill.cpp | ||||
| 		vhfmill.h | ||||
| 		led.cpp | ||||
| 		led.h | ||||
| 		gcodetovhf.cpp | ||||
| 		gcodetovhf.h | ||||
| 		mainwindow.h | ||||
| 		mainwindow.ui | ||||
| 		backplotwidget.cpp | ||||
| 		backplotwidget.h | ||||
| 		orbitcameracontroller.cpp | ||||
| 		orbitcameracontroller.h | ||||
| 		vhfmillthread.cpp | ||||
| 		vhfmillthread.h | ||||
| 		mainobject.cpp | ||||
| 		mainobject.h | ||||
| ) | ||||
| 
 | ||||
| qt_add_executable(VHFMill MANUAL_FINALIZATION ${PROJECT_SOURCES}) | ||||
| 
 | ||||
| target_link_libraries(VHFMill PRIVATE Qt6::Widgets Qt6::SerialPort Qt6::Network Qt6::3DCore Qt6::3DRender Qt6::3DExtras) | ||||
| target_include_directories(VHFMill PRIVATE .) | ||||
| 
 | ||||
| install(TARGETS VHFMill BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) | ||||
| 
 | ||||
| qt_finalize_executable(VHFMill) | ||||
							
								
								
									
										337
									
								
								backplotwidget.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										337
									
								
								backplotwidget.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,337 @@ | |||
| #include "backplotwidget.h" | ||||
| 
 | ||||
| #include <QWidget> | ||||
| #include <QCamera> | ||||
| #include <QCameraLens> | ||||
| #include <QMaterial> | ||||
| #include <QGeometry> | ||||
| #include <Qt3DExtras/QCylinderMesh> | ||||
| #include <Qt3DExtras/QPlaneMesh> | ||||
| #include <Qt3DRender/qpointlight.h> | ||||
| #include <QRenderSettings> | ||||
| 
 | ||||
| BackPlotWidget::BackPlotWidget(QWidget *parent, double xLimit, double yLimit, double zLimit) | ||||
| 	: limits(xLimit, yLimit, zLimit), | ||||
| 	  QWidget(parent) | ||||
| { | ||||
| 
 | ||||
| 	containerWdiget = QWidget::createWindowContainer(&view); | ||||
| 	hLayout.addWidget(containerWdiget); | ||||
| 	containerWdiget->setParent(this); | ||||
| 	setLayout(&hLayout); | ||||
| 	view.defaultFrameGraph()->setClearColor("Black"); | ||||
| 
 | ||||
| 	reset(); | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::reset() | ||||
| { | ||||
| 	view.setRootEntity(nullptr); | ||||
| 
 | ||||
| 	if(rootEntity) | ||||
| 		delete rootEntity; | ||||
| 	rootEntity = new Qt3DCore::QEntity(); | ||||
| 	view.setRootEntity(rootEntity); | ||||
| 	view.renderSettings()->setRenderPolicy(Qt3DRender::QRenderSettings::OnDemand); | ||||
| 
 | ||||
| 	camController = new OrbitCameraController(QVector2D(100, 100), rootEntity); | ||||
| 	camController->setLinearSpeed(200.0f); | ||||
| 	camController->setLookSpeed(360.0f); | ||||
| 	camController->setCamera(view.camera()); | ||||
| 
 | ||||
| 	axisMaterial = new Qt3DExtras::QPhongMaterial(rootEntity); | ||||
| 	rapidMaterial= new Qt3DExtras::QPhongMaterial(rootEntity); | ||||
| 	pathMaterial = new Qt3DExtras::QPhongMaterial(rootEntity); | ||||
| 	axisMaterial->setAmbient(QColorConstants::Red); | ||||
| 	rapidMaterial->setAmbient(QColorConstants::Gray); | ||||
| 	pathMaterial->setAmbient(QColorConstants::White); | ||||
| 
 | ||||
| 	view.camera()->setPosition(QVector3D(limits.x()/2, limits.y()/2, limits.z()*4)); | ||||
| 	view.camera()->setUpVector(QVector3D(0, 1, 0)); | ||||
| 	view.camera()->setViewCenter(QVector3D(limits.x()/2, limits.y()/2, 0)); | ||||
| 
 | ||||
| 	Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity); | ||||
| 	light->setColor(QColorConstants::White); | ||||
| 	light->setIntensity(0.2); | ||||
| 	lightEntity->addComponent(light); | ||||
| 	Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity); | ||||
| 	lightTransform->setTranslation(QVector3D(0-limits.x()/2, 0-limits.y()/2, 1000.0f)); | ||||
| 	lightEntity->addComponent(lightTransform); | ||||
| 
 | ||||
| 	Qt3DCore::QEntity* xAxisEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DCore::QEntity* yAxisEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DCore::QEntity* zAxisEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DExtras::QPhongMaterial* xAxisMaterial = new Qt3DExtras::QPhongMaterial(xAxisEntity); | ||||
| 	Qt3DExtras::QPhongMaterial* yAxisMaterial = new Qt3DExtras::QPhongMaterial(yAxisEntity); | ||||
| 	Qt3DExtras::QPhongMaterial* zAxisMaterial = new Qt3DExtras::QPhongMaterial(zAxisEntity); | ||||
| 	xAxisMaterial->setAmbient(QColorConstants::Green); | ||||
| 	yAxisMaterial->setAmbient(QColorConstants::Red); | ||||
| 	zAxisMaterial->setAmbient(QColor(18,128,255)); | ||||
| 	touchoffTransform = new Qt3DCore::QTransform(rootEntity); | ||||
| 	touchoffTransform->setTranslation(limits); | ||||
| 	xAxisEntity->addComponent(touchoffTransform); | ||||
| 	yAxisEntity->addComponent(touchoffTransform); | ||||
| 	zAxisEntity->addComponent(touchoffTransform); | ||||
| 	drawLine(QVector3D(0,0,0), QVector3D(-15,0,0), xAxisMaterial, xAxisEntity); | ||||
| 	drawLine(QVector3D(0,0,0), QVector3D(0,-15,0), yAxisMaterial, yAxisEntity); | ||||
| 	drawLine(QVector3D(0,0,0), QVector3D(0,0,15), zAxisMaterial, zAxisEntity); | ||||
| 
 | ||||
| 	drawBox(QVector3D(0, 0, 0), limits, axisMaterial, new Qt3DCore::QEntity(rootEntity)); | ||||
| 
 | ||||
| 	Qt3DCore::QEntity* planeEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DExtras::QPlaneMesh* plane = new Qt3DExtras::QPlaneMesh(planeEntity); | ||||
| 	Qt3DCore::QTransform *planeTransform = new Qt3DCore::QTransform(planeEntity); | ||||
| 	Qt3DExtras::QPhongMaterial* planeMaterial = new Qt3DExtras::QPhongMaterial(planeEntity); | ||||
| 	planeMaterial->setDiffuse(QColorConstants::DarkGray); | ||||
| 	planeTransform->setTranslation(QVector3D(limits.x()/2, limits.y()/2, -1)); | ||||
| 	planeTransform->setRotationX(90); | ||||
| 	plane->setHeight(limits.y()*2); | ||||
| 	plane->setWidth(limits.x()*2); | ||||
| 	planeEntity->addComponent(plane); | ||||
| 	planeEntity->addComponent(planeMaterial); | ||||
| 	planeEntity->addComponent(planeTransform); | ||||
| 
 | ||||
| 	Qt3DCore::QEntity* planeRevEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DExtras::QPlaneMesh* planeRev = new Qt3DExtras::QPlaneMesh(planeRevEntity); | ||||
| 	Qt3DCore::QTransform *planeRevTransform = new Qt3DCore::QTransform(planeRevEntity); | ||||
| 	planeRevTransform->setTranslation(QVector3D(limits.x()/2, limits.y()/2, -1)); | ||||
| 	planeRevTransform->setRotationX(-90); | ||||
| 	planeRev->setHeight(limits.y()*2); | ||||
| 	planeRev->setWidth(limits.x()*2); | ||||
| 	planeRevEntity->addComponent(planeRev); | ||||
| 	planeRevEntity->addComponent(planeMaterial); | ||||
| 	planeRevEntity->addComponent(planeRevTransform); | ||||
| 
 | ||||
| 	toolEntity = new Qt3DCore::QEntity(rootEntity); | ||||
| 	Qt3DExtras::QCylinderMesh* toolMesh = new Qt3DExtras::QCylinderMesh(toolEntity); | ||||
| 	Qt3DExtras::QPhongMaterial* toolMaterial = new Qt3DExtras::QPhongMaterial(toolEntity); | ||||
| 	toolTransform = new Qt3DCore::QTransform(toolEntity); | ||||
| 	toolTransform->setTranslation(limits + QVector3D(0,0,5)); | ||||
| 	toolTransform->setRotationX(90); | ||||
| 	toolMaterial->setDiffuse(QColorConstants::White); | ||||
| 	toolMaterial->setAmbient(QColor(64,64,64)); | ||||
| 	toolMesh->setRadius(1); | ||||
| 	toolMesh->setLength(10); | ||||
| 	toolEntity->addComponent(toolMesh); | ||||
| 	toolEntity->addComponent(toolMaterial); | ||||
| 	toolEntity->addComponent(toolTransform); | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::showView(ViewPos viewPos) | ||||
| { | ||||
| 	if(viewPos == VIEW_TOP) | ||||
| 	{ | ||||
| 		view.camera()->setPosition(QVector3D(limits.x()/2, limits.y()/2, limits.z()*4)); | ||||
| 		view.camera()->setUpVector(QVector3D(0, 1, 0)); | ||||
| 	} | ||||
| 	else if(viewPos == VIEW_FRONT) | ||||
| 	{ | ||||
| 		view.camera()->setPosition(QVector3D(limits.x()/2, 0-limits.y()*4, limits.z()/2)); | ||||
| 		view.camera()->setUpVector(QVector3D(0, 0, 1)); | ||||
| 	} | ||||
| 	else if(viewPos == VIEW_LEFT) | ||||
| 	{ | ||||
| 		view.camera()->setPosition(QVector3D(0-limits.x()*4, limits.y()/2, limits.z()/2)); | ||||
| 		view.camera()->setUpVector(QVector3D(0, 0, 1)); | ||||
| 	} | ||||
| 	else if(viewPos == VIEW_RIGHT) | ||||
| 	{ | ||||
| 		view.camera()->setPosition(QVector3D(limits.x()*4, limits.y()/2, limits.z()/2)); | ||||
| 		view.camera()->setUpVector(QVector3D(0, 0, 1)); | ||||
| 	} | ||||
| 
 | ||||
| 	if(viewPos == VIEW_TOP) | ||||
| 		view.camera()->setViewCenter(QVector3D(limits.x()/2, limits.y()/2, 0)); | ||||
| 	else | ||||
| 		view.camera()->setViewCenter(QVector3D(limits.x()/2, limits.y()/2, limits.z()/2)); | ||||
| 	camController->setZoomFactor(1); | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::positionUpdate(std::vector<int> position) | ||||
| { | ||||
| 	assert(position.size() >= 3); | ||||
| 	toolTransform->setTranslation(limits - QVector3D(position[0]/1000.0, position[1]/1000.0, (position[2]/1000.0)-5)); | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::resizeEvent(QResizeEvent *event) | ||||
| { | ||||
| 	QWidget::resizeEvent(event); | ||||
| 	double aspectRatio = static_cast<double>(geometry().width())/geometry().height(); | ||||
| 	double screenWidth; | ||||
| 	double screenHeight; | ||||
| 	if(aspectRatio > 1.0) | ||||
| 	{ | ||||
| 		screenWidth = 500.0; | ||||
| 		screenHeight = screenWidth/aspectRatio; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		screenHeight = 500; | ||||
| 		screenWidth = aspectRatio*screenHeight; | ||||
| 	} | ||||
| 	camController->setOrthoSize(QVector2D(screenWidth, screenHeight)); | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::drawBox(const QVector3D& a, const QVector3D& b, Qt3DRender::QMaterial* material, Qt3DCore::QEntity* parent) | ||||
| { | ||||
| 	drawLine(QVector3D(a.x(), a.y(), a.z()), QVector3D(b.x(), a.y(), a.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), a.y(), a.z()), QVector3D(a.x(), b.y(), a.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), a.y(), a.z()), QVector3D(a.x(), a.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(b.x(), a.y(), a.z()), QVector3D(b.x(), b.y(), a.z()), material, parent); | ||||
| 	drawLine(QVector3D(b.x(), a.y(), a.z()), QVector3D(b.x(), a.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), b.y(), a.z()), QVector3D(b.x(), b.y(), a.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), b.y(), a.z()), QVector3D(a.x(), b.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), a.y(), b.z()), QVector3D(b.x(), a.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), a.y(), b.z()), QVector3D(a.x(), b.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(b.x(), b.y(), a.z()), QVector3D(b.x(), b.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(a.x(), b.y(), b.z()), QVector3D(b.x(), b.y(), b.z()), material, parent); | ||||
| 	drawLine(QVector3D(b.x(), a.y(), b.z()), QVector3D(b.x(), b.y(), b.z()), material, parent); | ||||
| } | ||||
| 
 | ||||
| QByteArray BackPlotWidget::removeComments(const QByteArray& program) | ||||
| { | ||||
| 	int commentCounter = 0; | ||||
| 	QByteArray out; | ||||
| 	for(char ch : program) | ||||
| 	{ | ||||
| 		if(ch == '/') | ||||
| 			++commentCounter; | ||||
| 		else if(ch == '\\' && commentCounter > 0) | ||||
| 			--commentCounter; | ||||
| 		else if(commentCounter == 0) | ||||
| 			out.push_back(ch); | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| QList<int> BackPlotWidget::getFields(QByteArray command) | ||||
| { | ||||
| 	command.remove(0, 2); | ||||
| 	QList<QByteArray> fieldsText = command.split(','); | ||||
| 	QList<int> fields; | ||||
| 	for(const QByteArray& field : fieldsText) | ||||
| 	{ | ||||
| 		if(field.size() == 0) | ||||
| 			fields.push_back(NO_FIELD); | ||||
| 		else | ||||
| 			fields.push_back(field.toInt()); | ||||
| 	} | ||||
| 	return fields; | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::programChanged(QByteArray program) | ||||
| { | ||||
| 	for(Qt3DCore::QEntity* entitiy : pathEntitys) | ||||
| 		delete entitiy; | ||||
| 	pathEntitys.clear(); | ||||
| 
 | ||||
| 	program = removeComments(program); | ||||
| 	QList<QByteArray> commands = program.split(';'); | ||||
| 
 | ||||
| 	QVector3D lastPos = touchoffPosition; | ||||
| 
 | ||||
| 	qDebug()<<__func__; | ||||
| 
 | ||||
| 	for(QByteArray& command : commands) | ||||
| 	{ | ||||
| 		command = command.trimmed().toUpper(); | ||||
| 		if(command.size() < 2) | ||||
| 			continue; | ||||
| 		if(command[0] == 'P' || command[0] == 'G') | ||||
| 		{ | ||||
| 			QList<int> fields = getFields(command); | ||||
| 			QVector3D pos; | ||||
| 
 | ||||
| 			if(fields.size() <= 2 || fields[2] == NO_FIELD) | ||||
| 				pos.setZ(command[1] != 'R' ? lastPos.z()-touchoffPosition.z() : 0); | ||||
| 			else if(fields.size() > 2) | ||||
| 				pos.setZ(fields[2]/1000.0); | ||||
| 
 | ||||
| 			if(fields.size() <= 1 || fields[1] == NO_FIELD) | ||||
| 				pos.setY(command[1] != 'R' ? lastPos.y()-touchoffPosition.y() : 0); | ||||
| 			else if(fields.size() > 1) | ||||
| 				pos.setY(fields[1]/1000.0); | ||||
| 
 | ||||
| 			if(fields.size() <= 0 || fields[0] == NO_FIELD) | ||||
| 				pos.setX(command[1] != 'R' ? lastPos.x()-touchoffPosition.x() : 0); | ||||
| 			else if(fields.size() > 0) | ||||
| 				pos.setX(fields[0]/1000.0); | ||||
| 
 | ||||
| 			if(command[1] == 'A') | ||||
| 				pos = pos+touchoffPosition; | ||||
| 			else if(command[1] == 'R') | ||||
| 				pos = pos+lastPos; | ||||
| 
 | ||||
| 			pathEntitys.push_back(new Qt3DCore::QEntity(rootEntity)); | ||||
| 			drawLine(limits-lastPos, limits-pos, command[0] == 'G' ? rapidMaterial : pathMaterial, pathEntitys.back()); | ||||
| 
 | ||||
| 			lastPos = pos; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::touchoffUpdate(std::vector<int> position) | ||||
| { | ||||
| 	assert(position.size() >= 3); | ||||
| 	touchoffPosition.setX(position[0]/1000.0); | ||||
| 	touchoffPosition.setY(position[1]/1000.0); | ||||
| 	touchoffPosition.setZ(position[2]/1000.0); | ||||
| 	touchoffTransform->setTranslation(limits-touchoffPosition); | ||||
| } | ||||
| 
 | ||||
| void BackPlotWidget::drawLine(const QVector3D& start, const QVector3D& end, Qt3DRender::QMaterial* material, Qt3DCore::QEntity* parent) | ||||
| { | ||||
| 	 Qt3DCore::QGeometry* geometry = new Qt3DCore::QGeometry(parent); | ||||
| 
 | ||||
| 	// position vertices (start and end)
 | ||||
| 	QByteArray bufferBytes; | ||||
| 	bufferBytes.resize(3 * 2 * sizeof(float)); // start.x, start.y, start.end, end.x, end.y, end.z
 | ||||
| 	float* positions = reinterpret_cast<float*>(bufferBytes.data()); | ||||
| 	*positions++ = start.x(); | ||||
| 	*positions++ = start.y(); | ||||
| 	*positions++ = start.z(); | ||||
| 	*positions++ = end.x(); | ||||
| 	*positions++ = end.y(); | ||||
| 	*positions++ = end.z(); | ||||
| 
 | ||||
| 	Qt3DCore::QBuffer* buf = new Qt3DCore::QBuffer(geometry); | ||||
| 	buf->setData(bufferBytes); | ||||
| 
 | ||||
| 	auto *positionAttribute = new Qt3DCore::QAttribute(geometry); | ||||
| 	positionAttribute->setName(Qt3DCore::QAttribute::defaultPositionAttributeName()); | ||||
| 	positionAttribute->setVertexBaseType(Qt3DCore::QAttribute::Float); | ||||
| 	positionAttribute->setVertexSize(3); | ||||
| 	positionAttribute->setAttributeType(Qt3DCore::QAttribute::VertexAttribute); | ||||
| 	positionAttribute->setBuffer(buf); | ||||
| 	positionAttribute->setByteStride(3 * sizeof(float)); | ||||
| 	positionAttribute->setCount(2); | ||||
| 	geometry->addAttribute(positionAttribute); // We add the vertices in the geometry
 | ||||
| 
 | ||||
| 	// connectivity between vertices
 | ||||
| 	QByteArray indexBytes; | ||||
| 	indexBytes.resize(2 * sizeof(unsigned int)); // start to end
 | ||||
| 	unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data()); | ||||
| 	*indices++ = 0; | ||||
| 	*indices++ = 1; | ||||
| 
 | ||||
| 	Qt3DCore::QBuffer* indexBuffer = new Qt3DCore::QBuffer(geometry); | ||||
| 	indexBuffer->setData(indexBytes); | ||||
| 
 | ||||
| 	Qt3DCore::QAttribute *indexAttribute = new Qt3DCore::QAttribute(geometry); | ||||
| 	indexAttribute->setVertexBaseType(Qt3DCore::QAttribute::UnsignedInt); | ||||
| 	indexAttribute->setAttributeType(Qt3DCore::QAttribute::IndexAttribute); | ||||
| 	indexAttribute->setBuffer(indexBuffer); | ||||
| 	indexAttribute->setCount(2); | ||||
| 	geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry
 | ||||
| 
 | ||||
| 	// mesh
 | ||||
| 	auto *line = new Qt3DRender::QGeometryRenderer(parent); | ||||
| 	line->setGeometry(geometry); | ||||
| 	line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines); | ||||
| 
 | ||||
| 	// entity
 | ||||
| 	auto *lineEntity = new Qt3DCore::QEntity(parent); | ||||
| 	lineEntity->addComponent(line); | ||||
| 	lineEntity->addComponent(material); | ||||
| } | ||||
							
								
								
									
										86
									
								
								backplotwidget.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								backplotwidget.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| #ifndef BACKPLOTWIDGET_H | ||||
| #define BACKPLOTWIDGET_H | ||||
| 
 | ||||
| #include <QWidget> | ||||
| 
 | ||||
| #include <Qt3DExtras/qtorusmesh.h> | ||||
| #include <Qt3DRender/qmesh.h> | ||||
| #include <Qt3DRender/qtechnique.h> | ||||
| #include <Qt3DRender/qmaterial.h> | ||||
| #include <Qt3DRender/qeffect.h> | ||||
| #include <Qt3DRender/qtexture.h> | ||||
| #include <Qt3DRender/qrenderpass.h> | ||||
| #include <Qt3DRender/qsceneloader.h> | ||||
| 
 | ||||
| #include <Qt3DCore/qtransform.h> | ||||
| #include <Qt3DCore/qaspectengine.h> | ||||
| 
 | ||||
| #include <Qt3DRender/qrenderaspect.h> | ||||
| #include <Qt3DExtras/qforwardrenderer.h> | ||||
| 
 | ||||
| #include <Qt3DExtras/qt3dwindow.h> | ||||
| #include <QHBoxLayout> | ||||
| #include <QPhongMaterial> | ||||
| 
 | ||||
| #include "orbitcameracontroller.h" | ||||
| 
 | ||||
| class BackPlotWidget : public QWidget | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 
 | ||||
| 	Qt3DExtras::Qt3DWindow view; | ||||
| 	OrbitCameraController *camController; | ||||
| 	Qt3DCore::QEntity* rootEntity = nullptr; | ||||
| 	Qt3DExtras::QPhongMaterial* axisMaterial; | ||||
| 	Qt3DExtras::QPhongMaterial* rapidMaterial; | ||||
| 	Qt3DExtras::QPhongMaterial* pathMaterial; | ||||
| 	QWidget *containerWdiget; | ||||
| 
 | ||||
| 	Qt3DCore::QEntity* toolEntity; | ||||
| 	Qt3DCore::QTransform *toolTransform; | ||||
| 	std::vector<Qt3DCore::QEntity*> pathEntitys; | ||||
| 
 | ||||
| 	Qt3DCore::QTransform *touchoffTransform; | ||||
| 
 | ||||
| 	QVector3D limits; | ||||
| 	QVector3D touchoffPosition; | ||||
| 
 | ||||
| 	QHBoxLayout hLayout; | ||||
| 
 | ||||
| 	static constexpr int NO_FIELD = std::numeric_limits<int>::min(); | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
| 	typedef int ViewPos; | ||||
| 	static constexpr ViewPos VIEW_TOP = 0; | ||||
| 	static constexpr ViewPos VIEW_FRONT = 1; | ||||
| 	static constexpr ViewPos VIEW_LEFT = 2; | ||||
| 	static constexpr ViewPos VIEW_RIGHT = 3; | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
| 	static void drawBox(const QVector3D& bottomCloseLeft, const QVector3D& topFarRight, Qt3DRender::QMaterial* material, Qt3DCore::QEntity* parent); | ||||
| 	static void drawLine(const QVector3D& start, const QVector3D& end, Qt3DRender::QMaterial* material, Qt3DCore::QEntity* parent); | ||||
| 	static QList<int> getFields(QByteArray command); | ||||
| 	QByteArray removeComments(const QByteArray& program); | ||||
| 
 | ||||
| 	void reset(); | ||||
| 
 | ||||
| protected: | ||||
| 	virtual void resizeEvent(QResizeEvent *event) override; | ||||
| 
 | ||||
| public slots: | ||||
| 	void positionUpdate(std::vector<int> position); | ||||
| 	void touchoffUpdate(std::vector<int> position); | ||||
| 	void programChanged(const QByteArray program); | ||||
| 	void showView(ViewPos view); | ||||
| 
 | ||||
| public: | ||||
| 	explicit BackPlotWidget(QWidget *parent = nullptr, double xLimits = 190, double yLimits = 92, double zLimits = 85); | ||||
| 
 | ||||
| signals: | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif // BACKPLOTWIDGET_H
 | ||||
| 
 | ||||
							
								
								
									
										544
									
								
								gcodetovhf.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										544
									
								
								gcodetovhf.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,544 @@ | |||
| #include "gcodetovhf.h" | ||||
| 
 | ||||
| #include <QList> | ||||
| #include <cassert> | ||||
| #include <cmath> | ||||
| #include <QVector2D> | ||||
| #include <QVector3D> | ||||
| #include <QDebug> | ||||
| 
 | ||||
| static constexpr double TOLLERANCE = 0.005; | ||||
| 
 | ||||
| QByteArray removeComments(const QByteArray& gcodeCommand) | ||||
| { | ||||
| 	size_t comment = 0; | ||||
| 	QByteArray output; | ||||
| 	for(size_t i = 0; i < gcodeCommand.size(); ++i) | ||||
| 	{ | ||||
| 		if(gcodeCommand[i] == '(') | ||||
| 			++comment; | ||||
| 		else if(gcodeCommand[i] == ')' && comment > 0) | ||||
| 			--comment; | ||||
| 
 | ||||
| 		if(comment == 0) | ||||
| 			output.push_back(gcodeCommand[i]); | ||||
| 	} | ||||
| 	return output; | ||||
| } | ||||
| 
 | ||||
| class Gmove | ||||
| { | ||||
| public: | ||||
| 	int gmode = 0; | ||||
| 	int coordmode = 54; | ||||
| 	bool relative = false; | ||||
| 	double xStart = 0; | ||||
| 	double yStart = 0; | ||||
| 	double zStart = 0; | ||||
| 	double aStart = 0; | ||||
| 
 | ||||
| 	bool x = false; | ||||
| 	bool y = false; | ||||
| 	bool z = false; | ||||
| 	bool a = false; | ||||
| 	bool i = false; | ||||
| 	bool j = false; | ||||
| 	bool p = false; | ||||
| 	bool r = false; | ||||
| 	bool l = false; | ||||
| 
 | ||||
| 	double xVal; | ||||
| 	double yVal; | ||||
| 	double zVal; | ||||
| 	double aVal; | ||||
| 	double iVal; | ||||
| 	double jVal; | ||||
| 	double pVal; | ||||
| 	double rVal; | ||||
| 	double lVal; | ||||
| 
 | ||||
| 	void fill() | ||||
| 	{ | ||||
| 		if(!x) | ||||
| 			xVal = relative ? 0 : xStart; | ||||
| 		if(!y) | ||||
| 			yVal = relative ? 0 : yStart; | ||||
| 		if(!z) | ||||
| 			zVal = relative ? 0 : zStart; | ||||
| 		if(!a) | ||||
| 			aVal = relative ? 0 : aStart; | ||||
| 
 | ||||
| 		x = true; | ||||
| 		y = true; | ||||
| 		z = true; | ||||
| 	} | ||||
| 	void makeAbsolute() | ||||
| 	{ | ||||
| 		if(!relative) | ||||
| 			return; | ||||
| 		if(x) | ||||
| 			xVal = xVal+xStart; | ||||
| 		if(y) | ||||
| 			yVal = yVal+yStart; | ||||
| 		if(z) | ||||
| 			zVal = zVal+zStart; | ||||
| 		if(a) | ||||
| 			aVal = aVal+aStart; | ||||
| 		relative = false; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static QString checkMove(Gmove gmove) | ||||
| { | ||||
| 	if(gmove.gmode == 0 || gmove.gmode == 1) | ||||
| 	{ | ||||
| 		if(!gmove.x && !gmove.y && !gmove.z) | ||||
| 			return "At least one coordinate is required for linear move."; | ||||
| 		else if(gmove.i || gmove.j || gmove.p || gmove.r) | ||||
| 			return "Invalid parameter in linear move."; | ||||
| 	} | ||||
| 	else if(gmove.gmode == 2 || gmove.gmode == 3) | ||||
| 	{ | ||||
| 		if(!gmove.x && !gmove.y && !gmove.z) | ||||
| 			return "At least one coordinate is required for arc move."; | ||||
| 		else if(!gmove.i && !gmove.j && !gmove.r) | ||||
| 			return "No arc center or radius defined."; | ||||
| 		else if((gmove.i || gmove.j) && gmove.r) | ||||
| 			return "More than one arc center defined."; | ||||
| 
 | ||||
| 		gmove.fill(); | ||||
| 		gmove.makeAbsolute(); | ||||
| 		QVector2D xyVect(gmove.xVal, gmove.yVal); | ||||
| 		QVector2D startVect(gmove.xStart, gmove.yStart); | ||||
| 
 | ||||
| 		if(gmove.r) | ||||
| 		{ | ||||
| 			if(gmove.rVal < TOLLERANCE) | ||||
| 				return "Arc radius must be larger than zero."; | ||||
| 			if((xyVect-startVect).length()/2 > gmove.rVal+TOLLERANCE) | ||||
| 				return "Arc radius to small to fit to provided sart and end points."; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/*QVector2D ijVect(gmove.i ? gmove.iVal : 0, gmove.j ? gmove.jVal : 0);
 | ||||
| 			QVector2D center = startVect+ijVect; | ||||
| 			double r = (center-xyVect).length(); | ||||
| 			double r2 = (center-startVect).length(); | ||||
| 
 | ||||
| 			if(abs(r-r2) > TOLLERANCE) | ||||
| 				return "Arc start and end point radii differ";*/ | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return QString(); | ||||
| } | ||||
| 
 | ||||
| static QByteArray generateLinearCommand(const Gmove& gmove) | ||||
| { | ||||
| 	assert(gmove.gmode == 0 || gmove.gmode == 1); | ||||
| 
 | ||||
| 	QByteArray output; | ||||
| 	if(gmove.gmode == 0) | ||||
| 	{ | ||||
| 		if(gmove.relative) | ||||
| 			output.append("GR"); | ||||
| 		else if(gmove.coordmode != 53) | ||||
| 			output.append("GA"); | ||||
| 		else | ||||
| 			output.append("GB"); | ||||
| 	} | ||||
| 	else if(gmove.gmode == 1) | ||||
| 	{ | ||||
| 		if(gmove.relative) | ||||
| 			output.append("PR"); | ||||
| 		else if(gmove.coordmode != 53) | ||||
| 			output.append("PA"); | ||||
| 		else | ||||
| 			output.append("PB"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return output; | ||||
| 	} | ||||
| 
 | ||||
| 	if(gmove.x) | ||||
| 		output.append(QByteArray::number(static_cast<int>(gmove.xVal*1000))); | ||||
| 	if(gmove.y || gmove.z || gmove.a) | ||||
| 		output.append(','); | ||||
| 	if(gmove.y) | ||||
| 		output.append(QByteArray::number(static_cast<int>(gmove.yVal*1000))); | ||||
| 	if(gmove.z || gmove.a) | ||||
| 		output.append(','); | ||||
| 	if(gmove.z) | ||||
| 		output.append(QByteArray::number(static_cast<int>(gmove.zVal*-1000))); | ||||
| 	if(gmove.a) | ||||
| 	{ | ||||
| 		output.append(','); | ||||
| 		output.append(QByteArray::number(static_cast<int>(gmove.aVal*1000))); | ||||
| 	} | ||||
| 
 | ||||
| 	output.append(';'); | ||||
| 
 | ||||
| 	return output; | ||||
| } | ||||
| 
 | ||||
| static bool findCircleCenter(QVector2D a, QVector2D b, double r, bool leftHanded, QVector2D& result) | ||||
| {	float distance = (a-b).length(); | ||||
| 	if(distance/2 > r+TOLLERANCE) | ||||
| 		return false; | ||||
| 
 | ||||
| 	QVector2D baseVect = (b-a).normalized(); | ||||
| 	float loftDist = sqrt(pow(r, 2)-pow(distance/2, 2)); | ||||
| 	QVector2D loftVect; | ||||
| 	if(leftHanded) | ||||
| 	{ | ||||
| 		loftVect.setX(baseVect.y()*-1); | ||||
| 		loftVect.setY(baseVect.x()); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		loftVect.setX(baseVect.y()); | ||||
| 		loftVect.setY(baseVect.x()*-1); | ||||
| 	} | ||||
| 	loftVect = loftVect*loftDist; | ||||
| 	baseVect = baseVect*(distance/2); | ||||
| 	result = a+baseVect+loftVect; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static bool withinTollerance(double a, double b) | ||||
| { | ||||
| 	return a+TOLLERANCE > b && a-TOLLERANCE < b; | ||||
| } | ||||
| 
 | ||||
| static QByteArray generateArcCommand(Gmove gmove, size_t resolution) | ||||
| { | ||||
| 	assert(gmove.gmode == 2 || gmove.gmode == 3); | ||||
| 	gmove.fill(); | ||||
| 	gmove.makeAbsolute(); | ||||
| 
 | ||||
| 	QVector2D startMove(gmove.xStart, gmove.yStart); | ||||
| 	QVector2D endMove(gmove.xVal, gmove.yVal); | ||||
| 	QVector2D center; | ||||
| 	double radius; | ||||
| 	if(gmove.i && gmove.j) | ||||
| 	{ | ||||
| 		center.setX(gmove.xStart+gmove.iVal); | ||||
| 		center.setY(gmove.yStart+gmove.jVal); | ||||
| 		radius = (QVector2D(gmove.xStart, gmove.yStart)-center).length(); | ||||
| 	} | ||||
| 	else if(gmove.r) | ||||
| 	{ | ||||
| 		findCircleCenter(QVector2D(gmove.xStart, gmove.yStart), QVector2D(gmove.xVal, gmove.yVal), gmove.rVal, gmove.gmode == 3, center); | ||||
| 		radius = gmove.rVal; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		qCritical()<<"Can't create arc move"; | ||||
| 		return QByteArray(); | ||||
| 	} | ||||
| 
 | ||||
| 	QVector2D aVector = startMove-center; | ||||
| 	QVector2D bVector = endMove-center; | ||||
| 	double startAngle = acos(aVector.x()/(aVector.length())); | ||||
| 	double endAngle = acos(bVector.x()/(bVector.length())); | ||||
| 
 | ||||
| 	{ | ||||
| 		bool a = false; | ||||
| 		bool b = false; | ||||
| 		QVector2D computedEnpoint(cos(endAngle)*radius+center.x(), sin(endAngle)*radius+center.y()); | ||||
| 		if((computedEnpoint-endMove).length() > TOLLERANCE) | ||||
| 			endAngle = 0 - endAngle; | ||||
| 
 | ||||
| 		QVector2D computedSart(cos(startAngle)*radius+center.x(), sin(startAngle)*radius+center.y()); | ||||
| 		if((computedSart-startMove).length() > TOLLERANCE) | ||||
| 			startAngle = 0 - startAngle; | ||||
| 
 | ||||
| 		if((startAngle-endAngle) < 0) | ||||
| 			startAngle = startAngle+2*M_PI; | ||||
| 	} | ||||
| 	{ | ||||
| 		/*QVector2D computedEnpoint(cos(endAngle)*radius+center.x(), sin(endAngle)*radius+center.y());
 | ||||
| 		assert((computedEnpoint-endMove).length() > TOLLERANCE); | ||||
| 
 | ||||
| 		QVector2D computedSart(cos(startAngle)*radius+center.x(), sin(startAngle)*radius+center.y()); | ||||
| 		assert((computedSart-startMove).length() > TOLLERANCE);*/ | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	if(gmove.p && gmove.pVal > 1) | ||||
| 		endAngle = endAngle+std::copysign(1.0, endAngle-startAngle)*2*(gmove.pVal-1)*M_PI; | ||||
| 
 | ||||
| 	size_t steps = (resolution*(fabs(endAngle-startAngle)))/(2*M_PI); | ||||
| 
 | ||||
| 	double angleStep; | ||||
| 	if(gmove.gmode == 2) | ||||
| 		angleStep = (endAngle-startAngle)/steps; | ||||
| 	else | ||||
| 		angleStep = (2*M_PI-(startAngle-endAngle))/steps; | ||||
| 
 | ||||
| 	QByteArray output; | ||||
| 	double deltaZ = (gmove.zVal - gmove.zStart)/steps; | ||||
| 	for(size_t i = 1; i < steps; ++i) | ||||
| 	{ | ||||
| 		double workAngle = startAngle+angleStep*i; | ||||
| 		QVector2D point; | ||||
| 		point.setX(cos(workAngle)*radius); | ||||
| 		point.setY(sin(workAngle)*radius); | ||||
| 		point = point+center; | ||||
| 		QByteArray command("PA"); | ||||
| 		command.append(QByteArray::number(static_cast<int>(point.x()*1000)) + "," + | ||||
| 					   QByteArray::number(static_cast<int>(point.y()*1000)) + "," + | ||||
| 					   QByteArray::number(static_cast<int>((gmove.zStart+deltaZ*i)*-1000)) + ";"); | ||||
| 		output.append(command); | ||||
| 	} | ||||
| 
 | ||||
| 	QByteArray command("PA"); | ||||
| 	command.append(QByteArray::number(static_cast<int>(gmove.xVal*1000)) +"," + | ||||
| 				   QByteArray::number(static_cast<int>(gmove.yVal*1000)) + "," + | ||||
| 				   QByteArray::number(static_cast<int>(gmove.zVal*-1000)) + ";"); | ||||
| 	output.append(command); | ||||
| 
 | ||||
| 	return output; | ||||
| } | ||||
| 
 | ||||
| static QByteArray generateDrillingCycle(Gmove gmove) | ||||
| { | ||||
| 	if(!gmove.r) | ||||
| 		return QByteArray(); | ||||
| 	if(!gmove.z) | ||||
| 		return QByteArray(); | ||||
| 	gmove.gmode = 0; | ||||
| 	if(gmove.relative) | ||||
| 		gmove.rVal = gmove.rVal+gmove.zVal; | ||||
| 	gmove.makeAbsolute(); | ||||
| 
 | ||||
| 	QByteArray output("GA,,"+QByteArray::number(static_cast<int>(gmove.rVal*-1000))+"; "); | ||||
| 	if(gmove.x || gmove.y) | ||||
| 	{ | ||||
| 		gmove.z = false; | ||||
| 		output.append(generateLinearCommand(gmove)); | ||||
| 	} | ||||
| 
 | ||||
| 	size_t count = gmove.l ? gmove.lVal : 1; | ||||
| 
 | ||||
| 	for(size_t i = 0; i < count; ++i) | ||||
| 	{ | ||||
| 		output.append("PA,,"+QByteArray::number(static_cast<int>(gmove.zVal*-1000))+"; "); | ||||
| 		output.append("GA,,"+QByteArray::number(static_cast<int>(gmove.rVal*-1000))+"; "); | ||||
| 	} | ||||
| 	return output; | ||||
| } | ||||
| 
 | ||||
| static QByteArray generateMoveCommand(const Gmove& gmove) | ||||
| { | ||||
| 	if(gmove.gmode == 0 || gmove.gmode == 1) | ||||
| 		return generateLinearCommand(gmove); | ||||
| 	else if(gmove.gmode == 2 || gmove.gmode == 3) | ||||
| 		return generateArcCommand(gmove, 100); | ||||
| 	else if(gmove.gmode == 81) | ||||
| 		return generateDrillingCycle(gmove); | ||||
| 	return QByteArray(); | ||||
| } | ||||
| 
 | ||||
| static Gmove doMove(Gmove gmove) | ||||
| { | ||||
| 	gmove.fill(); | ||||
| 	gmove.makeAbsolute(); | ||||
| 
 | ||||
| 	Gmove out; | ||||
| 	out.xStart = gmove.xVal; | ||||
| 	out.yStart = gmove.yVal; | ||||
| 	out.zStart = gmove.zVal; | ||||
| 	out.aStart = gmove.aVal; | ||||
| 
 | ||||
| 	return out; | ||||
| } | ||||
| 
 | ||||
| QByteArray gcodeToVhf(const QByteArray& gcode, bool* ok, QList<QString>* errors) | ||||
| { | ||||
| 	int gmode = -1; | ||||
| 	int coordmode = 54; | ||||
| 	bool relmode = false; | ||||
| 	double spinspeed = 1000; | ||||
| 	double feedrate = std::numeric_limits<double>::min(); | ||||
| 	int tool = 0; | ||||
| 	Gmove move; | ||||
| 	bool clearMove; | ||||
| 
 | ||||
| 	QByteArray output; | ||||
| 
 | ||||
| 	if(gcode.size()< 2) | ||||
| 		return output; | ||||
| 
 | ||||
| 	QList<QByteArray> gcodeCommands = gcode.toUpper().split('\n'); | ||||
| 
 | ||||
| 	if(ok) | ||||
| 		*ok = true; | ||||
| 
 | ||||
| 	size_t line = 0; | ||||
| 	for(QByteArray& command : gcodeCommands) | ||||
| 	{ | ||||
| 		++line; | ||||
| 		move.gmode = gmode; | ||||
| 		move.coordmode = coordmode; | ||||
| 		move.relative = relmode; | ||||
| 		bool startSpindle = false; | ||||
| 		bool toolchange = false; | ||||
| 		command = removeComments(command); | ||||
| 
 | ||||
| 		QList<QByteArray> subcommands = command.split(' '); | ||||
| 		for(QByteArray& subcommand : subcommands) | ||||
| 		{ | ||||
| 			subcommand = subcommand.trimmed(); | ||||
| 			if(subcommand.size() < 1) | ||||
| 				continue; | ||||
| 			if(subcommand[0] == 'G') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				int gcodeCode = subcommand.toInt(); | ||||
| 				if(gcodeCode >= 0 && gcodeCode <= 3 || gcodeCode == 81) | ||||
| 					gmode = gcodeCode; | ||||
| 				else if(gcodeCode == 80 && gmode == 81) | ||||
| 					gmode = 0; | ||||
| 				else if(gcodeCode == 91) | ||||
| 					relmode = true; | ||||
| 				else if(gcodeCode == 90) | ||||
| 					relmode = false; | ||||
| 				else if(gcodeCode == 53) | ||||
| 					move.coordmode = 53; | ||||
| 				else if(gcodeCode > 54 && gcodeCode < 59) | ||||
| 					move.coordmode = gcodeCode; | ||||
| 				else if(gcodeCode == 28) | ||||
| 					output.append("PB0,0,0,0; "); | ||||
| 				else if(gcodeCode == 64) | ||||
| 					clearMove = true; | ||||
| 
 | ||||
| 				move.gmode = gmode; | ||||
| 				if(move.coordmode != 53) | ||||
| 					move.coordmode = coordmode; | ||||
| 				move.relative = relmode; | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'M') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				int mCode = subcommand.toDouble(); | ||||
| 				switch(mCode) | ||||
| 				{ | ||||
| 					case 0: | ||||
| 					case 1: | ||||
| 						output.append("!S; "); | ||||
| 						break; | ||||
| 					case 3: | ||||
| 						startSpindle = true; | ||||
| 						break; | ||||
| 					case 2: | ||||
| 					case 5: | ||||
| 						output.append("RVS0; "); | ||||
| 						startSpindle = false; | ||||
| 						break; | ||||
| 					case 6: | ||||
| 						toolchange = true; | ||||
| 					default: | ||||
| 						break; | ||||
| 				} | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'F') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				double newFeedrate = subcommand.toDouble(); | ||||
| 				if(abs(newFeedrate - feedrate) > TOLLERANCE) | ||||
| 				{ | ||||
| 					feedrate = newFeedrate; | ||||
| 					output.append("VS" + QByteArray::number(static_cast<int>(feedrate*(1000.0/60.0))) + "; "); | ||||
| 				} | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'T') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				tool = subcommand.toInt(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'S') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				spinspeed = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'X') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.x = true; | ||||
| 				move.xVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'Y') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.y = true; | ||||
| 				move.yVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'Z') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.z = true; | ||||
| 				move.zVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'P') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.p = true; | ||||
| 				move.pVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'A') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.a = true; | ||||
| 				move.aVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'I') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.i = true; | ||||
| 				move.iVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'J') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.j = true; | ||||
| 				move.jVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 			else if(subcommand[0] == 'R') | ||||
| 			{ | ||||
| 				subcommand.remove(0, 1); | ||||
| 				move.r = true; | ||||
| 				move.rVal = subcommand.toDouble(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if(toolchange) | ||||
| 			output.append("T" + QByteArray::number(static_cast<int>(tool)) + "; "); | ||||
| 		if(startSpindle) | ||||
| 			output.append("RVS" + QByteArray::number(static_cast<int>(spinspeed)) + "; "); | ||||
| 		if(move.x || move.y || move.z || move.a) | ||||
| 		{ | ||||
| 			QString error = checkMove(move); | ||||
| 			if(error.isEmpty()) | ||||
| 			{ | ||||
| 				output.append(generateMoveCommand(move)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				*ok = false; | ||||
| 				if(errors) | ||||
| 					errors->push_back("Error on line " + QString::number(line) + ": " + error); | ||||
| 				qWarning()<<"Error on line"<<line<<error; | ||||
| 			} | ||||
| 			move = doMove(move); | ||||
| 		} | ||||
| 		else if(clearMove) | ||||
| 			move = doMove(move); | ||||
| 		if(output.size() > 0 && output.back() != '\n') | ||||
| 			output.push_back('\n'); | ||||
| 	} | ||||
| 
 | ||||
| 	return output; | ||||
| } | ||||
							
								
								
									
										7
									
								
								gcodetovhf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								gcodetovhf.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #ifndef GCODETOVHF_H | ||||
| #define GCODETOVHF_H | ||||
| #include <QByteArray> | ||||
| 
 | ||||
| QByteArray gcodeToVhf(const QByteArray& gcode, bool* ok, QList<QString>* errors = nullptr); | ||||
| 
 | ||||
| #endif // GCODETOVHF_H
 | ||||
							
								
								
									
										55
									
								
								led.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								led.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,55 @@ | |||
| /*UVOS*/ | ||||
| 
 | ||||
| /* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
 | ||||
|  * | ||||
|  * MAClient is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License (GPL) version  | ||||
|  * 3 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * MAClient 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 MAClient.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| #include "led.h" | ||||
| #include <QPainter> | ||||
| #include <algorithm> | ||||
| 
 | ||||
| Led::Led(QWidget* parent): QWidget(parent) | ||||
| { | ||||
| 	setMinimumSize(QSize(40,40)); | ||||
| 	setSizePolicy(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed); | ||||
| } | ||||
| 
 | ||||
| bool Led::lit() const | ||||
| { | ||||
| 	return lit_; | ||||
| } | ||||
| 
 | ||||
| void Led::setLit(bool lit) | ||||
| { | ||||
| 	if(lit != lit_) | ||||
| 	{ | ||||
| 		lit_ = lit; | ||||
| 		stateChanged(lit_); | ||||
| 		update(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void Led::paintEvent(QPaintEvent* event) | ||||
| { | ||||
| 	Q_UNUSED(event) | ||||
| 	QPainter ledPainter(this); | ||||
| 	ledPainter.setRenderHint(QPainter::Antialiasing, true); | ||||
| 	ledPainter.setPen(Qt::black); | ||||
| 	if(lit_) | ||||
| 		ledPainter.setBrush(Qt::green); | ||||
| 	else | ||||
| 		ledPainter.setBrush(Qt::red); | ||||
| 	int size = std::min(rect().width(), rect().height()); | ||||
| 	QRect ellipseRect(rect().x()+(rect().width()-size)/2+1, rect().y()+(rect().height()-size)/2+1, size-2, size-2); | ||||
| 	ledPainter.drawEllipse(ellipseRect); | ||||
| } | ||||
							
								
								
									
										45
									
								
								led.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								led.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| /*UVOS*/ | ||||
| 
 | ||||
| /* This file is part of MAClient copyright © 2021 Carl Philipp Klemm.
 | ||||
|  * | ||||
|  * MAClient is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License (GPL) version  | ||||
|  * 3 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * MAClient 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 MAClient.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| */ | ||||
| #ifndef LED_H | ||||
| #define LED_H | ||||
| 
 | ||||
| #include <QWidget> | ||||
| 
 | ||||
| class Led : public QWidget | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 
 | ||||
| 	bool lit_ = false; | ||||
| 
 | ||||
| 	public: | ||||
| 
 | ||||
| 	Led(QWidget* parent = nullptr); | ||||
| 	bool lit() const; | ||||
| 
 | ||||
| 	public slots: | ||||
| 
 | ||||
| 	void setLit(bool lit); | ||||
| 
 | ||||
| 	signals: | ||||
| 
 | ||||
| 	void stateChanged(bool lit); | ||||
| 	protected: | ||||
| 	virtual void paintEvent(QPaintEvent* event) override; | ||||
| 
 | ||||
| 
 | ||||
| }; | ||||
| #endif // LED_H
 | ||||
							
								
								
									
										64
									
								
								main.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								main.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| #include "mainwindow.h" | ||||
| 
 | ||||
| #include <QApplication> | ||||
| #include <QSerialPort> | ||||
| #include <QTcpSocket> | ||||
| #include <QMessageBox> | ||||
| #include <QCommandLineParser> | ||||
| #include <QThread> | ||||
| 
 | ||||
| #include "vhfmill.h" | ||||
| #include "vhfmillthread.h" | ||||
| #include "mainobject.h" | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
| 	QApplication a(argc, argv); | ||||
| 
 | ||||
| 	QCoreApplication::setOrganizationName("UVOS"); | ||||
| 	QCoreApplication::setOrganizationDomain("uvos.xyz"); | ||||
| 	QCoreApplication::setApplicationName("VHFMill"); | ||||
| 	QCoreApplication::setApplicationVersion("0.1"); | ||||
| 
 | ||||
| 	QCommandLineParser parser; | ||||
| 	parser.setApplicationDescription("VHF mill cnc interface"); | ||||
| 	parser.addHelpOption(); | ||||
| 	parser.addVersionOption(); | ||||
| 	QCommandLineOption tcpOption(QStringList() << "t" << "tcp", QCoreApplication::translate("main", "Use Tcp connection")); | ||||
| 	parser.addOption(tcpOption); | ||||
| 	QCommandLineOption hostOption(QStringList() << "H" << "host", QCoreApplication::translate("main", | ||||
| 								  "Set server host ip addres"), "adress"); | ||||
| 	parser.addOption(hostOption); | ||||
| 	QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", | ||||
| 								  "Set server Port in TCP mode or Serial port in serial mode"), "port"); | ||||
| 	parser.addOption(portOption); | ||||
| 	QCommandLineOption serialOption(QStringList() << "s" << "serial", QCoreApplication::translate("main", | ||||
| 									"Use serial connection")); | ||||
| 	parser.addOption(serialOption); | ||||
| 	QCommandLineOption settingsPathOption(QStringList() << "c" << "config", QCoreApplication::translate("main", | ||||
| 										  "Set config file"), "configFilePath"); | ||||
| 	parser.addOption(settingsPathOption); | ||||
| 	QCommandLineOption secondaryOption(QStringList() << "e" << "secondary", QCoreApplication::translate("main", | ||||
| 									   "Set if instance is not main instance")); | ||||
| 	parser.addOption(secondaryOption); | ||||
| 	parser.process(a); | ||||
| 
 | ||||
| 	int port = 6856; | ||||
| 	QString serialPort("ttyUSB0"); | ||||
| 	QString host("127.0.0.1"); | ||||
| 	if(parser.isSet(hostOption)) | ||||
| 		host = parser.value(hostOption); | ||||
| 	if(parser.isSet(tcpOption) && parser.isSet(portOption)) | ||||
| 		port =  parser.value(portOption).toInt(); | ||||
| 	else if(parser.isSet(portOption)) | ||||
| 		serialPort = parser.value(portOption); | ||||
| 
 | ||||
| 	VhfMillThread vhfMillTread(parser.isSet(tcpOption), port, host, serialPort); | ||||
| 	MainObject mainObject(&a, &vhfMillTread); | ||||
| 	vhfMillTread.start(); | ||||
| 
 | ||||
| 	int ret = a.exec(); | ||||
| 
 | ||||
| 	vhfMillTread.exit(); | ||||
| 	return ret; | ||||
| } | ||||
							
								
								
									
										33
									
								
								mainobject.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								mainobject.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | |||
| #include "mainobject.h" | ||||
| #include <QMessageBox> | ||||
| 
 | ||||
| MainObject::MainObject(QApplication* appI, VhfMillThread* millThreadI, QObject *parent): | ||||
| 	app(appI), | ||||
| 	millThread(millThreadI), | ||||
| 	QObject{parent} | ||||
| { | ||||
| 	connect(millThread, &VhfMillThread::ready, this, &MainObject::activate); | ||||
| } | ||||
| 
 | ||||
| void MainObject::activate() | ||||
| { | ||||
| 	if(millThread->ret != 0) | ||||
| 	{ | ||||
| 		if(millThread->ret == -2) | ||||
| 			QMessageBox::critical(nullptr, "Error", "Can not connect to to Server"); | ||||
| 		if(millThread->ret == -3) | ||||
| 			QMessageBox::critical(nullptr, "Error", "Can not open serial port read write"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		w = new MainWindow(millThread->mill); | ||||
| 		app->installEventFilter(w); | ||||
| 		w->show(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| MainObject::~MainObject() | ||||
| { | ||||
| 	if(w) | ||||
| 		delete w; | ||||
| } | ||||
							
								
								
									
										26
									
								
								mainobject.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								mainobject.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| #ifndef MAINOBJECT_H | ||||
| #define MAINOBJECT_H | ||||
| 
 | ||||
| #include <QObject> | ||||
| #include <QApplication> | ||||
| 
 | ||||
| #include "mainwindow.h" | ||||
| #include "vhfmillthread.h" | ||||
| 
 | ||||
| class MainObject : public QObject | ||||
| { | ||||
| 	Q_OBJECT | ||||
| private: | ||||
| 	MainWindow* w; | ||||
| 	QApplication* app; | ||||
| 	VhfMillThread* millThread; | ||||
| 
 | ||||
| public: | ||||
| 	explicit MainObject(QApplication* appI, VhfMillThread* millThreadI, QObject *parent = nullptr); | ||||
| 	~MainObject(); | ||||
| 
 | ||||
| public slots: | ||||
| 	void activate(); | ||||
| }; | ||||
| 
 | ||||
| #endif // MAINOBJECT_H
 | ||||
							
								
								
									
										552
									
								
								mainwindow.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										552
									
								
								mainwindow.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,552 @@ | |||
| #include "mainwindow.h" | ||||
| #include "./ui_mainwindow.h" | ||||
| 
 | ||||
| #include <QMessageBox> | ||||
| #include <QInputDialog> | ||||
| #include <QFileDialog> | ||||
| 
 | ||||
| #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<int>::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<QKeyEvent *>(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<QKeyEvent *>(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<QString> 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__<<axis; | ||||
| 	QMetaObject::invokeMethod(mill_, [this, axis](){mill_->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<int> position) | ||||
| { | ||||
| 	if(position.size() < 4) | ||||
| 		return; | ||||
| 
 | ||||
| 	std::vector<int> 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<int> position) | ||||
| { | ||||
| 	if(position.size() < 4) | ||||
| 		return; | ||||
| 	ui->lcd_touchX->display(static_cast<double>(position[VhfMill::axisToIndex(VhfMill::AXIS_X)])/1000.0); | ||||
| 	ui->lcd_touchY->display(static_cast<double>(position[VhfMill::axisToIndex(VhfMill::AXIS_Y)])/1000.0); | ||||
| 	ui->lcd_touchZ->display(static_cast<double>(position[VhfMill::axisToIndex(VhfMill::AXIS_Z)])/1000.0); | ||||
| 	ui->lcd_touchA->display(static_cast<double>(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); | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										70
									
								
								mainwindow.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								mainwindow.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| #ifndef MAINWINDOW_H | ||||
| #define MAINWINDOW_H | ||||
| 
 | ||||
| #include <QMainWindow> | ||||
| #include <QComboBox> | ||||
| #include <QShortcut> | ||||
| #include "vhfmill.h" | ||||
| 
 | ||||
| QT_BEGIN_NAMESPACE | ||||
| namespace Ui { class MainWindow; } | ||||
| QT_END_NAMESPACE | ||||
| 
 | ||||
| class MainWindow : public QMainWindow | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 	VhfMill* mill_; | ||||
| 
 | ||||
| 	QShortcut viewTopAction; | ||||
| 	QShortcut viewFrontAction; | ||||
| 	QShortcut viewLeftAction; | ||||
| 	QShortcut viewRightAction; | ||||
| 	bool jogEnabled = false; | ||||
| 
 | ||||
| private slots: | ||||
| 	void raiseError(int errorNum); | ||||
| 	void positionUpdate(std::vector<int> position); | ||||
| 	void isHomed(VhfMill::Axis axis); | ||||
| 	void gotOutputs(uint8_t outputs); | ||||
| 	void gotPressureState(bool state); | ||||
| 	void checkBlocks(); | ||||
| 	void toolChangeDone(); | ||||
| 	void gotSpindleSpeed(int speed); | ||||
| 	void touchoffChanged(std::vector<int> position); | ||||
| 	void textChanged(); | ||||
| 	void selectedJogStepChanged(int index); | ||||
| 	void jog(VhfMill::Axis axis, int jogDirection); | ||||
| 
 | ||||
| 	void home(); | ||||
| 	void stopSpindle(); | ||||
| 	void run(); | ||||
| 	void toolSwitch(); | ||||
| 	void touchoff(); | ||||
| 	void touchoffAll(); | ||||
| 	void touchoffRst(); | ||||
| 	void toolUnload(); | ||||
| 	void openGcode(); | ||||
| 	void openVhfCode(); | ||||
| 
 | ||||
| private: | ||||
| 	void setAllBlocked(bool block); | ||||
| 	void setOutputsBlocked(bool block); | ||||
| 	void setJogBlocked(bool block); | ||||
| 	void setToolchangeBlocked(bool block); | ||||
| 	void setSpindleBlocked(bool block); | ||||
| 	void setHomeingBlocked(bool block); | ||||
| 	void setTouchoffBlocked(bool block); | ||||
| 
 | ||||
| 	static VhfMill::Axis comboBoxToAxis(const QComboBox& box); | ||||
| 
 | ||||
| protected: | ||||
| 	virtual bool eventFilter(QObject *o, QEvent *e) override; | ||||
| 
 | ||||
| public: | ||||
| 	MainWindow(VhfMill* mill, QWidget *parent = nullptr); | ||||
| 	~MainWindow(); | ||||
| 
 | ||||
| private: | ||||
| 	Ui::MainWindow *ui = nullptr; | ||||
| }; | ||||
| #endif // MAINWINDOW_H
 | ||||
							
								
								
									
										862
									
								
								mainwindow.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										862
									
								
								mainwindow.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,862 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>MainWindow</class> | ||||
|  <widget class="QMainWindow" name="MainWindow"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>1048</width> | ||||
|     <height>687</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>VHF Mill</string> | ||||
|   </property> | ||||
|   <widget class="QWidget" name="centralwidget"> | ||||
|    <layout class="QVBoxLayout" name="verticalLayout_4"> | ||||
|     <item> | ||||
|      <widget class="QSplitter" name="splitter"> | ||||
|       <property name="orientation"> | ||||
|        <enum>Qt::Vertical</enum> | ||||
|       </property> | ||||
|       <property name="handleWidth"> | ||||
|        <number>5</number> | ||||
|       </property> | ||||
|       <widget class="QWidget" name="horizontalLayoutWidget_3"> | ||||
|        <layout class="QHBoxLayout" name="horizontalLayout_5"> | ||||
|         <property name="leftMargin"> | ||||
|          <number>0</number> | ||||
|         </property> | ||||
|         <property name="rightMargin"> | ||||
|          <number>0</number> | ||||
|         </property> | ||||
|         <item> | ||||
|          <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|           <property name="bottomMargin"> | ||||
|            <number>10</number> | ||||
|           </property> | ||||
|           <item> | ||||
|            <widget class="QGroupBox" name="groupBox"> | ||||
|             <property name="title"> | ||||
|              <string>Setup</string> | ||||
|             </property> | ||||
|             <layout class="QGridLayout" name="gridLayout_2"> | ||||
|              <item row="2" column="0"> | ||||
|               <widget class="QComboBox" name="comboBox_TouchoffAxis"> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>x</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>y</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>z</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>a</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="2" column="1"> | ||||
|               <widget class="QPushButton" name="pushButton_touchoff"> | ||||
|                <property name="text"> | ||||
|                 <string>Touchoff Axis</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="1" column="0"> | ||||
|               <widget class="QComboBox" name="comboBox_homeAxis"> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>x</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>y</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>z</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>a</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="0" column="0"> | ||||
|               <widget class="QPushButton" name="pushButton_init"> | ||||
|                <property name="text"> | ||||
|                 <string>init</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="0" column="1"> | ||||
|               <widget class="QPushButton" name="pushButton_homeAll"> | ||||
|                <property name="text"> | ||||
|                 <string>Home All</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="1" column="1"> | ||||
|               <widget class="QPushButton" name="pushButton_home"> | ||||
|                <property name="text"> | ||||
|                 <string>Home Axis</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="3" column="1"> | ||||
|               <widget class="QPushButton" name="pushButton_touchoffAll"> | ||||
|                <property name="text"> | ||||
|                 <string>Touchoff All</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="3" column="0"> | ||||
|               <widget class="QPushButton" name="pushButton_touchoffRst"> | ||||
|                <property name="text"> | ||||
|                 <string>Reset Touchoff</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|             </layout> | ||||
|            </widget> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QGroupBox" name="groupBox_2"> | ||||
|             <property name="title"> | ||||
|              <string>Jog</string> | ||||
|             </property> | ||||
|             <layout class="QGridLayout" name="gridLayout_3"> | ||||
|              <item row="3" column="2"> | ||||
|               <widget class="QPushButton" name="pushButton_jogDown"> | ||||
|                <property name="text"> | ||||
|                 <string>⤓</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="3" column="0"> | ||||
|               <widget class="QPushButton" name="pushButton_jogAn"> | ||||
|                <property name="text"> | ||||
|                 <string>⟲</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="3" column="1"> | ||||
|               <widget class="QPushButton" name="pushButton_jogYn"> | ||||
|                <property name="text"> | ||||
|                 <string>↓</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="1" column="0"> | ||||
|               <widget class="QPushButton" name="pushButton_jogAp"> | ||||
|                <property name="text"> | ||||
|                 <string>⟳</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="2" column="0"> | ||||
|               <widget class="QPushButton" name="pushButton_jogXn"> | ||||
|                <property name="text"> | ||||
|                 <string>←</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="1" column="2"> | ||||
|               <widget class="QPushButton" name="pushButton_jogUp"> | ||||
|                <property name="text"> | ||||
|                 <string>↥</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="2" column="2"> | ||||
|               <widget class="QPushButton" name="pushButton_jogXp"> | ||||
|                <property name="text"> | ||||
|                 <string>→</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="1" column="1"> | ||||
|               <widget class="QPushButton" name="pushButton_jogYp"> | ||||
|                <property name="text"> | ||||
|                 <string>↑</string> | ||||
|                </property> | ||||
|               </widget> | ||||
|              </item> | ||||
|              <item row="2" column="1"> | ||||
|               <widget class="QComboBox" name="comboBox_jogStep"> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>Continues</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>5 mm</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>1 mm</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>0.25 mm</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>0.1 mm</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|                <item> | ||||
|                 <property name="text"> | ||||
|                  <string>0.05 mm</string> | ||||
|                 </property> | ||||
|                </item> | ||||
|               </widget> | ||||
|              </item> | ||||
|             </layout> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0"> | ||||
|           <property name="bottomMargin"> | ||||
|            <number>10</number> | ||||
|           </property> | ||||
|           <item> | ||||
|            <widget class="QTabWidget" name="tabWidget"> | ||||
|             <property name="currentIndex"> | ||||
|              <number>1</number> | ||||
|             </property> | ||||
|             <widget class="QWidget" name="tabDro"> | ||||
|              <attribute name="title"> | ||||
|               <string>DRO</string> | ||||
|              </attribute> | ||||
|              <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||
|               <item> | ||||
|                <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,1,1" columnstretch="0,1,1,1,1"> | ||||
|                 <item row="4" column="1"> | ||||
|                  <widget class="QLCDNumber" name="lcd_touchX"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="1" column="3"> | ||||
|                  <widget class="QLabel" name="label_3"> | ||||
|                   <property name="text"> | ||||
|                    <string>Z</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="1"> | ||||
|                  <widget class="Led" name="led_homeX" native="true"> | ||||
|                   <property name="sizePolicy"> | ||||
|                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|                     <horstretch>0</horstretch> | ||||
|                     <verstretch>0</verstretch> | ||||
|                    </sizepolicy> | ||||
|                   </property> | ||||
|                   <property name="minimumSize"> | ||||
|                    <size> | ||||
|                     <width>30</width> | ||||
|                     <height>30</height> | ||||
|                    </size> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="3" column="0"> | ||||
|                  <widget class="QLabel" name="label_7"> | ||||
|                   <property name="text"> | ||||
|                    <string>Position</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="1" column="2"> | ||||
|                  <widget class="QLabel" name="label_2"> | ||||
|                   <property name="text"> | ||||
|                    <string>Y</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="3"> | ||||
|                  <widget class="Led" name="led_homeZ" native="true"> | ||||
|                   <property name="sizePolicy"> | ||||
|                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|                     <horstretch>0</horstretch> | ||||
|                     <verstretch>0</verstretch> | ||||
|                    </sizepolicy> | ||||
|                   </property> | ||||
|                   <property name="minimumSize"> | ||||
|                    <size> | ||||
|                     <width>50</width> | ||||
|                     <height>30</height> | ||||
|                    </size> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="4" column="0"> | ||||
|                  <widget class="QLabel" name="label_8"> | ||||
|                   <property name="text"> | ||||
|                    <string>Touchoff Position</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="4"> | ||||
|                  <widget class="Led" name="led_homeA" native="true"> | ||||
|                   <property name="sizePolicy"> | ||||
|                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|                     <horstretch>0</horstretch> | ||||
|                     <verstretch>0</verstretch> | ||||
|                    </sizepolicy> | ||||
|                   </property> | ||||
|                   <property name="minimumSize"> | ||||
|                    <size> | ||||
|                     <width>50</width> | ||||
|                     <height>30</height> | ||||
|                    </size> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="3" column="3"> | ||||
|                  <widget class="QLCDNumber" name="lcd_z"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="3" column="2"> | ||||
|                  <widget class="QLCDNumber" name="lcd_y"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="0"> | ||||
|                  <widget class="QLabel" name="label_9"> | ||||
|                   <property name="text"> | ||||
|                    <string>Homed</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="3" column="4"> | ||||
|                  <widget class="QLCDNumber" name="lcd_a"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="1" column="1"> | ||||
|                  <widget class="QLabel" name="label"> | ||||
|                   <property name="text"> | ||||
|                    <string>X</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="1" column="4"> | ||||
|                  <widget class="QLabel" name="label_4"> | ||||
|                   <property name="text"> | ||||
|                    <string>A</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="3" column="1"> | ||||
|                  <widget class="QLCDNumber" name="lcd_x"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="4" column="2"> | ||||
|                  <widget class="QLCDNumber" name="lcd_touchY"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="4" column="4"> | ||||
|                  <widget class="QLCDNumber" name="lcd_touchA"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="4" column="3"> | ||||
|                  <widget class="QLCDNumber" name="lcd_touchZ"> | ||||
|                   <property name="segmentStyle"> | ||||
|                    <enum>QLCDNumber::Flat</enum> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="2" column="2"> | ||||
|                  <widget class="Led" name="led_homeY" native="true"> | ||||
|                   <property name="sizePolicy"> | ||||
|                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|                     <horstretch>0</horstretch> | ||||
|                     <verstretch>0</verstretch> | ||||
|                    </sizepolicy> | ||||
|                   </property> | ||||
|                   <property name="minimumSize"> | ||||
|                    <size> | ||||
|                     <width>50</width> | ||||
|                     <height>30</height> | ||||
|                    </size> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="0" column="1"> | ||||
|                  <widget class="QLabel" name="label_10"> | ||||
|                   <property name="text"> | ||||
|                    <string>Pressure</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="0" column="3"> | ||||
|                  <widget class="QLabel" name="label_11"> | ||||
|                   <property name="text"> | ||||
|                    <string>Probe</string> | ||||
|                   </property> | ||||
|                   <property name="alignment"> | ||||
|                    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="0" column="2"> | ||||
|                  <widget class="Led" name="led_pressure" native="true"> | ||||
|                   <property name="sizePolicy"> | ||||
|                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|                     <horstretch>0</horstretch> | ||||
|                     <verstretch>0</verstretch> | ||||
|                    </sizepolicy> | ||||
|                   </property> | ||||
|                   <property name="minimumSize"> | ||||
|                    <size> | ||||
|                     <width>0</width> | ||||
|                     <height>30</height> | ||||
|                    </size> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item row="0" column="4"> | ||||
|                  <widget class="Led" name="led_probe" native="true"> | ||||
|                   <property name="sizePolicy"> | ||||
|                    <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> | ||||
|                     <horstretch>0</horstretch> | ||||
|                     <verstretch>0</verstretch> | ||||
|                    </sizepolicy> | ||||
|                   </property> | ||||
|                   <property name="minimumSize"> | ||||
|                    <size> | ||||
|                     <width>0</width> | ||||
|                     <height>30</height> | ||||
|                    </size> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                </layout> | ||||
|               </item> | ||||
|               <item> | ||||
|                <layout class="QHBoxLayout" name="horizontalLayout_4"> | ||||
|                 <property name="spacing"> | ||||
|                  <number>6</number> | ||||
|                 </property> | ||||
|                 <property name="bottomMargin"> | ||||
|                  <number>0</number> | ||||
|                 </property> | ||||
|                 <item> | ||||
|                  <widget class="QRadioButton" name="radioButton"> | ||||
|                   <property name="text"> | ||||
|                    <string>Show Absolute</string> | ||||
|                   </property> | ||||
|                   <property name="checkable"> | ||||
|                    <bool>true</bool> | ||||
|                   </property> | ||||
|                   <property name="checked"> | ||||
|                    <bool>true</bool> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                 <item> | ||||
|                  <widget class="QRadioButton" name="radioButton_2"> | ||||
|                   <property name="text"> | ||||
|                    <string>Show Relative</string> | ||||
|                   </property> | ||||
|                  </widget> | ||||
|                 </item> | ||||
|                </layout> | ||||
|               </item> | ||||
|              </layout> | ||||
|             </widget> | ||||
|             <widget class="QWidget" name="tab3d"> | ||||
|              <attribute name="title"> | ||||
|               <string>3D</string> | ||||
|              </attribute> | ||||
|              <layout class="QHBoxLayout" name="horizontalLayout_7"> | ||||
|               <item> | ||||
|                <widget class="BackPlotWidget" name="backPlot" native="true"/> | ||||
|               </item> | ||||
|              </layout> | ||||
|             </widget> | ||||
|            </widget> | ||||
|           </item> | ||||
|           <item> | ||||
|            <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,1,0,0"> | ||||
|             <item> | ||||
|              <widget class="QLabel" name="label_5"> | ||||
|               <property name="text"> | ||||
|                <string>Current Tool</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QLCDNumber" name="lcd_tool"> | ||||
|               <property name="segmentStyle"> | ||||
|                <enum>QLCDNumber::Flat</enum> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QComboBox" name="comboBox_tool"> | ||||
|               <item> | ||||
|                <property name="text"> | ||||
|                 <string>1</string> | ||||
|                </property> | ||||
|               </item> | ||||
|               <item> | ||||
|                <property name="text"> | ||||
|                 <string>2</string> | ||||
|                </property> | ||||
|               </item> | ||||
|               <item> | ||||
|                <property name="text"> | ||||
|                 <string>3</string> | ||||
|                </property> | ||||
|               </item> | ||||
|               <item> | ||||
|                <property name="text"> | ||||
|                 <string>4</string> | ||||
|                </property> | ||||
|               </item> | ||||
|               <item> | ||||
|                <property name="text"> | ||||
|                 <string>5</string> | ||||
|                </property> | ||||
|               </item> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QPushButton" name="pushButton_toolSwitch"> | ||||
|               <property name="text"> | ||||
|                <string>Switch</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QPushButton" name="pushButton_toolUnload"> | ||||
|               <property name="text"> | ||||
|                <string>Unload</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|            </layout> | ||||
|           </item> | ||||
|           <item> | ||||
|            <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||||
|             <property name="bottomMargin"> | ||||
|              <number>0</number> | ||||
|             </property> | ||||
|             <item> | ||||
|              <widget class="QLabel" name="label_6"> | ||||
|               <property name="text"> | ||||
|                <string>Spindle</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QLCDNumber" name="lcd_spindle"> | ||||
|               <property name="segmentStyle"> | ||||
|                <enum>QLCDNumber::Flat</enum> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QSlider" name="horizontalSlider"> | ||||
|               <property name="minimum"> | ||||
|                <number>0</number> | ||||
|               </property> | ||||
|               <property name="maximum"> | ||||
|                <number>60000</number> | ||||
|               </property> | ||||
|               <property name="singleStep"> | ||||
|                <number>100</number> | ||||
|               </property> | ||||
|               <property name="pageStep"> | ||||
|                <number>100</number> | ||||
|               </property> | ||||
|               <property name="value"> | ||||
|                <number>0</number> | ||||
|               </property> | ||||
|               <property name="tracking"> | ||||
|                <bool>false</bool> | ||||
|               </property> | ||||
|               <property name="orientation"> | ||||
|                <enum>Qt::Horizontal</enum> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QPushButton" name="pushButton_stopSpindle"> | ||||
|               <property name="text"> | ||||
|                <string>Stop</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|            </layout> | ||||
|           </item> | ||||
|           <item> | ||||
|            <layout class="QHBoxLayout" name="horizontalLayout_3"> | ||||
|             <property name="rightMargin"> | ||||
|              <number>0</number> | ||||
|             </property> | ||||
|             <property name="bottomMargin"> | ||||
|              <number>10</number> | ||||
|             </property> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe1"> | ||||
|               <property name="text"> | ||||
|                <string>Unclamp Tool</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe2"> | ||||
|               <property name="text"> | ||||
|                <string>Bearing Air</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe5"> | ||||
|               <property name="text"> | ||||
|                <string>Air Assist</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe3"> | ||||
|               <property name="text"> | ||||
|                <string>Clamp Tools</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe4"> | ||||
|               <property name="text"> | ||||
|                <string>Compressor</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe6"> | ||||
|               <property name="text"> | ||||
|                <string>A Axis Clamp</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|             <item> | ||||
|              <widget class="QCheckBox" name="checkBox_oe7"> | ||||
|               <property name="text"> | ||||
|                <string>Fixture Air</string> | ||||
|               </property> | ||||
|              </widget> | ||||
|             </item> | ||||
|            </layout> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </widget> | ||||
|       <widget class="QGroupBox" name="groupBox_3"> | ||||
|        <property name="title"> | ||||
|         <string>Programm</string> | ||||
|        </property> | ||||
|        <layout class="QVBoxLayout" name="verticalLayout_5"> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout_8"> | ||||
|           <item> | ||||
|            <widget class="QPlainTextEdit" name="plainTextEdit"/> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QPlainTextEdit" name="plainTextEdit_compiled"> | ||||
|             <property name="readOnly"> | ||||
|              <bool>true</bool> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|         <item> | ||||
|          <layout class="QHBoxLayout" name="horizontalLayout_6"> | ||||
|           <item> | ||||
|            <widget class="QRadioButton" name="radioButton_vhfCode"> | ||||
|             <property name="text"> | ||||
|              <string>VHF code</string> | ||||
|             </property> | ||||
|             <property name="checked"> | ||||
|              <bool>true</bool> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QRadioButton" name="radioButton_gcode"> | ||||
|             <property name="text"> | ||||
|              <string>Gcode</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|           <item> | ||||
|            <spacer name="horizontalSpacer"> | ||||
|             <property name="orientation"> | ||||
|              <enum>Qt::Horizontal</enum> | ||||
|             </property> | ||||
|             <property name="sizeHint" stdset="0"> | ||||
|              <size> | ||||
|               <width>40</width> | ||||
|               <height>20</height> | ||||
|              </size> | ||||
|             </property> | ||||
|            </spacer> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QPushButton" name="pushButton_stop"> | ||||
|             <property name="text"> | ||||
|              <string>Stop</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|           <item> | ||||
|            <widget class="QPushButton" name="pushButton_run"> | ||||
|             <property name="text"> | ||||
|              <string>Run</string> | ||||
|             </property> | ||||
|            </widget> | ||||
|           </item> | ||||
|          </layout> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </widget> | ||||
|      </widget> | ||||
|     </item> | ||||
|    </layout> | ||||
|   </widget> | ||||
|   <widget class="QMenuBar" name="menubar"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>0</x> | ||||
|      <y>0</y> | ||||
|      <width>1048</width> | ||||
|      <height>22</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <widget class="QMenu" name="menuFile"> | ||||
|     <property name="title"> | ||||
|      <string>File</string> | ||||
|     </property> | ||||
|     <addaction name="actionOpen_Gcode"/> | ||||
|     <addaction name="actionOpen"/> | ||||
|     <addaction name="actionClear"/> | ||||
|    </widget> | ||||
|    <addaction name="menuFile"/> | ||||
|   </widget> | ||||
|   <widget class="QStatusBar" name="statusbar"/> | ||||
|   <action name="actionOpen"> | ||||
|    <property name="text"> | ||||
|     <string>Open VHL</string> | ||||
|    </property> | ||||
|    <property name="shortcut"> | ||||
|     <string>Ctrl+Shift+O</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionSerial_Port"> | ||||
|    <property name="text"> | ||||
|     <string>Serial Port</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionOpen_Gcode"> | ||||
|    <property name="text"> | ||||
|     <string>Open Gcode</string> | ||||
|    </property> | ||||
|    <property name="shortcut"> | ||||
|     <string>Ctrl+O</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionQuit"> | ||||
|    <property name="text"> | ||||
|     <string>Quit</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionClear"> | ||||
|    <property name="text"> | ||||
|     <string>Save VhfCode</string> | ||||
|    </property> | ||||
|   </action> | ||||
|  </widget> | ||||
|  <customwidgets> | ||||
|   <customwidget> | ||||
|    <class>Led</class> | ||||
|    <extends>QWidget</extends> | ||||
|    <header location="global">led.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|   <customwidget> | ||||
|    <class>BackPlotWidget</class> | ||||
|    <extends>QWidget</extends> | ||||
|    <header location="global">backplotwidget.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|  </customwidgets> | ||||
|  <resources/> | ||||
|  <connections/> | ||||
| </ui> | ||||
							
								
								
									
										164
									
								
								orbitcameracontroller.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								orbitcameracontroller.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,164 @@ | |||
| // Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
 | ||||
| // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 | ||||
| 
 | ||||
| #include "orbitcameracontroller.h" | ||||
| 
 | ||||
| #include <Qt3DRender/QCamera> | ||||
| 
 | ||||
| /*!
 | ||||
|     \class Qt3DExtras::OrbitCameraController | ||||
|     \ingroup qt3d-extras-cameracontrollers | ||||
|     \brief The OrbitCameraController class allows controlling the scene camera along orbital path. | ||||
|     \inmodule Qt3DExtras | ||||
|     \since 5.7 | ||||
|     \inherits Qt3DCore::QEntity | ||||
| 
 | ||||
|     The controls are: | ||||
|     \table | ||||
|     \header | ||||
|         \li Input | ||||
|         \li Action | ||||
|     \row | ||||
|         \li Left mouse button | ||||
|         \li While the left mouse button is pressed, mouse movement along x-axis moves the camera | ||||
|         left and right and movement along y-axis moves it up and down. | ||||
|     \row | ||||
|         \li Right mouse button | ||||
|         \li While the right mouse button is pressed, mouse movement along x-axis pans the camera | ||||
|         around the camera view center and movement along y-axis tilts it around the camera | ||||
|         view center. | ||||
|     \row | ||||
|         \li Both left and right mouse button | ||||
|         \li While both the left and the right mouse button are pressed, mouse movement along y-axis | ||||
|         zooms the camera in and out without changing the view center. | ||||
|     \row | ||||
|         \li Mouse scroll wheel | ||||
|         \li Zooms the camera in and out without changing the view center. | ||||
|     \row | ||||
|         \li Arrow keys | ||||
|         \li Move the camera vertically and horizontally relative to camera viewport. | ||||
|     \row | ||||
|         \li Page up and page down keys | ||||
|         \li Move the camera forwards and backwards. | ||||
|     \row | ||||
|         \li Shift key | ||||
|         \li Changes the behavior of the up and down arrow keys to zoom the camera in and out | ||||
|         without changing the view center. The other movement keys are disabled. | ||||
|     \row | ||||
|         \li Alt key | ||||
|         \li Changes the behovior of the arrow keys to pan and tilt the camera around the view | ||||
|         center. Disables the page up and page down keys. | ||||
|     \row | ||||
|         \li Escape | ||||
|         \li Moves the camera so that entire scene is visible in the camera viewport. | ||||
|     \endtable | ||||
| */ | ||||
| 
 | ||||
| OrbitCameraController::OrbitCameraController(QVector2D orthoSize, Qt3DCore::QNode *parent) | ||||
| 	: QAbstractCameraController(parent), | ||||
| 	  m_orthoSize(orthoSize) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| OrbitCameraController::~OrbitCameraController() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| /*!
 | ||||
|     \property OrbitCameraController::zoomInLimit | ||||
| 
 | ||||
|     Holds the current zoom-in limit. The zoom-in limit determines how close to the view center | ||||
|     the camera can be zoomed. | ||||
| */ | ||||
| float OrbitCameraController::zoomInLimit() const | ||||
| { | ||||
| 	return m_zoomInLimit; | ||||
| } | ||||
| 
 | ||||
| void OrbitCameraController::updateProjection() | ||||
| { | ||||
| 	camera()->lens()->setOrthographicProjection(0-(m_orthoSize.x()/m_zoomFactor)/2, (m_orthoSize.x()/m_zoomFactor)/2, | ||||
| 												0-(m_orthoSize.y()/m_zoomFactor)/2, (m_orthoSize.y()/m_zoomFactor)/2, 0.01, 100000); | ||||
| } | ||||
| 
 | ||||
| void OrbitCameraController::setZoomInLimit(float zoomInLimit) | ||||
| { | ||||
| 	if (m_zoomInLimit != zoomInLimit) | ||||
| 	{ | ||||
| 		m_zoomInLimit = zoomInLimit; | ||||
| 		emit zoomInLimitChanged(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OrbitCameraController::setZoomFactor(float factor) | ||||
| { | ||||
| 	m_zoomFactor = factor; | ||||
| 	updateProjection(); | ||||
| } | ||||
| 
 | ||||
| void OrbitCameraController::setOrthoSize(QVector2D orthoSize) | ||||
| { | ||||
| 	m_orthoSize = orthoSize; | ||||
| 	updateProjection(); | ||||
| } | ||||
| 
 | ||||
| inline float clampInputs(float input1, float input2) | ||||
| { | ||||
| 	float axisValue = input1 + input2; | ||||
| 	return (axisValue < -1) ? -1 : (axisValue > 1) ? 1 : axisValue; | ||||
| } | ||||
| 
 | ||||
| inline float zoomDistance(QVector3D firstPoint, QVector3D secondPoint) | ||||
| { | ||||
| 	return (secondPoint - firstPoint).lengthSquared(); | ||||
| } | ||||
| 
 | ||||
| void OrbitCameraController::moveCamera(const QAbstractCameraController::InputState &state, float dt) | ||||
| { | ||||
| 	Qt3DRender::QCamera *theCamera = camera(); | ||||
| 
 | ||||
| 	if (theCamera == nullptr) | ||||
| 		return; | ||||
| 
 | ||||
| 	const QVector3D upVector(0.0f, 0.0f, 1.0f); | ||||
| 
 | ||||
| 	if(state.tzAxisValue != 0) | ||||
| 	{ | ||||
| 		m_zoomFactor+=0.1*state.tzAxisValue; | ||||
| 		if(m_zoomFactor < 1) | ||||
| 			m_zoomFactor = 1; | ||||
| 		else if(m_zoomFactor > m_zoomInLimit) | ||||
| 			m_zoomFactor = m_zoomInLimit; | ||||
| 		updateProjection(); | ||||
| 	} | ||||
| 
 | ||||
| 	// Mouse input
 | ||||
| 	if (state.rightMouseButtonActive) | ||||
| 	{ | ||||
| 		// Translate
 | ||||
| 		theCamera->translate(QVector3D(clampInputs(0-state.rxAxisValue, 0-state.txAxisValue) * linearSpeed(), | ||||
| 									  clampInputs(0-state.ryAxisValue, 0-state.tyAxisValue) * linearSpeed(), | ||||
| 									  0) * dt); | ||||
| 	} | ||||
| 	else if (state.leftMouseButtonActive) | ||||
| 	{ | ||||
| 		// Orbit
 | ||||
| 		theCamera->panAboutViewCenter((state.rxAxisValue * -1 * lookSpeed()) * dt, upVector); | ||||
| 		theCamera->tiltAboutViewCenter((state.ryAxisValue * -1 * lookSpeed()) * dt); | ||||
| 	} | ||||
| 
 | ||||
| 	// Keyboard Input
 | ||||
| 	if (state.altKeyActive) | ||||
| 	{ | ||||
| 		// Orbit
 | ||||
| 		theCamera->panAboutViewCenter((state.txAxisValue * lookSpeed()) * dt, upVector); | ||||
| 		theCamera->tiltAboutViewCenter((state.tyAxisValue * lookSpeed()) * dt); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		// Translate
 | ||||
| 		theCamera->translate(QVector3D(clampInputs(state.leftMouseButtonActive ? state.rxAxisValue : 0, state.txAxisValue) * linearSpeed(), | ||||
| 									  clampInputs(state.leftMouseButtonActive ? state.ryAxisValue : 0, state.tyAxisValue) * linearSpeed(), | ||||
| 									  state.tzAxisValue * linearSpeed()) * dt); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										33
									
								
								orbitcameracontroller.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								orbitcameracontroller.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | |||
| // Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
 | ||||
| // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
 | ||||
| 
 | ||||
| #pragma once | ||||
| #include <QAbstractCameraController> | ||||
| #include <QVector2D> | ||||
| 
 | ||||
| class OrbitCameraController : public Qt3DExtras::QAbstractCameraController | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 
 | ||||
| 	float m_zoomInLimit = 10.0; | ||||
| 	float m_zoomFactor = 1.0; | ||||
| 	QVector2D m_orthoSize; | ||||
| 
 | ||||
| 	void updateProjection(); | ||||
| 
 | ||||
| public: | ||||
| 	explicit OrbitCameraController(QVector2D orthoSize, Qt3DCore::QNode *parent = nullptr); | ||||
| 	~OrbitCameraController(); | ||||
| 
 | ||||
| 	float zoomInLimit() const; | ||||
| 
 | ||||
| 	void setZoomInLimit(float zoomInLimit); | ||||
| 	void setZoomFactor(float factor); | ||||
| 	void setOrthoSize(QVector2D orthoSize); | ||||
| 
 | ||||
| signals: | ||||
| 	void zoomInLimitChanged(); | ||||
| 
 | ||||
| private: | ||||
| 	virtual void moveCamera(const Qt3DExtras::QAbstractCameraController::InputState &state, float dt) override; | ||||
| }; | ||||
							
								
								
									
										628
									
								
								vhfmill.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										628
									
								
								vhfmill.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,628 @@ | |||
| #include "vhfmill.h" | ||||
| #include <QDebug> | ||||
| 
 | ||||
| VhfMill::VhfMill(QIODevice* serial, uint8_t nAxis, QObject *parent) | ||||
| 	: serial_(serial), nAxis_(nAxis), QObject{parent} | ||||
| { | ||||
| 	QObject::connect(serial_, &QIODevice::readyRead, this, &VhfMill::serialReadyRead); | ||||
| 
 | ||||
| 	qDebug()<<__func__<<" object created"; | ||||
| 
 | ||||
| 	lastKnownPos_.assign(5, 0); | ||||
| 	touchoffPos_.assign(5, 0); | ||||
| 
 | ||||
| 	initTimer.callOnTimeout(this, &VhfMill::initTimerFn); | ||||
| 	initTimer.setInterval(3000); | ||||
| 
 | ||||
| 	stateTimer.callOnTimeout(this, &VhfMill::stateTimerFn); | ||||
| 	stateTimer.setInterval(1000); | ||||
| 
 | ||||
| 	positionTimer.callOnTimeout(this, &VhfMill::reqPosition); | ||||
| 	positionTimer.setInterval(100); | ||||
| 
 | ||||
| 	limits_ = {190000, 92000, 85000, 100000}; | ||||
| } | ||||
| 
 | ||||
| void VhfMill::serialReadyRead() | ||||
| { | ||||
| 	char charBuf; | ||||
| 	while(serial_->getChar(&charBuf)) | ||||
| 	{ | ||||
| 		lineBuffer_.push_back(charBuf); | ||||
| 		if(lineBuffer_.endsWith(';') ) | ||||
| 		{ | ||||
| 			lineBuffer_.chop(1); | ||||
| 			processIncomeingLine(); | ||||
| 			gotLine(lineBuffer_); | ||||
| 			lineBuffer_.clear(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void VhfMill::init() | ||||
| { | ||||
| 	initTimerFn(); | ||||
| 	initTimer.start(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::setSpindleSpeed(int speed) | ||||
| { | ||||
| 	serial_->write("RVS"+QByteArray::number(speed)+";\n"); | ||||
| 	serial_->write("?RV;"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::setjogStep(int step) | ||||
| { | ||||
| 	jogStep_ = step; | ||||
| 	jogStepChanged(jogStep_); | ||||
| } | ||||
| 
 | ||||
| VhfMill::Axis VhfMill::homed() const | ||||
| { | ||||
| 	return axisHomed_; | ||||
| } | ||||
| 
 | ||||
| void VhfMill::jog(VhfMill::Axis axis, int jogDirection) | ||||
| { | ||||
| 	if(homed() & axis) | ||||
| 	{ | ||||
| 		if(jogStep_ > 0 && jogDirection != 0 && jogAxis_ == AXIS_NONE) | ||||
| 		{ | ||||
| 			QByteArray command("GR"); | ||||
| 			if(axis == AXIS_X) | ||||
| 				command.append(QByteArray::number(jogStep_*jogDirection*-1)); | ||||
| 			else | ||||
| 				command.push_back('0'); | ||||
| 			command.push_back(','); | ||||
| 			if(axis == AXIS_Y) | ||||
| 				command.append(QByteArray::number(jogStep_*jogDirection)); | ||||
| 			else | ||||
| 				command.push_back('0'); | ||||
| 			command.push_back(','); | ||||
| 			if(axis == AXIS_Z) | ||||
| 				command.append(QByteArray::number(jogStep_*jogDirection*-1)); | ||||
| 			else | ||||
| 				command.push_back('0'); | ||||
| 			command.push_back(','); | ||||
| 			if(axis == AXIS_A) | ||||
| 				command.append(QByteArray::number(jogStep_*jogDirection*-1)); | ||||
| 			else | ||||
| 				command.push_back('0'); | ||||
| 			command.push_back(';'); | ||||
| 			send(command); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if(jogAxis_ == axis && jogDirection == 0) | ||||
| 			{ | ||||
| 				serial_->write("!M;"); | ||||
| 				jogDirection_ = 0; | ||||
| 				jogAxis_ = AXIS_NONE; | ||||
| 			} | ||||
| 			else if(jogAxis_ == AXIS_NONE && jogDirection != 0) | ||||
| 			{ | ||||
| 				jogAxis_ = axis; | ||||
| 				jogDirection_ = jogDirection; | ||||
| 				jogDirection = jogDirection == -1 ? 1 : 0; | ||||
| 				QByteArray command("GA"); | ||||
| 				if(axis == AXIS_X) | ||||
| 					command.append(QByteArray::number(getLimits()[0]*jogDirection)); | ||||
| 				else | ||||
| 					command.push_back(QByteArray::number(getLastKnownPosition()[0])); | ||||
| 				command.push_back(','); | ||||
| 				if(axis == AXIS_Y) | ||||
| 					command.append(QByteArray::number(getLimits()[1]*jogDirection)); | ||||
| 				else | ||||
| 					command.push_back(QByteArray::number(getLastKnownPosition()[1])); | ||||
| 				command.push_back(','); | ||||
| 				if(axis == AXIS_Z) | ||||
| 					command.append(QByteArray::number(getLimits()[2]*jogDirection)); | ||||
| 				else | ||||
| 					command.push_back(QByteArray::number(getLastKnownPosition()[2])); | ||||
| 				command.push_back(','); | ||||
| 				if(axis == AXIS_A) | ||||
| 					command.append(QByteArray::number(getLimits()[3]*jogDirection)); | ||||
| 				else | ||||
| 					command.push_back(QByteArray::number(getLastKnownPosition()[3])); | ||||
| 				command.push_back(';'); | ||||
| 				send(command); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const std::vector<int>& VhfMill::getLimits() const | ||||
| { | ||||
| 	return limits_; | ||||
| } | ||||
| 
 | ||||
| QByteArray VhfMill::generateCmdForOffset(QByteArray command) | ||||
| { | ||||
| 	QByteArray output = command.first(2); | ||||
| 	command.remove(0, 2); | ||||
| 	QList<QByteArray> values = command.split(','); | ||||
| 
 | ||||
| 	for(size_t i = 0; i < values.size(); ++i) | ||||
| 	{ | ||||
| 		if(values[i].size() != 0) | ||||
| 		{ | ||||
| 			bool ok; | ||||
| 			int value = values[i].toInt(&ok); | ||||
| 			if(!ok) | ||||
| 			{ | ||||
| 				raiseError(10); | ||||
| 				return QByteArray(); | ||||
| 			} | ||||
| 			output.append(QByteArray::number(value+touchoffPos_[i])); | ||||
| 		} | ||||
| 		output.push_back(','); | ||||
| 	} | ||||
| 
 | ||||
| 	output.back() == ','; | ||||
| 	output.chop(1); | ||||
| 	return output; | ||||
| } | ||||
| 
 | ||||
| void VhfMill::send(const QByteArray& cmd) | ||||
| { | ||||
| 	QList<QByteArray> commands = cmd.split(';'); | ||||
| 
 | ||||
| 	for(const QByteArray& command : commands) | ||||
| 	{ | ||||
| 		QByteArray trimmedCmd = command.trimmed().toUpper(); | ||||
| 		if(trimmedCmd.size() < 2) | ||||
| 			continue; | ||||
| 		if(trimmedCmd.first(2) == "PA" || trimmedCmd.first(2) == "GA") | ||||
| 			trimmedCmd = generateCmdForOffset(trimmedCmd); | ||||
| 		else if(trimmedCmd.first(2) == "PB") | ||||
| 			trimmedCmd[1] = 'A'; | ||||
| 		else if(trimmedCmd.first(2) == "GB") | ||||
| 			trimmedCmd[1] = 'A'; | ||||
| 		qDebug()<<"Writeing"<<(trimmedCmd + ";\n"); | ||||
| 		serial_->write(trimmedCmd + ";\n"); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void VhfMill::stop() | ||||
| { | ||||
| 	send("!B;"); | ||||
| 	send("CONT;"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::home(VhfMill::Axis axis) | ||||
| { | ||||
| 	if(mode_ != MODE_NORMAL || homeAxis_ != AXIS_NONE) | ||||
| 	{ | ||||
| 		raiseError(3); | ||||
| 		return; | ||||
| 	} | ||||
| 	if(axis == AXIS_ALL) | ||||
| 		serial_->write("RF;\n"); | ||||
| 	else if(axis == AXIS_NONE) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		int axisNum = axisToMashineNumber(axis); | ||||
| 		qDebug()<<__func__<<axisNum; | ||||
| 		if(axisNum == 0) | ||||
| 		{ | ||||
| 			raiseError(20); | ||||
| 			return; | ||||
| 		} | ||||
| 		serial_->write("RF" + QByteArray::number(axisNum) + ";\n"); | ||||
| 	} | ||||
| 	homeAxis_ = axis; | ||||
| 	mode_ = MODE_HOME; | ||||
| 	axisHomed_ &= ~axis; | ||||
| 	isHomed(axisHomed_); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::stateTimerFn() | ||||
| { | ||||
| 	reqOutputs(); | ||||
| 	reqSensors(); | ||||
| 	reqSpindleSpeed(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::setOutput(int output, bool state) | ||||
| { | ||||
| 	serial_->write("OA" + QByteArray::number(static_cast<int>(output)) + "," + QByteArray::number(static_cast<int>(state)) + ";\n"); | ||||
| 	reqOutputs(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::setTool(int tool) | ||||
| { | ||||
| 	if(mode_ != MODE_NORMAL) | ||||
| 	{ | ||||
| 		VhfMill::raiseError(3); | ||||
| 		return; | ||||
| 	} | ||||
| 	mode_ = MODE_TOOLCHANGE; | ||||
| 	serial_->write("T" + QByteArray::number(tool) + ";\n"); | ||||
| 	reqTool(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::reqTool() | ||||
| { | ||||
| 	serial_->write("?T;\n"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::reqOutputs() | ||||
| { | ||||
| 	serial_->write("?OA;\n"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::reqPosition() | ||||
| { | ||||
| 	serial_->write("?PA;\n"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::reqSpindleSpeed() | ||||
| { | ||||
| 	serial_->write("?RV;\n"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::reqSensors() | ||||
| { | ||||
| 	serial_->write("?IA;\n"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::enablePosUpdates(bool enable) | ||||
| { | ||||
| 	if(enable && !positionTimer.isActive()) | ||||
| 		positionTimer.start(); | ||||
| 	else | ||||
| 		positionTimer.stop(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::enableStateUpdates(bool enable) | ||||
| { | ||||
| 	if(enable && !stateTimer.isActive()) | ||||
| 		stateTimer.start(); | ||||
| 	else | ||||
| 		stateTimer.stop(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::reinit() | ||||
| { | ||||
| 	mode_ = MODE_PREINIT; | ||||
| 	enablePosUpdates(false); | ||||
| 	enableStateUpdates(false); | ||||
| 	serial_->write("!N;\n"); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::initTimerFn() | ||||
| { | ||||
| 	if(mode_ != MODE_PREINIT) | ||||
| 	{ | ||||
| 		initTimer.stop(); | ||||
| 		enablePosUpdates(true); | ||||
| 		enableStateUpdates(true); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	reinit(); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::processIncomeingLine() | ||||
| { | ||||
| 	if(lineBuffer_.isEmpty()) | ||||
| 	{ | ||||
| 		if(mode_ == MODE_PREINIT) | ||||
| 		{ | ||||
| 			qDebug()<<"init done signal"; | ||||
| 			mode_ = MODE_NORMAL; | ||||
| 			initDone(); | ||||
| 		} | ||||
| 		else if(mode_ == MODE_TOOLCHANGE) | ||||
| 		{ | ||||
| 			qDebug()<<"toolchange done signal"; | ||||
| 			mode_ = MODE_NORMAL; | ||||
| 			toolChangeDone(); | ||||
| 		} | ||||
| 		else if(mode_ == MODE_HOME) | ||||
| 		{ | ||||
| 			qDebug()<<"homeing done"; | ||||
| 			axisHomed_ = axisHomed_ | homeAxis_; | ||||
| 			mode_ = MODE_NORMAL; | ||||
| 			homeAxis_ = AXIS_NONE; | ||||
| 			isHomed(axisHomed_); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if(lineBuffer_.size() == 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(lineBuffer_[0] == 'E') | ||||
| 	{ | ||||
| 		lineBuffer_.remove(0,1); | ||||
| 		bool ok; | ||||
| 		int errorNumber = lineBuffer_.toInt(&ok); | ||||
| 		if(!ok) | ||||
| 			errorNumber = 90; | ||||
| 		VhfMill::raiseError(errorNumber); | ||||
| 	} | ||||
| 	else if(lineBuffer_.startsWith("PA=")) | ||||
| 	{ | ||||
| 		lineBuffer_.remove(0,3); | ||||
| 		QList<QByteArray> list = lineBuffer_.split(','); | ||||
| 		if(list.size() != nAxis_) | ||||
| 		{ | ||||
| 			VhfMill::raiseError(22); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		std::vector<int> postion(5, 0); | ||||
| 		for(int i = 0; i < list.size(); ++i) | ||||
| 		{ | ||||
| 			bool ok; | ||||
| 			postion[i] = list[i].toInt(&ok); | ||||
| 			if(!ok) | ||||
| 			{ | ||||
| 				VhfMill::raiseError(90); | ||||
| 				return; | ||||
| 			} | ||||
| 			lastKnownPos_ = postion; | ||||
| 			positionUpdate(lastKnownPos_); | ||||
| 		} | ||||
| 	} | ||||
| 	else if(lineBuffer_.startsWith("T=")) | ||||
| 	{ | ||||
| 		lineBuffer_.remove(0,2); | ||||
| 		bool ok; | ||||
| 		int toolNumber = lineBuffer_.toInt(&ok); | ||||
| 		if(!ok) | ||||
| 		{ | ||||
| 			VhfMill::raiseError(90); | ||||
| 			return; | ||||
| 		} | ||||
| 		gotToolNum(toolNumber); | ||||
| 	} | ||||
| 	else if(lineBuffer_.startsWith("O=")) | ||||
| 	{ | ||||
| 		lineBuffer_.remove(0,2); | ||||
| 		bool ok; | ||||
| 		int outputs = lineBuffer_.toInt(&ok); | ||||
| 		if(!ok) | ||||
| 		{ | ||||
| 			VhfMill::raiseError(90); | ||||
| 			return; | ||||
| 		} | ||||
| 		if(outputs_ != outputs) | ||||
| 		{ | ||||
| 			outputs_ = outputs; | ||||
| 			gotOutputs(outputs_); | ||||
| 		} | ||||
| 	} | ||||
| 	else if(lineBuffer_.startsWith("RV=")) | ||||
| 	{ | ||||
| 		lineBuffer_.remove(0,3); | ||||
| 		bool ok; | ||||
| 		int speed = lineBuffer_.toInt(&ok); | ||||
| 		if(!ok) | ||||
| 		{ | ||||
| 			VhfMill::raiseError(90); | ||||
| 			return; | ||||
| 		} | ||||
| 		if(spindleSpeed_ != speed) | ||||
| 		{ | ||||
| 			spindleSpeed_ = speed; | ||||
| 			gotSindleSpeed(spindleSpeed_); | ||||
| 		} | ||||
| 	} | ||||
| 	else if(lineBuffer_.startsWith("I=")) | ||||
| 	{ | ||||
| 		lineBuffer_.remove(0,2); | ||||
| 		bool ok; | ||||
| 		unsigned int sensorBits = lineBuffer_.toUInt(&ok); | ||||
| 		if(!ok) | ||||
| 		{ | ||||
| 			VhfMill::raiseError(90); | ||||
| 			return; | ||||
| 		} | ||||
| 		if(sensors_ != sensorBits) | ||||
| 		{ | ||||
| 			sensors_ = sensorBits; | ||||
| 			gotProbeState(sensors_ & 1U); | ||||
| 			gotPressureState(sensors_ & 1U<<1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool VhfMill::presureReady() const | ||||
| { | ||||
| 	return !(sensors_ & 1<<1); | ||||
| } | ||||
| 
 | ||||
| bool VhfMill::isInitDone() const | ||||
| { | ||||
| 	return mode_ != MODE_PREINIT; | ||||
| } | ||||
| 
 | ||||
| int VhfMill::getLastSpindleSpeed() const | ||||
| { | ||||
| 	return spindleSpeed_; | ||||
| } | ||||
| 
 | ||||
| bool VhfMill::allHomed() const | ||||
| { | ||||
| 	bool allHomed = !(~axisHomed_ & (AXIS_X | AXIS_Y | AXIS_Z | AXIS_A | (nAxis_ > 4 ? AXIS_B : 0))); | ||||
| 	qDebug()<<__func__<<allHomed; | ||||
| 	return allHomed; | ||||
| } | ||||
| 
 | ||||
| uint8_t VhfMill::axisCount() const | ||||
| { | ||||
| 	return nAxis_; | ||||
| } | ||||
| 
 | ||||
| void VhfMill::touchOff(VhfMill::Axis axis, int offset) | ||||
| { | ||||
| 	if(axis == AXIS_ALL) | ||||
| 	{ | ||||
| 		for(size_t i = 0; i < nAxis_; ++i) | ||||
| 			touchoffPos_[i] = lastKnownPos_[i] + offset; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		touchoffPos_[axisToIndex(axis)] = lastKnownPos_[axisToIndex(axis)] + offset; | ||||
| 	} | ||||
| 	touchoffChanged(touchoffPos_); | ||||
| } | ||||
| 
 | ||||
| void VhfMill::touchOffAbsolute(std::vector<int> touchoffPos) | ||||
| { | ||||
| 	for(size_t i = 0; i < touchoffPos.size() && i < touchoffPos_.size(); ++i) | ||||
| 		touchoffPos_[i] = touchoffPos[i]; | ||||
| 	touchoffChanged(touchoffPos_); | ||||
| } | ||||
| 
 | ||||
| size_t VhfMill::axisToIndex(Axis axis) | ||||
| { | ||||
| 	return axisToMashineNumber(axis)-1; | ||||
| } | ||||
| 
 | ||||
| std::vector<int> VhfMill::getLastTouchoffPosition() const | ||||
| { | ||||
| 	return touchoffPos_; | ||||
| } | ||||
| 
 | ||||
| std::vector<int> VhfMill::getLastKnownPosition() const | ||||
| { | ||||
| 	return lastKnownPos_; | ||||
| } | ||||
| 
 | ||||
| int VhfMill::axisToMashineNumber(Axis axis) | ||||
| { | ||||
| 	switch(axis) | ||||
| 	{ | ||||
| 		case AXIS_X: | ||||
| 			return 1; | ||||
| 		case AXIS_Y: | ||||
| 			return 2; | ||||
| 		case AXIS_Z: | ||||
| 			return 3; | ||||
| 		case AXIS_A: | ||||
| 			return 4; | ||||
| 		case AXIS_B: | ||||
| 			return 5; | ||||
| 		default: | ||||
| 			return 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const QString VhfMill::textForErrno(int errorNumber) | ||||
| { | ||||
| 	switch(errorNumber) | ||||
| 	{ | ||||
| 		case 0: | ||||
| 			return "No error"; | ||||
| 		case 1: | ||||
| 			return "unsupported command"; | ||||
| 		case 2: | ||||
| 			return "invalid command"; | ||||
| 		case 3: | ||||
| 			return "command not allowed in this state"; | ||||
| 		case 4: | ||||
| 			return "syntax error"; | ||||
| 		case 5: | ||||
| 			return "invalid feature"; | ||||
| 		case 6: | ||||
| 			return "stopped by user"; | ||||
| 		case 7: | ||||
| 			return "unknown error"; | ||||
| 		case 10: | ||||
| 			return "invalid parameter"; | ||||
| 		case 12: | ||||
| 			return "missing parameter"; | ||||
| 		case 13: | ||||
| 			return "parameter is out of range"; | ||||
| 		case 14: | ||||
| 			return "no customer profile"; | ||||
| 		case 20: | ||||
| 			return "axis not defined"; | ||||
| 		case 21: | ||||
| 			return "axis not combinable"; | ||||
| 		case 22: | ||||
| 			return "axis not referenced"; | ||||
| 		case 23: | ||||
| 			return "no referenzpoint found"; | ||||
| 		case 24: | ||||
| 			return "no measurepoint found"; | ||||
| 		case 25: | ||||
| 			return "axis range ended"; | ||||
| 		case 26: | ||||
| 			return "tool too long"; | ||||
| 		case 27: | ||||
| 			return "tool too short"; | ||||
| 		case 30: | ||||
| 			return "no spindle defined"; | ||||
| 		case 31: | ||||
| 			return "no spindle response"; | ||||
| 		case 32: | ||||
| 			return "spindle input active"; | ||||
| 		case 40: | ||||
| 			return "can not record macro"; | ||||
| 		case 41: | ||||
| 			return "macro too long"; | ||||
| 		case 42: | ||||
| 			return "error in last macro"; | ||||
| 		case 43: | ||||
| 			return "macro not found"; | ||||
| 		case 50: | ||||
| 			return "initial stop"; | ||||
| 		case 51: | ||||
| 			return "external stop"; | ||||
| 		case 52: | ||||
| 			return "power driver stop"; | ||||
| 		case 53: | ||||
| 			return "external spindle stop"; | ||||
| 		case 54: | ||||
| 			return "internal spindle stop"; | ||||
| 		case 55: | ||||
| 			return "hbox stop"; | ||||
| 		case 56: | ||||
| 			return "powerfail stop"; | ||||
| 		case 57: | ||||
| 			return "fpga confdone stop"; | ||||
| 		case 58: | ||||
| 			return "refswitch stop"; | ||||
| 		case 59: | ||||
| 			return "fpga error stop"; | ||||
| 		case 60: | ||||
| 			return "overcurrent spindle stop"; | ||||
| 		case 61: | ||||
| 			return "overload spindle stop"; | ||||
| 		case 62: | ||||
| 			return "wait for input stop"; | ||||
| 		case 63: | ||||
| 			return "unexpected input stop"; | ||||
| 		case 70: | ||||
| 			return "leveloffset too high"; | ||||
| 		case 71: | ||||
| 			return "internal error"; | ||||
| 		case 72: | ||||
| 			return "error opening/reading file"; | ||||
| 		case 73: | ||||
| 			return "no answer from device"; | ||||
| 		case 74: | ||||
| 			return "error while loading fpga"; | ||||
| 		case 75: | ||||
| 			return "update not feasible"; | ||||
| 		case 76: | ||||
| 			return "update failed"; | ||||
| 		case 77: | ||||
| 			return "wait for input failed"; | ||||
| 		case 90: | ||||
| 			return "return parse error"; | ||||
| 		default: | ||||
| 			return "errno not valid"; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										125
									
								
								vhfmill.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								vhfmill.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,125 @@ | |||
| #ifndef VHFMILL_H | ||||
| #define VHFMILL_H | ||||
| 
 | ||||
| #include <QObject> | ||||
| #include <QIODevice> | ||||
| #include <QThread> | ||||
| #include <QString> | ||||
| #include <vector> | ||||
| #include <stdint.h> | ||||
| #include <QTimer> | ||||
| 
 | ||||
| class VhfMill : public QObject | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
| 	enum { | ||||
| 		AXIS_NONE = 0, | ||||
| 		AXIS_X = 1, | ||||
| 		AXIS_Y = 1<<1, | ||||
| 		AXIS_Z = 1<<2, | ||||
| 		AXIS_A = 1<<3, | ||||
| 		AXIS_B = 1<<4, | ||||
| 		AXIS_ALL = AXIS_X | AXIS_Y | AXIS_Z | AXIS_A | AXIS_B, | ||||
| 	}; | ||||
| 	typedef int Axis; | ||||
| 
 | ||||
| private: | ||||
| 
 | ||||
| 	typedef enum { | ||||
| 		MODE_PREINIT, | ||||
| 		MODE_HOME, | ||||
| 		MODE_NORMAL, | ||||
| 		MODE_TOOLCHANGE, | ||||
| 		MODE_JOG, | ||||
| 	} Mode; | ||||
| 
 | ||||
| 	std::vector<int> limits_; | ||||
| 
 | ||||
| 	QIODevice* serial_; | ||||
| 	uint8_t nAxis_; | ||||
| 
 | ||||
| 	uint8_t outputs_ = 0; | ||||
| 	int spindleSpeed_ = 0; | ||||
| 	uint16_t sensors_; | ||||
| 	std::vector<int> lastKnownPos_; | ||||
| 	std::vector<int> touchoffPos_; | ||||
| 	Mode mode_ = MODE_PREINIT; | ||||
| 	Axis axisHomed_ = AXIS_NONE; | ||||
| 	Axis homeAxis_ = AXIS_NONE; | ||||
| 
 | ||||
| 	Axis jogAxis_ = AXIS_NONE; | ||||
| 	int jogStep_ = -1; | ||||
| 	int jogDirection_ = 0; | ||||
| 
 | ||||
| 	QTimer positionTimer; | ||||
| 	QTimer stateTimer; | ||||
| 	QTimer initTimer; | ||||
| 
 | ||||
| 	QByteArray lineBuffer_; | ||||
| 
 | ||||
| 	void processIncomeingLine(); | ||||
| 	static int axisToMashineNumber(Axis axis); | ||||
| 	QByteArray generateCmdForOffset(QByteArray command); | ||||
| 
 | ||||
| private slots: | ||||
| 	void serialReadyRead(); | ||||
| 	void initTimerFn(); | ||||
| 	void stateTimerFn(); | ||||
| 	void reinit(); | ||||
| 
 | ||||
| public: | ||||
| 	explicit VhfMill(QIODevice* serial, uint8_t nAxis = 4, QObject *parent = nullptr); | ||||
| 	std::vector<int> getLastKnownPosition() const; | ||||
| 	Axis homed() const; | ||||
| 	bool allHomed() const; | ||||
| 	uint8_t axisCount() const; | ||||
| 	uint16_t getLastKnownSensors() const; | ||||
| 	bool presureReady() const; | ||||
| 	bool isInitDone() const; | ||||
| 	int getLastSpindleSpeed() const; | ||||
| 	std::vector<int> getLastTouchoffPosition() const; | ||||
| 	const std::vector<int>& getLimits() const; | ||||
| 
 | ||||
| 	static const QString textForErrno(int errorNumber); | ||||
| 	static size_t axisToIndex(Axis axis); | ||||
| 
 | ||||
| public slots: | ||||
| 	void setSpindleSpeed(int speed); | ||||
| 	void send(const QByteArray& cmd); | ||||
| 	void stop(); | ||||
| 	void home(VhfMill::Axis axis); | ||||
| 	void jog(VhfMill::Axis axis, int jogDirection); | ||||
| 	void setOutput(int output, bool state); | ||||
| 	void setTool(int tool); | ||||
| 	void reqTool(); | ||||
| 	void reqOutputs(); | ||||
| 	void reqPosition(); | ||||
| 	void reqSensors(); | ||||
| 	void reqSpindleSpeed(); | ||||
| 	void enablePosUpdates(bool enable); | ||||
| 	void enableStateUpdates(bool enable); | ||||
| 	void touchOff(VhfMill::Axis axis, int offset); | ||||
| 	void touchOffAbsolute(std::vector<int> touchoffPos); | ||||
| 	void setjogStep(int step); | ||||
| 	void init(); | ||||
| 
 | ||||
| signals: | ||||
| 	void raiseError(int errorNumber); | ||||
| 	void positionUpdate(std::vector<int> position); | ||||
| 	void isHomed(VhfMill::Axis axis); | ||||
| 	void gotLine(QByteArray string); | ||||
| 	void gotToolNum(int tool); | ||||
| 	void gotOutputs(uint8_t outputs); | ||||
| 	void gotSindleSpeed(int speed); | ||||
| 	void gotProbeState(bool state); | ||||
| 	void gotPressureState(bool state); | ||||
| 	void touchOffChanged(); | ||||
| 	void initDone(); | ||||
| 	void toolChangeDone(); | ||||
| 	void touchoffChanged(std::vector<int> touchoffPos); | ||||
| 	void jogStepChanged(int step); | ||||
| }; | ||||
| 
 | ||||
| #endif // VHFMILL_H
 | ||||
							
								
								
									
										53
									
								
								vhfmillthread.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								vhfmillthread.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | |||
| #include "vhfmillthread.h" | ||||
| 
 | ||||
| VhfMillThread::VhfMillThread(bool tcpI, int portI, const QString& hostI,  const QString& serialPortI, QObject *parent): | ||||
| 	tcp(tcpI), | ||||
| 	port(portI), | ||||
| 	serialPort(serialPortI), | ||||
| 	host(hostI), | ||||
| 	QThread(parent) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void VhfMillThread::run() | ||||
| { | ||||
| 	if(tcp) | ||||
| 	{ | ||||
| 		QTcpSocket* microSocket = new QTcpSocket; | ||||
| 		microSocket->connectToHost(host, port, QIODevice::ReadWrite); | ||||
| 		if(!microSocket->waitForConnected(1000)) | ||||
| 		{ | ||||
| 			ret = -2; | ||||
| 			ready(); | ||||
| 			return; | ||||
| 		} | ||||
| 		masterIODevice = microSocket; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		QSerialPort* microPort = new QSerialPort; | ||||
| 		microPort->setPortName(serialPort); | ||||
| 		microPort->setBaudRate(115200); | ||||
| 
 | ||||
| 		if(!microPort->open(QIODevice::ReadWrite)) | ||||
| 		{ | ||||
| 			qDebug()<<"could not open serial port "<<serialPort; | ||||
| 			ret = -3; | ||||
| 			ready(); | ||||
| 			return; | ||||
| 		} | ||||
| 		masterIODevice = microPort; | ||||
| 	} | ||||
| 
 | ||||
| 	mill = new VhfMill(masterIODevice); | ||||
| 	ret = 0; | ||||
| 	ready(); | ||||
| 	exec(); | ||||
| 	delete mill; | ||||
| 	delete masterIODevice; | ||||
| } | ||||
| 
 | ||||
| VhfMillThread::~VhfMillThread() | ||||
| { | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										36
									
								
								vhfmillthread.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vhfmillthread.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| #ifndef VHFMILLTHREAD_H | ||||
| #define VHFMILLTHREAD_H | ||||
| 
 | ||||
| #include <QThread> | ||||
| #include <QSerialPort> | ||||
| #include <QTcpSocket> | ||||
| 
 | ||||
| #include "vhfmill.h" | ||||
| 
 | ||||
| class VhfMillThread : public QThread | ||||
| { | ||||
| 	Q_OBJECT | ||||
| private: | ||||
| 	const bool tcp; | ||||
| 	const int port; | ||||
| 	const QString serialPort; | ||||
| 	const QString host; | ||||
| 
 | ||||
| public: | ||||
| 	VhfMill* mill = nullptr; | ||||
| 	QIODevice* masterIODevice = nullptr; | ||||
| 	int ret = -1; | ||||
| 
 | ||||
| public: | ||||
| 	VhfMillThread(bool tcpI, int portI, const QString& hostI, const QString& serialPortI, QObject *parent = nullptr); | ||||
| 	~VhfMillThread(); | ||||
| 
 | ||||
| signals: | ||||
| 	void ready(); | ||||
| 
 | ||||
| protected: | ||||
| 	virtual void run() override; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| #endif // VHFMILLTHREAD_H
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue