From 1ba252ffc18fdbadf648f74abdfaa00ac3fb12ce Mon Sep 17 00:00:00 2001
From: Jan Hausberg <jan.hausberg@kit.edu>
Date: Tue, 21 Jun 2022 16:21:44 +0200
Subject: [PATCH] Update HandUnitGuiPlugin UI and functionality for the left
 hand

---
 .../HandUnitPlugin/HandUnitGuiPlugin.cpp      | 191 +++++++++++-------
 .../HandUnitPlugin/HandUnitGuiPlugin.h        |   7 +-
 .../HandUnitPlugin/HandUnitGuiPlugin.ui       |  95 ++++++---
 3 files changed, 200 insertions(+), 93 deletions(-)

diff --git a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.cpp b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.cpp
index 438e65788..7233e276e 100644
--- a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.cpp
+++ b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.cpp
@@ -38,6 +38,7 @@
 #include <QtWidgets/QSlider>
 #include <QtWidgets/QGridLayout>
 #include <QtWidgets/QLabel>
+#include <QtWidgets/QTableWidgetItem>
 #include <QString>
 
 #include <cmath>
@@ -59,7 +60,7 @@ namespace armarx
         // init gui
         ui.setupUi(getWidget());
 
-        leftHandJointAngleUpdateTask = new PeriodicTask<HandUnitWidget>(this, &HandUnitWidget::setLeftHandJointAngles, 50);
+        setLeftHandJointAngleUpdateTask = new PeriodicTask<HandUnitWidget>(this, &HandUnitWidget::setLeftHandJointAngles, 50);
         rightHandJointAngleUpdateTask = new PeriodicTask<HandUnitWidget>(this, &HandUnitWidget::setRightHandJointAngles, 50);
         updateInfoTimer = new QTimer(this);
     }
@@ -75,22 +76,21 @@ namespace armarx
 
     void HandUnitWidget::onConnectComponent()
     {
-        initGUIJointFrames();
         updateInfoTimer->start(50);
 
-        leftHandJointAngleUpdateTask->start();
+        setLeftHandJointAngleUpdateTask->start();
 
         leftHandUnitProxy = getProxy<HandUnitInterfacePrx>(leftHandUnitProxyName);
         leftHandName = leftHandUnitProxy->getHandName();
 
-        // @@@ In simulation hand is called 'Hand L'/'Hand R'. On 3b Hand is called 'TCP R'
-        if (leftHandName != "Hand L" && leftHandName != "TCP L")
+        if (leftHandName == "Hand L" || leftHandName == "TCP L")
         {
-            //QMessageBox::warning(NULL, "Hand not supported", QString("Hand with name \"") + QString::fromStdString(handName) + " \" is not suppored.");
-            ARMARX_WARNING << "Hand with name \"" << leftHandName << "\" is not supported.";
+            leftHandConversionFactor *= M_PI / 2;
+        }
+        else if (leftHandName != "Hand_L_EEF")
+        {
+            ARMARX_WARNING << "Left hand with name \"" << leftHandName << "\" is not supported.";
         }
-
-        //ui.labelInfo->setText(QString::fromStdString(handUnitProxyName + " :: " + handName));
 
         SingleTypeVariantListPtr leftHandPreshapeStrings = SingleTypeVariantListPtr::dynamicCast(leftHandUnitProxy->getShapeNames());
         QStringList leftHandList;
@@ -99,6 +99,7 @@ namespace armarx
         for (int i = 0; i < leftHandPreshapeCount; ++i)
         {
             std::string shape = ((leftHandPreshapeStrings->getVariant(i))->get<std::string>());
+//            ARMARX_INFO << VAROUT(shape);
             leftHandList << QString::fromStdString(shape);
         }
 
@@ -112,10 +113,9 @@ namespace armarx
         rightHandUnitProxy = getProxy<HandUnitInterfacePrx>(rightHandUnitProxyName);
         rightHandName = rightHandUnitProxy->getHandName();
 
-        // @@@ In simulation hand is called 'Hand L'/'Hand R'. On 3b Hand is called 'TCP R'
-        if (rightHandName != "Hand R" && rightHandName != "TCP R")
+        if (rightHandName != "Hand R" && rightHandName != "TCP R" && rightHandName != "Hand_R_EEF")
         {
-            ARMARX_WARNING << "Hand with name \"" << rightHandName << "\" is not supported.";
+            ARMARX_WARNING << "Right hand with name \"" << rightHandName << "\" is not supported.";
         }
 
         SingleTypeVariantListPtr rightHandPreshapeStrings = SingleTypeVariantListPtr::dynamicCast(rightHandUnitProxy->getShapeNames());
@@ -130,12 +130,20 @@ namespace armarx
 
         ui.comboRightHandPreshapes->clear();
         ui.comboRightHandPreshapes->addItems(rightHandList);
+
+
+
+        ARMARX_INFO << "initGUIJointFrames";
+        initGUIJointFrames();
+        displayJointAngleUpdateTask = new PeriodicTask<HandUnitWidget>(this, &HandUnitWidget::updateJointValueTable, 50);
+        displayJointAngleUpdateTask->start();
     }
 
     void HandUnitWidget::onDisconnectComponent()
     {
-        leftHandJointAngleUpdateTask->stop();
+        setLeftHandJointAngleUpdateTask->stop();
         rightHandJointAngleUpdateTask->stop();
+        displayJointAngleUpdateTask->stop();
         updateInfoTimer->stop();
     }
 
