diff --git a/translations/fr/trikGui_fr.ts b/translations/fr/trikGui_fr.ts
index 5ad0a81b..b8d866db 100644
--- a/translations/fr/trikGui_fr.ts
+++ b/translations/fr/trikGui_fr.ts
@@ -414,48 +414,54 @@
-
+
Analog sensors
-
-
+
+
+ PWM Capture
+
+
+
+
+
Digital sensors
-
-
+
+
Encoders
-
-
+
+
Gyroscope
-
-
+
+
Accelerometer
-
-
+
+
Camera
-
-
+
+
Testing
-
+
More...
diff --git a/translations/ru/trikGui_ru.ts b/translations/ru/trikGui_ru.ts
index b8084fa0..0b96b499 100644
--- a/translations/ru/trikGui_ru.ts
+++ b/translations/ru/trikGui_ru.ts
@@ -472,48 +472,54 @@
-
+
Testing
Тестирование
-
+
More...
Еще...
-
+
Analog sensors
Аналоговые датчики
-
-
+
+
+ PWM Capture
+ ШИМ захват
+
+
+
+
Digital sensors
Цифровые датчики
-
-
+
+
Encoders
Энкодеры
-
-
+
+
Gyroscope
Гироскоп
-
-
+
+
Accelerometer
Акселерометр
-
-
+
+
Camera
Камера
diff --git a/trikControl/configs/kernel-3.6/system-config.xml b/trikControl/configs/kernel-3.6/system-config.xml
index 1a51cab1..1fc64a33 100644
--- a/trikControl/configs/kernel-3.6/system-config.xml
+++ b/trikControl/configs/kernel-3.6/system-config.xml
@@ -113,18 +113,18 @@ equal to its class name.
/>
diff --git a/trikControl/include/trikControl/pwmCaptureInterface.h b/trikControl/include/trikControl/pwmCaptureInterface.h
index 9afbec3f..cab945e6 100644
--- a/trikControl/include/trikControl/pwmCaptureInterface.h
+++ b/trikControl/include/trikControl/pwmCaptureInterface.h
@@ -28,12 +28,22 @@ class TRIKCONTROL_EXPORT PwmCaptureInterface : public QObject, public DeviceInte
{
Q_OBJECT
+public:
+ /// Gets minimal possible value for PWM capture reading received by duty() slot.
+ virtual long minValue() const = 0;
+
+ /// Gets maximal possible value for PWM capture reading received by duty() slot.
+ virtual long maxValue() const = 0;
+
public slots:
/// Returns three readings of PWM signal frequency.
virtual QVector frequency() = 0;
- /// Returns PWM signal duty.
- virtual int duty() = 0;
+ /// Returns scaled PWM signal duty.
+ virtual long duty() = 0;
+
+ /// Returns raw PWM signal duty.
+ virtual long dutyRaw() = 0;
};
}
diff --git a/trikControl/src/configurerHelper.cpp b/trikControl/src/configurerHelper.cpp
index 64f530f9..a7330e7f 100644
--- a/trikControl/src/configurerHelper.cpp
+++ b/trikControl/src/configurerHelper.cpp
@@ -45,6 +45,26 @@ int ConfigurerHelper::configureInt(const trikKernel::Configurer &configurer, Dev
}
}
+long ConfigurerHelper::configureLong(const trikKernel::Configurer &configurer, DeviceState &state, const QString &port
+ , const QString ¶meterName)
+{
+ try {
+ bool ok = false;
+ long parameter = configurer.attributeByPort(port, parameterName).toLong(&ok, 0);
+ if (!ok) {
+ QLOG_ERROR() << QString(R"(Incorrect configuration for parameter "%1" for port "%2": "%3" )")
+ .arg(parameterName).arg(port).arg(configurer.attributeByPort(port, parameterName));
+ state.fail();
+ return 0;
+ }
+
+ return parameter;
+ } catch (trikKernel::MalformedConfigException &) {
+ state.fail();
+ return 0;
+ }
+}
+
qreal ConfigurerHelper::configureReal(const trikKernel::Configurer &configurer, DeviceState &state, const QString &port
, const QString ¶meterName)
{
diff --git a/trikControl/src/configurerHelper.h b/trikControl/src/configurerHelper.h
index edd8fa35..bbbca9cf 100644
--- a/trikControl/src/configurerHelper.h
+++ b/trikControl/src/configurerHelper.h
@@ -38,6 +38,14 @@ class ConfigurerHelper
static int configureInt(const trikKernel::Configurer &configurer, DeviceState &state, const QString &port
, const QString ¶meterName);
+ /// Reads long integer parameter from configurer, modifies device state. Returns 0 if parameter is incorrect.
+ /// @param configurer - configurer object from which parameter will be read.
+ /// @param state - reference to device state, will be set to "fail" if parameter can not be read correctly.
+ /// @param port - port of a device.
+ /// @param parameterName - name of a parameter to read.
+ static long configureLong(const trikKernel::Configurer &configurer, DeviceState &state, const QString &port
+ , const QString ¶meterName);
+
/// Reads real parameter from configurer, modifies device state. Returns 0.0 if parameter is incorrect.
/// @param configurer - configurer object from which parameter will be read.
/// @param state - reference to device state, will be set to "fail" if parameter can not be read correctly.
diff --git a/trikControl/src/pwmCapture.cpp b/trikControl/src/pwmCapture.cpp
index db183f46..8fe39c52 100644
--- a/trikControl/src/pwmCapture.cpp
+++ b/trikControl/src/pwmCapture.cpp
@@ -14,11 +14,14 @@
#include "pwmCapture.h"
+#include
+
#include
#include
#include
#include
+#include "configurerHelper.h"
#include
@@ -38,6 +41,21 @@ PwmCapture::PwmCapture(const QString &port, const trikKernel::Configurer &config
mState.fail();
}
+ mMinValue = ConfigurerHelper::configureLong(configurer, mState, port, "minValue");
+ mMaxValue = ConfigurerHelper::configureLong(configurer, mState, port, "maxValue");
+ mMinValueScaled = ConfigurerHelper::configureLong(configurer, mState, port, "minValueScaled");
+ mMaxValueScaled = ConfigurerHelper::configureLong(configurer, mState, port, "maxValueScaled");
+
+ if (mMinValue == mMaxValue) {
+ QLOG_ERROR() << "PWM Capture configuration error: minValue = maxValue!";
+ mState.fail();
+ mK = 0;
+ mB = 0;
+ } else {
+ mK = static_cast(mMaxValueScaled - mMinValueScaled) / (mMaxValue - mMinValue);
+ mB = mMinValueScaled - mK * mMinValue;
+ }
+
mState.ready();
}
@@ -63,15 +81,39 @@ QVector PwmCapture::frequency()
return data;
}
-int PwmCapture::duty()
+long PwmCapture::duty()
+{
+ if (!mState.isReady()) {
+ return {};
+ }
+
+ long data = dutyRaw();
+
+ long result = std::min(mMaxValue, std::max(mMinValue, data));
+ result = mK * result + mB;
+
+ return result;
+}
+
+long PwmCapture::dutyRaw()
{
if (!mState.isReady()) {
return {};
}
mDutyFile->reset();
- int data = 0;
+ long data = 0;
char c = '\0';
mDutyFile->stream() >> data >> c;
return data;
}
+
+long PwmCapture::minValue() const
+{
+ return mMinValueScaled;
+}
+
+long PwmCapture::maxValue() const
+{
+ return mMaxValueScaled;
+}
diff --git a/trikControl/src/pwmCapture.h b/trikControl/src/pwmCapture.h
index 62f7cc9c..223cb892 100644
--- a/trikControl/src/pwmCapture.h
+++ b/trikControl/src/pwmCapture.h
@@ -46,17 +46,30 @@ class PwmCapture : public PwmCaptureInterface
Status status() const override;
+ long minValue() const override;
+
+ long maxValue() const override;
+
public slots:
/// Returns three readings of PWM signal frequency.
QVector frequency() override;
- /// Returns PWM signal duty.
- int duty() override;
+ /// Returns scaled PWM signal duty.
+ long duty() override;
+
+ /// Returns raw PWM signal duty.
+ long dutyRaw() override;
private:
QScopedPointer mFrequencyFile;
QScopedPointer mDutyFile;
DeviceState mState;
+ long mMinValue;
+ long mMaxValue;
+ long mMinValueScaled;
+ long mMaxValueScaled;
+ qreal mK;
+ qreal mB;
};
}
diff --git a/trikGui/pwmCaptureIndicator.cpp b/trikGui/pwmCaptureIndicator.cpp
new file mode 100644
index 00000000..beb4d2fb
--- /dev/null
+++ b/trikGui/pwmCaptureIndicator.cpp
@@ -0,0 +1,63 @@
+/* Copyright 2023 Nick Ponomarev
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. */
+
+#include "pwmCaptureIndicator.h"
+
+#include
+#include
+
+#include
+
+#include
+
+using namespace trikGui;
+
+PwmCaptureIndicator::PwmCaptureIndicator(const QString &port
+ , trikControl::PwmCaptureInterface &pwmCapture
+ , QWidget *parent)
+ : AbstractIndicator(parent)
+ , mPwmCapture(pwmCapture)
+ , mNameLabel(port)
+ , mValueLabel("0")
+{
+ mValueBar.setOrientation(Qt::Horizontal);
+ mValueBar.setMaximum(pwmCapture.maxValue());
+ mValueBar.setMinimum(pwmCapture.minValue());
+ mValueBar.setValue(0);
+ mValueBar.setTextVisible(false);
+ mValueBar.setAlignment(Qt::AlignRight);
+
+ mNameLabel.setAlignment(Qt::AlignLeft);
+ mValueLabel.setAlignment(Qt::AlignRight);
+ // mValueLabel can change its width during work. It will cause mValueBar
+ // width change. To prevent it, we set fixed width for mValueLabel.
+ // It is equal to maximum width of the widget which it achieves
+ // when the label text is set to "100".
+ mValueLabel.setFixedWidth(fontMetricsHorizontalAdvance(this, "WWWW"));
+ mLayout.addWidget(&mNameLabel);
+ mLayout.addWidget(&mValueBar);
+ mLayout.addWidget(&mValueLabel);
+ setLayout(&mLayout);
+
+ setFocusPolicy(Qt::StrongFocus);
+}
+
+void PwmCaptureIndicator::renew()
+{
+ int value = mPwmCapture.duty();
+ mValueLabel.setText(QString::number(value));
+ value = std::max(value, mValueBar.minimum());
+ value = std::min(value, mValueBar.maximum());
+ mValueBar.setValue(value);
+}
diff --git a/trikGui/pwmCaptureIndicator.h b/trikGui/pwmCaptureIndicator.h
new file mode 100644
index 00000000..d49a4f27
--- /dev/null
+++ b/trikGui/pwmCaptureIndicator.h
@@ -0,0 +1,54 @@
+/* Copyright 2023 Nick Ponomarev
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#include "abstractIndicator.h"
+
+namespace trikControl {
+class PwmCaptureInterface;
+}
+
+namespace trikGui {
+
+/// Widget that shows current PWM capture reading.
+class PwmCaptureIndicator : public AbstractIndicator
+{
+ Q_OBJECT
+
+public:
+ /// Constructor.
+ /// @param port - port to which PWM input is plugged.
+ /// @param pwmCapture - PWM duty value which we will read.
+ /// @param parent - parent of this widget in Qt widget parent-child system.
+ PwmCaptureIndicator(const QString &port, trikControl::PwmCaptureInterface &pwmCapture, QWidget *parent = nullptr);
+
+public slots:
+ void renew() override;
+
+private:
+ trikControl::PwmCaptureInterface &mPwmCapture;
+
+ QHBoxLayout mLayout;
+ QLabel mNameLabel;
+ QProgressBar mValueBar;
+ QLabel mValueLabel;
+};
+
+}
diff --git a/trikGui/sensorsWidget.cpp b/trikGui/sensorsWidget.cpp
index 1641f248..c02ee978 100644
--- a/trikGui/sensorsWidget.cpp
+++ b/trikGui/sensorsWidget.cpp
@@ -24,6 +24,7 @@
#include "gyroscopeIndicator.h"
#include "accelerometerWidget.h"
#include "cameraWidget.h"
+#include "pwmCaptureIndicator.h"
using namespace trikGui;
@@ -136,6 +137,9 @@ AbstractIndicator *SensorsWidget::produceIndicator(const QString &port, SensorTy
case SensorType::camera: {
return new CameraWidget(mBrick, this);
}
+ case SensorType::pwmCapture: {
+ return new PwmCaptureIndicator(port, *mBrick.pwmCapture(port), this);
+ }
}
return nullptr;
diff --git a/trikGui/sensorsWidget.h b/trikGui/sensorsWidget.h
index 3921d54f..2a67a89e 100644
--- a/trikGui/sensorsWidget.h
+++ b/trikGui/sensorsWidget.h
@@ -49,6 +49,7 @@ class SensorsWidget : public TrikGuiDialog
, gyroscope
, accelerometer
, camera
+ , pwmCapture
};
/// Constructor.
diff --git a/trikGui/startWidget.cpp b/trikGui/startWidget.cpp
index 1c64008b..08d31ed5 100644
--- a/trikGui/startWidget.cpp
+++ b/trikGui/startWidget.cpp
@@ -66,6 +66,9 @@ StartWidget::StartWidget(Controller &controller, QWidget *parent)
testingItem->appendRow(new QStandardItem(tr("Analog sensors")));
+ if (mController.brick().pwmCapturePorts().length() != 0) {
+ testingItem->appendRow(new QStandardItem(tr("PWM Capture")));
+ }
testingItem->appendRow(new QStandardItem(MotorsWidget::menuEntry(MotorInterface::Type::servoMotor)));
testingItem->appendRow(new QStandardItem(MotorsWidget::menuEntry(MotorInterface::Type::powerMotor)));
@@ -152,6 +155,13 @@ void StartWidget::launch()
SensorsWidget sensorsWidget(mController.brick(), ports, SensorsWidget::SensorType::analogOrDigitalSensor);
emit newWidget(sensorsWidget);
+ result = sensorsWidget.exec();
+ } else if (currentItemText == tr("PWM Capture")) {
+ ports = (mController.brick()).pwmCapturePorts();
+ ports.sort();
+ SensorsWidget sensorsWidget(mController.brick(), ports, SensorsWidget::SensorType::pwmCapture);
+ emit newWidget(sensorsWidget);
+
result = sensorsWidget.exec();
} else if (currentItemText == tr("Digital sensors")) {
ports = (mController.brick()).sensorPorts(trikControl::SensorInterface::Type::digitalSensor);
diff --git a/trikGui/trikGui.pro b/trikGui/trikGui.pro
index a564d865..472f8161 100644
--- a/trikGui/trikGui.pro
+++ b/trikGui/trikGui.pro
@@ -63,7 +63,8 @@ HEADERS += \
$$PWD/accelerometerWidget.h \
$$PWD/networkWidget.h \
$$PWD/fileSystemFilter.h \
- $$PWD/cameraWidget.h
+ $$PWD/cameraWidget.h \
+ $$PWD/pwmCaptureIndicator.h
SOURCES += \
$$PWD/autoRunner.cpp \
@@ -109,7 +110,8 @@ SOURCES += \
$$PWD/accelerometerWidget.cpp \
$$PWD/networkWidget.cpp \
$$PWD/fileSystemFilter.cpp \
- $$PWD/cameraWidget.cpp
+ $$PWD/cameraWidget.cpp \
+ $$PWD/pwmCaptureIndicator.cpp
TRANSLATIONS = \
$$PWD/../translations/ru/trikGui_ru.ts \
diff --git a/trikScriptRunner/include/trikScriptRunner/trikScriptRunnerInterface.h b/trikScriptRunner/include/trikScriptRunner/trikScriptRunnerInterface.h
index 8e4f4749..1f292d94 100644
--- a/trikScriptRunner/include/trikScriptRunner/trikScriptRunnerInterface.h
+++ b/trikScriptRunner/include/trikScriptRunner/trikScriptRunnerInterface.h
@@ -78,6 +78,7 @@
TEMPLATE(trikControl::VectorSensorInterface) \
TEMPLATE(trikNetwork::MailboxInterface) \
TEMPLATE(trikControl::LidarInterface) \
+ TEMPLATE(trikControl::PwmCaptureInterface) \
namespace trikScriptRunner {