Skip to content

Commit 7ff9657

Browse files
authored
TRIK feature: Add a metric system (trikset#1959)
* Add a metric system * Implicitly set default unit in twoDModelWidget * Change precision for Pixels in Cm spinbox * Fix clazy warnings * Fix Vera issues * Fix all clazy warnings --------- Co-authored-by: iakov <iakov@users.noreply.github.com> --------- This `pull request` is one of many proposed ones and is the first step towards updating `twoDModel`. This `pull request` does not address issues related to the `physical parameters` of `world items` or (for example) the ability to resize objects (unless this is already implemented in the previous version). 1. Add the `sizeUnit`(`mm`, `m`, `cm`) field to the <settings> tag in the `WorldModel xml` to specify units of measurement when working with items. 2. Thus, the `coordinates`, `starting position`, and `sizes` for all objects specified in `WorldModel xml` (`robot`, `sensor`, `ball`, `region`, ...) will be interpreted based on the value of the 'sizeUnit` field (pixels by default). 3. The user interface for selecting units of measurement is located in the panel on the bottom right. Changing the unit of measurement implies changing the `Grid` (as well as loading the `WorldModel`) and also affects the further serialization of objects. <img width="1481" height="913" alt="image" src="https://github.com/user-attachments/assets/f9f6286c-7e0b-46e5-a402-8ea3355f874d" /> 4. This functionality is only used for `TRIK twoDModel`. When using the `sizeUnit` field with older `TRIK Studio` versions, all values will be interpreted by default (`pixels`). 5. Add unit tests for `WorldModel` deserialization. 6. Also, in the future, it is necessary to consider the possibility of changing parameters in the `UI` with `PopupItem` in the current units of measurement, as well as making the `Pixels in cm` field editable (part of the next pull request).
1 parent 0e0e6ac commit 7ff9657

File tree

90 files changed

+2229
-706
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+2229
-706
lines changed

plugins/robots/common/kitBase/include/kitBase/robotModel/configuration.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ class ROBOTS_KIT_BASE_EXPORT Configuration : public ConfigurationInterface
4242

4343
void clearDevice(const PortInfo &port) override;
4444

45-
signals:
45+
Q_SIGNALS:
4646
/// Emitted when all pending devices are configured (or failed to configure).
4747
void allDevicesConfigured();
4848

49-
private slots:
49+
private Q_SLOTS:
5050
/// Called when some device is finished configuring.
5151
/// @param success - true if configuration was successful.
5252
void onDeviceConfigured(bool success);

plugins/robots/common/kitBase/include/kitBase/robotModel/configurationInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ROBOTS_KIT_BASE_EXPORT ConfigurationInterface : public QObject
5353
/// Removes device on a given port from configuration.
5454
virtual void clearDevice(const PortInfo &port) = 0;
5555

56-
signals:
56+
Q_SIGNALS:
5757
/// Emitted when some device is ready to be used.
5858
void deviceConfigured(robotParts::Device *device);
5959
};

plugins/robots/common/kitBase/include/kitBase/robotModel/portInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ inline bool operator !=(const PortInfo &left, const PortInfo &right)
9797
return !(left == right);
9898
}
9999

100-
inline uint qHash(const PortInfo &key)
100+
inline size_t qHash(const PortInfo &key)
101101
{
102102
return qHash(key.name()) ^ qHash(QString(key.direction() == input ? "input" : "output"));
103103
}

plugins/robots/common/kitBase/include/kitBase/robotModel/robotModelInterface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,11 @@ class ROBOTS_KIT_BASE_EXPORT RobotModelInterface : public QObject
180180
/// failures in common code.
181181
virtual utils::TimelineInterface &timeline() = 0;
182182

183-
public slots:
183+
public Q_SLOTS:
184184
/// Called each time when interpretation starts its work. Implementation must reset robot to its default state.
185185
virtual void onInterpretationStarted() = 0;
186186

187-
signals:
187+
Q_SIGNALS:
188188
/// Emitted when model is connected to a robot. If there is no need to connect (for example, 2d model), emitted
189189
/// immediately after connectToRobot() call.
190190
/// @param success - true, if connected successfully.