@@ -173,6 +181,7 @@ namespace armarx
 
     void HandUnitWidget::setLeftHandJointAngles()
     {    
+//        ARMARX_INFO << "setLeftHandJointAngles";
         if (!leftHandUnitProxy)
         {
             ARMARX_WARNING << "invalid proxy";
@@ -188,26 +197,30 @@ namespace armarx
 
         NameValueMap leftHandJa;
         NameValueMap currentLeftHandJointValues = leftHandUnitProxy->getCurrentJointValues();
-
-        if (leftHandName == "Hand L EEF")
+        float value = 0;
+        if (leftHandName == "Hand L" || leftHandName == "TCP L")
         {
-            for (const auto& pair : currentLeftHandJointValues)
-            {
-                leftHandJa[pair.first] = ui.frameLeftHand->findChild<QSlider *>(pair.first.c_str())->value();
-            }
+            leftHandConversionFactor *= M_PI / 2;
         }
-        else if (leftHandName == "Hand L" || leftHandName == "TCP L")
+        else if (leftHandName != "Hand_L_EEF")
         {
-            for (const auto& pair : currentLeftHandJointValues)
-            {
-                leftHandJa[pair.first] = ui.frameLeftHand->findChild<QSlider *>(pair.first.c_str())->value() * M_PI / 2;
-            }
+            ARMARX_WARNING << "Left hand with name \"" << leftHandName << "\" is not supported.";
+            return;
         }
-        else
+
+        for (const auto& pair : currentLeftHandJointValues)
         {
-            ARMARX_WARNING << "Left hand with name \"" << leftHandName << "\" is not supported.";
+            if (pair.first == currentLeftHandJoint)
+            {
+                value = static_cast<float>(ui.horizontalSliderLeftHandJointPos->value() * leftHandConversionFactor);
+                ARMARX_INFO << VAROUT(value);
+                leftHandJa[pair.first] = value;
+                break;
+            }
         }
 
+        ARMARX_INFO << VAROUT(value / leftHandConversionFactor);
+        ui.lcdNumberLeftHandJointValue->display(value / leftHandConversionFactor);
         leftHandUnitProxy->setJointAngles(leftHandJa);
     }
 
@@ -229,18 +242,18 @@ namespace armarx
         NameValueMap rightHandJa;
         NameValueMap currentRightHandJointValues = rightHandUnitProxy->getCurrentJointValues();
 
-        if (rightHandName == "Hand L EEF")
+        if (rightHandName == "Hand_R_EEF")
         {
             for (const auto& pair : currentRightHandJointValues)
             {
-                rightHandJa[pair.first] = ui.frameRightHand->findChild<QSlider *>(pair.first.c_str())->value();
+                rightHandJa[pair.first] = ui.frameRightHand->findChild<QSlider *>("horizontalSlider" + QString::fromUtf8(pair.first.c_str()))->value() / 100.0f;
             }
         }
-        else if (rightHandName == "Hand L" || rightHandName == "TCP L")
+        else if (rightHandName == "Hand R" || rightHandName == "TCP R")
         {
             for (const auto& pair : currentRightHandJointValues)
             {
-                rightHandJa[pair.first] = ui.frameRightHand->findChild<QSlider *>(pair.first.c_str())->value() * M_PI / 2;
+                rightHandJa[pair.first] = ui.frameRightHand->findChild<QSlider *>("horizontalSlider" + QString::fromUtf8(pair.first.c_str()))->value() / 100.0f * M_PI / 2;
             }
         }
         else
@@ -297,6 +310,43 @@ namespace armarx
         ui.labelInfoRightHand->setText(QString::fromStdString(rightHandUnitProxyName + " :: " + rightHandName + " State: " + rightHandUnitProxy->describeHandState()));
     }
 
