From 57c6060ea378f34b55622351dd05529e1b563e29 Mon Sep 17 00:00:00 2001 From: VDm Date: Fri, 27 Jun 2025 16:53:41 +0400 Subject: [PATCH 01/11] feat(robodk_interface): update PluginInterface with new classes of Matrix4x4 and Vector3 --- Plugin-OPC-UA/PluginOPCUA.pro | 10 +- PluginAppLoader/AppLoader.pro | 10 +- PluginAttachObject/PluginAttachObject.pro | 10 +- PluginAttachView/PluginAttachView.pro | 10 +- PluginBallbarTracker/PluginBallbarTracker.pro | 10 +- .../PluginCollisionSensor.pro | 10 +- PluginExample/PluginExample.pro | 10 +- PluginLVDT/PluginLVDT.pro | 10 +- PluginLockTCP/PluginLockTCP.pro | 10 +- PluginOpenGL-Shaders/PluginChip8Opengl.pro | 10 +- PluginOpenGL/PluginOpengl.pro | 10 +- PluginRealTime/PluginRealTime.pro | 10 +- PluginRoboUI/PluginRoboUI.pro | 25 +- PluginRobotPilot/PluginRobotPilot.pro | 10 +- robodk_interface/constants.h | 47 ++ robodk_interface/deprecated.h | 45 ++ robodk_interface/joints.cpp | 231 ++++++ robodk_interface/joints.h | 173 +++++ robodk_interface/matrix4x4.cpp | 617 +++++++++++++++ robodk_interface/matrix4x4.h | 354 +++++++++ robodk_interface/robodktypes.cpp | 701 ------------------ robodk_interface/robodktypes.h | 382 +--------- robodk_interface/vector3.cpp | 72 ++ robodk_interface/vector3.h | 74 ++ 24 files changed, 1753 insertions(+), 1098 deletions(-) create mode 100644 robodk_interface/constants.h create mode 100644 robodk_interface/deprecated.h create mode 100644 robodk_interface/joints.cpp create mode 100644 robodk_interface/joints.h create mode 100644 robodk_interface/matrix4x4.cpp create mode 100644 robodk_interface/matrix4x4.h create mode 100644 robodk_interface/vector3.cpp create mode 100644 robodk_interface/vector3.h diff --git a/Plugin-OPC-UA/PluginOPCUA.pro b/Plugin-OPC-UA/PluginOPCUA.pro index 07e570a..c1c0611 100644 --- a/Plugin-OPC-UA/PluginOPCUA.pro +++ b/Plugin-OPC-UA/PluginOPCUA.pro @@ -124,10 +124,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginAppLoader/AppLoader.pro b/PluginAppLoader/AppLoader.pro index f6a6818..14eb1af 100644 --- a/PluginAppLoader/AppLoader.pro +++ b/PluginAppLoader/AppLoader.pro @@ -123,10 +123,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface ./zip #-------------------------- diff --git a/PluginAttachObject/PluginAttachObject.pro b/PluginAttachObject/PluginAttachObject.pro index db55631..9633351 100644 --- a/PluginAttachObject/PluginAttachObject.pro +++ b/PluginAttachObject/PluginAttachObject.pro @@ -110,10 +110,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginAttachView/PluginAttachView.pro b/PluginAttachView/PluginAttachView.pro index 7601e8c..adab489 100644 --- a/PluginAttachView/PluginAttachView.pro +++ b/PluginAttachView/PluginAttachView.pro @@ -109,10 +109,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginBallbarTracker/PluginBallbarTracker.pro b/PluginBallbarTracker/PluginBallbarTracker.pro index 7e91b61..84be89b 100644 --- a/PluginBallbarTracker/PluginBallbarTracker.pro +++ b/PluginBallbarTracker/PluginBallbarTracker.pro @@ -110,10 +110,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginCollisionSensor/PluginCollisionSensor.pro b/PluginCollisionSensor/PluginCollisionSensor.pro index 36a17a6..425dc1f 100644 --- a/PluginCollisionSensor/PluginCollisionSensor.pro +++ b/PluginCollisionSensor/PluginCollisionSensor.pro @@ -109,10 +109,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginExample/PluginExample.pro b/PluginExample/PluginExample.pro index 1b8bc31..5080534 100644 --- a/PluginExample/PluginExample.pro +++ b/PluginExample/PluginExample.pro @@ -114,10 +114,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginLVDT/PluginLVDT.pro b/PluginLVDT/PluginLVDT.pro index 018c73a..a1e0e52 100644 --- a/PluginLVDT/PluginLVDT.pro +++ b/PluginLVDT/PluginLVDT.pro @@ -109,10 +109,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginLockTCP/PluginLockTCP.pro b/PluginLockTCP/PluginLockTCP.pro index 659a8e3..d3778e0 100644 --- a/PluginLockTCP/PluginLockTCP.pro +++ b/PluginLockTCP/PluginLockTCP.pro @@ -111,10 +111,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginOpenGL-Shaders/PluginChip8Opengl.pro b/PluginOpenGL-Shaders/PluginChip8Opengl.pro index ab6fa14..ebe4000 100644 --- a/PluginOpenGL-Shaders/PluginChip8Opengl.pro +++ b/PluginOpenGL-Shaders/PluginChip8Opengl.pro @@ -143,10 +143,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginOpenGL/PluginOpengl.pro b/PluginOpenGL/PluginOpengl.pro index 6e8abb2..fb9ae10 100644 --- a/PluginOpenGL/PluginOpengl.pro +++ b/PluginOpenGL/PluginOpengl.pro @@ -128,10 +128,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginRealTime/PluginRealTime.pro b/PluginRealTime/PluginRealTime.pro index b42152d..9a764af 100644 --- a/PluginRealTime/PluginRealTime.pro +++ b/PluginRealTime/PluginRealTime.pro @@ -113,10 +113,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/PluginRoboUI/PluginRoboUI.pro b/PluginRoboUI/PluginRoboUI.pro index d6306db..aa1af39 100644 --- a/PluginRoboUI/PluginRoboUI.pro +++ b/PluginRoboUI/PluginRoboUI.pro @@ -74,8 +74,6 @@ SOURCES += \ imgui/imgui_impl_qt.cpp \ imgui/imgui_tables.cpp \ imgui/imgui_widgets.cpp \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ roboui.cpp HEADERS += \ @@ -86,13 +84,26 @@ HEADERS += \ imgui/imstb_rectpack.h \ imgui/imstb_textedit.h \ imgui/imstb_truetype.h \ - ../robodk_interface/iapprobodk.h \ + roboui.h + +HEADERS += \ ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h \ - ../robodk_interface/robodk_interface.h \ - ../robodk_interface/robodktools.h \ + ../robodk_interface/irobodk.h\ + ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ - roboui.h + ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ + +SOURCES += \ + ../robodk_interface/robodktools.cpp \ + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp RESOURCES += \ roboui.qrc diff --git a/PluginRobotPilot/PluginRobotPilot.pro b/PluginRobotPilot/PluginRobotPilot.pro index 664c000..1cfc02b 100644 --- a/PluginRobotPilot/PluginRobotPilot.pro +++ b/PluginRobotPilot/PluginRobotPilot.pro @@ -113,10 +113,18 @@ HEADERS += \ ../robodk_interface/iapprobodk.h \ ../robodk_interface/robodktypes.h \ ../robodk_interface/robodktools.h \ + ../robodk_interface/matrix4x4.h \ + ../robodk_interface/vector3.h \ + ../robodk_interface/deprecated.h \ + ../robodk_interface/constants.h \ + ../robodk_interface/joints.h \ SOURCES += \ ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp + ../robodk_interface/robodktypes.cpp \ + ../robodk_interface/matrix4x4.cpp \ + ../robodk_interface/vector3.cpp \ + ../robodk_interface/joints.cpp INCLUDEPATH += ../robodk_interface #-------------------------- diff --git a/robodk_interface/constants.h b/robodk_interface/constants.h new file mode 100644 index 0000000..97331fe --- /dev/null +++ b/robodk_interface/constants.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_CONSTANTS_H +#define ROBODK_CONSTANTS_H + + +namespace robodk +{ + +namespace constants +{ + +constexpr double pi = 3.141592653589793; + +} // namespace constants + +} // namespace robodk + + +#endif // ROBODK_CONSTANTS_H diff --git a/robodk_interface/deprecated.h b/robodk_interface/deprecated.h new file mode 100644 index 0000000..6ea079b --- /dev/null +++ b/robodk_interface/deprecated.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_DEPRECATED_H +#define ROBODK_DEPRECATED_H + + +#ifndef ROBODK_DEPRECATED +# if (defined(_MSC_VER) && _MSC_VER <= 1900) || defined(__MINGW64__) +# define ROBODK_DEPRECATED(text) __declspec(deprecated(text)) +# elif defined __GNUC__ +# define ROBODK_DEPRECATED(text) __attribute__((deprecated)) +# else +# define ROBODK_DEPRECATED(text) [[deprecated(text)]] +# endif +#endif // ROBODK_DEPRECATED + + +#endif // ROBODK_DEPRECATED_H diff --git a/robodk_interface/joints.cpp b/robodk_interface/joints.cpp new file mode 100644 index 0000000..8c8af1d --- /dev/null +++ b/robodk_interface/joints.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#include "joints.h" + +#include +#include + +#include "robodktypes.h" + + +namespace robodk +{ + +Joints::Joints() + : _dofCount(0) +{ + std::memset(_joints, 0, sizeof(_joints)); + std::memset(_jointsFloat, 0, sizeof(_jointsFloat)); +} + +Joints::Joints(int ndofs) +{ + _dofCount = std::min(ndofs, maximumJoints); + for (int i = 0; i < _dofCount; i++) + { + _joints[i] = 0.0; + } +} + +Joints::Joints(const double *joints, int ndofs) +{ + SetValues(joints, ndofs); +} + +Joints::Joints(const float *joints, int ndofs) +{ + int ndofs_ok = std::min(ndofs, maximumJoints); + double jnts[maximumJoints]; + + for (int i=0; i < ndofs_ok; i++) + { + jnts[i] = joints[i]; + } + SetValues(jnts, ndofs_ok); +} + +Joints::Joints(const tMatrix2D *mat2d, int column, int ndofs) +{ + if (column >= Matrix2D_Size(mat2d, 2)) + { + _dofCount = 0; + } + if (ndofs < 0) + { + ndofs = Matrix2D_Size(mat2d, 1); + } + _dofCount = qMin(ndofs, RDK_SIZE_JOINTS_MAX); + + double *ptr = Matrix2D_Get_col(mat2d, column); + SetValues(ptr, _dofCount); +} + +Joints::Joints(const QString &str) +{ + _dofCount = 0; + FromString(str); +} + +const double* Joints::ValuesD() const +{ + return _joints; +} + +const float* Joints::ValuesF() const +{ + for (int i = 0; i < RDK_SIZE_JOINTS_MAX; i++) + { + _jointsFloat[i] = _joints[i]; + } + + return _jointsFloat; +} + +#ifdef ROBODK_API_FLOATS +const float* Joints::Values() const +{ + return ValuesF(); +} +#else +const double* Joints::Values() const +{ + return _joints; +} +#endif + +double Joints::Compare(const Joints &other) const +{ + double sum_diff = 0.0; + for (int i = 0; i = 0 && new_length < _dofCount) + { + _dofCount = new_length; + } +} + +bool Joints::Valid() +{ + return _dofCount > 0; +} + +void Joints::SetValues(const double *values, int ndofs) +{ + if (ndofs >= 0) + { + _dofCount = qMin(ndofs, RDK_SIZE_JOINTS_MAX); + } + + for (int i = 0; i < _dofCount; i++) + { + _joints[i] = values[i]; + } +} + +void Joints::SetValues(const float *values, int ndofs) +{ + if (ndofs >= 0) + { + _dofCount = qMin(ndofs, RDK_SIZE_JOINTS_MAX); + } + + for (int i = 0; i < _dofCount; i++) + { + _joints[i] = values[i]; + } +} + +int Joints::GetValues(double *values) +{ + for (int i = 0; i < _dofCount; i++) + { + values[i] = _joints[i]; + } + + return _dofCount; +} + +#ifdef QT_GUI_LIB +QString Joints::ToString(const QString &separator, int precision) const +{ + QString values; + for (int i = 0; i < _dofCount; i++) + { + if (i > 0) + { + values.append(separator); + } + values.append(QString::number(_joints[i], 'f', precision)); + } + return values; +} + +bool Joints::FromString(const QString &str) +{ + const QLatin1Char separator(','); + + QString s = str; + s.replace(QLatin1Char(';'), separator); + s.replace(QLatin1Char('\t'), separator); + +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + const QString::SplitBehavior behavior = QString::SkipEmptyParts; +#else + const Qt::SplitBehavior behavior = Qt::SkipEmptyParts; +#endif + + QStringList jointList = s.split(separator, behavior); + _dofCount = qMin(jointList.length(), RDK_SIZE_JOINTS_MAX); + for (int i = 0; i < _dofCount; i++) + { + _joints[i] = jointList[i].trimmed().toDouble(); + } + return true; +} +#endif // QT_GUI_LIB + +} // namespace robodk diff --git a/robodk_interface/joints.h b/robodk_interface/joints.h new file mode 100644 index 0000000..efb937b --- /dev/null +++ b/robodk_interface/joints.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_JOINTS_H +#define ROBODK_JOINTS_H + + +#ifdef QT_GUI_LIB +#include +#else +#error "This class cannot yet be used without the Qt Framework" +#endif + + +struct tMatrix2D; + + +namespace robodk +{ + +/// The Joints class represents a joint position of a robot (robot axes). +class Joints +{ +public: + /// \brief Joints + Joints(); + + /// \brief Joints + /// \param ndofs number of robot joint axes or degrees of freedom + explicit Joints(int ndofs); + + /// \brief Set joint values given a double array and the number of joint values + /// \param joints Pointer to the joint values + /// \param ndofs Number of joints + Joints(const double* joints, int ndofs = 0); + + /// \brief Set joint values given a float array and the number of joint values + /// \param joints Pointer to the joint values + /// \param ndofs Number of joints + Joints(const float* joints, int ndofs = 0); + + /// \brief Create a copy of an object + /// \param jnts + Joints(const Joints& joints) = default; + + Joints& operator=(const Joints& joints) = default; + + /// \brief Create joint values given a 2D matrix and the column selecting the desired values + /// \param mat2d + /// \param column + /// \param ndofs + Joints(const tMatrix2D* mat2d, int column = 0, int ndofs = -1); + + /// \brief Convert a string to joint values + /// \param str Comma separated joint values (spaces or tabs are also accepted) + Joints(const QString& str); + + ~Joints() = default; + + /// \brief Joint values + /// \return Returns a pointer to the joint data array (doubles) + const double* ValuesD() const; + + /// \brief Joint values + /// \return Returns a pointer to the joint data array (floats) + const float* ValuesF() const; + +#ifdef ROBODK_API_FLOATS + /// \brief Joint values + /// \return Returns a pointer to the joint data array (doubles or floats if ROBODK_API_FLOATS is defined) + const float* Values() const; +#else + /// \brief Joint values + /// \return Returns a pointer to the joint data array (doubles or floats if ROBODK_API_FLOATS is defined) + const double* Values() const; +#endif + + + double Compare(const Joints &other) const; + + /// \brief + /// \return Data same as Values. The only difference is that the array pointer is not const. This is provided for backwards compatibility. + double *Data(); + + /// \brief Number of joint axes of the robot (or degrees of freedom) + /// \return + int Length() const; + + /// Set the length of the array (only shrinking the array is allowed) + void setLength(int new_length); + + /// \brief Check if the joints are valid. For example, when we request the Inverse kinematics and there is no solution the joints will not be valid. + /// (for example, an invalid result after calling class: IItem::SolveIK returns a non valid joints) + /// \return true if it has 1 degree of freedom or more + bool Valid(); + + /// \brief GetValues + /// \param joints joint values in deg or mm + /// \return returns the number of degrees of freedom + int GetValues(double *joints); + + /// \brief Set the joint values in deg or mm. You can also important provide the number of degrees of freedom (6 for a 6 axis robot). + /// \param joints joint values in deg or mm + /// \param ndofs number of degrees of freedom (number of axes or joints) + void SetValues(const double *joints, int ndofs = -1); + + /// \brief Set the joint values in deg or mm (floats). You can also important provide the number of degrees of freedom (6 for a 6 axis robot). + /// \param joints joint values in deg or mm + /// \param ndofs number of degrees of freedom (number of axes or joints) + void SetValues(const float *joints, int ndofs = -1); + +#ifdef QT_GUI_LIB + /// To String operator (use with qDebug() << Joints; + inline operator QString() const { return ToString(); } + + /// \brief Retrieve a string representation of the joint values. + /// \param separator String to add between consecutive joint values + /// \param precision Number of decimals + /// \return string as a QString + QString ToString( + const QString& separator = QLatin1String(", "), + int precision = 3) const; + + /// \brief Set the joint values given a comma-separated string. Tabs and spaces are also allowed. + /// \param str string. Such as "10, 20, 30, 40, 50, 60" + /// \return false if parsing the string failed. True otherwise. + bool FromString(const QString& str); +#endif + +public: + static constexpr int maximumJoints = 12; + + /// number of degrees of freedom + int _dofCount; + + /// joint values (doubles, used to store the joint values) + double _joints[maximumJoints]; + + /// joint values (floats, used to return a copy as a float pointer) + mutable float _jointsFloat[maximumJoints]; +}; + + +} // namespace robodk + + +#endif // ROBODK_JOINTS_H diff --git a/robodk_interface/matrix4x4.cpp b/robodk_interface/matrix4x4.cpp new file mode 100644 index 0000000..4a02228 --- /dev/null +++ b/robodk_interface/matrix4x4.cpp @@ -0,0 +1,617 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#include "matrix4x4.h" + +#include + +#include "vector3.h" +#include "constants.h" + + +namespace robodk +{ + +Matrix4x4::Matrix4x4() + : QMatrix4x4() + , _valid(true) +{ + setToIdentity(); +} + +Matrix4x4::Matrix4x4(bool valid) + : QMatrix4x4() + , _valid(valid ? 1.0 : 0.0) +{ + setToIdentity(); +} + +Matrix4x4::Matrix4x4(const Matrix4x4 &matrix) + : QMatrix4x4(matrix) + , _valid(matrix._valid) +{ +} + +Matrix4x4::Matrix4x4(const double* values) + : QMatrix4x4( + values[0], values[4], values[8], values[12], + values[1], values[5], values[9], values[13], + values[2], values[6], values[10], values[14], + values[3], values[7], values[11], values[15]) + , _valid(1.0) +{ +} + +Matrix4x4::Matrix4x4(const float* values) + : QMatrix4x4( + values[0], values[4], values[8], values[12], + values[1], values[5], values[9], values[13], + values[2], values[6], values[10], values[14], + values[3], values[7], values[11], values[15]) + , _valid(1.0) +{ +} + +Matrix4x4::Matrix4x4(double x, double y, double z) + : QMatrix4x4( + 1.0f, 0.0f, 0.0f, x, + 0.0f, 1.0f, 0.0f, y, + 0.0f, 0.0f, 1.0f, z, + 0.0f, 0.0f, 0.0f, 1.0f) + , _valid(1.0) +{ + setToIdentity(); + (*this)(0, 3) = x; + (*this)(1, 3) = y; + (*this)(2, 3) = z; +} + + +Matrix4x4::Matrix4x4( + double nx, + double ox, + double ax, + double tx, + double ny, + double oy, + double ay, + double ty, + double nz, + double oz, + double az, + double tz) + : QMatrix4x4( + nx, ox, ax, tx, + ny, oy, ay, ty, + nz, oz, az, tz, + 0.0f, 0.0f, 0.0f, 1.0f) + , _valid(1.0) +{ +} + +void Matrix4x4::setVX(const Vector3& n) +{ + (*this)(0, 0) = n.x(); + (*this)(1, 0) = n.y(); + (*this)(2, 0) = n.z(); +} + +void Matrix4x4::setVY(const Vector3& o) +{ + (*this)(0, 1) = o.x(); + (*this)(1, 1) = o.y(); + (*this)(2, 1) = o.z(); +} + +void Matrix4x4::setVZ(const Vector3& a) +{ + (*this)(0, 2) = a.x(); + (*this)(1, 2) = a.y(); + (*this)(2, 2) = a.z(); +} + +void Matrix4x4::setVX(double x, double y, double z) +{ + Set(0,0, x); + Set(1,0, y); + Set(2,0, z); +} + +void Matrix4x4::setVY(double x, double y, double z) +{ + Set(0,1, x); + Set(1,1, y); + Set(2,1, z); +} + +void Matrix4x4::setVZ(double x, double y, double z) +{ + Set(0,2, x); + Set(1,2, y); + Set(2,2, z); +} + +void Matrix4x4::setPos(double x, double y, double z) +{ + Set(0,3, x); + Set(1,3, y); + Set(2,3, z); +} + +void Matrix4x4::setVX(const double* xyz) +{ + Set(0,0, xyz[0]); + Set(1,0, xyz[1]); + Set(2,0, xyz[2]); +} + +void Matrix4x4::setVY(const double* xyz) +{ + Set(0,1, xyz[0]); + Set(1,1, xyz[1]); + Set(2,1, xyz[2]); +} + +void Matrix4x4::setVZ(const double* xyz) +{ + Set(0,2, xyz[0]); + Set(1,2, xyz[1]); + Set(2,2, xyz[2]); +} + +void Matrix4x4::setPos(const double* xyz) +{ + Set(0,3, xyz[0]); + Set(1,3, xyz[1]); + Set(2,3, xyz[2]); +} + +Vector3 Matrix4x4::vx() const +{ + return Vector3( + (*this)(0, 0), + (*this)(1, 0), + (*this)(2, 0)); +} + +Vector3 Matrix4x4::vy() const +{ + return Vector3( + (*this)(0, 1), + (*this)(1, 1), + (*this)(2, 1)); +} + +Vector3 Matrix4x4::vz() const +{ + return Vector3( + (*this)(0, 2), + (*this)(1, 2), + (*this)(2, 2)); +} + +void Matrix4x4::VX(double* xyz) const +{ + xyz[0] = Get(0, 0); + xyz[1] = Get(1, 0); + xyz[2] = Get(2, 0); +} + +void Matrix4x4::VY(double* xyz) const +{ + xyz[0] = Get(0, 1); + xyz[1] = Get(1, 1); + xyz[2] = Get(2, 1); +} + +void Matrix4x4::VZ(double* xyz) const +{ + xyz[0] = Get(0, 2); + xyz[1] = Get(1, 2); + xyz[2] = Get(2, 2); +} + +void Matrix4x4::Pos(double* xyz) const +{ + xyz[0] = Get(0, 3); + xyz[1] = Get(1, 3); + xyz[2] = Get(2, 3); +} + +void Matrix4x4::setValues(const double* values) +{ + Set(0,0, values[0]); + Set(1,0, values[1]); + Set(2,0, values[2]); + Set(3,0, values[3]); + + Set(0,1, values[4]); + Set(1,1, values[5]); + Set(2,1, values[6]); + Set(3,1, values[7]); + + Set(0,2, values[8]); + Set(1,2, values[9]); + Set(2,2, values[10]); + Set(3,2, values[11]); + + Set(0,3, values[12]); + Set(1,3, values[13]); + Set(2,3, values[14]); + Set(3,3, values[15]); +} + +void Matrix4x4::Set(int i, int j, double value) +{ + QVector4D rw(this->row(i)); + rw[j] = value; + setRow(i, rw); +} + +double Matrix4x4::Get(int i, int j) const +{ + return row(i)[j]; +} + +Matrix4x4 Matrix4x4::inv() const +{ + return this->inverted(); +} + +bool Matrix4x4::isHomogeneous() const +{ + auto tx = vx(); + auto ty = vy(); + auto tz = vz(); + + const double tol = 1e-7; + + if (std::fabs(Vector3::dotProduct(tx, ty)) > tol) + { + return false; + } + else if (std::fabs(Vector3::dotProduct(tx, tz)) > tol) + { + return false; + } + else if (std::fabs(Vector3::dotProduct(ty, tz)) > tol) + { + return false; + } + else if (std::fabs(tx.length() - 1.0) > tol) + { + return false; + } + else if (std::fabs(ty.length() - 1.0) > tol) + { + return false; + } + else if (std::fabs(tz.length() - 1.0) > tol) + { + return false; + } + + return true; +} + +bool Matrix4x4::MakeHomogeneous() +{ + auto tx = vx(); + auto ty = vy(); + auto tz = vz(); + + bool result = isHomogeneous(); + + tx.normalize(); + tz = Vector3::crossProduct(tx, ty); + tz.normalize(); + ty = Vector3::crossProduct(tz, tx); + ty.normalize(); + + setVX(tx); + setVY(ty); + setVZ(tz); + + (*this)(3, 0) = 0.0f; + (*this)(3, 1) = 0.0f; + (*this)(3, 2) = 0.0f; + (*this)(3, 3) = 1.0f; + + return !result; +} + +void Matrix4x4::ToXYZRPW(double* xyzwpr) const +{ + double x = Get(0,3); + double y = Get(1,3); + double z = Get(2,3); + double w, p, r; + + if (Get(2,0) > (1.0 - 1e-6)) + { + p = -constants::pi * 0.5; + r = 0; + w = atan2(-Get(1,2), Get(1,1)); + } + else if (Get(2,0) < -1.0 + 1e-6) + { + p = 0.5 * constants::pi; + r = 0; + w = atan2(Get(1,2),Get(1,1)); + } + else + { + p = atan2(-Get(2, 0), sqrt(Get(0, 0) * Get(0, 0) + Get(1, 0) * Get(1, 0))); + w = atan2(Get(1, 0), Get(0, 0)); + r = atan2(Get(2, 1), Get(2, 2)); + } + + xyzwpr[0] = x; + xyzwpr[1] = y; + xyzwpr[2] = z; + xyzwpr[3] = r * 180.0 / constants::pi; + xyzwpr[4] = p * 180.0 / constants::pi; + xyzwpr[5] = w * 180.0 / constants::pi; +} + +Matrix4x4 Matrix4x4::XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w) +{ + double a = r * constants::pi / 180.0; + double b = p * constants::pi / 180.0; + double c = w * constants::pi / 180.0; + double ca = cos(a); + double sa = sin(a); + double cb = cos(b); + double sb = sin(b); + double cc = cos(c); + double sc = sin(c); + return Matrix4x4(cb * cc, cc * sa * sb - ca * sc, sa * sc + ca * cc * sb, x, + cb * sc, ca * cc + sa * sb * sc, ca * sb * sc - cc * sa, y, + -sb, cb * sa, ca * cb, z); +} + +Matrix4x4 Matrix4x4::XYZRPW_2_Mat(const double* xyzwpr) +{ + return XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]); +} + +void Matrix4x4::FromXYZRPW(const double* xyzwpr) +{ + Matrix4x4 newmat = Matrix4x4::XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], + xyzwpr[3], xyzwpr[4], xyzwpr[5]); + + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + this->Set(i, j, newmat.Get(i, j)); + } + } +} + +const double* Matrix4x4::ValuesD() const +{ + for(int i = 0; i < 16; ++i) + { + _md[i] = constData()[i]; + } + return _md; +} + +const float* Matrix4x4::ValuesF() const +{ + return constData(); +} + +#ifdef ROBODK_API_FLOATS +const float* Matrix4x4::Values() const +{ + return constData(); +} +#else +const double* Matrix4x4::Values() const +{ + return ValuesD(); +} +#endif + +void Matrix4x4::Values(double data[16]) const +{ + for(int i = 0; i < 16; ++i) + { + data[i] = constData()[i]; + } +} + +void Matrix4x4::Values(float data[16]) const +{ + for(int i = 0; i < 16; ++i) + { + data[i] = constData()[i]; + } +} + +bool Matrix4x4::Valid() const +{ + return _valid; +} + +Matrix4x4& Matrix4x4::operator=(const Matrix4x4& matrix) +{ + QMatrix4x4::operator=(matrix); + _valid = 1.0; + return *this; +} + +Matrix4x4 Matrix4x4::transl(double x, double y, double z) +{ + Matrix4x4 mat; + mat.setToIdentity(); + mat.setPos(x, y, z); + return mat; +} + +Matrix4x4 Matrix4x4::rotx(double rx) +{ + double cx = cos(rx); + double sx = sin(rx); + return Matrix4x4(1, 0, 0, 0, 0, cx, -sx, 0, 0, sx, cx, 0); +} + +Matrix4x4 Matrix4x4::roty(double ry) +{ + double cy = cos(ry); + double sy = sin(ry); + return Matrix4x4(cy, 0, sy, 0, 0, 1, 0, 0, -sy, 0, cy, 0); +} + +Matrix4x4 Matrix4x4::rotz(double rz) +{ + double cz = cos(rz); + double sz = sin(rz); + return Matrix4x4(cz, -sz, 0, 0, sz, cz, 0, 0, 0, 0, 1, 0); +} + +#ifdef QT_GUI_LIB +Matrix4x4::Matrix4x4(const QMatrix4x4 &matrix) + : QMatrix4x4(matrix) + , _valid(1.0) +{ +} + +bool Matrix4x4::FromString(const QString &pose_str) +{ + QString pose_str2 = pose_str.trimmed(); + + const Qt::CaseSensitivity cs = Qt::CaseInsensitive; + if (pose_str2.startsWith("Mat(", cs)) + { + pose_str2.remove(0, 4); + pose_str2 = pose_str2.trimmed(); + } + + if (pose_str2.startsWith("XYZRPW_2_Mat(", cs)) + { + pose_str2.remove(0, 13); + pose_str2 = pose_str2.trimmed(); + } + + while (pose_str2.endsWith(')')) + { + pose_str2.chop(1); + } + + const QLatin1Char separator(','); + pose_str2.replace(QLatin1Char(';'), separator); + pose_str2.replace(QLatin1Char('\t'), separator); + +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + const QString::SplitBehavior behavior = QString::SkipEmptyParts; +#else + const Qt::SplitBehavior behavior = Qt::SkipEmptyParts; +#endif + + QStringList values_list = pose_str2.split(separator, behavior); + double xyzwpr[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + if (values_list.length() < 6) + { + FromXYZRPW(xyzwpr); + return false; + } + + for (int i = 0; i < 6; i++) + { + xyzwpr[i] = values_list[i].trimmed().toDouble(); + } + + FromXYZRPW(xyzwpr); + return true; +} + +QString Matrix4x4::ToString(const QString &separator, int precision, bool xyzwpr_only) const +{ + if (!Valid()) + { + return "Mat(Invalid)"; + } + + QString str; + if (!isHomogeneous()) + { + str.append("Warning!! Pose is not homogeneous! Use Matrix4x4::MakeHomogeneous() to make this matrix homogeneous\n"); + } + + str.append("Mat(XYZRPW_2_Mat("); + + double xyzwpr[6]; + ToXYZRPW(xyzwpr); + + for (int i = 0; i < 6; i++) + { + if (i > 0) + { + str.append(separator); + } + str.append(QString::number(xyzwpr[i], 'f', precision)); + } + str.append("))"); + + if (xyzwpr_only) + { + return str; + } + + str.append("\n"); + + for (int i = 0; i < 4; i++) + { + str.append("["); + for (int j = 0; j < 4; j++) + { + str.append(QString::number(row(i)[j], 'f', precision)); + if (j < 3) + { + str.append(separator); + } + } + str.append("];\n"); + } + return str; +} + +Matrix4x4& Matrix4x4::operator=(const QMatrix4x4& matrix) +{ + QMatrix4x4::operator=(matrix); + _valid = 1.0; + return *this; +} +#endif // QT_GUI_LIB + +} // namespace robodk diff --git a/robodk_interface/matrix4x4.h b/robodk_interface/matrix4x4.h new file mode 100644 index 0000000..49fb385 --- /dev/null +++ b/robodk_interface/matrix4x4.h @@ -0,0 +1,354 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_MATRIX4X4_H +#define ROBODK_MATRIX4X4_H + + +#include "vector3.h" + + +#ifdef QT_GUI_LIB +#include +#include + +namespace robodk +{ +typedef ::QMatrix4x4 BaseMatrix4x4; +} +#else +#error "This class cannot yet be used without the Qt Framework" +#endif + + +namespace robodk +{ + +class Matrix4x4 : public BaseMatrix4x4 +{ +public: + /// Create the identity matrix + Matrix4x4(); + + /// Create a valid or an invalid matrix + explicit Matrix4x4(bool valid); + + /// Create a copy of the matrix + Matrix4x4(const Matrix4x4& matrix); + + /// \brief Create a homogeneoux matrix given a one dimensional 16-value array (doubles) + /// \param values [nx,ny,nz,0, ox,oy,oz,0, ax,ay,az,0, tx,ty,tz,1] + /// \f$ \begin{bmatrix} n_x & o_x & a_x & x \\ + /// n_y & o_y & a_y & y \\ + /// n_z & o_z & a_z & z \\ + /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ + /// + Matrix4x4(const double* values); + + /// \brief Create a homogeneoux matrix given a one dimensional 16-value array (floats) + /// \param values [nx,ny,nz,0, ox,oy,oz,0, ax,ay,az,0, tx,ty,tz,1] + /// \f$ transl(x,y,z) rotx(r) roty(p) rotz(w) = \\ + /// \begin{bmatrix} n_x & o_x & a_x & x \\ + /// n_y & o_y & a_y & y \\ + /// n_z & o_z & a_z & z \\ + /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ + /// + Matrix4x4(const float* values); + + /// + /// Create a translation matrix. + /// + /// translation along X (mm) + /// translation along Y (mm) + /// translation along Z (mm) + /// + /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & x \\ + /// 0 & 1 & 0 & y \\ + /// 0 & 0 & 1 & z \\ + /// 0 & 0 & 0 & 1 \\ + /// \end{bmatrix} \f$ + /// + Matrix4x4(double x, double y, double z); + + + /// + /// Matrix class constructor for a 4x4 homogeneous matrix given N, O, A & T vectors + /// + /// Matrix[0,0] + /// Matrix[0,1] + /// Matrix[0,2] + /// Matrix[0,3] + /// Matrix[1,0] + /// Matrix[1,1] + /// Matrix[1,2] + /// Matrix[1,3] + /// Matrix[2,0] + /// Matrix[2,1] + /// Matrix[2,2] + /// Matrix[2,3] + /// \f$ \begin{bmatrix} n_x & o_x & a_x & x \\ + /// n_y & o_y & a_y & y \\ + /// n_z & o_z & a_z & z \\ + /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ + /// + Matrix4x4( + double nx, + double ox, + double ax, + double tx, + double ny, + double oy, + double ay, + double ty, + double nz, + double oz, + double az, + double tz); + + ~Matrix4x4() = default; + + /// Set the X vector values (N vector) + void setVX(const Vector3& n); + + /// Set the Y vector values (O vector) + void setVY(const Vector3& o); + + /// Set the Z vector values (A vector) + void setVZ(const Vector3& a); + + /// Set the X vector values (N vector) + void setVX(double x, double y, double z); + + /// Set the Y vector values (O vector) + void setVY(double x, double y, double z); + + /// Set the Z vector values (A vector) + void setVZ(double x, double y, double z); + + /// Set the position (T position) in mm + void setPos(double x, double y, double z); + + /// Set the X vector values (N vector) + void setVX(const double* xyz); + + /// Set the Y vector values (O vector) + void setVY(const double* xyz); + + /// Set the Z vector values (A vector) + void setVZ(const double* xyz); + + /// Set the position (T position) in mm + void setPos(const double* xyz); + + /// Set the pose values + void setValues(const double* values); + + /// Get the X vector (N vector) + Vector3 vx() const; + + /// Get the Y vector (O vector) + Vector3 vy() const; + + /// Get the Z vector (A vector) + Vector3 vz() const; + + /// Get the X vector (N vector) + void VX(double* xyz) const; + + /// Get the Y vector (O vector) + void VY(double* xyz) const; + + /// Get the Z vector (A vector) + void VZ(double* xyz) const; + + /// Get the position (T position), in mm + void Pos(double* xyz) const; + + /// \brief Set a matrix value + /// \param r row + /// \param c column + /// \param value value + void Set(int r, int c, double value); + + /// \brief Get a matrix value + /// \param r row + /// \param c column + /// \return value + double Get(int r, int c) const; + + /// Invert the pose (homogeneous matrix assumed) + Matrix4x4 inv() const; + + /// Returns true if the matrix is homogeneous, otherwise it returns false + bool isHomogeneous() const; + + /// Forces 4x4 matrix to be homogeneous (vx,vy,vz must be unitary vectors and respect: vx x vy = vz). Returns True if the matrix was not homogeneous and it was be modified to make it homogeneous. + bool MakeHomogeneous(); + + /// + /// Calculates the equivalent position and euler angles ([x,y,z,r,p,w] vector) of the given pose + /// Note: transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) + /// See also: FromXYZRPW() + /// + /// XYZWPR translation and rotation in mm and degrees + void ToXYZRPW(double* xyzwpr) const; + + /// + /// Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) + /// The result is the same as: + ///
+ /// H = transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) + ///
+ /// Homogeneous matrix (4x4) + void FromXYZRPW(const double* xyzwpr); + + /// + /// Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) + /// The result is the same as: + ///
+ /// H = transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) + ///
+ /// Homogeneous matrix (4x4) + static Matrix4x4 XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w); + static Matrix4x4 XYZRPW_2_Mat(const double* xyzwpr); + + /// Get a pointer to the 16-digit double array. + const double* ValuesD() const; + + /// Get a pointer to the 16-digit array as an array of floats. + const float* ValuesF() const; + +#ifdef ROBODK_API_FLOATS + /// Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined). + const float* Values() const; +#else + /// Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined). + const double* Values() const; +#endif + + /// Copy the 16-values of the 4x4 matrix to a double array. + void Values(double values[16]) const; + + /// Copy the 16-values of the 4x4 matrix to a double array. + void Values(float values[16]) const; + + /// Check if the matrix is valid + bool Valid() const; + + Matrix4x4& operator=(const Matrix4x4& matrix); + + /// + /// Return a translation matrix. + /// + /// translation along X (mm) + /// translation along Y (mm) + /// translation along Z (mm) + /// + /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & x \\ + /// 0 & 1 & 0 & y \\ + /// 0 & 0 & 1 & z \\ + /// 0 & 0 & 0 & 1 \\ + /// \end{bmatrix} \f$ + /// + static Matrix4x4 transl(double x, double y, double z); + + /// + /// Return the X-axis rotation matrix. + /// + /// Rotation around X axis (in radians). + /// + /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ + /// 0 & c_\theta & -s_\theta & 0 \\ + /// 0 & s_\theta & c_\theta & 0 \\ + /// 0 & 0 & 0 & 1 \\ + /// \end{bmatrix} \f$ + /// + static Matrix4x4 rotx(double rx); + + /// + /// Return a Y-axis rotation matrix + /// + /// Rotation around Y axis (in radians) + /// + /// \f$ roty(\theta) = \begin{bmatrix} c_\theta & 0 & s_\theta & 0 \\ + /// 0 & 1 & 0 & 0 \\ + /// -s_\theta & 0 & c_\theta & 0 \\ + /// 0 & 0 & 0 & 1 \\ + /// \end{bmatrix} \f$ + /// + static Matrix4x4 roty(double ry); + + /// + /// Return a Z-axis rotation matrix. + /// + /// Rotation around Z axis (in radians) + /// + /// \f$ rotz(\theta) = \begin{bmatrix} c_\theta & -s_\theta & 0 & 0 \\ + /// s_\theta & c_\theta & 0 & 0 \\ + /// 0 & 0 & 1 & 0 \\ + /// 0 & 0 & 0 & 1 \\ + /// \end{bmatrix} \f$ + /// + static Matrix4x4 rotz(double rz); + +#ifdef QT_GUI_LIB + /// Create a copy of the matrix + Matrix4x4(const BaseMatrix4x4& matrix); + + /// To String operator (use with qDebug() << tJoints; + inline operator QString() const { return ToString(); } + + /// Set the matrix given a XYZRPW string array (6-values) + bool FromString(const QString &str); + + /// \brief Retrieve a string representation of the pose + /// \param separator String separator + /// \param precision Number of decimals + /// \param in_xyzwpr if set to true (default), the pose will be represented as XYZWPR 6-dimensional array using ToXYZRPW + /// \return + QString ToString( + const ::QString& separator = QLatin1String(", "), + int precision = 3, + bool xyzrpw_only = false) const; + + Matrix4x4& operator=(const QMatrix4x4& matrix); +#endif + +private: + /// Flags if a matrix is not valid + double _valid; + + /// Copy of the data as a double array + mutable double _md[16]; +}; + +} // namespace robodk + + +#endif // ROBODK_MATRIX4X4_H diff --git a/robodk_interface/robodktypes.cpp b/robodk_interface/robodktypes.cpp index 14b6e22..acb3033 100644 --- a/robodk_interface/robodktypes.cpp +++ b/robodk_interface/robodktypes.cpp @@ -4,196 +4,6 @@ #include -//----------------------------------- tJoints class ------------------- -tJoints::tJoints(int ndofs) -{ - _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX); - for (int i=0; i < _nDOFs; i++) - { - _Values[i] = 0.0; - } -} - -tJoints::tJoints(const tJoints ©) -{ - SetValues(copy._Values, copy._nDOFs); -} - -tJoints::tJoints(const double *joints, int ndofs) -{ - SetValues(joints, ndofs); -} - -tJoints::tJoints(const float *joints, int ndofs) -{ - int ndofs_ok = qMin(ndofs, RDK_SIZE_JOINTS_MAX); - double jnts[RDK_SIZE_JOINTS_MAX]; - - for (int i=0; i < ndofs_ok; i++) - { - jnts[i] = joints[i]; - } - SetValues(jnts, ndofs_ok); -} - -tJoints::tJoints(const tMatrix2D *mat2d, int column, int ndofs) -{ - if (column >= Matrix2D_Size(mat2d, 2)) - { - _nDOFs = 0; - qDebug() << "Warning: tMatrix2D column outside range when creating joints"; - } - if (ndofs < 0) - { - ndofs = Matrix2D_Size(mat2d, 1); - } - _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX); - - double *ptr = Matrix2D_Get_col(mat2d, column); - SetValues(ptr, _nDOFs); -} - -tJoints::tJoints(const QString &str) -{ - _nDOFs = 0; - FromString(str); -} - -const double* tJoints::ValuesD() const -{ - return _Values; -} - -const float* tJoints::ValuesF() const -{ - for (int i = 0; i < RDK_SIZE_JOINTS_MAX; i++) - { - _ValuesF[i] = _Values[i]; - } - - return _ValuesF; -} - -#ifdef ROBODK_API_FLOATS -const float* tJoints::Values() const -{ - return ValuesF(); -} -#else -const double* tJoints::Values() const -{ - return _Values; -} -#endif - -double tJoints::Compare(const tJoints &other) const -{ - double sum_diff = 0.0; - for (int i = 0; i = 0) - { - _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX); - } - - for (int i = 0; i < _nDOFs; i++) - { - _Values[i] = values[i]; - } -} - -void tJoints::SetValues(const float *values, int ndofs) -{ - if (ndofs >= 0) - { - _nDOFs = qMin(ndofs, RDK_SIZE_JOINTS_MAX); - } - - for (int i = 0; i < _nDOFs; i++) - { - _Values[i] = values[i]; - } -} - -int tJoints::GetValues(double *values) -{ - for (int i = 0; i < _nDOFs; i++) - { - values[i] = _Values[i]; - } - - return _nDOFs; -} - -QString tJoints::ToString(const QString &separator, int precision) const -{ - QString values; - for (int i = 0; i < _nDOFs; i++) - { - if (i > 0) - { - values.append(separator); - } - values.append(QString::number(_Values[i], 'f', precision)); - } - return values; -} - -bool tJoints::FromString(const QString &str) -{ - const QLatin1Char separator(','); - - QString s = str; - s.replace(QLatin1Char(';'), separator); - s.replace(QLatin1Char('\t'), separator); - -#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) - const QString::SplitBehavior behavior = QString::SkipEmptyParts; -#else - const Qt::SplitBehavior behavior = Qt::SkipEmptyParts; -#endif - - QStringList jointList = s.split(separator, behavior); - _nDOFs = qMin(jointList.length(), RDK_SIZE_JOINTS_MAX); - for (int i = 0; i < _nDOFs; i++) - { - _Values[i] = jointList[i].trimmed().toDouble(); - } - return true; -} - -int tJoints::Length() const -{ - return _nDOFs; -} - -void tJoints::setLength(int new_length) -{ - if (new_length >= 0 && new_length < _nDOFs) - { - _nDOFs = new_length; - } -} - -bool tJoints::Valid() -{ - return _nDOFs > 0; -} -//--------------------------------------------------------------------- - - //----------------------------------- Mat class ----------------------- Mat transl(double x, double y, double z) { @@ -214,517 +24,6 @@ Mat rotz(double rz) { return Mat::rotz(rz); } - -Mat::Mat() - : QMatrix4x4() - , _valid(true) -{ - setToIdentity(); -} - -Mat::Mat(bool valid) - : QMatrix4x4() - , _valid(valid) -{ - setToIdentity(); -} - -Mat::Mat(const QMatrix4x4 &matrix) - : QMatrix4x4(matrix) - , _valid(true) -{ -} - -Mat::Mat(const Mat &matrix) - : QMatrix4x4(matrix) - , _valid(matrix._valid) -{ -} - -Mat::Mat(double nx, double ox, double ax, double tx, - double ny, double oy, double ay, double ty, - double nz, double oz, double az, double tz) - : QMatrix4x4(nx, ox, ax, tx, ny, oy, ay, ty, nz, oz, az, tz, 0.0, 0.0, 0.0, 1.0) - , _valid(true) -{ -} - -Mat::Mat(const double v[16]) - : QMatrix4x4(v[0], v[4], v[8], v[12], v[1], v[5], v[9], v[13], - v[2], v[6], v[10], v[14], v[3], v[7], v[11], v[15]) - , _valid(true) -{ -} - -Mat::Mat(const float v[16]) - : QMatrix4x4(v[0], v[4], v[8], v[12], v[1], v[5], v[9], v[13], - v[2], v[6], v[10], v[14], v[3], v[7], v[11], v[15]) - , _valid(true) -{ -} - -Mat::Mat(double x, double y, double z) - : QMatrix4x4(1.0, 0.0, 0.0, x, 0.0, 1.0, 0.0, y, 0.0, 0.0, 1.0, z, 0.0, 0.0, 0.0, 1.0) - , _valid(true) -{ -} - -Mat::~Mat() -{ -} - -void Mat::VX(tXYZ xyz) const -{ - xyz[0] = Get(0, 0); - xyz[1] = Get(1, 0); - xyz[2] = Get(2, 0); -} - -void Mat::VY(tXYZ xyz) const -{ - xyz[0] = Get(0, 1); - xyz[1] = Get(1, 1); - xyz[2] = Get(2, 1); -} - -void Mat::VZ(tXYZ xyz) const -{ - xyz[0] = Get(0, 2); - xyz[1] = Get(1, 2); - xyz[2] = Get(2, 2); -} - -void Mat::Pos(tXYZ xyz) const -{ - xyz[0] = Get(0, 3); - xyz[1] = Get(1, 3); - xyz[2] = Get(2, 3); -} - -void Mat::setVX(double x, double y, double z) -{ - Set(0,0, x); - Set(1,0, y); - Set(2,0, z); -} - -void Mat::setVY(double x, double y, double z) -{ - Set(0,1, x); - Set(1,1, y); - Set(2,1, z); -} - -void Mat::setVZ(double x, double y, double z) -{ - Set(0,2, x); - Set(1,2, y); - Set(2,2, z); -} - -void Mat::setPos(double x, double y, double z) -{ - Set(0,3, x); - Set(1,3, y); - Set(2,3, z); -} - -void Mat::setVX(double xyz[3]) -{ - Set(0,0, xyz[0]); - Set(1,0, xyz[1]); - Set(2,0, xyz[2]); -} - -void Mat::setVY(double xyz[3]) -{ - Set(0,1, xyz[0]); - Set(1,1, xyz[1]); - Set(2,1, xyz[2]); -} - -void Mat::setVZ(double xyz[3]) -{ - Set(0,2, xyz[0]); - Set(1,2, xyz[1]); - Set(2,2, xyz[2]); -} - -void Mat::setPos(double xyz[3]) -{ - Set(0,3, xyz[0]); - Set(1,3, xyz[1]); - Set(2,3, xyz[2]); -} - -void Mat::setValues(double pose[16]) -{ - Set(0,0, pose[0]); - Set(1,0, pose[1]); - Set(2,0, pose[2]); - Set(3,0, pose[3]); - - Set(0,1, pose[4]); - Set(1,1, pose[5]); - Set(2,1, pose[6]); - Set(3,1, pose[7]); - - Set(0,2, pose[8]); - Set(1,2, pose[9]); - Set(2,2, pose[10]); - Set(3,2, pose[11]); - - Set(0,3, pose[12]); - Set(1,3, pose[13]); - Set(2,3, pose[14]); - Set(3,3, pose[15]); -} - -void Mat::Set(int i, int j, double value) -{ - QVector4D rw(this->row(i)); - rw[j] = value; - setRow(i, rw); -} - -double Mat::Get(int i, int j) const -{ - return row(i)[j]; -} - -Mat Mat::inv() const -{ - return this->inverted(); -} - -bool Mat::isHomogeneous() const -{ - const bool debug_info = false; - tXYZ vx, vy, vz; - const double tol = 1e-7; - VX(vx); - VY(vy); - VZ(vz); - - if (fabs((double) DOT(vx,vy)) > tol) - { - if (debug_info) - { - qDebug() << "Vector X and Y are not perpendicular!"; - } - return false; - } - else if (fabs((double) DOT(vx,vz)) > tol) - { - if (debug_info) - { - qDebug() << "Vector X and Z are not perpendicular!"; - } - return false; - } - else if (fabs((double) DOT(vy,vz)) > tol) - { - if (debug_info) - { - qDebug() << "Vector Y and Z are not perpendicular!"; - } - return false; - } - else if (fabs((double) (NORM(vx)-1.0)) > tol) - { - if (debug_info) - { - qDebug() << "Vector X is not unitary! " << NORM(vx); - } - return false; - } - else if (fabs((double) (NORM(vy)-1.0)) > tol) - { - if (debug_info) - { - qDebug() << "Vector Y is not unitary! " << NORM(vy); - } - return false; - } - else if (fabs((double) (NORM(vz)-1.0)) > tol) - { - if (debug_info) - { - qDebug() << "Vector Z is not unitary! " << NORM(vz); - } - return false; - } - return true; -} - -bool Mat::MakeHomogeneous() -{ - tXYZ vx, vy, vz; - VX(vx); - VY(vy); - VZ(vz); - bool is_homogeneous = isHomogeneous(); - - NORMALIZE(vx); - CROSS(vz, vx, vy); - NORMALIZE(vz); - CROSS(vy, vz, vx); - NORMALIZE(vy); - setVX(vx); - setVY(vy); - setVZ(vz); - Set(3,0, 0.0); - Set(3,1, 0.0); - Set(3,2, 0.0); - Set(3,3, 1.0); - return !is_homogeneous; -} - -void Mat::ToXYZRPW(tXYZWPR xyzwpr) const -{ - double x = Get(0,3); - double y = Get(1,3); - double z = Get(2,3); - double w, p, r; - - if (Get(2,0) > (1.0 - 1e-6)) - { - p = -M_PI*0.5; - r = 0; - w = atan2(-Get(1,2), Get(1,1)); - } - else if (Get(2,0) < -1.0 + 1e-6) - { - p = 0.5*M_PI; - r = 0; - w = atan2(Get(1,2),Get(1,1)); - } - else - { - p = atan2(-Get(2, 0), sqrt(Get(0, 0) * Get(0, 0) + Get(1, 0) * Get(1, 0))); - w = atan2(Get(1, 0), Get(0, 0)); - r = atan2(Get(2, 1), Get(2, 2)); - } - - xyzwpr[0] = x; - xyzwpr[1] = y; - xyzwpr[2] = z; - xyzwpr[3] = r*180.0/M_PI; - xyzwpr[4] = p*180.0/M_PI; - xyzwpr[5] = w*180.0/M_PI; -} - -QString Mat::ToString(const QString &separator, int precision, bool xyzwpr_only) const -{ - if (!Valid()) - { - return "Mat(Invalid)"; - } - - QString str; - if (!isHomogeneous()) - { - str.append("Warning!! Pose is not homogeneous! Use Mat::MakeHomogeneous() to make this matrix homogeneous\n"); - } - - str.append("Mat(XYZRPW_2_Mat("); - - tXYZWPR xyzwpr; - ToXYZRPW(xyzwpr); - - for (int i = 0; i < 6; i++) - { - if (i > 0) - { - str.append(separator); - } - str.append(QString::number(xyzwpr[i], 'f', precision)); - } - str.append("))"); - - if (xyzwpr_only) - { - return str; - } - - str.append("\n"); - - for (int i = 0; i < 4; i++) - { - str.append("["); - for (int j = 0; j < 4; j++) - { - str.append(QString::number(row(i)[j], 'f', precision)); - if (j < 3) - { - str.append(separator); - } - } - str.append("];\n"); - } - return str; -} - -bool Mat::FromString(const QString &pose_str) -{ - QString pose_str2 = pose_str.trimmed(); - - const Qt::CaseSensitivity cs = Qt::CaseInsensitive; - if (pose_str2.startsWith("Mat(", cs)) - { - pose_str2.remove(0, 4); - pose_str2 = pose_str2.trimmed(); - } - - if (pose_str2.startsWith("XYZRPW_2_Mat(", cs)) - { - pose_str2.remove(0, 13); - pose_str2 = pose_str2.trimmed(); - } - - while (pose_str2.endsWith(')')) - { - pose_str2.chop(1); - } - - const QLatin1Char separator(','); - pose_str2.replace(QLatin1Char(';'), separator); - pose_str2.replace(QLatin1Char('\t'), separator); - -#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) - const QString::SplitBehavior behavior = QString::SkipEmptyParts; -#else - const Qt::SplitBehavior behavior = Qt::SkipEmptyParts; -#endif - - QStringList values_list = pose_str2.split(separator, behavior); - tXYZWPR xyzwpr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; - - if (values_list.length() < 6) - { - FromXYZRPW(xyzwpr); - return false; - } - - for (int i = 0; i < 6; i++) - { - xyzwpr[i] = values_list[i].trimmed().toDouble(); - } - - FromXYZRPW(xyzwpr); - return true; -} - -Mat Mat::XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w) -{ - double a = r * M_PI / 180.0; - double b = p * M_PI / 180.0; - double c = w * M_PI / 180.0; - double ca = cos(a); - double sa = sin(a); - double cb = cos(b); - double sb = sin(b); - double cc = cos(c); - double sc = sin(c); - return Mat(cb * cc, cc * sa * sb - ca * sc, sa * sc + ca * cc * sb, x, - cb * sc, ca * cc + sa * sb * sc, ca * sb * sc - cc * sa, y, - -sb, cb * sa, ca * cb, z); -} - -Mat Mat::XYZRPW_2_Mat(tXYZWPR xyzwpr) -{ - return XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], xyzwpr[3], xyzwpr[4], xyzwpr[5]); -} - -void Mat::FromXYZRPW(tXYZWPR xyzwpr) -{ - Mat newmat = Mat::XYZRPW_2_Mat(xyzwpr[0], xyzwpr[1], xyzwpr[2], - xyzwpr[3], xyzwpr[4], xyzwpr[5]); - - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - this->Set(i, j, newmat.Get(i, j)); - } - } -} - -const double* Mat::ValuesD() const -{ - for(int i = 0; i < 16; ++i) - { - _ddata16[i] = constData()[i]; - } - return _ddata16; -} - -const float* Mat::ValuesF() const -{ - return constData(); -} - -#ifdef ROBODK_API_FLOATS -const float* Mat::Values() const -{ - return constData(); -} -#else -const double* Mat::Values() const -{ - return ValuesD(); -} -#endif - -void Mat::Values(double data[16]) const -{ - for(int i = 0; i < 16; ++i) - { - data[i] = constData()[i]; - } -} - -void Mat::Values(float data[16]) const -{ - for(int i = 0; i < 16; ++i) - { - data[i] = constData()[i]; - } -} - -bool Mat::Valid() const -{ - return _valid; -} - -Mat Mat::transl(double x, double y, double z) -{ - Mat mat; - mat.setToIdentity(); - mat.setPos(x, y, z); - return mat; -} - -Mat Mat::rotx(double rx) -{ - double cx = cos(rx); - double sx = sin(rx); - return Mat(1, 0, 0, 0, 0, cx, -sx, 0, 0, sx, cx, 0); -} - -Mat Mat::roty(double ry) -{ - double cy = cos(ry); - double sy = sin(ry); - return Mat(cy, 0, sy, 0, 0, 1, 0, 0, -sy, 0, cy, 0); -} - -Mat Mat::rotz(double rz) -{ - double cz = cos(rz); - double sz = sin(rz); - return Mat(cz, -sz, 0, 0, sz, cz, 0, 0, 0, 0, 1, 0); -} //--------------------------------------------------------------------- diff --git a/robodk_interface/robodktypes.h b/robodk_interface/robodktypes.h index 3776f53..24d35b6 100644 --- a/robodk_interface/robodktypes.h +++ b/robodk_interface/robodktypes.h @@ -6,6 +6,9 @@ #include #include +#include "matrix4x4.h" +#include "joints.h" + #ifndef M_PI #define M_PI 3.14159265358979323846264338327950288 @@ -233,120 +236,7 @@ void Matrix2D_Save(QTextStream *st, tMatrix2D *emx, bool csv=false); void Matrix2D_Load(QDataStream *st, tMatrix2D **emx); -//--------------------- Joints class ----------------------- - -/// The tJoints class represents a joint position of a robot (robot axes). -class tJoints { - -public: - /// \brief tJoints - /// \param ndofs number of robot joint axes or degrees of freedom - tJoints(int ndofs = 0); - - /// \brief Set joint values given a double array and the number of joint values - /// \param joints Pointer to the joint values - /// \param ndofs Number of joints - tJoints(const double *joints, int ndofs = 0); - - /// \brief Set joint values given a float array and the number of joint values - /// \param joints Pointer to the joint values - /// \param ndofs Number of joints - tJoints(const float *joints, int ndofs = 0); - - /// \brief Create a copy of an object - /// \param jnts - tJoints(const tJoints &jnts); - - /// \brief Create joint values given a 2D matrix and the column selecting the desired values - /// \param mat2d - /// \param column - /// \param ndofs - tJoints(const tMatrix2D *mat2d, int column=0, int ndofs=-1); - - /// \brief Convert a string to joint values - /// \param str Comma separated joint values (spaces or tabs are also accepted) - tJoints(const QString &str); - - /// To String operator (use with qDebug() << tJoints; - operator QString() const { return ToString(); } - - /// \brief Joint values - /// \return Returns a pointer to the joint data array (doubles) - const double *ValuesD() const; - - /// \brief Joint values - /// \return Returns a pointer to the joint data array (floats) - const float *ValuesF() const; - -#ifdef ROBODK_API_FLOATS - /// \brief Joint values - /// \return Returns a pointer to the joint data array (doubles or floats if ROBODK_API_FLOATS is defined) - const float *Values() const; -#else - /// \brief Joint values - /// \return Returns a pointer to the joint data array (doubles or floats if ROBODK_API_FLOATS is defined) - const double *Values() const; -#endif - - - - double Compare(const tJoints &other) const; - - /// \brief - /// \return Data same as Values. The only difference is that the array pointer is not const. This is provided for backwards compatibility. - double *Data(); - - /// \brief Number of joint axes of the robot (or degrees of freedom) - /// \return - int Length() const; - - /// Set the length of the array (only shrinking the array is allowed) - void setLength(int new_length); - - /// \brief Check if the joints are valid. For example, when we request the Inverse kinematics and there is no solution the joints will not be valid. - /// (for example, an invalid result after calling class: IItem::SolveIK returns a non valid joints) - /// \return true if it has 1 degree of freedom or more - bool Valid(); - - /// \brief GetValues - /// \param joints joint values in deg or mm - /// \return returns the number of degrees of freedom - int GetValues(double *joints); - - /// \brief Set the joint values in deg or mm. You can also important provide the number of degrees of freedom (6 for a 6 axis robot). - /// \param joints joint values in deg or mm - /// \param ndofs number of degrees of freedom (number of axes or joints) - void SetValues(const double *joints, int ndofs = -1); - - /// \brief Set the joint values in deg or mm (floats). You can also important provide the number of degrees of freedom (6 for a 6 axis robot). - /// \param joints joint values in deg or mm - /// \param ndofs number of degrees of freedom (number of axes or joints) - void SetValues(const float *joints, int ndofs = -1); - - /// \brief Retrieve a string representation of the joint values. - /// \param separator String to add between consecutive joint values - /// \param precision Number of decimals - /// \return string as a QString - QString ToString(const QString &separator=", ", int precision = 3) const ; - - /// \brief Set the joint values given a comma-separated string. Tabs and spaces are also allowed. - /// \param str string. Such as "10, 20, 30, 40, 50, 60" - /// \return false if parsing the string failed. True otherwise. - bool FromString(const QString &str); - - -public: - /// number of degrees of freedom - int _nDOFs; - - /// joint values (doubles, used to store the joint values) - double _Values[RDK_SIZE_JOINTS_MAX]; - - /// joint values (floats, used to return a copy as a float pointer) - mutable float _ValuesF[RDK_SIZE_JOINTS_MAX]; -}; - - +typedef robodk::Joints tJoints; /// \brief The Mat class represents a 4x4 pose matrix. The main purpose of this object is to represent a pose in the 3D space (position and orientation). @@ -358,269 +248,7 @@ class tJoints { /// n_y & o_y & a_y & y \\ /// n_z & o_z & a_z & z \\ /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ -class Mat : public QMatrix4x4 { - -public: - - /// Create the identity matrix - Mat(); - - /// Create a valid or an invalid matrix - Mat(bool valid); - - /// Create a copy of the matrix - Mat(const QMatrix4x4 &matrix); - - /// \brief Create a copy of the matrix - /// \param matrix - Mat(const Mat &matrix); - - /// - /// Matrix class constructor for a 4x4 homogeneous matrix given N, O, A & T vectors - /// - /// Matrix[0,0] - /// Matrix[0,1] - /// Matrix[0,2] - /// Matrix[0,3] - /// Matrix[1,0] - /// Matrix[1,1] - /// Matrix[1,2] - /// Matrix[1,3] - /// Matrix[2,0] - /// Matrix[2,1] - /// Matrix[2,2] - /// Matrix[2,3] - /// \f$ \begin{bmatrix} n_x & o_x & a_x & x \\ - /// n_y & o_y & a_y & y \\ - /// n_z & o_z & a_z & z \\ - /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ - /// - Mat(double nx, double ox, double ax, double tx, double ny, double oy, double ay, double ty, double nz, double oz, double az, double tz); - - /// \brief Create a homogeneoux matrix given a one dimensional 16-value array (doubles) - /// \param values [nx,ny,nz,0, ox,oy,oz,0, ax,ay,az,0, tx,ty,tz,1] - /// \f$ \begin{bmatrix} n_x & o_x & a_x & x \\ - /// n_y & o_y & a_y & y \\ - /// n_z & o_z & a_z & z \\ - /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ - /// - Mat(const double values[16]); - - /// \brief Create a homogeneoux matrix given a one dimensional 16-value array (floats) - /// \param values [nx,ny,nz,0, ox,oy,oz,0, ax,ay,az,0, tx,ty,tz,1] - /// \f$ transl(x,y,z) rotx(r) roty(p) rotz(w) = \\ - /// \begin{bmatrix} n_x & o_x & a_x & x \\ - /// n_y & o_y & a_y & y \\ - /// n_z & o_z & a_z & z \\ - /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ - /// - Mat(const float values[16]); - - /// - /// Create a translation matrix. - /// - /// translation along X (mm) - /// translation along Y (mm) - /// translation along Z (mm) - /// - /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & x \\ - /// 0 & 1 & 0 & y \\ - /// 0 & 0 & 1 & z \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// - Mat(double x, double y, double z); - - ~Mat(); - - /// To String operator (use with qDebug() << tJoints; - operator QString() const { return ToString(); } - - /// Set the X vector values (N vector) - void setVX(double x, double y, double z); - - /// Set the Y vector values (O vector) - void setVY(double x, double y, double z); - - /// Set the Z vector values (A vector) - void setVZ(double x, double y, double z); - - /// Set the position (T position) in mm - void setPos(double x, double y, double z); - - /// Set the X vector values (N vector) - void setVX(double xyz[3]); - - /// Set the Y vector values (O vector) - void setVY(double xyz[3]); - - /// Set the Z vector values (A vector) - void setVZ(double xyz[3]); - - /// Set the position (T position) in mm - void setPos(double xyz[3]); - - /// Set the pose values - void setValues(double pose[16]); - - /// Get the X vector (N vector) - void VX(tXYZ xyz) const; - - /// Get the Y vector (O vector) - void VY(tXYZ xyz) const; - - /// Get the Z vector (A vector) - void VZ(tXYZ xyz) const; - - /// Get the position (T position), in mm - void Pos(tXYZ xyz) const; - - /// \brief Set a matrix value - /// \param r row - /// \param c column - /// \param value value - void Set(int r, int c, double value); - - /// \brief Get a matrix value - /// \param r row - /// \param c column - /// \return value - double Get(int r, int c) const; - - /// Invert the pose (homogeneous matrix assumed) - Mat inv() const; - - /// Returns true if the matrix is homogeneous, otherwise it returns false - bool isHomogeneous() const; - - /// Forces 4x4 matrix to be homogeneous (vx,vy,vz must be unitary vectors and respect: vx x vy = vz). Returns True if the matrix was not homogeneous and it was be modified to make it homogeneous. - bool MakeHomogeneous(); - - //------ Pose to xyzrpw and xyzrpw to pose------------ - - /// - /// Calculates the equivalent position and euler angles ([x,y,z,r,p,w] vector) of the given pose - /// Note: transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) - /// See also: FromXYZRPW() - /// - /// XYZWPR translation and rotation in mm and degrees - void ToXYZRPW(tXYZWPR xyzwpr) const; - - /// \brief Retrieve a string representation of the pose - /// \param separator String separator - /// \param precision Number of decimals - /// \param in_xyzwpr if set to true (default), the pose will be represented as XYZWPR 6-dimensional array using ToXYZRPW - /// \return - QString ToString(const QString &separator=", ", int precision = 3, bool xyzrpw_only = false) const; - - /// Set the matrix given a XYZRPW string array (6-values) - bool FromString(const QString &str); - - /// - /// Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) - /// The result is the same as: - ///
- /// H = transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) - ///
- /// Homogeneous matrix (4x4) - void FromXYZRPW(tXYZWPR xyzwpr); - - /// - /// Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) - /// The result is the same as: - ///
- /// H = transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) - ///
- /// Homogeneous matrix (4x4) - static Mat XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w); - static Mat XYZRPW_2_Mat(tXYZWPR xyzwpr); - - /// Get a pointer to the 16-digit double array. - const double* ValuesD() const; - - /// Get a pointer to the 16-digit array as an array of floats. - const float* ValuesF() const; - -#ifdef ROBODK_API_FLOATS - /// Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined). - const float* Values() const; -#else - /// Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined). - const double* Values() const; -#endif - - /// Copy the 16-values of the 4x4 matrix to a double array. - void Values(double values[16]) const; - - /// Copy the 16-values of the 4x4 matrix to a double array. - void Values(float values[16]) const; - - /// Check if the matrix is valid - bool Valid() const; - - /// - /// Return a translation matrix. - /// - /// translation along X (mm) - /// translation along Y (mm) - /// translation along Z (mm) - /// - /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & x \\ - /// 0 & 1 & 0 & y \\ - /// 0 & 0 & 1 & z \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// - static Mat transl(double x, double y, double z); - - /// - /// Return the X-axis rotation matrix. - /// - /// Rotation around X axis (in radians). - /// - /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ - /// 0 & c_\theta & -s_\theta & 0 \\ - /// 0 & s_\theta & c_\theta & 0 \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// - static Mat rotx(double rx); - - /// - /// Return a Y-axis rotation matrix - /// - /// Rotation around Y axis (in radians) - /// - /// \f$ roty(\theta) = \begin{bmatrix} c_\theta & 0 & s_\theta & 0 \\ - /// 0 & 1 & 0 & 0 \\ - /// -s_\theta & 0 & c_\theta & 0 \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// - static Mat roty(double ry); - - /// - /// Return a Z-axis rotation matrix. - /// - /// Rotation around Z axis (in radians) - /// - /// \f$ rotz(\theta) = \begin{bmatrix} c_\theta & -s_\theta & 0 & 0 \\ - /// s_\theta & c_\theta & 0 & 0 \\ - /// 0 & 0 & 1 & 0 \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// - static Mat rotz(double rz); - -private: - /// Flags if a matrix is not valid. - double _valid; - -// this is a dummy variable to easily obtain a pointer to a 16-double-array for matrix multiplications -private: - /// Copy of the data as a double array. - mutable double _ddata16[16]; -}; +typedef robodk::Matrix4x4 Mat; /// Translation matrix class: Mat::transl. Mat transl(double x, double y, double z); diff --git a/robodk_interface/vector3.cpp b/robodk_interface/vector3.cpp new file mode 100644 index 0000000..9839dd6 --- /dev/null +++ b/robodk_interface/vector3.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#include "vector3.h" + +#include + + +namespace robodk +{ + +Vector3::Vector3(double x, double y, double z) +{ + _v[0] = x; + _v[1] = y; + _v[2] = z; +} + +double Vector3::length() const +{ + return std::sqrt(_v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2]); +} + +void Vector3::normalize() +{ + double len = length(); + _v[0] /= len; + _v[1] /= len; + _v[2] /= len; +} + +double Vector3::dotProduct(const Vector3& v1, const Vector3& v2) +{ + return v1._v[0] * v2._v[0] + v1._v[1] * v2._v[1] + v1._v[2] * v2._v[2]; +} + +Vector3 Vector3::crossProduct(const Vector3& v1, const Vector3& v2) +{ + return Vector3( + v1._v[1] * v2._v[2] - v1._v[2] * v2._v[1], + v1._v[2] * v2._v[0] - v1._v[0] * v2._v[2], + v1._v[0] * v2._v[1] - v1._v[1] * v2._v[0]); +} + + +} // namespace robodk diff --git a/robodk_interface/vector3.h b/robodk_interface/vector3.h new file mode 100644 index 0000000..32272aa --- /dev/null +++ b/robodk_interface/vector3.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_VECTOR3_H +#define ROBODK_VECTOR3_H + + +#include + + +namespace robodk +{ + +class Vector3 +{ +public: + Vector3() = default; + Vector3(double x, double y, double z); + Vector3(const Vector3& v) = default; + + double length() const; + + void normalize(); + + inline double x() const { return _v[0]; } + inline double y() const { return _v[1]; } + inline double z() const { return _v[2]; } + + inline void setX(double x) { _v[0] = x; } + inline void setY(double y) { _v[0] = y; } + inline void setZ(double z) { _v[0] = z; } + + inline const double& operator[](size_t i) const { return _v[i]; } + inline double& operator[](size_t i) { return _v[i]; } + + static double dotProduct(const Vector3& v1, const Vector3& v2); + static Vector3 crossProduct(const Vector3& v1, const Vector3& v2); + + Vector3& operator=(const Vector3& v) = default; + +private: + double _v[3] = {0.0, 0.0, 0.0}; +}; + +} // namespace robodk + + +#endif // ROBODK_VECTOR3_H From 03910846bd811ea72d2b6341330c1746bff8b39a Mon Sep 17 00:00:00 2001 From: VDm Date: Sat, 28 Jun 2025 00:26:26 +0400 Subject: [PATCH 02/11] docs(robodk_interface): update descriptions of Matrix4x4 constructors --- robodk_interface/matrix4x4.h | 143 ++++++++++++++++++++------------- robodk_interface/robodktypes.h | 31 ++++--- 2 files changed, 109 insertions(+), 65 deletions(-) diff --git a/robodk_interface/matrix4x4.h b/robodk_interface/matrix4x4.h index 49fb385..e974c82 100644 --- a/robodk_interface/matrix4x4.h +++ b/robodk_interface/matrix4x4.h @@ -50,73 +50,105 @@ typedef ::QMatrix4x4 BaseMatrix4x4; namespace robodk { +/*! + \class Matrix4x4 + \brief The Matrix4x4 class represents a 4x4 transformation matrix in 3D space. + + The Matrix4x4 class in general is treated as a row-major matrix, in that the + constructors and operator() functions take data in row-major format, as is + familiar in C-style usage. + + Internally the data is stored as column-major format. + + When using these functions be aware that they return data in \b column-major format: + - data() + - constData() +*/ class Matrix4x4 : public BaseMatrix4x4 { public: - /// Create the identity matrix + /*! + Constructs an identity matrix. + */ Matrix4x4(); - /// Create a valid or an invalid matrix + /*! + Constructs a valid or an invalid identity matrix. + */ explicit Matrix4x4(bool valid); - /// Create a copy of the matrix + /*! + Constructs this Matrix4x4 object as a copy of matrix. + */ Matrix4x4(const Matrix4x4& matrix); - /// \brief Create a homogeneoux matrix given a one dimensional 16-value array (doubles) - /// \param values [nx,ny,nz,0, ox,oy,oz,0, ax,ay,az,0, tx,ty,tz,1] - /// \f$ \begin{bmatrix} n_x & o_x & a_x & x \\ - /// n_y & o_y & a_y & y \\ - /// n_z & o_z & a_z & z \\ - /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix from the given 16 double-precision \a values. + + The contents of the array \a values is assumed to be in \b column-major order. + + \param values + \f$ \begin{bmatrix} + v_1 & v_2 & v_3 & v_4 & v_5 & v_6 & v_7 & v_8 & + v_9 & v_{10} & v_{11} & v_{12} & v_{13} & v_{14} & v_{15} & v_{16} + \end{bmatrix} \f$ + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + v_1 & v_5 & v_9 & v_{13} \\ + v_2 & v_6 & v_{10} & v_{14} \\ + v_3 & v_7 & v_{11} & v_{15} \\ + v_4 & v_8 & v_{12} & v_{16} + \end{bmatrix} \f$ + */ Matrix4x4(const double* values); - /// \brief Create a homogeneoux matrix given a one dimensional 16-value array (floats) - /// \param values [nx,ny,nz,0, ox,oy,oz,0, ax,ay,az,0, tx,ty,tz,1] - /// \f$ transl(x,y,z) rotx(r) roty(p) rotz(w) = \\ - /// \begin{bmatrix} n_x & o_x & a_x & x \\ - /// n_y & o_y & a_y & y \\ - /// n_z & o_z & a_z & z \\ - /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix from the given 16 single-precision \a values. + + The contents of the array \a values is assumed to be in \b column-major order. + + \param values + \f$ \begin{bmatrix} + v_1 & v_2 & v_3 & v_4 & v_5 & v_6 & v_7 & v_8 & + v_9 & v_{10} & v_{11} & v_{12} & v_{13} & v_{14} & v_{15} & v_{16} + \end{bmatrix} \f$ + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + v_1 & v_5 & v_9 & v_{13} \\ + v_2 & v_6 & v_{10} & v_{14} \\ + v_3 & v_7 & v_{11} & v_{15} \\ + v_4 & v_8 & v_{12} & v_{16} + \end{bmatrix} \f$ + */ Matrix4x4(const float* values); - /// - /// Create a translation matrix. - /// - /// translation along X (mm) - /// translation along Y (mm) - /// translation along Z (mm) - /// - /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & x \\ - /// 0 & 1 & 0 & y \\ - /// 0 & 0 & 1 & z \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix that translates coordinates by the components + \a x, \a y, and \a z. + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + 1 & 0 & 0 & x \\ + 0 & 1 & 0 & y \\ + 0 & 0 & 1 & z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} \f$ + */ Matrix4x4(double x, double y, double z); - - /// - /// Matrix class constructor for a 4x4 homogeneous matrix given N, O, A & T vectors - /// - /// Matrix[0,0] - /// Matrix[0,1] - /// Matrix[0,2] - /// Matrix[0,3] - /// Matrix[1,0] - /// Matrix[1,1] - /// Matrix[1,2] - /// Matrix[1,3] - /// Matrix[2,0] - /// Matrix[2,1] - /// Matrix[2,2] - /// Matrix[2,3] - /// \f$ \begin{bmatrix} n_x & o_x & a_x & x \\ - /// n_y & o_y & a_y & y \\ - /// n_z & o_z & a_z & z \\ - /// 0 & 0 & 0 & 1 \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix from the \a N, \a O, \a A, \a T vector components. + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + n_x & o_x & a_x & t_x \\ + n_y & o_y & a_y & t_y \\ + n_z & o_z & a_z & t_z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} \f$ + */ Matrix4x4( double nx, double ox, @@ -341,11 +373,12 @@ class Matrix4x4 : public BaseMatrix4x4 #endif private: - /// Flags if a matrix is not valid - double _valid; + /*! \cond */ - /// Copy of the data as a double array + double _valid; mutable double _md[16]; + + /*! \endcond */ }; } // namespace robodk diff --git a/robodk_interface/robodktypes.h b/robodk_interface/robodktypes.h index 24d35b6..ea60188 100644 --- a/robodk_interface/robodktypes.h +++ b/robodk_interface/robodktypes.h @@ -238,16 +238,27 @@ void Matrix2D_Load(QDataStream *st, tMatrix2D **emx); typedef robodk::Joints tJoints; - -/// \brief The Mat class represents a 4x4 pose matrix. The main purpose of this object is to represent a pose in the 3D space (position and orientation). -/// In other words, a pose is a 4x4 matrix that represents the position and orientation of one reference frame with respect to another one, in the 3D space. -/// Poses are commonly used in robotics to place objects, reference frames and targets with respect to each other. -///
-/// \f$ transl(x,y,z) rotx(r) roty(p) rotz(w) = \\ -/// \begin{bmatrix} n_x & o_x & a_x & x \\ -/// n_y & o_y & a_y & y \\ -/// n_z & o_z & a_z & z \\ -/// 0 & 0 & 0 & 1 \end{bmatrix} \f$ +/*! + \typedef Mat + \brief The Mat class represents a 4x4 pose matrix. + + The main purpose of this object is to represent a pose + in the 3D space (position and orientation). + + In other words, a pose is a 4x4 matrix that represents + the position and orientation of one reference frame with + respect to another one, in the 3D space. + + Poses are commonly used in robotics to place objects, + reference frames and targets with respect to each other. + +
+ \f$ transl(x,y,z) rotx(r) roty(p) rotz(w) = \\ + \begin{bmatrix} n_x & o_x & a_x & x \\ + n_y & o_y & a_y & y \\ + n_z & o_z & a_z & z \\ + 0 & 0 & 0 & 1 \end{bmatrix} \f$ +*/ typedef robodk::Matrix4x4 Mat; /// Translation matrix class: Mat::transl. From 72306113df46c4017539b874496d5a4e80f963b2 Mon Sep 17 00:00:00 2001 From: VDm Date: Mon, 30 Jun 2025 15:31:54 +0400 Subject: [PATCH 03/11] docs(robodk_interface): update description of Matrix4x4 --- robodk_interface/matrix4x4.cpp | 18 +- robodk_interface/matrix4x4.h | 361 ++++++++++++++++++++++----------- 2 files changed, 252 insertions(+), 127 deletions(-) diff --git a/robodk_interface/matrix4x4.cpp b/robodk_interface/matrix4x4.cpp index 4a02228..cd7d403 100644 --- a/robodk_interface/matrix4x4.cpp +++ b/robodk_interface/matrix4x4.cpp @@ -267,16 +267,14 @@ void Matrix4x4::setValues(const double* values) Set(3,3, values[15]); } -void Matrix4x4::Set(int i, int j, double value) +void Matrix4x4::Set(int row, int column, double value) { - QVector4D rw(this->row(i)); - rw[j] = value; - setRow(i, rw); + (*this)(row, column) = value; } -double Matrix4x4::Get(int i, int j) const +double Matrix4x4::Get(int row, int column) const { - return row(i)[j]; + return (*this)(row, column); } Matrix4x4 Matrix4x4::inv() const @@ -441,7 +439,7 @@ const double* Matrix4x4::Values() const } #endif -void Matrix4x4::Values(double data[16]) const +void Matrix4x4::Values(double* data) const { for(int i = 0; i < 16; ++i) { @@ -449,7 +447,7 @@ void Matrix4x4::Values(double data[16]) const } } -void Matrix4x4::Values(float data[16]) const +void Matrix4x4::Values(float* data) const { for(int i = 0; i < 16; ++i) { @@ -555,7 +553,7 @@ bool Matrix4x4::FromString(const QString &pose_str) return true; } -QString Matrix4x4::ToString(const QString &separator, int precision, bool xyzwpr_only) const +QString Matrix4x4::ToString(const QString &separator, int precision, bool xyzrpwOnly) const { if (!Valid()) { @@ -583,7 +581,7 @@ QString Matrix4x4::ToString(const QString &separator, int precision, bool xyzwpr } str.append("))"); - if (xyzwpr_only) + if (xyzrpwOnly) { return str; } diff --git a/robodk_interface/matrix4x4.h b/robodk_interface/matrix4x4.h index e974c82..2367006 100644 --- a/robodk_interface/matrix4x4.h +++ b/robodk_interface/matrix4x4.h @@ -78,7 +78,7 @@ class Matrix4x4 : public BaseMatrix4x4 explicit Matrix4x4(bool valid); /*! - Constructs this Matrix4x4 object as a copy of matrix. + Constructs this Matrix4x4 object as a copy of \a matrix. */ Matrix4x4(const Matrix4x4& matrix); @@ -165,210 +165,337 @@ class Matrix4x4 : public BaseMatrix4x4 ~Matrix4x4() = default; - /// Set the X vector values (N vector) + /*! + Sets the X vector (N vector). + */ void setVX(const Vector3& n); - /// Set the Y vector values (O vector) + /*! + Sets the Y vector (O vector). + */ void setVY(const Vector3& o); - /// Set the Z vector values (A vector) + /*! + Sets the Z vector (A vector). + */ void setVZ(const Vector3& a); - /// Set the X vector values (N vector) + /*! + Sets the X vector values (N vector). + */ void setVX(double x, double y, double z); - /// Set the Y vector values (O vector) + /*! + Sets the Y vector values (O vector). + */ void setVY(double x, double y, double z); - /// Set the Z vector values (A vector) + /*! + Sets the Z vector values (A vector). + */ void setVZ(double x, double y, double z); - /// Set the position (T position) in mm + /*! + Sets the position (T). + */ void setPos(double x, double y, double z); - /// Set the X vector values (N vector) + /*! + Sets the X vector values (N vector). + */ void setVX(const double* xyz); - /// Set the Y vector values (O vector) + /*! + Sets the Y vector values (O vector). + */ void setVY(const double* xyz); - /// Set the Z vector values (A vector) + /*! + Sets the Z vector values (A vector). + */ void setVZ(const double* xyz); - /// Set the position (T position) in mm + /*! + Sets the position (T). + */ void setPos(const double* xyz); - /// Set the pose values + /*! + \brief Sets the elements of matrix from the given 16 double-precision \a values. + + The contents of the array \a values is assumed to be in \b column-major order. + + \f$ \begin{bmatrix} + v_1 & v_5 & v_9 & v_{13} \\ + v_2 & v_6 & v_{10} & v_{14} \\ + v_3 & v_7 & v_{11} & v_{15} \\ + v_4 & v_8 & v_{12} & v_{16} + \end{bmatrix} \f$ + + \param values + \f$ \begin{bmatrix} + v_1 & v_2 & v_3 & v_4 & v_5 & v_6 & v_7 & v_8 & + v_9 & v_{10} & v_{11} & v_{12} & v_{13} & v_{14} & v_{15} & v_{16} + \end{bmatrix} \f$ + */ void setValues(const double* values); - /// Get the X vector (N vector) + /*! + Returns the X vector (N vector). + */ Vector3 vx() const; - /// Get the Y vector (O vector) + /*! + Returns the Y vector (O vector). + */ Vector3 vy() const; - /// Get the Z vector (A vector) + /*! + Returns the Z vector (A vector). + */ Vector3 vz() const; - /// Get the X vector (N vector) + /*! + Writes the X vector (N vector) into array of 3 double-precision \a xyz values. + */ void VX(double* xyz) const; - /// Get the Y vector (O vector) + /*! + Writes the Y vector (O vector) into array of 3 double-precision \a xyz values. + */ void VY(double* xyz) const; - /// Get the Z vector (A vector) + /*! + Writes the Z vector (A vector) into array of 3 double-precision \a xyz values. + */ void VZ(double* xyz) const; - /// Get the position (T position), in mm + /*! + Writes the position (T vector) into array of 3 double-precision \a xyz values. + */ void Pos(double* xyz) const; - /// \brief Set a matrix value - /// \param r row - /// \param c column - /// \param value value - void Set(int r, int c, double value); + /*! + Sets a new \a value to the element at position (\a row, \a column) in this matrix. + */ + void Set(int row, int column, double value); - /// \brief Get a matrix value - /// \param r row - /// \param c column - /// \return value - double Get(int r, int c) const; + /*! + Returns the value of the element at position (\a row, \a column) in this matrix. + */ + double Get(int row, int column) const; - /// Invert the pose (homogeneous matrix assumed) + /*! + Returns the inverse of this matrix. Returns the identity if + this matrix cannot be inverted; i.e. determinant() is zero. + */ Matrix4x4 inv() const; - /// Returns true if the matrix is homogeneous, otherwise it returns false + /*! + Returns \c true if the matrix is homogeneous; false otherwise. + */ bool isHomogeneous() const; - /// Forces 4x4 matrix to be homogeneous (vx,vy,vz must be unitary vectors and respect: vx x vy = vz). Returns True if the matrix was not homogeneous and it was be modified to make it homogeneous. + /*! + \brief Forces this matrix to be homogeneous. + The \a vx, \a vy, \a vz must be unitary vectors and respect: vx x vy = vz. + Returns \c true if the matrix was not homogeneous and it was modified to be homogeneous. + */ bool MakeHomogeneous(); - /// - /// Calculates the equivalent position and euler angles ([x,y,z,r,p,w] vector) of the given pose - /// Note: transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) - /// See also: FromXYZRPW() - /// - /// XYZWPR translation and rotation in mm and degrees + /*! + \brief Calculates the position and euler angles ([x,y,z,r,p,w] vector) from this matrix. + + Note: transl(x, y, z) * rotz(w * pi / 180) * roty(p * pi / 180) * rotx(r * pi / 180) + + \returns The XYZWPR translation and rotation in the length units and degrees. + \sa FromXYZRPW() + */ void ToXYZRPW(double* xyzwpr) const; - /// - /// Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) - /// The result is the same as: - ///
- /// H = transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) - ///
- /// Homogeneous matrix (4x4) + /*! + \brief Calculates this matrix from the position and euler angles ([x,y,z,r,p,w] vector). + + The result is the same as: + H = transl(x, y, z) * rotz(w * pi / 180) * roty(p * pi / 180) * rotx(r * pi / 180) + + \sa ToXYZRPW() + */ void FromXYZRPW(const double* xyzwpr); - /// - /// Calculates the pose from the position and euler angles ([x,y,z,r,p,w] vector) - /// The result is the same as: - ///
- /// H = transl(x,y,z)*rotz(w*pi/180)*roty(p*pi/180)*rotx(r*pi/180) - ///
- /// Homogeneous matrix (4x4) + + /*! + \brief Constructs a matrix from the position and euler angles ([x,y,z,r,p,w] vector). + + The result is the same as: + H = transl(x, y, z) * rotz(w * pi / 180) * roty(p * pi / 180) * rotx(r * pi / 180) + + \returns New homogeneous Matrix4x4 object. + + \sa FromXYZRPW() + */ static Matrix4x4 XYZRPW_2_Mat(double x, double y, double z, double r, double p, double w); + + /*! + \brief Constructs a matrix from the position and euler angles ([x,y,z,r,p,w] vector). + + The result is the same as: + H = transl(x, y, z) * rotz(w * pi / 180) * roty(p * pi / 180) * rotx(r * pi / 180) + + \returns New homogeneous Matrix4x4 object. + + \sa FromXYZRPW() + */ static Matrix4x4 XYZRPW_2_Mat(const double* xyzwpr); - /// Get a pointer to the 16-digit double array. + /*! + Returns a constant pointer to the raw data of this matrix as 16 double-precision numbers. + This raw data is stored in column-major format. + + \sa Values(), ValuesF(), constData() + */ const double* ValuesD() const; - /// Get a pointer to the 16-digit array as an array of floats. + /*! + Returns a constant pointer to the raw data of this matrix as 16 single-precision numbers. + This raw data is stored in column-major format. + + \sa Values(), ValuesD(), constData() + */ const float* ValuesF() const; #ifdef ROBODK_API_FLOATS - /// Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined). + /*! + Returns a constant pointer to the raw data of this matrix as + 16 double- or single-precision numbers. + This raw data is stored in column-major format. + + \sa ValuesF(), ValuesD(), constData() + */ const float* Values() const; #else - /// Get a pointer to the 16-digit array (doubles or floats if ROBODK_API_FLOATS is defined). + /*! + Returns a constant pointer to the raw data of this matrix as + 16 double- or single-precision numbers. + This raw data is stored in column-major format. + + \sa ValuesF(), ValuesD(), constData() + */ const double* Values() const; #endif - /// Copy the 16-values of the 4x4 matrix to a double array. - void Values(double values[16]) const; + /*! + Writes the contents of this matrix into array of 16 double-precision \a values. - /// Copy the 16-values of the 4x4 matrix to a double array. - void Values(float values[16]) const; + \sa Values(), ValuesF(), ValuesD(), constData() + */ + void Values(double* values) const; - /// Check if the matrix is valid + /*! + Writes the contents of this matrix into array of 16 single-precision \a values. + + \sa Values(), ValuesF(), ValuesD(), constData() + */ + void Values(float* values) const; + + /*! + Returns \c true if the matrix is marked as valid; false otherwise. + */ bool Valid() const; + /*! + Sets this Matrix4x4 object as a copy of \a matrix. + */ Matrix4x4& operator=(const Matrix4x4& matrix); - /// - /// Return a translation matrix. - /// - /// translation along X (mm) - /// translation along Y (mm) - /// translation along Z (mm) - /// - /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & x \\ - /// 0 & 1 & 0 & y \\ - /// 0 & 0 & 1 & z \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix that translates coordinates by the components + \a x, \a y, and \a z. + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + 1 & 0 & 0 & x \\ + 0 & 1 & 0 & y \\ + 0 & 0 & 1 & z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} \f$ + */ static Matrix4x4 transl(double x, double y, double z); - /// - /// Return the X-axis rotation matrix. - /// - /// Rotation around X axis (in radians). - /// - /// \f$ rotx(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ - /// 0 & c_\theta & -s_\theta & 0 \\ - /// 0 & s_\theta & c_\theta & 0 \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix that rotates coordinates around X axis. + \param rx rotation angle in radians. + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & \cos rx & - \sin rx & 0 \\ + 0 & \sin rx & \cos rx & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} \f$ + */ static Matrix4x4 rotx(double rx); - /// - /// Return a Y-axis rotation matrix - /// - /// Rotation around Y axis (in radians) - /// - /// \f$ roty(\theta) = \begin{bmatrix} c_\theta & 0 & s_\theta & 0 \\ - /// 0 & 1 & 0 & 0 \\ - /// -s_\theta & 0 & c_\theta & 0 \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix that rotates coordinates around Y axis. + \param ry rotation angle in radians. + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + \cos ry & 0 & \sin ry & 0 \\ + 0 & 1 & 0 & 0 \\ + - \sin ry & 0 & \cos ry & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} \f$ + */ static Matrix4x4 roty(double ry); - /// - /// Return a Z-axis rotation matrix. - /// - /// Rotation around Z axis (in radians) - /// - /// \f$ rotz(\theta) = \begin{bmatrix} c_\theta & -s_\theta & 0 & 0 \\ - /// s_\theta & c_\theta & 0 & 0 \\ - /// 0 & 0 & 1 & 0 \\ - /// 0 & 0 & 0 & 1 \\ - /// \end{bmatrix} \f$ - /// + /*! + \brief Constructs a matrix that rotates coordinates around Z axis. + \param rz rotation angle in radians. + + \returns New Matrix4x4 object with the following structure: + \f$ \begin{bmatrix} + \cos rz & - \sin rz & 0 & 0 \\ + \sin rz & \cos rx & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} \f$ + */ static Matrix4x4 rotz(double rz); #ifdef QT_GUI_LIB - /// Create a copy of the matrix + /*! + Constructs this Matrix4x4 object as a copy of \a matrix. + */ Matrix4x4(const BaseMatrix4x4& matrix); - /// To String operator (use with qDebug() << tJoints; + /*! + Returns string representation of this matrix. + \sa ToString() + */ inline operator QString() const { return ToString(); } /// Set the matrix given a XYZRPW string array (6-values) - bool FromString(const QString &str); + bool FromString(const QString& str); + - /// \brief Retrieve a string representation of the pose - /// \param separator String separator - /// \param precision Number of decimals - /// \param in_xyzwpr if set to true (default), the pose will be represented as XYZWPR 6-dimensional array using ToXYZRPW - /// \return + /*! + Returns string representation of this matrix with each element separated by + the given \a separator (which can be an empty string). + \param separator string that separates elements of the matrix. + \param precision represents the number of digits after the decimal point. + \param xyzrpwOnly if set to \s true, the pose will be represented as + XYZWPR 6-dimensional array using ToXYZRPW(). + */ QString ToString( const ::QString& separator = QLatin1String(", "), int precision = 3, - bool xyzrpw_only = false) const; + bool xyzrpwOnly = false) const; + /*! + Sets this Matrix4x4 object as a copy of \a matrix. + */ Matrix4x4& operator=(const QMatrix4x4& matrix); #endif From 8788f51aad5c8562f1859994f2f50575ede07c53 Mon Sep 17 00:00:00 2001 From: VDm Date: Mon, 28 Jul 2025 12:58:08 +0400 Subject: [PATCH 04/11] chore(build): add robodk_interface.pri --- Plugin-OPC-UA/PluginOPCUA.pro | 21 +-------------- PluginAppLoader/AppLoader.pro | 24 +++-------------- PluginAttachObject/PluginAttachObject.pro | 21 +-------------- PluginAttachView/PluginAttachView.pro | 21 +-------------- PluginBallbarTracker/PluginBallbarTracker.pro | 21 +-------------- .../PluginCollisionSensor.pro | 21 +-------------- PluginEmbedding/PluginEmbedding.pro | 12 +++------ PluginExample/PluginExample.pro | 22 +--------------- PluginLVDT/PluginLVDT.pro | 22 +--------------- PluginLockTCP/PluginLockTCP.pro | 23 +--------------- PluginOpenGL-Shaders/PluginChip8Opengl.pro | 21 +-------------- PluginOpenGL/PluginOpengl.pro | 21 +-------------- PluginRealTime/PluginRealTime.pro | 21 +-------------- PluginRoboUI/PluginRoboUI.pro | 26 +++++-------------- PluginRobotPilot/PluginRobotPilot.pro | 21 +-------------- robodk_interface/robodk_interface.pri | 21 +++++++++++++++ 16 files changed, 45 insertions(+), 294 deletions(-) create mode 100644 robodk_interface/robodk_interface.pri diff --git a/Plugin-OPC-UA/PluginOPCUA.pro b/Plugin-OPC-UA/PluginOPCUA.pro index c1c0611..632958f 100644 --- a/Plugin-OPC-UA/PluginOPCUA.pro +++ b/Plugin-OPC-UA/PluginOPCUA.pro @@ -118,26 +118,7 @@ FORMS += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginAppLoader/AppLoader.pro b/PluginAppLoader/AppLoader.pro index 14eb1af..4c8f5b6 100644 --- a/PluginAppLoader/AppLoader.pro +++ b/PluginAppLoader/AppLoader.pro @@ -90,6 +90,8 @@ CONFIG(release, debug|release) { #-------------------------- # Add header and source files (use File->New File or Project and add your files) # This can be modified manually or automatically by Qt Creator +INCLUDEPATH += ./zip + HEADERS += \ applistdelegate.h \ apploader.h \ @@ -117,25 +119,5 @@ FORMS += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface ./zip +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- - diff --git a/PluginAttachObject/PluginAttachObject.pro b/PluginAttachObject/PluginAttachObject.pro index 9633351..5d2663f 100644 --- a/PluginAttachObject/PluginAttachObject.pro +++ b/PluginAttachObject/PluginAttachObject.pro @@ -104,24 +104,5 @@ SOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginAttachView/PluginAttachView.pro b/PluginAttachView/PluginAttachView.pro index adab489..20b0abe 100644 --- a/PluginAttachView/PluginAttachView.pro +++ b/PluginAttachView/PluginAttachView.pro @@ -103,24 +103,5 @@ SOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginBallbarTracker/PluginBallbarTracker.pro b/PluginBallbarTracker/PluginBallbarTracker.pro index 84be89b..0f1b897 100644 --- a/PluginBallbarTracker/PluginBallbarTracker.pro +++ b/PluginBallbarTracker/PluginBallbarTracker.pro @@ -104,24 +104,5 @@ SOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginCollisionSensor/PluginCollisionSensor.pro b/PluginCollisionSensor/PluginCollisionSensor.pro index 425dc1f..2413cd1 100644 --- a/PluginCollisionSensor/PluginCollisionSensor.pro +++ b/PluginCollisionSensor/PluginCollisionSensor.pro @@ -103,24 +103,5 @@ SOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginEmbedding/PluginEmbedding.pro b/PluginEmbedding/PluginEmbedding.pro index 96b701a..952f531 100644 --- a/PluginEmbedding/PluginEmbedding.pro +++ b/PluginEmbedding/PluginEmbedding.pro @@ -96,17 +96,11 @@ SOURCES += \ pluginembedding.cpp \ pluginform.cpp +FORMS += \ + pluginform.ui #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- - -FORMS += \ - pluginform.ui diff --git a/PluginExample/PluginExample.pro b/PluginExample/PluginExample.pro index 5080534..4b3d3db 100644 --- a/PluginExample/PluginExample.pro +++ b/PluginExample/PluginExample.pro @@ -104,28 +104,8 @@ RESOURCES += \ resources1.qrc - #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginLVDT/PluginLVDT.pro b/PluginLVDT/PluginLVDT.pro index a1e0e52..ef49480 100644 --- a/PluginLVDT/PluginLVDT.pro +++ b/PluginLVDT/PluginLVDT.pro @@ -99,28 +99,8 @@ SOURCES += \ - #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginLockTCP/PluginLockTCP.pro b/PluginLockTCP/PluginLockTCP.pro index d3778e0..bd42114 100644 --- a/PluginLockTCP/PluginLockTCP.pro +++ b/PluginLockTCP/PluginLockTCP.pro @@ -100,29 +100,8 @@ SOURCES += \ PluginLockTCP.cpp - - #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginOpenGL-Shaders/PluginChip8Opengl.pro b/PluginOpenGL-Shaders/PluginChip8Opengl.pro index ebe4000..8f6bd14 100644 --- a/PluginOpenGL-Shaders/PluginChip8Opengl.pro +++ b/PluginOpenGL-Shaders/PluginChip8Opengl.pro @@ -137,26 +137,7 @@ SOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginOpenGL/PluginOpengl.pro b/PluginOpenGL/PluginOpengl.pro index fb9ae10..77f7724 100644 --- a/PluginOpenGL/PluginOpengl.pro +++ b/PluginOpenGL/PluginOpengl.pro @@ -122,24 +122,5 @@ SOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginRealTime/PluginRealTime.pro b/PluginRealTime/PluginRealTime.pro index 9a764af..3138225 100644 --- a/PluginRealTime/PluginRealTime.pro +++ b/PluginRealTime/PluginRealTime.pro @@ -107,24 +107,5 @@ RESOURCES += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/PluginRoboUI/PluginRoboUI.pro b/PluginRoboUI/PluginRoboUI.pro index aa1af39..56c23a8 100644 --- a/PluginRoboUI/PluginRoboUI.pro +++ b/PluginRoboUI/PluginRoboUI.pro @@ -65,7 +65,6 @@ exists( "$$PWD/../../destdir_rdk_plugins.pri" ) { INCLUDEPATH += \ $${PROJECT_ROOT}/imgui \ - $${PROJECT_ROOT}/../robodk_interface SOURCES += \ imgui/imgui.cpp \ @@ -86,24 +85,11 @@ HEADERS += \ imgui/imstb_truetype.h \ roboui.h -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - RESOURCES += \ roboui.qrc + +#-------------------------- +# Header and source files required by any RoboDK plugin +# Do not change this section, make sure to have the robodk_interface folder up one folder +include($$PWD/../robodk_interface/robodk_interface.pri) +#-------------------------- diff --git a/PluginRobotPilot/PluginRobotPilot.pro b/PluginRobotPilot/PluginRobotPilot.pro index 1cfc02b..5b08fe6 100644 --- a/PluginRobotPilot/PluginRobotPilot.pro +++ b/PluginRobotPilot/PluginRobotPilot.pro @@ -107,24 +107,5 @@ FORMS += \ #-------------------------- # Header and source files required by any RoboDK plugin # Do not change this section, make sure to have the robodk_interface folder up one folder -HEADERS += \ - ../robodk_interface/iitem.h \ - ../robodk_interface/irobodk.h\ - ../robodk_interface/iapprobodk.h \ - ../robodk_interface/robodktypes.h \ - ../robodk_interface/robodktools.h \ - ../robodk_interface/matrix4x4.h \ - ../robodk_interface/vector3.h \ - ../robodk_interface/deprecated.h \ - ../robodk_interface/constants.h \ - ../robodk_interface/joints.h \ - -SOURCES += \ - ../robodk_interface/robodktools.cpp \ - ../robodk_interface/robodktypes.cpp \ - ../robodk_interface/matrix4x4.cpp \ - ../robodk_interface/vector3.cpp \ - ../robodk_interface/joints.cpp - -INCLUDEPATH += ../robodk_interface +include($$PWD/../robodk_interface/robodk_interface.pri) #-------------------------- diff --git a/robodk_interface/robodk_interface.pri b/robodk_interface/robodk_interface.pri new file mode 100644 index 0000000..0b03874 --- /dev/null +++ b/robodk_interface/robodk_interface.pri @@ -0,0 +1,21 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/constants.h \ + $$PWD/deprecated.h \ + $$PWD/iapprobodk.h \ + $$PWD/iitem.h \ + $$PWD/irobodk.h \ + $$PWD/joints.h \ + $$PWD/matrix4x4.h \ + $$PWD/robodktools.h \ + $$PWD/robodktypes.h \ + $$PWD/robodk_interface.h \ + $$PWD/vector3.h + +SOURCES += \ + $$PWD/joints.cpp \ + $$PWD/matrix4x4.cpp \ + $$PWD/robodktools.cpp \ + $$PWD/robodktypes.cpp \ + $$PWD/vector3.cpp From 0128e59851c581a03c8a7ecf204cb96010fb4b66 Mon Sep 17 00:00:00 2001 From: VDm Date: Mon, 28 Jul 2025 13:58:31 +0400 Subject: [PATCH 05/11] style(robodk_interface): update Matrix4x4 and Vector3 classes --- robodk_interface/matrix4x4.cpp | 186 ++++++++++++++++----------------- robodk_interface/matrix4x4.h | 66 +++++++----- robodk_interface/vector3.cpp | 14 +-- robodk_interface/vector3.h | 99 +++++++++++++++--- 4 files changed, 225 insertions(+), 140 deletions(-) diff --git a/robodk_interface/matrix4x4.cpp b/robodk_interface/matrix4x4.cpp index cd7d403..01bd809 100644 --- a/robodk_interface/matrix4x4.cpp +++ b/robodk_interface/matrix4x4.cpp @@ -115,105 +115,105 @@ Matrix4x4::Matrix4x4( { } -void Matrix4x4::setVX(const Vector3& n) +void Matrix4x4::SetVX(const Vector3& n) { - (*this)(0, 0) = n.x(); - (*this)(1, 0) = n.y(); - (*this)(2, 0) = n.z(); + (*this)(0, 0) = n.X(); + (*this)(1, 0) = n.Y(); + (*this)(2, 0) = n.Z(); } -void Matrix4x4::setVY(const Vector3& o) +void Matrix4x4::SetVY(const Vector3& o) { - (*this)(0, 1) = o.x(); - (*this)(1, 1) = o.y(); - (*this)(2, 1) = o.z(); + (*this)(0, 1) = o.X(); + (*this)(1, 1) = o.Y(); + (*this)(2, 1) = o.Z(); } -void Matrix4x4::setVZ(const Vector3& a) +void Matrix4x4::SetVZ(const Vector3& a) { - (*this)(0, 2) = a.x(); - (*this)(1, 2) = a.y(); - (*this)(2, 2) = a.z(); + (*this)(0, 2) = a.X(); + (*this)(1, 2) = a.Y(); + (*this)(2, 2) = a.Z(); } -void Matrix4x4::setVX(double x, double y, double z) +void Matrix4x4::SetVX(double x, double y, double z) { Set(0,0, x); Set(1,0, y); Set(2,0, z); } -void Matrix4x4::setVY(double x, double y, double z) +void Matrix4x4::SetVY(double x, double y, double z) { Set(0,1, x); Set(1,1, y); Set(2,1, z); } -void Matrix4x4::setVZ(double x, double y, double z) +void Matrix4x4::SetVZ(double x, double y, double z) { Set(0,2, x); Set(1,2, y); Set(2,2, z); } -void Matrix4x4::setPos(double x, double y, double z) +void Matrix4x4::SetPos(double x, double y, double z) { - Set(0,3, x); - Set(1,3, y); - Set(2,3, z); + Set(0, 3, x); + Set(1, 3, y); + Set(2, 3, z); } -void Matrix4x4::setVX(const double* xyz) +void Matrix4x4::SetVX(const double* xyz) { - Set(0,0, xyz[0]); - Set(1,0, xyz[1]); - Set(2,0, xyz[2]); + Set(0, 0, xyz[0]); + Set(1, 0, xyz[1]); + Set(2, 0, xyz[2]); } -void Matrix4x4::setVY(const double* xyz) +void Matrix4x4::SetVY(const double* xyz) { - Set(0,1, xyz[0]); - Set(1,1, xyz[1]); - Set(2,1, xyz[2]); + Set(0, 1, xyz[0]); + Set(1, 1, xyz[1]); + Set(2, 1, xyz[2]); } -void Matrix4x4::setVZ(const double* xyz) +void Matrix4x4::SetVZ(const double* xyz) { - Set(0,2, xyz[0]); - Set(1,2, xyz[1]); - Set(2,2, xyz[2]); + Set(0, 2, xyz[0]); + Set(1, 2, xyz[1]); + Set(2, 2, xyz[2]); } -void Matrix4x4::setPos(const double* xyz) +void Matrix4x4::SetPos(const double* xyz) { - Set(0,3, xyz[0]); - Set(1,3, xyz[1]); - Set(2,3, xyz[2]); + Set(0, 3, xyz[0]); + Set(1, 3, xyz[1]); + Set(2, 3, xyz[2]); } -Vector3 Matrix4x4::vx() const +Vector3 Matrix4x4::VX() const { return Vector3( - (*this)(0, 0), - (*this)(1, 0), - (*this)(2, 0)); + Get(0, 0), + Get(1, 0), + Get(2, 0)); } -Vector3 Matrix4x4::vy() const +Vector3 Matrix4x4::VY() const { return Vector3( - (*this)(0, 1), - (*this)(1, 1), - (*this)(2, 1)); + Get(0, 1), + Get(1, 1), + Get(2, 1)); } -Vector3 Matrix4x4::vz() const +Vector3 Matrix4x4::VZ() const { return Vector3( - (*this)(0, 2), - (*this)(1, 2), - (*this)(2, 2)); + Get(0, 2), + Get(1, 2), + Get(2, 2)); } void Matrix4x4::VX(double* xyz) const @@ -244,27 +244,27 @@ void Matrix4x4::Pos(double* xyz) const xyz[2] = Get(2, 3); } -void Matrix4x4::setValues(const double* values) +void Matrix4x4::SetValues(const double* values) { - Set(0,0, values[0]); - Set(1,0, values[1]); - Set(2,0, values[2]); - Set(3,0, values[3]); + Set(0, 0, values[0]); + Set(1, 0, values[1]); + Set(2, 0, values[2]); + Set(3, 0, values[3]); - Set(0,1, values[4]); - Set(1,1, values[5]); - Set(2,1, values[6]); - Set(3,1, values[7]); + Set(0, 1, values[4]); + Set(1, 1, values[5]); + Set(2, 1, values[6]); + Set(3, 1, values[7]); - Set(0,2, values[8]); - Set(1,2, values[9]); - Set(2,2, values[10]); - Set(3,2, values[11]); + Set(0, 2, values[8]); + Set(1, 2, values[9]); + Set(2, 2, values[10]); + Set(3, 2, values[11]); - Set(0,3, values[12]); - Set(1,3, values[13]); - Set(2,3, values[14]); - Set(3,3, values[15]); + Set(0, 3, values[12]); + Set(1, 3, values[13]); + Set(2, 3, values[14]); + Set(3, 3, values[15]); } void Matrix4x4::Set(int row, int column, double value) @@ -277,40 +277,40 @@ double Matrix4x4::Get(int row, int column) const return (*this)(row, column); } -Matrix4x4 Matrix4x4::inv() const +Matrix4x4 Matrix4x4::Inverted(bool* invertible) const { - return this->inverted(); + return this->inverted(invertible); } -bool Matrix4x4::isHomogeneous() const +bool Matrix4x4::IsHomogeneous() const { - auto tx = vx(); - auto ty = vy(); - auto tz = vz(); + auto tx = VX(); + auto ty = VY(); + auto tz = VZ(); const double tol = 1e-7; - if (std::fabs(Vector3::dotProduct(tx, ty)) > tol) + if (std::fabs(Vector3::DotProduct(tx, ty)) > tol) { return false; } - else if (std::fabs(Vector3::dotProduct(tx, tz)) > tol) + else if (std::fabs(Vector3::DotProduct(tx, tz)) > tol) { return false; } - else if (std::fabs(Vector3::dotProduct(ty, tz)) > tol) + else if (std::fabs(Vector3::DotProduct(ty, tz)) > tol) { return false; } - else if (std::fabs(tx.length() - 1.0) > tol) + else if (std::fabs(tx.Length() - 1.0) > tol) { return false; } - else if (std::fabs(ty.length() - 1.0) > tol) + else if (std::fabs(ty.Length() - 1.0) > tol) { return false; } - else if (std::fabs(tz.length() - 1.0) > tol) + else if (std::fabs(tz.Length() - 1.0) > tol) { return false; } @@ -320,21 +320,21 @@ bool Matrix4x4::isHomogeneous() const bool Matrix4x4::MakeHomogeneous() { - auto tx = vx(); - auto ty = vy(); - auto tz = vz(); + auto tx = VX(); + auto ty = VY(); + auto tz = VZ(); - bool result = isHomogeneous(); + bool result = IsHomogeneous(); - tx.normalize(); - tz = Vector3::crossProduct(tx, ty); - tz.normalize(); - ty = Vector3::crossProduct(tz, tx); - ty.normalize(); + tx.Normalize(); + tz = Vector3::CrossProduct(tx, ty); + tz.Normalize(); + ty = Vector3::CrossProduct(tz, tx); + ty.Normalize(); - setVX(tx); - setVY(ty); - setVZ(tz); + SetVX(tx); + SetVY(ty); + SetVZ(tz); (*this)(3, 0) = 0.0f; (*this)(3, 1) = 0.0f; @@ -346,9 +346,9 @@ bool Matrix4x4::MakeHomogeneous() void Matrix4x4::ToXYZRPW(double* xyzwpr) const { - double x = Get(0,3); - double y = Get(1,3); - double z = Get(2,3); + double x = Get(0, 3); + double y = Get(1, 3); + double z = Get(2, 3); double w, p, r; if (Get(2,0) > (1.0 - 1e-6)) @@ -471,7 +471,7 @@ Matrix4x4 Matrix4x4::transl(double x, double y, double z) { Matrix4x4 mat; mat.setToIdentity(); - mat.setPos(x, y, z); + mat.SetPos(x, y, z); return mat; } @@ -561,7 +561,7 @@ QString Matrix4x4::ToString(const QString &separator, int precision, bool xyzrpw } QString str; - if (!isHomogeneous()) + if (!IsHomogeneous()) { str.append("Warning!! Pose is not homogeneous! Use Matrix4x4::MakeHomogeneous() to make this matrix homogeneous\n"); } diff --git a/robodk_interface/matrix4x4.h b/robodk_interface/matrix4x4.h index 2367006..a9da6cc 100644 --- a/robodk_interface/matrix4x4.h +++ b/robodk_interface/matrix4x4.h @@ -31,6 +31,7 @@ #define ROBODK_MATRIX4X4_H +#include "deprecated.h" #include "vector3.h" @@ -42,9 +43,9 @@ namespace robodk { typedef ::QMatrix4x4 BaseMatrix4x4; } -#else +#else // QT_GUI_LIB #error "This class cannot yet be used without the Qt Framework" -#endif +#endif // QT_GUI_LIB namespace robodk @@ -61,8 +62,9 @@ namespace robodk Internally the data is stored as column-major format. When using these functions be aware that they return data in \b column-major format: - - data() - - constData() + - Values() + - ValuesD() + - ValuesF() */ class Matrix4x4 : public BaseMatrix4x4 { @@ -168,57 +170,57 @@ class Matrix4x4 : public BaseMatrix4x4 /*! Sets the X vector (N vector). */ - void setVX(const Vector3& n); + void SetVX(const Vector3& n); /*! Sets the Y vector (O vector). */ - void setVY(const Vector3& o); + void SetVY(const Vector3& o); /*! Sets the Z vector (A vector). */ - void setVZ(const Vector3& a); + void SetVZ(const Vector3& a); /*! Sets the X vector values (N vector). */ - void setVX(double x, double y, double z); + void SetVX(double x, double y, double z); /*! Sets the Y vector values (O vector). */ - void setVY(double x, double y, double z); + void SetVY(double x, double y, double z); /*! Sets the Z vector values (A vector). */ - void setVZ(double x, double y, double z); + void SetVZ(double x, double y, double z); /*! Sets the position (T). */ - void setPos(double x, double y, double z); + void SetPos(double x, double y, double z); /*! Sets the X vector values (N vector). */ - void setVX(const double* xyz); + void SetVX(const double* xyz); /*! Sets the Y vector values (O vector). */ - void setVY(const double* xyz); + void SetVY(const double* xyz); /*! Sets the Z vector values (A vector). */ - void setVZ(const double* xyz); + void SetVZ(const double* xyz); /*! Sets the position (T). */ - void setPos(const double* xyz); + void SetPos(const double* xyz); /*! \brief Sets the elements of matrix from the given 16 double-precision \a values. @@ -238,22 +240,22 @@ class Matrix4x4 : public BaseMatrix4x4 v_9 & v_{10} & v_{11} & v_{12} & v_{13} & v_{14} & v_{15} & v_{16} \end{bmatrix} \f$ */ - void setValues(const double* values); + void SetValues(const double* values); /*! Returns the X vector (N vector). */ - Vector3 vx() const; + Vector3 VX() const; /*! Returns the Y vector (O vector). */ - Vector3 vy() const; + Vector3 VY() const; /*! Returns the Z vector (A vector). */ - Vector3 vz() const; + Vector3 VZ() const; /*! Writes the X vector (N vector) into array of 3 double-precision \a xyz values. @@ -289,12 +291,12 @@ class Matrix4x4 : public BaseMatrix4x4 Returns the inverse of this matrix. Returns the identity if this matrix cannot be inverted; i.e. determinant() is zero. */ - Matrix4x4 inv() const; + Matrix4x4 Inverted(bool* invertible = nullptr) const; /*! Returns \c true if the matrix is homogeneous; false otherwise. */ - bool isHomogeneous() const; + bool IsHomogeneous() const; /*! \brief Forces this matrix to be homogeneous. @@ -352,7 +354,7 @@ class Matrix4x4 : public BaseMatrix4x4 Returns a constant pointer to the raw data of this matrix as 16 double-precision numbers. This raw data is stored in column-major format. - \sa Values(), ValuesF(), constData() + \sa Values(), ValuesF() */ const double* ValuesD() const; @@ -360,7 +362,7 @@ class Matrix4x4 : public BaseMatrix4x4 Returns a constant pointer to the raw data of this matrix as 16 single-precision numbers. This raw data is stored in column-major format. - \sa Values(), ValuesD(), constData() + \sa Values(), ValuesD() */ const float* ValuesF() const; @@ -370,7 +372,7 @@ class Matrix4x4 : public BaseMatrix4x4 16 double- or single-precision numbers. This raw data is stored in column-major format. - \sa ValuesF(), ValuesD(), constData() + \sa ValuesF(), ValuesD() */ const float* Values() const; #else @@ -379,7 +381,7 @@ class Matrix4x4 : public BaseMatrix4x4 16 double- or single-precision numbers. This raw data is stored in column-major format. - \sa ValuesF(), ValuesD(), constData() + \sa ValuesF(), ValuesD() */ const double* Values() const; #endif @@ -387,14 +389,14 @@ class Matrix4x4 : public BaseMatrix4x4 /*! Writes the contents of this matrix into array of 16 double-precision \a values. - \sa Values(), ValuesF(), ValuesD(), constData() + \sa Values(), ValuesF(), ValuesD() */ void Values(double* values) const; /*! Writes the contents of this matrix into array of 16 single-precision \a values. - \sa Values(), ValuesF(), ValuesD(), constData() + \sa Values(), ValuesF(), ValuesD() */ void Values(float* values) const; @@ -499,6 +501,16 @@ class Matrix4x4 : public BaseMatrix4x4 Matrix4x4& operator=(const QMatrix4x4& matrix); #endif + /* Deprecated methods */ +public: + ROBODK_DEPRECATED("Use Inverted() instead") + inline Matrix4x4 inv() { return Inverted(); } + + ROBODK_DEPRECATED("Use SetPos() instead") + inline void setPos(double x, double y, double z) { SetPos(x, y, z); } + + + private: /*! \cond */ diff --git a/robodk_interface/vector3.cpp b/robodk_interface/vector3.cpp index 9839dd6..3fa2801 100644 --- a/robodk_interface/vector3.cpp +++ b/robodk_interface/vector3.cpp @@ -42,25 +42,28 @@ Vector3::Vector3(double x, double y, double z) _v[2] = z; } -double Vector3::length() const +double Vector3::Length() const { return std::sqrt(_v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2]); } -void Vector3::normalize() +void Vector3::Normalize() { - double len = length(); + double len = Length(); + if (std::abs(len) <= 0.000000000001) + return; + _v[0] /= len; _v[1] /= len; _v[2] /= len; } -double Vector3::dotProduct(const Vector3& v1, const Vector3& v2) +double Vector3::DotProduct(const Vector3& v1, const Vector3& v2) { return v1._v[0] * v2._v[0] + v1._v[1] * v2._v[1] + v1._v[2] * v2._v[2]; } -Vector3 Vector3::crossProduct(const Vector3& v1, const Vector3& v2) +Vector3 Vector3::CrossProduct(const Vector3& v1, const Vector3& v2) { return Vector3( v1._v[1] * v2._v[2] - v1._v[2] * v2._v[1], @@ -68,5 +71,4 @@ Vector3 Vector3::crossProduct(const Vector3& v1, const Vector3& v2) v1._v[0] * v2._v[1] - v1._v[1] * v2._v[0]); } - } // namespace robodk diff --git a/robodk_interface/vector3.h b/robodk_interface/vector3.h index 32272aa..0ca9ee9 100644 --- a/robodk_interface/vector3.h +++ b/robodk_interface/vector3.h @@ -37,35 +37,106 @@ namespace robodk { +/*! + \class Vector3 + \brief The Vector3 class represents a vector or vertex in 3D space. + + Vectors are one of the main building blocks of 3D representation and + drawing. They consist of three coordinates, traditionally called + x, y, and z. +*/ class Vector3 { public: + /*! + Constructs a null vector, i.e. with coordinates (0, 0, 0). + */ Vector3() = default; - Vector3(double x, double y, double z); - Vector3(const Vector3& v) = default; - - double length() const; - void normalize(); - - inline double x() const { return _v[0]; } - inline double y() const { return _v[1]; } - inline double z() const { return _v[2]; } + /*! + Constructs a vector with coordinates (\a x, \a y, \a z). + */ + Vector3(double x, double y, double z); - inline void setX(double x) { _v[0] = x; } - inline void setY(double y) { _v[0] = y; } - inline void setZ(double z) { _v[0] = z; } + /*! + Constructs a vector object as a copy of \a v. + */ + Vector3(const Vector3& v) = default; + /*! + Returns the length of the vector from the origin. + */ + double Length() const; + + /*! + Normalizes the currect vector in place. Nothing happens if this + vector is a null vector or the length of the vector is very close to 1. + */ + void Normalize(); + + /*! + Returns the x coordinate of this vector. + */ + inline double X() const { return _v[0]; } + + /*! + Returns the y coordinate of this vector. + */ + inline double Y() const { return _v[1]; } + + /*! + Returns the z coordinate of this vector. + */ + inline double Z() const { return _v[2]; } + + /*! + Sets the x coordinate of this vector to the given \a x coordinate. + */ + inline void SetX(double x) { _v[0] = x; } + + /*! + Sets the y coordinate of this vector to the given \a y coordinate. + */ + inline void SetY(double y) { _v[0] = y; } + + /*! + Sets the z coordinate of this vector to the given \a z coordinate. + */ + inline void SetZ(double z) { _v[0] = z; } + + /*! + Returns the component of the vector at index position \a i. + */ inline const double& operator[](size_t i) const { return _v[i]; } + + /*! + Returns the component of the vector at index position \a i + as a modifiable reference. + */ inline double& operator[](size_t i) { return _v[i]; } - static double dotProduct(const Vector3& v1, const Vector3& v2); - static Vector3 crossProduct(const Vector3& v1, const Vector3& v2); + /*! + Returns the dot product of \a v1 and \a v2. + */ + static double DotProduct(const Vector3& v1, const Vector3& v2); + + /*! + Returns the cross-product of vectors \a v1 and \a v2, which corresponds + to the normal vector of a plane defined by \a v1 and \a v2. + */ + static Vector3 CrossProduct(const Vector3& v1, const Vector3& v2); + /*! + Sets this Vector3 object as a copy of \a v. + */ Vector3& operator=(const Vector3& v) = default; private: + /*! \cond */ + double _v[3] = {0.0, 0.0, 0.0}; + + /*! \endcond */ }; } // namespace robodk From 3cbd8ed94665495ad43a132acd5fc23f59c46a58 Mon Sep 17 00:00:00 2001 From: VDm Date: Mon, 28 Jul 2025 18:26:13 +0400 Subject: [PATCH 06/11] feat(robodk_interface): convert tMatrix2D into robodk::legacy::Matrix2D (RDK-4895) --- robodk_interface/joints.cpp | 28 +- robodk_interface/joints.h | 16 +- robodk_interface/legacymatrix2d.cpp | 350 +++++++++++++++++++++++++ robodk_interface/legacymatrix2d.h | 191 ++++++++++++++ robodk_interface/robodk_interface.pri | 2 + robodk_interface/robodktypes.cpp | 353 -------------------------- robodk_interface/robodktypes.h | 275 ++++++++++++-------- 7 files changed, 732 insertions(+), 483 deletions(-) create mode 100644 robodk_interface/legacymatrix2d.cpp create mode 100644 robodk_interface/legacymatrix2d.h diff --git a/robodk_interface/joints.cpp b/robodk_interface/joints.cpp index 8c8af1d..e9258ef 100644 --- a/robodk_interface/joints.cpp +++ b/robodk_interface/joints.cpp @@ -32,7 +32,9 @@ #include #include -#include "robodktypes.h" +#include + +#include "legacymatrix2d.h" namespace robodk @@ -47,7 +49,7 @@ Joints::Joints() Joints::Joints(int ndofs) { - _dofCount = std::min(ndofs, maximumJoints); + _dofCount = std::min(ndofs, MaximumJoints); for (int i = 0; i < _dofCount; i++) { _joints[i] = 0.0; @@ -61,8 +63,8 @@ Joints::Joints(const double *joints, int ndofs) Joints::Joints(const float *joints, int ndofs) { - int ndofs_ok = std::min(ndofs, maximumJoints); - double jnts[maximumJoints]; + int ndofs_ok = std::min(ndofs, MaximumJoints); + double jnts[MaximumJoints]; for (int i=0; i < ndofs_ok; i++) { @@ -71,19 +73,19 @@ Joints::Joints(const float *joints, int ndofs) SetValues(jnts, ndofs_ok); } -Joints::Joints(const tMatrix2D *mat2d, int column, int ndofs) +Joints::Joints(const legacy::Matrix2D *mat2d, int column, int ndofs) { - if (column >= Matrix2D_Size(mat2d, 2)) + if (column >= Matrix2D_GetDimension(mat2d, 2)) { _dofCount = 0; } if (ndofs < 0) { - ndofs = Matrix2D_Size(mat2d, 1); + ndofs = Matrix2D_GetDimension(mat2d, 1); } - _dofCount = qMin(ndofs, RDK_SIZE_JOINTS_MAX); + _dofCount = qMin(ndofs, MaximumJoints); - double *ptr = Matrix2D_Get_col(mat2d, column); + double *ptr = Matrix2D_GetColumn(mat2d, column); SetValues(ptr, _dofCount); } @@ -100,7 +102,7 @@ const double* Joints::ValuesD() const const float* Joints::ValuesF() const { - for (int i = 0; i < RDK_SIZE_JOINTS_MAX; i++) + for (int i = 0; i < MaximumJoints; i++) { _jointsFloat[i] = _joints[i]; } @@ -157,7 +159,7 @@ void Joints::SetValues(const double *values, int ndofs) { if (ndofs >= 0) { - _dofCount = qMin(ndofs, RDK_SIZE_JOINTS_MAX); + _dofCount = qMin(ndofs, MaximumJoints); } for (int i = 0; i < _dofCount; i++) @@ -170,7 +172,7 @@ void Joints::SetValues(const float *values, int ndofs) { if (ndofs >= 0) { - _dofCount = qMin(ndofs, RDK_SIZE_JOINTS_MAX); + _dofCount = qMin(ndofs, MaximumJoints); } for (int i = 0; i < _dofCount; i++) @@ -219,7 +221,7 @@ bool Joints::FromString(const QString &str) #endif QStringList jointList = s.split(separator, behavior); - _dofCount = qMin(jointList.length(), RDK_SIZE_JOINTS_MAX); + _dofCount = qMin(jointList.length(), MaximumJoints); for (int i = 0; i < _dofCount; i++) { _joints[i] = jointList[i].trimmed().toDouble(); diff --git a/robodk_interface/joints.h b/robodk_interface/joints.h index efb937b..d433e97 100644 --- a/robodk_interface/joints.h +++ b/robodk_interface/joints.h @@ -38,12 +38,14 @@ #endif -struct tMatrix2D; - - namespace robodk { +namespace legacy +{ +struct Matrix2D; +} + /// The Joints class represents a joint position of a robot (robot axes). class Joints { @@ -75,7 +77,7 @@ class Joints /// \param mat2d /// \param column /// \param ndofs - Joints(const tMatrix2D* mat2d, int column = 0, int ndofs = -1); + Joints(const legacy::Matrix2D* mat2d, int column = 0, int ndofs = -1); /// \brief Convert a string to joint values /// \param str Comma separated joint values (spaces or tabs are also accepted) @@ -154,16 +156,16 @@ class Joints #endif public: - static constexpr int maximumJoints = 12; + static constexpr int MaximumJoints = 12; /// number of degrees of freedom int _dofCount; /// joint values (doubles, used to store the joint values) - double _joints[maximumJoints]; + double _joints[MaximumJoints]; /// joint values (floats, used to return a copy as a float pointer) - mutable float _jointsFloat[maximumJoints]; + mutable float _jointsFloat[MaximumJoints]; }; diff --git a/robodk_interface/legacymatrix2d.cpp b/robodk_interface/legacymatrix2d.cpp new file mode 100644 index 0000000..fbcc6cc --- /dev/null +++ b/robodk_interface/legacymatrix2d.cpp @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#include "legacymatrix2d.h" + +#include + +#ifdef QT_GUI_LIB +#include +#include +#include +#endif // QT_GUI_LIB + + +namespace robodk +{ + +namespace legacy +{ + +static void emxInit_real_T(Matrix2D** pMatrix, int dimensions) +{ + if (!pMatrix) + return; + + if (dimensions < 0) + { + *pMatrix = nullptr; + return; + } + + *pMatrix = (Matrix2D*) malloc(sizeof(Matrix2D)); + Matrix2D* matrix = *pMatrix; + if (!matrix) + return; + + matrix->data = nullptr; + matrix->numDimensions = dimensions; + matrix->size = (int*) malloc(sizeof(int) * dimensions); + matrix->allocatedSize = 0; + matrix->canFreeData = true; + + for (int i = 0; i < dimensions; i++) + matrix->size[i] = 0; +} + +static void emxFree_real_T(Matrix2D** pMatrix) +{ + if (!pMatrix) + return; + + auto matrix = *pMatrix; + if (!matrix) + return; + + if (matrix->canFreeData) + free(matrix->data); + + free(matrix->size); + free(matrix); + + *pMatrix = nullptr; +} + +static void emxEnsureCapacity(Matrix2D* matrix, int oldNumel, size_t elementSize) +{ + if (!matrix) + return; + + double *newData; + + if (oldNumel < 0) + oldNumel = 0; + + int newNumel = 1; + for (int i = 0; i < matrix->numDimensions; i++) + newNumel *= matrix->size[i]; + + if (newNumel <= matrix->allocatedSize) + return; + + int newSize = matrix->allocatedSize; + if (newSize < 16) + newSize = 16; + + while (newSize < newNumel) + { + if (newSize > 1073741823) + { + newSize = 2147483647; //MAX_int32_T; + } + else + { + newSize <<= 1; + } + } + + newData = (double*) calloc(newSize, elementSize); + if (matrix->data) + { + memcpy(newData, matrix->data, elementSize * oldNumel); + if (matrix->canFreeData) + free(matrix->data); + } + + matrix->data = newData; + matrix->allocatedSize = newSize; + matrix->canFreeData = true; +} + +Matrix2D* Matrix2D_Create() +{ + Matrix2D* matrix; + emxInit_real_T(&matrix, 2); + return matrix; +} + +void Matrix2D_Delete(Matrix2D** matrix) +{ + emxFree_real_T(matrix); +} + +void Matrix2D_SetDimensions(Matrix2D* matrix, int rows, int columns) +{ + int size = matrix->size[0] * matrix->size[1]; + matrix->size[0] = rows; + matrix->size[1] = columns; + emxEnsureCapacity(matrix, size, sizeof(double)); +} + +int Matrix2D_GetDimension(const Matrix2D* matrix, int dimension) +{ + // ONE BASED!! + if (matrix->numDimensions >= dimension) + { + return matrix->size[dimension - 1]; + } + else + { + return 0; + } +} + +int Matrix2D_ColumnCount(const Matrix2D* matrix) +{ + return Matrix2D_GetDimension(matrix, 2); +} + +int Matrix2D_RowCount(const Matrix2D* matrix) +{ + return Matrix2D_GetDimension(matrix, 1); +} + +double Matrix2D_Get(const Matrix2D* matrix, int row, int column) +{ + // ZERO BASED!! + return matrix->data[matrix->size[0] * column + row]; +} + +void Matrix2D_Set(const Matrix2D* matrix, int row, int column, double value) +{ + // ZERO BASED!! + matrix->data[matrix->size[0] * column + row] = value; +} + +double* Matrix2D_GetColumn(const Matrix2D* matrix, int column) +{ + // ZERO BASED!! + return (matrix->data + matrix->size[0] * column); +} + +bool Matrix2D_Copy(const Matrix2D* source, Matrix2D* destination) +{ + if (source->numDimensions != 2 || destination->numDimensions != 2) + { + Matrix2D_SetDimensions(destination, 0, 0); + return false; + } + + int sz1 = Matrix2D_GetDimension(source, 1); + int sz2 = Matrix2D_GetDimension(source, 2); + Matrix2D_SetDimensions(destination, sz1, sz2); + int numel = sz1 * sz2; + for (int i = 0; i < numel; i++) + { + destination->data[i] = source->data[i]; + } + + return true; +} + +#ifdef QT_GUI_LIB +void Matrix2D_DebugArray(const double *array, int size) +{ + int i; + QString strout; + for (i = 0; i < size; i++) { + strout.append(QString::number(array[i], 'f', 3)); + if (i < size - 1) { + strout.append(" , "); + } + } + qDebug().noquote() << strout; +} + +void Matrix2D_Debug(const Matrix2D* matrix) +{ + int size1; + int size2; + int j; + double *column; + size1 = Matrix2D_RowCount(matrix); + size2 = Matrix2D_ColumnCount(matrix); + qDebug().noquote() << "Matrix size = " << size1 << " x " << size2; + if (size1*size2 == 0) + { + return; + } + for (j = 0; jnumDimensions; + int size_values = 1; + for (i = 0; i < matrix->numDimensions; i++) + { + qint32 sizei = matrix->size[i]; + size_values = size_values * sizei; + *stream << sizei; + } + for (i = 0; i < size_values; i++) + { + *stream << matrix->data[i]; + } +} + +void Matrix2D_Load(QDataStream *stream, Matrix2D** matrix) +{ + if (stream->atEnd()) + { + qDebug() << "No data to read"; + return; + } + + if (*matrix != nullptr) + { + Matrix2D_Delete(matrix); + } + + int i; + qint32 ndim; + qint32 sizei; + *stream >> ndim; + qDebug() << "Loading matrix of dimensions: " << ndim; + emxInit_real_T(matrix, ndim); + int size_values = 1; + for (i = 0; i < ndim; i++) + { + *stream >> sizei; + size_values = size_values * sizei; + (*matrix)->size[i] = sizei; + } + //emxEnsureCapacity((emxArray__common *) *emx, 0, (int32_T)sizeof(real_T)); + emxEnsureCapacity(*matrix, 0, sizeof(double)); + double value; + for (i = 0; i < size_values; i++) + { + *stream >> value; + (*matrix)->data[i] = value; + } +} +#endif // QT_GUI_LIB + + +} // namespace legacy + +} // namespace robodk diff --git a/robodk_interface/legacymatrix2d.h b/robodk_interface/legacymatrix2d.h new file mode 100644 index 0000000..ad3a505 --- /dev/null +++ b/robodk_interface/legacymatrix2d.h @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_LEGACY_MATRIX2D_H +#define ROBODK_LEGACY_MATRIX2D_H + + +#ifdef QT_GUI_LIB +class QTextStream; +class QDataStream; +#endif // QT_GUI_LIB + + +namespace robodk +{ + +namespace legacy +{ + +/*! + \struct Matrix2D + \brief The Matrix2D struct represents a variable size 2D matrix. + + Use the Matrix2D_... functions to operate on this variable sized matrix. + This type of data can be used to get/set a program as a list. + This is also useful for backwards compatibility functions related to RoKiSim. +*/ +struct Matrix2D +{ + /*! + Pointer to the data. + */ + double* data; + + /*! + Pointer to the size array. + */ + int* size; + + /*! + Allocated size. + */ + int allocatedSize; + + /*! + Number of dimensions (usually 2). + */ + int numDimensions; + + bool canFreeData; +}; + +/*! + Creates a new \ref Matrix2D object with no dimensions. + + \returns pointer to the Matrix2D object if no allocation errors occurred; nullptr otherwise. + + \sa Matrix2D_Delete() +*/ +Matrix2D* Matrix2D_Create(); + +/*! + Deletes an existing \ref Matrix2D object. + + \param matrix pointer of the pointer variable to the matrix object. + + \sa Matrix2D_Create() +*/ +void Matrix2D_Delete(Matrix2D** matrix); + +/*! + Sets new dimensions for existing matrix object. + + \param matrix pointer to the matrix object. + \param rows number of rows. + \param columns number of columns. + + \sa Matrix2D_GetDimension() +*/ +void Matrix2D_SetDimensions(Matrix2D* matrix, int rows, int columns); + +/*! + Returns \a dimension (number of rows or columns) of \a matrix. + + \param matrix pointer to the matrix object. + \param dimension may have a value of 1 or 2 to retrieve number of + rows or columns respectively. + + \sa Matrix2D_SetDimensions(), Matrix2D_ColumnCount(), Matrix2D_RowCount() +*/ +int Matrix2D_GetDimension(const Matrix2D* matrix, int dimension); + +/*! + Returns the total number of columns in the \a matrix. + + \sa Matrix2D_SetDimensions(), Matrix2D_RowCount() +*/ +int Matrix2D_ColumnCount(const Matrix2D* matrix); + +/*! + Returns the total number of rows in the \a matrix. + + \sa Matrix2D_SetDimensions(), Matrix2D_RowCount() +*/ +int Matrix2D_RowCount(const Matrix2D* matrix); + +/*! + Returns the value of the element at position (\a row, \a column) in the \a matrix. +*/ +double Matrix2D_Get(const Matrix2D* matrix, int row, int column); + +/*! + Sets a new \a value to the element at position (\a row, \a column) in the \a matrix. +*/ +void Matrix2D_Set(const Matrix2D* matrix, int row, int column, double value); + +/*! + Returns the elements of \a column as a pointer to its values in the \a matrix. +*/ +double* Matrix2D_GetColumn(const Matrix2D* matrix, int column); + +/*! + \brief Copies the matrix \a source to the \a destination. + + Both matrices must be initialized and have the same size. + + \returns true if successful; otherwise returns false. +*/ +bool Matrix2D_Copy(const Matrix2D* source, Matrix2D* destination); + +#ifdef QT_GUI_LIB +/*! + Writes the contents of the \a array with \a size elements using qDebug(). +*/ +void Matrix2D_DebugArray(const double* array, int size); + +/*! + Writes the contents of the \a matrix using qDebug(). +*/ +void Matrix2D_Debug(const Matrix2D* matrix); + +/*! + \brief Writes the contents of the \a matrix into text \a stream. + + The values can be written in the CSV format. +*/ +void Matrix2D_Save(QTextStream* stream, Matrix2D* matrix, bool csv = false); + +/*! + Writes the contents of the \a matrix into binary \a stream. +*/ +void Matrix2D_Save(QDataStream* stream, Matrix2D* matrix); + +/*! + Creates a new \ref Matrix2D object by loading its contents from a binary \a stream. +*/ +void Matrix2D_Load(QDataStream* stream, Matrix2D** matrix); +#endif // QT_GUI_LIB + +} // namespace legacy + +} // namespace robodk + + +#endif // ROBODK_LEGACY_MATRIX2D_H diff --git a/robodk_interface/robodk_interface.pri b/robodk_interface/robodk_interface.pri index 0b03874..2d9db22 100644 --- a/robodk_interface/robodk_interface.pri +++ b/robodk_interface/robodk_interface.pri @@ -7,6 +7,7 @@ HEADERS += \ $$PWD/iitem.h \ $$PWD/irobodk.h \ $$PWD/joints.h \ + $$PWD/legacymatrix2d.h \ $$PWD/matrix4x4.h \ $$PWD/robodktools.h \ $$PWD/robodktypes.h \ @@ -15,6 +16,7 @@ HEADERS += \ SOURCES += \ $$PWD/joints.cpp \ + $$PWD/legacymatrix2d.cpp \ $$PWD/matrix4x4.cpp \ $$PWD/robodktools.cpp \ $$PWD/robodktypes.cpp \ diff --git a/robodk_interface/robodktypes.cpp b/robodk_interface/robodktypes.cpp index acb3033..e1647f2 100644 --- a/robodk_interface/robodktypes.cpp +++ b/robodk_interface/robodktypes.cpp @@ -1,354 +1 @@ #include "robodktypes.h" - -#include -#include - - -//----------------------------------- Mat class ----------------------- -Mat transl(double x, double y, double z) -{ - return Mat::transl(x,y,z); -} - -Mat rotx(double rx) -{ - return Mat::rotx(rx); -} - -Mat roty(double ry) -{ - return Mat::roty(ry); -} - -Mat rotz(double rz) -{ - return Mat::rotz(rz); -} -//--------------------------------------------------------------------- - - -//----------------------------------- 2D matrix functions ------------- -void emxInit_real_T(tMatrix2D **pEmxArray, int numDimensions) -{ - tMatrix2D *emxArray; - int i; - *pEmxArray = (tMatrix2D *)malloc(sizeof(tMatrix2D)); - emxArray = *pEmxArray; - emxArray->data = (double *)NULL; - emxArray->numDimensions = numDimensions; - emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions)); - emxArray->allocatedSize = 0; - emxArray->canFreeData = true; - for (i = 0; i < numDimensions; i++) - { - emxArray->size[i] = 0; - } -} - -tMatrix2D* Matrix2D_Create() -{ - tMatrix2D *matrix; - emxInit_real_T((tMatrix2D**)(&matrix), 2); - return matrix; -} - -void emxFree_real_T(tMatrix2D **pEmxArray) -{ - if (*pEmxArray != (tMatrix2D *)NULL) - { - if (((*pEmxArray)->data != (double *)NULL) && (*pEmxArray)->canFreeData) - { - free((void *)(*pEmxArray)->data); - } - free((void *)(*pEmxArray)->size); - free((void *)*pEmxArray); - *pEmxArray = (tMatrix2D *)NULL; - } -} - -void Matrix2D_Delete(tMatrix2D **mat) -{ - emxFree_real_T((tMatrix2D**)(mat)); -} - -void emxEnsureCapacity(tMatrix2D *emxArray, int oldNumel, unsigned int elementSize) -{ - int newNumel; - int i; - double *newData; - if (oldNumel < 0) - { - oldNumel = 0; - } - newNumel = 1; - for (i = 0; i < emxArray->numDimensions; i++) - { - newNumel *= emxArray->size[i]; - } - - if (newNumel > emxArray->allocatedSize) - { - i = emxArray->allocatedSize; - if (i < 16) - { - i = 16; - } - while (i < newNumel) - { - if (i > 1073741823) - { - i =(2147483647);//MAX_int32_T; - } - else - { - i <<= 1; - } - } - - newData = (double*) calloc((unsigned int)i, elementSize); - if (emxArray->data != NULL) - { - memcpy(newData, emxArray->data, elementSize * oldNumel); - if (emxArray->canFreeData) - { - free(emxArray->data); - } - } - emxArray->data = newData; - emxArray->allocatedSize = i; - emxArray->canFreeData = true; - } -} - -void Matrix2D_Set_Size(tMatrix2D *mat, int rows, int cols) -{ - int old_numel; - old_numel = mat->size[0] * mat->size[1]; - mat->size[0] = rows; - mat->size[1] = cols; - emxEnsureCapacity(mat, old_numel, sizeof(double)); -} - -int Matrix2D_Size(const tMatrix2D *var, int dim) -{ - // ONE BASED!! - if (var->numDimensions >= dim) - { - return var->size[dim - 1]; - } - else - { - return 0; - } -} - -int Matrix2D_Get_ncols(const tMatrix2D *var) -{ - return Matrix2D_Size(var, 2); -} - -int Matrix2D_Get_nrows(const tMatrix2D *var) -{ - return Matrix2D_Size(var, 1); -} - -double Matrix2D_Get_ij(const tMatrix2D *var, int i, int j) -{ - // ZERO BASED!! - return var->data[var->size[0] * j + i]; -} - -void Matrix2D_Set_ij(const tMatrix2D *var, int i, int j, double value) -{ - // ZERO BASED!! - var->data[var->size[0] * j + i] = value; -} - -double *Matrix2D_Get_col(const tMatrix2D *var, int col) -{ - // ZERO BASED!! - return (var->data + var->size[0] * col); -} - -bool Matrix2D_Copy(const tMatrix2D *from, tMatrix2D *to) -{ - if (from->numDimensions != 2 || to->numDimensions != 2) - { - Matrix2D_Set_Size(to, 0,0); - return false; - } - - int sz1 = Matrix2D_Size(from,1); - int sz2 = Matrix2D_Size(from,2); - Matrix2D_Set_Size(to, sz1, sz2); - int numel = sz1*sz2; - for (int i = 0; i < numel; i++) - { - to->data[i] = from->data[i]; - } - - return true; -} - - -void Matrix2D_Add(tMatrix2D *var, const double *array, int numel) -{ - int oldnumel; - int size1 = var->size[0]; - int size2 = var->size[1]; - oldnumel = size1*size2; - var->size[1] = size2 + 1; - emxEnsureCapacity(var, oldnumel, (int)sizeof(double)); - numel = qMin(numel, size1); - for (int i=0; idata[size1*size2 + i] = array[i]; - } -} - -void Matrix2D_Add(tMatrix2D *var, const tMatrix2D *varadd) -{ - int oldnumel; - int size1 = var->size[0]; - int size2 = var->size[1]; - int size1_ap = varadd->size[0]; - int size2_ap = varadd->size[1]; - int numel = size1_ap*size2_ap; - if (size1 != size1_ap) - { - return; - } - oldnumel = size1*size2; - var->size[1] = size2 + size2_ap; - emxEnsureCapacity(var, oldnumel, (int)sizeof(double)); - for (int i=0; idata[size1*size2 + i] = varadd->data[i]; - } -} - -void Debug_Array(const double *array, int arraysize) -{ - int i; - QString strout; - for (i = 0; i < arraysize; i++) { - strout.append(QString::number(array[i], 'f', 3)); - if (i < arraysize - 1) { - strout.append(" , "); - } - } - qDebug().noquote() << strout; -} - -void Debug_Matrix2D(const tMatrix2D *emx) -{ - int size1; - int size2; - int j; - double *column; - size1 = Matrix2D_Get_nrows(emx); - size2 = Matrix2D_Get_ncols(emx); - qDebug().noquote() << "Matrix size = " << size1 << " x " << size2; - if (size1*size2 == 0) - { - return; - } - for (j = 0; jnumDimensions; - int size_values = 1; - for (i = 0; i < emx->numDimensions; i++) - { - qint32 sizei = emx->size[i]; - size_values = size_values * sizei; - *st << sizei; - } - for (i = 0; i < size_values; i++) - { - *st << emx->data[i]; - } -} - -void Matrix2D_Save(QTextStream *st, tMatrix2D *emx, bool csv) -{ - int size1; - int size2; - int j; - double *column; - size1 = Matrix2D_Get_nrows(emx); - size2 = Matrix2D_Get_ncols(emx); - //*st << "% Matrix size = " << size1 << " x " << size2; - if (size1 * size2 == 0) - { - return; - } - - if (csv) - { - for (j = 0; jatEnd()) - { - qDebug() << "No data to read"; - return; - } - - if (*emx != nullptr) - { - Matrix2D_Delete(emx); - } - - int i; - qint32 ndim; - qint32 sizei; - *st >> ndim; - qDebug() << "Loading matrix of dimensions: " << ndim; - emxInit_real_T(emx, ndim); - int size_values = 1; - for (i = 0; i < ndim; i++) - { - *st >> sizei; - size_values = size_values * sizei; - (*emx)->size[i] = sizei; - } - //emxEnsureCapacity((emxArray__common *) *emx, 0, (int32_T)sizeof(real_T)); - emxEnsureCapacity(*emx, 0, sizeof(double)); - double value; - for (i = 0; i < size_values; i++) - { - *st >> value; - (*emx)->data[i] = value; - } -} diff --git a/robodk_interface/robodktypes.h b/robodk_interface/robodktypes.h index ea60188..187e41c 100644 --- a/robodk_interface/robodktypes.h +++ b/robodk_interface/robodktypes.h @@ -7,6 +7,7 @@ #include #include "matrix4x4.h" +#include "legacymatrix2d.h" #include "joints.h" @@ -136,150 +137,204 @@ struct tColor{ +typedef robodk::legacy::Matrix2D tMatrix2D; +/*! + Creates a new \ref Matrix2D object with no dimensions. + \returns pointer to the Matrix2D object if no allocation errors occurred; nullptr otherwise. -//------------------------------------------------------------------------------------------------------------ - - - -/// \brief The tMatrix2D struct represents a variable size 2d Matrix. Use the Matrix2D_... functions to oeprate on this variable sized matrix. -/// This type of data can be used to get/set a program as a list. This is also useful for backwards compatibility functions related to RoKiSim. -struct tMatrix2D { - /// Pointer to the data - double *data; - - /// Pointer to the size array. - int *size; - - /// Allocated size. - int allocatedSize; - - /// Number of dimensions (usually 2) - int numDimensions; - - bool canFreeData; -}; - - - - -// ------------------------------------------- - + \sa Matrix2D_Delete() +*/ +inline tMatrix2D* Matrix2D_Create() +{ + return robodk::legacy::Matrix2D_Create(); +} -/// @brief Creates a new 2D matrix \ref Matrix2D.. Use \ref Matrix2D_Delete to delete the matrix (to free the memory). -/// The Procedure \ref Debug_Matrix2D shows an example to read data from a tMatrix2D -tMatrix2D* Matrix2D_Create(); +/*! + Deletes an existing \ref Matrix2D object. -/// @brief Deletes a \ref tMatrix2D. -/// @param[in] mat: Pointer of the pointer to the matrix -void Matrix2D_Delete(tMatrix2D **mat); + \param matrix pointer of the pointer variable to the matrix object. -/// @brief Sets the size of a \ref tMatrix2D. -/// @param[in/out] mat: Pointer to the matrix -/// @param[in] rows: The number of rows. -/// @param[in] cols: The number of columns. -void Matrix2D_Set_Size(tMatrix2D *mat, int rows, int cols); + \sa Matrix2D_Create() +*/ +inline void Matrix2D_Delete(tMatrix2D** matrix) +{ + robodk::legacy::Matrix2D_Delete(matrix); +} -/// @brief Sets the size of a \ref tMatrix2D. -/// @param[in/out] mat: Pointer to the matrix -/// @param[in] dim: Dimension (1 or 2) -int Matrix2D_Size(const tMatrix2D *mat, int dim); +/*! + Sets new dimensions for existing matrix object. -/// @brief Returns the number of columns of a \ref tMatrix2D. -/// @param[in] mat: Pointer to the matrix -/// Returns the number of columns (Second dimension) -int Matrix2D_Get_ncols(const tMatrix2D *var); + \param matrix pointer to the matrix object. + \param rows number of rows. + \param columns number of columns. -/// @brief Returns the number of rows of a \ref tMatrix2D. -/// @param[in] mat: Pointer to the matrix -/// Returns the number of rows (First dimension) -int Matrix2D_Get_nrows(const tMatrix2D *var); + \sa Matrix2D_Size() +*/ +inline void Matrix2D_Set_Size(tMatrix2D* matrix, int rows, int columns) +{ + robodk::legacy::Matrix2D_SetDimensions(matrix, rows, columns); +} -/// @brief Returns the value at location [i,j] of a \ref tMatrix2D. -/// @param[in] mat: Pointer to the matrix -/// Returns the value of the cell -double Matrix2D_Get_ij(const tMatrix2D *var, int i, int j); +/*! + Returns \a dimension (number of rows or columns) of \a matrix. -/// @brief Set the value at location [i,j] of a \ref tMatrix2D. -/// @param[in] mat: Pointer to the matrix -/// @param[in] i: Row -/// @param[in] j: Column -/// @param[in] value: matrix value -void Matrix2D_Set_ij(const tMatrix2D *var, int i, int j, double value); + \deprecated Use \ref Matrix2D_ColumnCount() and \ref Matrix2D_RowCount() instead of this one. -/// @brief Returns the pointer of a column of a \ref tMatrix2D. -/// A column has \ref Matrix2D_Get_nrows(mat) values that can be accessed/modified from the returned pointer continuously. -/// @param[in] mat: Pointer to the matrix -/// @param[in] col: Column to retreive. -/// /return double array (internal pointer) to the column -double* Matrix2D_Get_col(const tMatrix2D *var, int col); + \param matrix pointer to the matrix object. + \param dimension may have a value of 1 or 2 to retrieve number of + rows or columns respectively. -/// @brief Copy a Matrix2D -bool Matrix2D_Copy(const tMatrix2D *in, tMatrix2D *out); + \sa Matrix2D_Set_Size(), Matrix2D_Get_ncols(), Matrix2D_Get_nrows() +*/ +inline int Matrix2D_Size(const tMatrix2D* matrix, int dimension) +{ + return robodk::legacy::Matrix2D_GetDimension(matrix, dimension); +} -/// @brief Show an array through STDOUT -/// Given an array of doubles, it generates a string -void Debug_Array(const double *array, int arraysize); +/*! + Returns the total number of columns in the \a matrix. -/// @brief Display the content of a \ref tMatrix2D through STDOUT. This is only intended for debug purposes. -/// @param[in] mat: Pointer to the matrix -void Debug_Matrix2D(const tMatrix2D *mat); + \sa Matrix2D_Set_Size(), Matrix2D_Get_nrows() +*/ +inline int Matrix2D_Get_ncols(const tMatrix2D* matrix) +{ + return robodk::legacy::Matrix2D_ColumnCount(matrix); +} -/// @brief Save a matrix as binary data -void Matrix2D_Save(QDataStream *st, tMatrix2D *emx); +/*! + Returns the total number of rows in the \a matrix. -/// @brief Save a matrix as text -void Matrix2D_Save(QTextStream *st, tMatrix2D *emx, bool csv=false); + \sa Matrix2D_Set_Size(), Matrix2D_Get_ncols() +*/ +inline int Matrix2D_Get_nrows(const tMatrix2D* matrix) +{ + return robodk::legacy::Matrix2D_RowCount(matrix); +} -/// @brief Load a matrix -void Matrix2D_Load(QDataStream *st, tMatrix2D **emx); +/*! + Returns the value of the element at position (\a row, \a column) in the \a matrix. +*/ +inline double Matrix2D_Get_ij(const tMatrix2D* matrix, int row, int column) +{ + return robodk::legacy::Matrix2D_Get(matrix, row, column); +} +/*! + Sets a new \a value to the element at position (\a row, \a column) in the \a matrix. +*/ +inline void Matrix2D_Set_ij(const tMatrix2D* matrix, int row, int column, double value) +{ + robodk::legacy::Matrix2D_Set(matrix, row, column, value); +} -typedef robodk::Joints tJoints; +/*! + Returns the elements of \a column as a pointer to its values in the \a matrix. +*/ +inline double* Matrix2D_Get_col(const tMatrix2D* matrix, int column) +{ + return robodk::legacy::Matrix2D_GetColumn(matrix, column); +} /*! - \typedef Mat - \brief The Mat class represents a 4x4 pose matrix. + \brief Copies the matrix \a source to the \a destination. - The main purpose of this object is to represent a pose - in the 3D space (position and orientation). + Both matrices must be initialized and have the same size. - In other words, a pose is a 4x4 matrix that represents - the position and orientation of one reference frame with - respect to another one, in the 3D space. + \returns true if successful; otherwise returns false. +*/ +inline bool Matrix2D_Copy(const tMatrix2D* source, tMatrix2D* destination) +{ + return robodk::legacy::Matrix2D_Copy(source, destination); +} - Poses are commonly used in robotics to place objects, - reference frames and targets with respect to each other. +/*! + Writes the contents of the \a array with \a size elements using qDebug(). +*/ +inline void Debug_Array(const double* array, int size) +{ + robodk::legacy::Matrix2D_DebugArray(array, size); +} -
- \f$ transl(x,y,z) rotx(r) roty(p) rotz(w) = \\ - \begin{bmatrix} n_x & o_x & a_x & x \\ - n_y & o_y & a_y & y \\ - n_z & o_z & a_z & z \\ - 0 & 0 & 0 & 1 \end{bmatrix} \f$ +/*! + Writes the contents of the \a matrix using qDebug(). */ -typedef robodk::Matrix4x4 Mat; +inline void Debug_Matrix2D(const tMatrix2D* matrix) +{ + robodk::legacy::Matrix2D_Debug(matrix); +} -/// Translation matrix class: Mat::transl. -Mat transl(double x, double y, double z); +/*! + \brief Writes the contents of the \a matrix into text \a stream. -/// Translation matrix class: Mat::rotx. -Mat rotx(double rx); + The values can be written in the CSV format. +*/ +inline void Matrix2D_Save(QTextStream* stream, tMatrix2D* matrix, bool csv = false) +{ + robodk::legacy::Matrix2D_Save(stream, matrix, csv); +} -/// Translation matrix class: Mat::roty. -Mat roty(double ry); +/*! + Writes the contents of the \a matrix into binary \a stream. +*/ +inline void Matrix2D_Save(QDataStream* stream, tMatrix2D* matrix) +{ + robodk::legacy::Matrix2D_Save(stream, matrix); +} -/// Translation matrix class: Mat::rotz. -Mat rotz(double rz); +/*! + Creates a new \ref Matrix2D object by loading its contents from a binary \a stream. +*/ +inline void Matrix2D_Load(QDataStream* stream, tMatrix2D** matrix) +{ + robodk::legacy::Matrix2D_Load(stream, matrix); +} -//QDataStream &operator<<(QDataStream &data, const QMatrix4x4 &); -inline QDebug operator<<(QDebug dbg, const Mat &m){ return dbg.noquote() << m.ToString(); } -inline QDebug operator<<(QDebug dbg, const tJoints &jnts){ return dbg.noquote() << jnts.ToString(); } -inline QDebug operator<<(QDebug dbg, const Mat *m){ return dbg.noquote() << (m == nullptr ? "Mat(null)" : m->ToString()); } -inline QDebug operator<<(QDebug dbg, const tJoints *jnts){ return dbg.noquote() << (jnts == nullptr ? "tJoints(null)" : jnts->ToString()); } +typedef robodk::Joints tJoints; +typedef robodk::Matrix4x4 Mat; +inline Mat transl(double x, double y, double z) +{ + return Mat::transl(x,y,z); +} + +inline Mat rotx(double rx) +{ + return Mat::rotx(rx); +} + +inline Mat roty(double ry) +{ + return Mat::roty(ry); +} + +inline Mat rotz(double rz) +{ + return Mat::rotz(rz); +} + + +inline QDebug operator<<(QDebug dbg, const Mat &m) +{ + return dbg.noquote() << m.ToString(); +} + +inline QDebug operator<<(QDebug dbg, const tJoints &jnts) +{ + return dbg.noquote() << jnts.ToString(); +} + +inline QDebug operator<<(QDebug dbg, const Mat *m) +{ + return dbg.noquote() << (m == nullptr ? "Mat(null)" : m->ToString()); +} + +inline QDebug operator<<(QDebug dbg, const tJoints *jnts) +{ + return dbg.noquote() << (jnts == nullptr ? "tJoints(null)" : jnts->ToString()); +} #endif // ROBODKTYPES_H From aaf5b72a49b602f8c7ddcea8a01aaa4502c29bf0 Mon Sep 17 00:00:00 2001 From: VDm Date: Thu, 31 Jul 2025 17:32:43 +0400 Subject: [PATCH 07/11] feat(robodk_interface): add StationTreeEventMonitor class --- robodk_interface/robodk_interface.pri | 2 + robodk_interface/stationtreeeventmonitor.cpp | 331 +++++++++++++++++++ robodk_interface/stationtreeeventmonitor.h | 127 +++++++ 3 files changed, 460 insertions(+) create mode 100644 robodk_interface/stationtreeeventmonitor.cpp create mode 100644 robodk_interface/stationtreeeventmonitor.h diff --git a/robodk_interface/robodk_interface.pri b/robodk_interface/robodk_interface.pri index 2d9db22..5d3f09c 100644 --- a/robodk_interface/robodk_interface.pri +++ b/robodk_interface/robodk_interface.pri @@ -12,6 +12,7 @@ HEADERS += \ $$PWD/robodktools.h \ $$PWD/robodktypes.h \ $$PWD/robodk_interface.h \ + $$PWD/stationtreeeventmonitor.h \ $$PWD/vector3.h SOURCES += \ @@ -20,4 +21,5 @@ SOURCES += \ $$PWD/matrix4x4.cpp \ $$PWD/robodktools.cpp \ $$PWD/robodktypes.cpp \ + $$PWD/stationtreeeventmonitor.cpp \ $$PWD/vector3.cpp diff --git a/robodk_interface/stationtreeeventmonitor.cpp b/robodk_interface/stationtreeeventmonitor.cpp new file mode 100644 index 0000000..bd5ade5 --- /dev/null +++ b/robodk_interface/stationtreeeventmonitor.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#include "stationtreeeventmonitor.h" + +#include + +#include +#include +#include + +#include "iitem.h" + + +namespace robodk +{ + +StationTreeEventMonitor::StationTreeEventMonitor(IRoboDK* rdk, QObject* parent) + : QObject(parent) + , _rdk(rdk) +{ + if (!_rdk) + return; + + const auto items = _rdk->getItemList(); + for (const auto& item : items) + { + auto treeItem = dynamic_cast(item); + if (treeItem && treeItem->treeWidget()) + { + _tree = treeItem->treeWidget(); + break; + } + } + + if (!_tree) + return; + + auto model = _tree->model(); + + using ModelClass = QAbstractItemModel; + using ThisClass = StationTreeEventMonitor; + connect(model, &ModelClass::modelReset, this, &ThisClass::refresh); + connect(model, &ModelClass::dataChanged, this, &ThisClass::onModelDataChanged); + connect(model, &ModelClass::rowsInserted, this, &ThisClass::onModelRowsInserted); + connect(model, &ModelClass::rowsRemoved, this, &ThisClass::onModelRowsRemoved); + + refresh(); +} + +void StationTreeEventMonitor::refresh() +{ + _nameTable.clear(); + _nameCache.clear(); + + if (!_tree || !_tree->model()) + return; + + iterateOverTree(QModelIndex(), [this] (const QModelIndex& index) + { + auto item = itemFromIndex(index); + if (!item) + return; + + const QString name = index.data().toString(); + _nameTable.insert({name, item}); + _nameCache[item] = name; + }); +} + +void StationTreeEventMonitor::onModelDataChanged( + const QModelIndex& topLeft, + const QModelIndex& bottomRight, + const QVector& roles) +{ + if (!topLeft.isValid() || !bottomRight.isValid() || topLeft.parent() != bottomRight.parent()) + return; + + bool nameChanged = false; + bool iconChanged = false; + + for (int role : roles) + { + switch (role) + { + case Qt::DisplayRole: + case Qt::EditRole: + nameChanged = true; + break; + case Qt::DecorationRole: + iconChanged = true; + break; + default: + break; + } + } + + bool isActive = (_filter & IgnoreInactiveStations) == 0 || isActiveStationItem(topLeft); + const auto parent = topLeft.parent(); + + auto updateItem = [this, nameChanged, iconChanged, isActive, parent] (const QModelIndex& index) + { + auto item = itemFromIndex(index); + if (!item) + return; + + const auto cache = _nameCache.find(item); + if (cache == _nameCache.end()) + return; + + const auto range = _nameTable.equal_range(cache->second); + for (auto it = range.first; it != range.second; ++it) + { + if (it->second == item) + { + _nameTable.erase(it); + break; + } + } + + const QString name = index.data().toString(); + _nameTable.insert({name, item}); + _nameCache[item] = name; + + if (!isActive) + return; + + if ((_filter & IgnoreChildren) && parent != index.parent()) + return; + + if (nameChanged && (_filter & IgnoreNameChange) == 0) + emit itemNameChanged(item, name); + + if (iconChanged && (_filter & IgnoreIconChange) == 0) + emit itemIconChanged(item, qvariant_cast(index.data(Qt::DecorationRole))); + }; + + for (int row = topLeft.row(); row <= bottomRight.row(); ++row) + { + auto index = _tree->model()->index(row, 0, topLeft.parent()); + if (!index.isValid()) + continue; + + updateItem(index); + iterateOverTree(index, updateItem); + } +} + +void StationTreeEventMonitor::onModelRowsInserted(const QModelIndex& parent, int first, int last) +{ + auto addItem = [this, &parent] (const QModelIndex& index) + { + auto item = itemFromIndex(index); + if (!item) + return; + + const QString name = index.data().toString(); + _nameTable.insert({name, item}); + _nameCache[item] = name; + + if (_filter & IgnoreAdd) + return; + + if ((_filter & IgnoreChildren) && parent != index.parent()) + return; + + if ((_filter & IgnoreInactiveStations) && !isActiveStationItem(index)) + return; + + emit itemAdded(item); + }; + + for (int row = first; row <= last; ++row) + { + auto index = _tree->model()->index(row, 0, parent); + if (!index.isValid()) + continue; + + addItem(index); + iterateOverTree(index, addItem); + } +} + +void StationTreeEventMonitor::onModelRowsRemoved(const QModelIndex& parent, int first, int last) +{ + auto removeItem = [this, &parent] (const QModelIndex& index) + { + auto item = itemFromIndex(index); + if (!item) + return; + + const auto cache = _nameCache.find(item); + if (cache == _nameCache.end()) + return; + + const auto range = _nameTable.equal_range(cache->second); + for (auto it = range.first; it != range.second; ++it) + { + if (it->second == item) + { + _nameTable.erase(it); + break; + } + } + + _nameCache.erase(cache); + + if (_filter & IgnoreRemove) + return; + + if ((_filter & IgnoreChildren) && parent != index.parent()) + return; + + if ((_filter & IgnoreInactiveStations) && !isActiveStationItem(index)) + return; + + emit itemRemoved(item); + }; + + for (int row = last; row >= first; --row) + { + auto index = _tree->model()->index(row, 0, parent); + if (!index.isValid()) + continue; + + iterateOverTree(index, removeItem, true); + removeItem(index); + } +} + +void StationTreeEventMonitor::iterateOverTree( + const QModelIndex& parent, + const TreeCallback& callback, + bool reverse) +{ + auto model = _tree->model(); + + using StackEntry = std::pair; + std::stack stack; + stack.push({0, parent}); + + while (!stack.empty()) + { + auto& entry = stack.top(); + const auto& parent = entry.second; + const int start = entry.first; + const int count = model->rowCount(parent); + + bool goBack = true; + + if (reverse && start > 0) + { + auto index = model->index(count - start, 0, parent); + callback(index); + } + + for (int i = start; i < count; ++i) + { + int row = reverse ? (count - i - 1) : i; + + auto index = model->index(row, 0, parent); + if (!index.isValid()) + continue; + + if (!reverse) + callback(index); + + if (model->hasChildren(index)) + { + entry.first = i + 1; + stack.push({0, index}); + goBack = false; + break; + } + else if (reverse) + { + callback(index); + } + } + + if (goBack) + stack.pop(); + } +} + +IItem* StationTreeEventMonitor::itemFromIndex(const QModelIndex& index) const +{ + auto treeItem = static_cast(index.internalPointer()); + return dynamic_cast(treeItem); +} + +bool StationTreeEventMonitor::isActiveStationItem(const QModelIndex& index) const +{ + QModelIndex parent = index; + while (parent.parent().isValid()) + parent = parent.parent(); + + if (!parent.isValid()) + return false; + + auto item = itemFromIndex(parent); + return item && _rdk && item == _rdk->getActiveStation(); +} + +} // namespace robodk diff --git a/robodk_interface/stationtreeeventmonitor.h b/robodk_interface/stationtreeeventmonitor.h new file mode 100644 index 0000000..c8608ef --- /dev/null +++ b/robodk_interface/stationtreeeventmonitor.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (c) 2015-2025 RoboDK Inc. +** Contact: https://robodk.com/ +** +** This file is part of the RoboDK API. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in all +** copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +** SOFTWARE. +** +** RoboDK is a registered trademark of RoboDK Inc. +** +****************************************************************************/ + +#ifndef ROBODK_STATIONTREEEVENTMONITOR_H +#define ROBODK_STATIONTREEEVENTMONITOR_H + +#include +#include +#include + +#include +#include +#include + + +class QIcon; +class QModelIndex; +class QTreeWidget; +class QTreeWidgetItem; +class IRoboDK; +class IItem; + + +namespace robodk +{ + +class StationTreeEventMonitor : public QObject +{ + Q_OBJECT + +public: + enum Filter : uint32_t + { + NoFilter = 0x00000000, + IgnoreInactiveStations = 0x00000001, + IgnoreNameChange = 0x00000002, + IgnoreIconChange = 0x00000004, + IgnoreAdd = 0x00000008, + IgnoreRemove = 0x00000010, + IgnoreChildren = 0x00000020, + }; + +public: + explicit StationTreeEventMonitor(IRoboDK* rdk, QObject* parent = nullptr); + + void setFilter(uint32_t filter); + + void test(); + +signals: + void itemNameChanged(IItem* item, const QString& name); + void itemIconChanged(IItem* item, const QIcon& icon); + void itemAdded(IItem* item); + void itemRemoved(IItem* item); + +public slots: + void refresh(); + +private slots: + void onModelDataChanged( + const QModelIndex& topLeft, + const QModelIndex& bottomRight, + const QVector& roles = QVector()); + void onModelRowsInserted(const QModelIndex& parent, int first, int last); + void onModelRowsRemoved(const QModelIndex& parent, int first, int last); + +private: + struct QStringHash + { + inline size_t operator()(const QString& s) const { return qHash(s); }; + }; + + using TreeCallback = std::function; + +private: + void iterateOverTree( + const QModelIndex& parent, + const TreeCallback& callback, + bool reverse = false); + IItem* itemFromIndex(const QModelIndex& index) const; + bool isActiveStationItem(const QModelIndex& index) const; + +private: + IRoboDK* _rdk = nullptr; + QTreeWidget* _tree = nullptr; + + uint32_t _filter = IgnoreInactiveStations; + + std::unordered_multimap _nameTable; + std::unordered_map _nameCache; +}; + + +inline void StationTreeEventMonitor::setFilter(uint32_t filter) +{ + _filter = filter; +} + +} // namespace robodk + +#endif // STATIONTREEEVENTMONITOR_H From 08992c5da303f96902e9275d7f8b4cb5faf8c677 Mon Sep 17 00:00:00 2001 From: VDm Date: Thu, 31 Jul 2025 19:02:34 +0400 Subject: [PATCH 08/11] feat(robodk_interface): add StationTreeEventMonitor::submit methods --- robodk_interface/stationtreeeventmonitor.cpp | 71 ++++++++++++-------- robodk_interface/stationtreeeventmonitor.h | 21 +++++- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/robodk_interface/stationtreeeventmonitor.cpp b/robodk_interface/stationtreeeventmonitor.cpp index bd5ade5..32f4a3b 100644 --- a/robodk_interface/stationtreeeventmonitor.cpp +++ b/robodk_interface/stationtreeeventmonitor.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "iitem.h" @@ -94,6 +95,44 @@ void StationTreeEventMonitor::refresh() }); } +void StationTreeEventMonitor::submit() +{ + bool child = false; + + auto addItem = [this, &child] (const QModelIndex& index) + { + auto item = itemFromIndex(index); + if (!item) + return; + + const QString name = index.data().toString(); + _nameTable.insert({name, item}); + _nameCache[item] = name; + + if (_filter & IgnoreAdd) + return; + + if ((_filter & IgnoreChildren) && child) + return; + + if ((_filter & IgnoreInactiveStations) && !isActiveStationItem(index)) + return; + + emit itemAdded(item); + }; + + for (const auto& index : _addedIndices) + { + child = false; + addItem(index); + + child = true; + iterateOverTree(index, addItem); + } + + _addedIndices.clear(); +} + void StationTreeEventMonitor::onModelDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight, @@ -174,37 +213,15 @@ void StationTreeEventMonitor::onModelDataChanged( void StationTreeEventMonitor::onModelRowsInserted(const QModelIndex& parent, int first, int last) { - auto addItem = [this, &parent] (const QModelIndex& index) - { - auto item = itemFromIndex(index); - if (!item) - return; - - const QString name = index.data().toString(); - _nameTable.insert({name, item}); - _nameCache[item] = name; - - if (_filter & IgnoreAdd) - return; - - if ((_filter & IgnoreChildren) && parent != index.parent()) - return; - - if ((_filter & IgnoreInactiveStations) && !isActiveStationItem(index)) - return; - - emit itemAdded(item); - }; - for (int row = first; row <= last; ++row) { auto index = _tree->model()->index(row, 0, parent); - if (!index.isValid()) - continue; - - addItem(index); - iterateOverTree(index, addItem); + if (index.isValid()) + _addedIndices.push_back(index); } + + if (_policy == AutoSubmit) + QTimer::singleShot(0, this, &StationTreeEventMonitor::submit); } void StationTreeEventMonitor::onModelRowsRemoved(const QModelIndex& parent, int first, int last) diff --git a/robodk_interface/stationtreeeventmonitor.h b/robodk_interface/stationtreeeventmonitor.h index c8608ef..58243bd 100644 --- a/robodk_interface/stationtreeeventmonitor.h +++ b/robodk_interface/stationtreeeventmonitor.h @@ -32,15 +32,16 @@ #include #include +#include #include #include #include #include +#include class QIcon; -class QModelIndex; class QTreeWidget; class QTreeWidgetItem; class IRoboDK; @@ -66,12 +67,17 @@ class StationTreeEventMonitor : public QObject IgnoreChildren = 0x00000020, }; + enum SubmitPolicy + { + AutoSubmit, + ManualSubmit + }; + public: explicit StationTreeEventMonitor(IRoboDK* rdk, QObject* parent = nullptr); void setFilter(uint32_t filter); - - void test(); + void setSubmitPolicy(SubmitPolicy policy); signals: void itemNameChanged(IItem* item, const QString& name); @@ -81,6 +87,7 @@ class StationTreeEventMonitor : public QObject public slots: void refresh(); + void submit(); private slots: void onModelDataChanged( @@ -111,9 +118,12 @@ private slots: QTreeWidget* _tree = nullptr; uint32_t _filter = IgnoreInactiveStations; + SubmitPolicy _policy = AutoSubmit; std::unordered_multimap _nameTable; std::unordered_map _nameCache; + + std::list _addedIndices; }; @@ -122,6 +132,11 @@ inline void StationTreeEventMonitor::setFilter(uint32_t filter) _filter = filter; } +inline void StationTreeEventMonitor::setSubmitPolicy(SubmitPolicy policy) +{ + _policy = policy; +} + } // namespace robodk #endif // STATIONTREEEVENTMONITOR_H From 069e9251aee9125d0c5ab0f21cb84c4589266a75 Mon Sep 17 00:00:00 2001 From: VDm Date: Fri, 15 Aug 2025 19:06:19 +0400 Subject: [PATCH 09/11] ci(windows): update plug-in-interface.yml --- .github/workflows/plug-in-interface.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/plug-in-interface.yml b/.github/workflows/plug-in-interface.yml index 94ebb98..78911fb 100644 --- a/.github/workflows/plug-in-interface.yml +++ b/.github/workflows/plug-in-interface.yml @@ -27,7 +27,7 @@ jobs: fail-fast: true matrix: include: - - os: windows-2019 + - os: windows-latest OUTPUT_DIR: C:/RoboDK/bin/plugins QT_VERSION: "5.15.2" From 3e7ed0cc4fcfd58c053a62a09333fa3d046dec2b Mon Sep 17 00:00:00 2001 From: VDm Date: Fri, 15 Aug 2025 19:45:28 +0400 Subject: [PATCH 10/11] ci(windows): update plug-in-interface.yml --- .github/workflows/plug-in-interface.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/plug-in-interface.yml b/.github/workflows/plug-in-interface.yml index 78911fb..a3a080f 100644 --- a/.github/workflows/plug-in-interface.yml +++ b/.github/workflows/plug-in-interface.yml @@ -51,14 +51,17 @@ jobs: cache: "true" cache-key-prefix: "install-qt-action-${{ matrix.os }}" + - name: Prepare Visual Studio environment on Windows + if: startsWith(matrix.os, 'windows') + uses: johnnynunez/vsdevenv-shell@v2 + - name: Configure and build Plug-In-Interface on Windows if: startsWith(matrix.os, 'windows') run: | cd ${{ github.workspace }} - call "%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64 qmake Plug-In-Interface.pro -spec win32-msvc CONFIG+=qtquickcompiler CONFIG+=${{ env.BUILD_TYPE }} call %IQTA_TOOLS%\QtCreator\bin\jom\jom.exe - shell: cmd + shell: vsdevenv x64 cmd {0} - name: Configure and build Plug-In-Interface on Unix if: (!startsWith(matrix.os, 'windows')) From aafaeb88b77976f606752603a2d7a5679d8b6858 Mon Sep 17 00:00:00 2001 From: VDm Date: Thu, 21 Aug 2025 13:37:53 +0400 Subject: [PATCH 11/11] chore: update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 0cc3378..f35c935 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,11 @@ Requirements ------------- Each RoboDK Plug-In must be developed using the Qt Creator and follow Qt's project guidelines. +For convenience in connecting the Plugin Interface to third-party projects, the `robodk_interface` folder contains a file with all dependencies. +This file can be included using the `include` directive in the qmake project: +``` +include($$PWD/../robodk_interface/robodk_interface.pri) +``` It is recommended to use the [PluginExample](./PluginExample/) project to get started with your new RoboDK Plug-In (double click PluginExample.pro to open it with Qt Creator). RoboDK must be installed to develop Plug-Ins. The free version of RoboDK is enough to develop a Plug-In as a proof of concept.