plugins/robots/common/kitBase/include/kitBase/robotModel/robotParts/device.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class ROBOTS_KIT_BASE_EXPORT Device : public QObject
5454
/// Configure device.
5555
void configure();
5656

57-
signals:
57+
Q_SIGNALS:
5858
/// Emitted when device finished its configuration, successfully or by failure. Note that configuration can be
5959
/// synchronous or asynchronous for various devices (configure() can be in a stack when this signal is emitted).
6060
/// Shall not be emitted directly from descendants, use configurationCompleted() instead due to timeout handling
@@ -73,7 +73,7 @@ class ROBOTS_KIT_BASE_EXPORT Device : public QObject
7373
/// Concrete devices shall call this method when they finish their configuration.
7474
void configurationCompleted(bool success);
7575

76-
private slots:
76+
private Q_SLOTS:
7777
/// Called when configuration takes more than timeout time. Note that if configuration is done synchronously,
7878
/// timer signal will never be emitted and this slot will not be called.
7979
void configurationTimerTimeoutSlot();
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* Copyright 2025 CyberTech Labs Ltd.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License. */
14+
15+
#pragma once
16+
#include <QObject>
17+
#include <QPointer>
18+
#include <qrutils/graphicsUtils/abstractCoordinateSystem.h>
19+
20+
namespace twoDModel {
21+
22+
namespace model {
23+
24+
class SizeUnit;
25+
26+
/// The metric system, which is an implementation of the qrutils
27+
/// AbstractCoordinateSystem interface for using the metric system in 2D model items
28+
class MetricCoordinateSystem: public graphicsUtils::AbstractCoordinateSystem
29+
{
30+
Q_OBJECT
31+
public:
32+
explicit MetricCoordinateSystem(twoDModel::model::SizeUnit *metricSystem,
33+
QObject* parent = nullptr);
34+
35+
~MetricCoordinateSystem();
36+
37+
/// Conversе of units of measurement into pixels
38+
qreal toPx(const qreal size) const override;
39+
40+
/// Conversе of QPointF into pixels
41+
QPointF toPx(const QPointF &size) const override;
42+
43+
/// Converting pixels to units of measurement
44+
qreal toUnit(const qreal size) const override;
45+
46+
/// Converting pixels to QPointF
47+
QPointF toUnit(const QPointF &size) const override;
48+
private:
49+
// Doesn't take ownership, ownership is twoDModel::model::Settings.
50+
// The lifetime of this object is greater than MetricCoordinateSystem (see Model.h)
51+
QPointer<twoDModel::model::SizeUnit> mMetricSystem;
52+
};
53+
54+
}
55+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* Copyright 2025 CyberTech Labs Ltd.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License. */
14+
15+
#pragma once
16+
17+
#include <QtCore/QObject>
18+
#include "constants.h"
19+
#include "twoDModel/twoDModelDeclSpec.h"
20+
21+
class QDomElement;
22+
23+
namespace twoDModel {
24+
namespace model {
25+
26+
/// Incapsulates size unit settings used by 2D model.
27+
class TWO_D_MODEL_EXPORT SizeUnit : public QObject
28+
{
29+
Q_OBJECT
30+
31+
public:
32+
/// Possible units of measurement
33+
enum class Unit {
34+
Pixels
35+
, Centimeters
36+
, Meters
37+
, Millimeters
38+
};
39+
40+
SizeUnit() = default;
41+
42+
/// The current pixel value in centimeters
43+
qreal pixelsInCm() const;
44+
45+
/// Serialize the sizeUnit in the WorldModel
46+
void serialize(QDomElement &parent) const;
47+
48+
/// Derialize the sizeUnit in the WorldModel
49+
void deserialize(const QDomElement &parent);
50+
51+
/// Set the current unit of measurement
52+
void setUnit(twoDModel::model::SizeUnit::Unit unit);
53+
54+
/// Multiplier for conversion to pixels
55+
qreal countFactor() const;
56+
57+
/// Convert size from WorldModel to pixels
58+
qreal toPx(const qreal size) const;
59+
60+
std::map<QString, Unit> currentValues() const;
61+
62+
Unit defaultUnit() const;
63+
64+
Q_SIGNALS:
65+
/// Emit when the sizeUnit is serialized
66+
void sizeUnitChanged(const twoDModel::model::SizeUnit::Unit &unit);
67+
68+
private:
69+
Unit mSizeUnit { Unit::Pixels };
70+
qreal mPixelsInCm { twoDModel::pixelsInCm };
71+
};
72+
73+
}
74+
}
75+
76+
Q_DECLARE_METATYPE(twoDModel::model::SizeUnit::Unit)

plugins/robots/common/twoDModel/include/twoDModel/engine/model/model.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "robotModel.h"
1919
#include "timeline.h"
2020
#include "settings.h"
21+
#include "metricCoordinateSystem.h"
2122
#include <twoDModel/robotModel/twoDRobotModel.h>
2223

2324
#include "twoDModel/twoDModelDeclSpec.h"
@@ -39,14 +40,20 @@ class ConstraintsChecker;
3940

4041
namespace model {
4142

43+
namespace physics {
44+
class PhysicsEngineFactory;
45+
}
46+
4247
/// A main class managing model part of 2D emulator. Creates and maintains different parts
4348
/// such as world map, robot model, timelines and physical engines.
4449
class TWO_D_MODEL_EXPORT Model : public QObject
4550
{
4651
Q_OBJECT
4752

4853
public:
49-
explicit Model(QObject *parent = nullptr);
54+
/// Dependency injection for the physics engine
55+
explicit Model(physics::PhysicsEngineFactory *engineFactory,
56+
QObject *parent = nullptr);
5057
~Model();
5158

5259
void init(qReal::ErrorReporterInterface &errorReporter
@@ -65,6 +72,9 @@ class TWO_D_MODEL_EXPORT Model : public QObject
6572
/// Returns a reference to a 2D model`s settings storage.
6673
Settings &settings();
6774

75+
/// Metric coordinate system for usage in twoDModelWidget
76+
MetricCoordinateSystem &coordinateMetricSystem();
77+
6878
/// Returns a pointer to an object that reports system errors.
6979
qReal::ErrorReporterInterface *errorReporter();
7080

@@ -74,7 +84,7 @@ class TWO_D_MODEL_EXPORT Model : public QObject
7484
/// Add new robot model
7585
/// @param robotModel Model to be added
7686
/// @param pos Initial positon of robot model
77-
void addRobotModel(robotModel::TwoDRobotModel &robotModel, const QPointF &pos = QPointF());
87+
void addRobotModel(robotModel::TwoDRobotModel &robotModel, QPointF pos = QPointF());
7888

7989
/// Remove robot model
8090
void removeRobotModel();
@@ -88,7 +98,7 @@ class TWO_D_MODEL_EXPORT Model : public QObject
8898
/// Activates or deactivates constraints checker.
8999
void setConstraintsEnabled(bool enabled);
90100

91-
signals:
101+
Q_SIGNALS:
92102
/// Emitted each time when some user actions lead to world model modifications
93103
/// @param xml World model description in xml format
94104
void modelChanged(const QDomDocument &xml);
@@ -99,28 +109,30 @@ class TWO_D_MODEL_EXPORT Model : public QObject
99109

100110
/// Emitted after new robot model added
101111
/// @param robotModel Pointer to robot model which was removed
102-
void robotAdded(RobotModel *robotModel);
112+
void robotAdded(twoDModel::model::RobotModel *robotModel);
103113

104114
/// Emitted after robot model removed
105115
/// @param robotModel Pointer to robot model which was added
106-
void robotRemoved(RobotModel *robotModel);
116+
void robotRemoved(twoDModel::model::RobotModel *robotModel);
107117

108-
private slots:
118+
private Q_SLOTS:
109119
void resetPhysics();
110120
void recalculatePhysicsParams();
111121

112122
private:
113123
void initPhysics();
114124

115-
Settings mSettings;
125+
QPointer<Settings> mSettings; //Has ownership
126+
QPointer<MetricCoordinateSystem> mMetricCoordinateSystem; //Has ownership
116127
WorldModel mWorldModel;
117128
Timeline mTimeline;
118129
QScopedPointer<constraints::ConstraintsChecker> mChecker;
119130
RobotModel * mRobotModel {}; //Has ownership
120131
qReal::ErrorReporterInterface *mErrorReporter; // Doesn`t take ownership.
121132
qReal::LogicalModelAssistInterface *mLogicalModel; // Doesn`t take ownership.
122-
physics::PhysicsEngineBase *mRealisticPhysicsEngine; // Takes ownership.
123-
physics::PhysicsEngineBase *mSimplePhysicsEngine; // Takes ownership.
133+
QScopedPointer<physics::PhysicsEngineFactory> mEngineFactory;
134+
physics::PhysicsEngineBase *mRealisticPhysicsEngine {}; // Takes ownership.
135+
physics::PhysicsEngineBase *mSimplePhysicsEngine {}; // Takes ownership.
124136
quint64 mStartTimestamp {0};
125137
};
126138

plugins/robots/common/twoDModel/include/twoDModel/engine/model/robotModel.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class StartPosition;
3535

3636
namespace model {
3737

38+
class MetricCoordinateSystem;
3839
class Settings;
3940
namespace physics {
4041
class PhysicsEngineBase;
@@ -76,7 +77,9 @@ class TWO_D_MODEL_EXPORT RobotModel : public QObject
7677
};
7778

7879
RobotModel(twoDModel::robotModel::TwoDRobotModel &robotModel
79-
, const Settings &settings, QObject *parent = nullptr);
80+
, Settings *settings
81+
, twoDModel::model::MetricCoordinateSystem *metricSystem
82+
, QObject *parent = nullptr);
8083

8184
~RobotModel();
8285

@@ -104,7 +107,7 @@ class TWO_D_MODEL_EXPORT RobotModel : public QObject
104107
Q_INVOKABLE void resetEncoder(const kitBase::robotModel::PortInfo &port);
105108

106109
QPointF position() const;
107-
void setPosition(const QPointF &newPos);
110+
void setPosition(QPointF newPos);
108111

109112
qreal rotation() const;
110113
void setRotation(qreal angle);
@@ -126,6 +129,7 @@ class TWO_D_MODEL_EXPORT RobotModel : public QObject
126129
void onRobotReturnedOnGround();
127130

128131
void setMotorPortOnWheel(WheelEnum wheel, const kitBase::robotModel::PortInfo &port);
132+
kitBase::robotModel::PortInfo getPortInfoOnWheel(WheelEnum wheel) const;
129133

130134
QRectF sensorRect(const kitBase::robotModel::PortInfo &port, const QPointF sensorPos) const;
131135
QPainterPath sensorBoundingPath(const kitBase::robotModel::PortInfo &port) const;
@@ -186,7 +190,8 @@ public slots:
186190
void playingSoundChanged(bool playing);
187191

188192
/// Emitted when left or right wheel was reconnected to another port.
189-
void wheelOnPortChanged(WheelEnum wheel, const kitBase::robotModel::PortInfo &port);
193+
void wheelOnPortChanged(twoDModel::model::RobotModel::WheelEnum wheel,
194+
const kitBase::robotModel::PortInfo &port);
190195

191196
private:
192197
QVector2D robotDirectionVector() const;
@@ -218,10 +223,11 @@ public slots:
218223
/// Describes which wheel is driven by which motor.
219224
QHash<WheelEnum, kitBase::robotModel::PortInfo> mWheelsToMotorPortsMap;
220225
QHash<kitBase::robotModel::PortInfo, kitBase::robotModel::PortInfo> mMotorToEncoderPortMap;
221-
222-
const Settings &mSettings;
226+
// Doesn't take ownership, ownership is twoDModel::model::Model.
227+
QPointer<Settings> mSettings;
223228
twoDModel::robotModel::TwoDRobotModel &mRobotModel;
224-
SensorsConfiguration mSensorsConfiguration;
229+
// Takes ownership.
230+
QPointer<SensorsConfiguration> mSensorsConfiguration;
225231

226232
QPointF mPos { 0, 0 };
227233
qreal mAngle { 0 };
@@ -238,6 +244,8 @@ public slots:
238244
physics::PhysicsEngineBase *mPhysicsEngine {}; // Does not take ownership
239245

240246
QPointer<items::StartPosition> mStartPositionMarker;
247+
// Doesn't take ownership, ownership is twoDModel::model::Model.
248+
QPointer<twoDModel::model::MetricCoordinateSystem> mMetricSystem;
241249
};
242250

243251
}

0 commit comments

Comments
 (0)