+    void HandUnitWidget::updateJointValueTable()
+    {
+        NameValueMap currentLeftHandJointValues = leftHandUnitProxy->getCurrentJointValues();
+//        ARMARX_INFO << VAROUT(leftHandUnitProxy->getCurrentJointValues());
+        int frameLeftHandRowIdx = 0;
+
+        for (const auto& pair : currentLeftHandJointValues)
+        {
+//            ARMARX_INFO << VAROUT(pair.first);
+            QString name(pair.first.c_str());
+            QTableWidgetItem* newItem = new QTableWidgetItem(QString::number(pair.second));
+            ui.tableWidgetLeftHand->setItem(frameLeftHandRowIdx, 1, newItem);
+            frameLeftHandRowIdx++;
+        }
+    }
+
+    void HandUnitWidget::selectLeftHandJoint(int i)
+    {
+        ARMARX_INFO << "selectLeftHandJoint " << i;
+        NameValueMap currentLeftHandJointValues = leftHandUnitProxy->getCurrentJointValues();
+        int idx = 0;
+
+        for (const auto& pair: currentLeftHandJointValues)
+        {
+            if (idx == i)
+            {
+                currentLeftHandJoint = pair.first;
+                int convertedValue = static_cast<int>(pair.second / leftHandConversionFactor);
+                ui.horizontalSliderLeftHandJointPos->setSliderPosition(convertedValue);
+                ui.lcdNumberLeftHandJointValue->display(convertedValue);
+                ARMARX_INFO << "Found joint";
+                break;
+            }
+            idx++;
+        }
+    }
+
     void HandUnitWidget::setLeftHandPreshape(std::string preshape)
     {
         ARMARX_INFO << "Setting new left hand shape: " << preshape;
@@ -329,66 +379,69 @@ namespace armarx
     void HandUnitWidget::initGUIJointFrames()
     {
         NameValueMap currentLeftHandJointValues = leftHandUnitProxy->getCurrentJointValues();
-        QGridLayout* gridLayoutLeftHand = new QGridLayout(ui.frameLeftHand);
+//        ARMARX_INFO << VAROUT(leftHandUnitProxy->getCurrentJointValues());
         int frameLeftHandRowIdx = 0;
 
         connect(ui.buttonPreshapeLeftHand, SIGNAL(clicked()), this, SLOT(preshapeLeftHand()), Qt::UniqueConnection);
         connect(ui.buttonOpenLeftHand, SIGNAL(clicked()), this, SLOT(openLeftHand()), Qt::UniqueConnection);
         connect(ui.buttonCloseLeftHand, SIGNAL(clicked()), this, SLOT(closeLeftHand()), Qt::UniqueConnection);
         connect(ui.buttonRelaxLeftHand, SIGNAL(clicked()), this, SLOT(relaxLeftHand()), Qt::UniqueConnection);
-        connect(ui.buttonSetLeftHandJointAngles, SIGNAL(clicked()), this, SLOT(requestSetLeftHandJointAngles()), Qt::UniqueConnection);
+        ui.horizontalSliderLeftHandJointPos->setMaximum(100);
+        ui.horizontalSliderLeftHandJointPos->setMinimum(0);
+        connect(ui.horizontalSliderLeftHandJointPos, SIGNAL(sliderMoved(int)), this, SLOT(requestSetLeftHandJointAngles()), Qt::UniqueConnection);
+        connect(ui.comboLeftHandJoints, SIGNAL(currentIndexChanged(int)), this, SLOT(selectLeftHandJoint(int)), Qt::UniqueConnection);
 
-        for (const auto& pair : currentLeftHandJointValues)
-        {
-            QLabel* label = new QLabel(ui.frameLeftHand);
-            label->setText(QString::fromUtf8(pair.first.c_str()));
-            gridLayoutLeftHand->addWidget(label, frameLeftHandRowIdx, 0, 1, 1);
+        ui.tableWidgetLeftHand->setRowCount(currentLeftHandJointValues.size());
+        ui.tableWidgetLeftHand->setColumnCount(2);
 
-            QSlider* horizontalSlider = new QSlider(ui.frameLeftHand);
-            horizontalSlider->setObjectName("horizontalSlider" + QString::fromUtf8(pair.first.c_str()));
-            horizontalSlider->setMaximum(1);
-            horizontalSlider->setOrientation(Qt::Horizontal);
-            connect(horizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(requestSetLeftHandJointAngles()), Qt::UniqueConnection);
-            gridLayoutLeftHand->addWidget(horizontalSlider, frameLeftHandRowIdx, 1, 1, 2);
+        ui.comboLeftHandJoints->clear();
 
+        qRegisterMetaType<QVector<int> >("QVector<int>");
+        for (const auto& pair : currentLeftHandJointValues)
+        {
+//            ARMARX_INFO << VAROUT(pair.first);
+            QString name(pair.first.c_str());
+            QTableWidgetItem* newItem = new QTableWidgetItem(name);
+            ui.tableWidgetLeftHand->setItem(frameLeftHandRowIdx, 0, newItem);
+            ui.comboLeftHandJoints->addItem(name);
             frameLeftHandRowIdx++;
         }
 
-        ui.frameLeftHand->setLayout(gridLayoutLeftHand);
+        ui.comboLeftHandJoints->setCurrentIndex(-1);
 
 
 
-        NameValueMap currentRightHandJointValues = rightHandUnitProxy->getCurrentJointValues();
-        QGridLayout* gridLayoutRightHand = new QGridLayout(ui.frameRightHand);
-        int frameRightHandRowIdx = 0;
+//        NameValueMap currentRightHandJointValues = rightHandUnitProxy->getCurrentJointValues();
+//        QGridLayout* gridLayoutRightHand = new QGridLayout(ui.frameRightHand);
+//        int frameRightHandRowIdx = 0;
 
-        connect(ui.buttonPreshapeRightHand, SIGNAL(clicked()), this, SLOT(preshapeRightHand()), Qt::UniqueConnection);
-        connect(ui.buttonOpenRightHand, SIGNAL(clicked()), this, SLOT(openRightHand()), Qt::UniqueConnection);
-        connect(ui.buttonCloseRightHand, SIGNAL(clicked()), this, SLOT(closeRightHand()), Qt::UniqueConnection);
-        connect(ui.buttonRelaxRightHand, SIGNAL(clicked()), this, SLOT(relaxRightHand()), Qt::UniqueConnection);
-        connect(ui.buttonSetRightHandJointAngles, SIGNAL(clicked()), this, SLOT(requestSetRightHandJointAngles()), Qt::UniqueConnection);
+//        connect(ui.buttonPreshapeRightHand, SIGNAL(clicked()), this, SLOT(preshapeRightHand()), Qt::UniqueConnection);
+//        connect(ui.buttonOpenRightHand, SIGNAL(clicked()), this, SLOT(openRightHand()), Qt::UniqueConnection);
+//        connect(ui.buttonCloseRightHand, SIGNAL(clicked()), this, SLOT(closeRightHand()), Qt::UniqueConnection);
+//        connect(ui.buttonRelaxRightHand, SIGNAL(clicked()), this, SLOT(relaxRightHand()), Qt::UniqueConnection);
+//        connect(ui.buttonSetRightHandJointAngles, SIGNAL(clicked()), this, SLOT(requestSetRightHandJointAngles()), Qt::UniqueConnection);
 
-        for (const auto& pair : currentRightHandJointValues)
-        {
-            QLabel* label = new QLabel(ui.frameRightHand);
-            label->setText(QString::fromUtf8(pair.first.c_str()));
-            gridLayoutRightHand->addWidget(label, frameRightHandRowIdx, 0, 1, 1);
-
-            QSlider* horizontalSlider = new QSlider(ui.frameRightHand);
-            horizontalSlider->setObjectName("horizontalSlider" + QString::fromUtf8(pair.first.c_str()));
-            horizontalSlider->setMaximum(1);
-            horizontalSlider->setOrientation(Qt::Horizontal);
-            connect(horizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(requestSetRightHandJointAngles()), Qt::UniqueConnection);
-            gridLayoutRightHand->addWidget(horizontalSlider, frameRightHandRowIdx, 1, 1, 2);
-
-            frameRightHandRowIdx++;
-        }
+//        for (const auto& pair : currentRightHandJointValues)
+//        {
+//            QLabel* label = new QLabel(ui.frameRightHand);
+//            label->setText(QString::fromUtf8(pair.first.c_str()));
+//            gridLayoutRightHand->addWidget(label, frameRightHandRowIdx, 0, 1, 1);
+
+//            QSlider* horizontalSlider = new QSlider(ui.frameRightHand);
+//            horizontalSlider->setObjectName("horizontalSlider" + QString::fromUtf8(pair.first.c_str()));
+//            horizontalSlider->setMaximum(1);
+//            horizontalSlider->setOrientation(Qt::Horizontal);
+//            connect(horizontalSlider, SIGNAL(sliderMoved(int)), this, SLOT(requestSetRightHandJointAngles()), Qt::UniqueConnection);
+//            gridLayoutRightHand->addWidget(horizontalSlider, frameRightHandRowIdx, 1, 1, 2);
+
+//            frameRightHandRowIdx++;
+//        }
 
-        ui.frameRightHand->setLayout(gridLayoutRightHand);
+//        ui.frameRightHand->setLayout(gridLayoutRightHand);
 
 
 
-        connect(updateInfoTimer, SIGNAL(timeout()), this, SLOT(updateInfoLabel()));
+//        connect(updateInfoTimer, SIGNAL(timeout()), this, SLOT(updateInfoLabel()));
     }
 
 
diff --git a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.h b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.h
index 353156cff..60415021b 100644
--- a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.h
+++ b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.h
@@ -125,6 +125,8 @@ namespace armarx
         void relaxLeftHand();
         void relaxRightHand();
         void updateInfoLabel();
+        void updateJointValueTable();
+        void selectLeftHandJoint(int i);
 
     private:
         void setLeftHandPreshape(std::string preshape);
@@ -148,11 +150,14 @@ namespace armarx
         //QPointer<QWidget> __widget;
         QPointer<HandUnitConfigDialog> dialog;
 
-        PeriodicTask<HandUnitWidget>::pointer_type leftHandJointAngleUpdateTask;
+        PeriodicTask<HandUnitWidget>::pointer_type setLeftHandJointAngleUpdateTask;
         PeriodicTask<HandUnitWidget>::pointer_type rightHandJointAngleUpdateTask;
+        PeriodicTask<HandUnitWidget>::pointer_type displayJointAngleUpdateTask;
         QTimer* updateInfoTimer;
         bool setLeftHandJointAnglesFlag;
         bool setRightHandJointAnglesFlag;
+        std::basic_string<char> currentLeftHandJoint;
+        double leftHandConversionFactor= 1.0 / 100.0;
 
 
         // HandUnitListener interface
diff --git a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.ui b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.ui
index 7f9fbdc67..cda76d797 100644
--- a/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.ui
+++ b/source/RobotAPI/gui-plugins/HandUnitPlugin/HandUnitGuiPlugin.ui
@@ -36,9 +36,9 @@
    <property name="geometry">
     <rect>
      <x>9</x>
-     <y>66</y>
-     <width>230</width>
-     <height>321</height>
+     <y>156</y>
+     <width>301</width>
+     <height>231</height>
     </rect>
    </property>
    <property name="frameShape">
@@ -47,7 +47,11 @@
    <property name="frameShadow">
     <enum>QFrame::Raised</enum>
    </property>
-   <layout class="QGridLayout" name="gridLayout_2"/>
+   <layout class="QGridLayout" name="gridLayout_2">
+    <item row="0" column="0">
+     <widget class="QTableWidget" name="tableWidgetLeftHand"/>
+    </item>
+   </layout>
   </widget>
   <widget class="QComboBox" name="comboLeftHandPreshapes">
    <property name="geometry">
@@ -148,25 +152,6 @@
     <enum>Qt::Vertical</enum>
    </property>
   </widget>
-  <widget class="QPushButton" name="buttonSetLeftHandJointAngles">
-   <property name="geometry">
-    <rect>
-     <x>250</x>
-     <y>215</y>
-     <width>50</width>
-     <height>25</height>
-    </rect>
-   </property>
-   <property name="maximumSize">
-    <size>
-     <width>50</width>
-     <height>16777215</height>
-    </size>
-   </property>
-   <property name="text">
-    <string>Set</string>
-   </property>
-  </widget>
   <widget class="QPushButton" name="buttonSetRightHandJointAngles">
    <property name="geometry">
     <rect>
@@ -318,6 +303,70 @@
     <enum>Qt::Vertical</enum>
    </property>
   </widget>
+  <widget class="QLabel" name="labelSelectLeftHandJoint">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>80</y>
+     <width>81</width>
+     <height>17</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Select Joint</string>
+   </property>
+  </widget>
+  <widget class="QComboBox" name="comboLeftHandJoints">
+   <property name="geometry">
+    <rect>
+     <x>100</x>
+     <y>75</y>
+     <width>150</width>
+     <height>25</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLCDNumber" name="lcdNumberLeftHandJointValue">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>117</y>
+     <width>64</width>
+     <height>26</height>
+    </rect>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>80</width>
+     <height>100</height>
+    </size>
+   </property>
+   <property name="toolTip">
+    <string/>
+   </property>
+   <property name="smallDecimalPoint">
+    <bool>false</bool>
+   </property>
+  </widget>
+  <widget class="QSlider" name="horizontalSliderLeftHandJointPos">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>120</y>
+     <width>221</width>
+     <height>16</height>
+    </rect>
+   </property>
+   <property name="maximum">
+    <number>100</number>
+   </property>
+   <property name="orientation">
+    <enum>Qt::Horizontal</enum>
+   </property>
+  </widget>
  </widget>
  <resources/>
  <connections/>
-- 
GitLab