LookAtClickWidgetController.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * \package VisionX::gui-plugins::LookAtClickWidgetController
17  * \author [Author Name] ( [Author Email] )
18  * \date 2020
19  * \copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
24 
26 
27 #include <RobotAPI/interface/core/RobotState.h>
28 
30 
31 #include <QImage>
32 
33 #include <string>
34 #include <iostream>
35 #include <algorithm>
36 
37 namespace armarx
38 {
40  {
41  widget.setupUi(getWidget());
42 
43  _turnOnClick = new LookAtClick;
44  widget.verticalLayoutImage->addWidget(_turnOnClick);
45  // _turnOnClick->drawBackground();
46  connect(_turnOnClick, SIGNAL(clickedAt(const QPoint&)), this, SLOT(clickedAt(const QPoint&)));
47  startTimer(10);
48  }
49 
50 
52  {
53 
54 
55  }
56 
57 
58  QPointer<QDialog> LookAtClickWidgetController::getConfigDialog(QWidget* parent)
59  {
60  if (!_dialog)
61  {
62  _dialog = new SimpleConfigDialog(parent);
63  _dialog->addProxyFinder<visionx::ImageProviderInterfacePrx>("ImageProvider", "ImageProvider", "Image*|*Provider");
64  _dialog->addProxyFinder<RobotStateComponentInterfacePrx>("rsc", "Robot State Component", "*Component");
65  _dialog->addProxyFinder<KinematicUnitInterfacePrx>("KinematicUnitInterface", "Kinematic Unit Interface", "*KinematicUnit");
66  _dialog->addLineEdit("pitch", "Pitch Joint (empty = autodetect)", "");
67  _dialog->addLineEdit("yaw", "Yaw Joint (empty = autodetect)", "");
68  }
69  return qobject_cast<SimpleConfigDialog*>(_dialog);
70  }
71 
73  {
74  _imageProviderName = settings->value("_imageProviderName").toString().toStdString();
75  _robotStateUnitComponentName = settings->value("rsc").toString().toStdString();
76  _kinematicUnitInterfaceName = settings->value("KinematicUnitInterface").toString().toStdString();
77  _pitchJointName = settings->value("pitch").toString().toStdString();
78  _yawJointName = settings->value("yaw").toString().toStdString();
79  _inverseYaw = settings->value("inverseYaw").toFloat();
80 
81  widget.doubleSpinBoxFactorPitch->setValue(settings->value("pitchFactor").toDouble());
82  widget.doubleSpinBoxFactorYaw->setValue(settings->value("yawFactor").toDouble());
83  }
84 
86  {
87  settings->setValue("_imageProviderName", QString::fromStdString(_imageProviderName));
88  settings->setValue("rsc", QString::fromStdString(getRobotStateComponentPlugin().getRobotStateComponentName()));
89  settings->setValue("KinematicUnitInterface", QString::fromStdString(_kinematicUnitInterfaceName));
90  settings->setValue("pitch", QString::fromStdString(_pitchJointName));
91  settings->setValue("yaw", QString::fromStdString(_yawJointName));
92  settings->setValue("inverseYaw", _inverseYaw);
93 
94  settings->setValue("pitchFactor", widget.doubleSpinBoxFactorPitch->value());
95  settings->setValue("yawFactor", widget.doubleSpinBoxFactorPitch->value());
96  }
97 
98 
100  {
101  usingImageProvider(_imageProviderName);
102  usingProxy(_kinematicUnitInterfaceName);
103  }
104 
105  void LookAtClickWidgetController::autoDetectRobotSpecificVariables()
106  {
107  synchronizeLocalClone(_robot);
108  if (_yawJointName == "")
109  {
110  if (_robot->getName() == "Armar6")
111  {
112  _inverseYaw = -1;
113  _yawJointName = "Neck_1_Yaw";
114  }
115  else if (_robot->getName() == "Armar3")
116  {
117  _inverseYaw = 1;
118  _yawJointName = "Neck_3_Yaw";
119  }
120  else
121  {
122  throw std::invalid_argument("Could not autodetect yaw!");
123  }
124  }
125  if (_pitchJointName == "")
126  {
127  if (_robot->getName() == "Armar6")
128  {
129  _pitchJointName = "Neck_2_Pitch";
130  }
131  else if (_robot->getName() == "Armar3")
132  {
133  _pitchJointName = "Neck_1_Pitch";
134  }
135  else
136  {
137  throw std::invalid_argument("Could not autodetect pitch!");
138  }
139  }
140  }
141 
143  {
144  _robot = addRobot("state robot", VirtualRobot::RobotIO::eStructure);
145  try
146  {
147  autoDetectRobotSpecificVariables();
148  }
149  catch (...)
150  {
151  ARMARX_ERROR << "Could not autodetect joints!";
152  }
153  getProxy(kinematicUnitInterfacePrx, _kinematicUnitInterfaceName);
154  //image provider
155  {
156  _imageProviderInfo = getImageProvider(_imageProviderName, true);
157  _imageProvider = _imageProviderInfo.proxy;
158  ARMARX_CHECK_GREATER(_imageProviderInfo.numberImages, 0);
159  ARMARX_CHECK_EQUAL(_imageProviderInfo.imageFormat.type, visionx::ImageType::eRgb);
160  //reserve buffers
161  _providerImagesOwner.reserve(_imageProviderInfo.numberImages);
162  _providerImages.reserve(_imageProviderInfo.numberImages);
163  for (int i = 0; i < _imageProviderInfo.numberImages; ++i)
164  {
165  _providerImagesOwner.emplace_back(visionx::tools::createByteImage(_imageProviderInfo));
166  _providerImages.emplace_back(static_cast<void*>(_providerImagesOwner.back()->pixels));
167  }
168  _numberOfImages = _imageProviderInfo.numberImages;
169  }
170  }
171 
173  {
174  if (!waitForImages(_imageProviderName, 1000))
175  {
176  return;
177  }
178  getImages(_providerImages.data());
179  const CByteImage& img = *(_providerImagesOwner.at(_imageIndex));
180  {
181  std::lock_guard<std::mutex> guard {_currentImageMutex};
182  _currentImage = QImage(img.width, img.height, QImage::Format_RGB888);
183  ARMARX_CHECK_NOT_NULL(_currentImage.bits());
184  ARMARX_CHECK_NOT_NULL(img.pixels);
185  std::memcpy(_currentImage.bits(), img.pixels, 3 * img.width * img.height);
186  _currentImageDirty = true;
187  }
188  }
189 
191  {
192  _imageProviderName = _dialog->getProxyName("ImageProvider");
193  _pitchJointName = _dialog->getLineEditText("pitch");
194  _yawJointName = _dialog->getLineEditText("yaw");
195  _kinematicUnitInterfaceName = _dialog->getProxyName("KinematicUnitInterface");
196  }
197 
198  void LookAtClickWidgetController::refreshWidgetData(float* factorPitch, float* factorYaw)
199  {
200  *factorPitch = widget.doubleSpinBoxFactorPitch->value();
201  *factorYaw = widget.doubleSpinBoxFactorYaw->value();
202 
203  }
204 
205  void LookAtClickWidgetController::determineNewAngles(const QPoint& offset, NameValueMap& jointAngles, NameControlModeMap& jointModes, float factorPitch, float factorYaw)
206  {
207  jointModes[_pitchJointName] = ePositionControl;
208  jointModes[_yawJointName] = ePositionControl;
209  ARMARX_INFO << _robot->getRobotNode(_pitchJointName)->getJointValue();
210  ARMARX_INFO << _robot->getRobotNode(_yawJointName)->getJointValue();
211  auto pitch = _robot->getRobotNode(_pitchJointName);
212  auto yaw = _robot->getRobotNode(_yawJointName);
213  const float pitchValue = offset.y() * factorPitch + pitch->getJointValue();
214  const float yawValue = _inverseYaw * offset.x() * factorYaw + yaw->getJointValue();
215  jointAngles[_pitchJointName] = std::clamp(pitchValue, pitch->getJointLimitLo(), pitch->getJointLimitHi());
216  jointAngles[_yawJointName] = std::clamp(yawValue, yaw->getJointLimitLo(), yaw->getJointLimitHi());
217  ARMARX_INFO << "pitch value: " << jointAngles[_pitchJointName] << "yaw value: " << jointAngles[_yawJointName];
218 
219  }
220  void LookAtClickWidgetController::clickedAt(const QPoint& offset)
221  {
222  ARMARX_INFO << "ClickedAt called!";
223  float factorPitch, factorYaw;
225  NameControlModeMap jointModes;
226 
227  refreshWidgetData(&factorPitch, &factorYaw);
228  synchronizeLocalClone(_robot);
229  determineNewAngles(offset, jointAngles, jointModes, factorPitch, factorYaw);
230  try
231  {
232  kinematicUnitInterfacePrx->switchControlMode(jointModes);
233  kinematicUnitInterfacePrx->setJointAngles(jointAngles);
234  }
235  catch (...)
236  {
237  ARMARX_ERROR << "Error occurred in clickedAt";
238  }
239  ARMARX_INFO << "after setjointangles";
240  }
241 
242 
244  {
245  if (!_currentImageDirty)
246  {
247  return;
248  }
249  {
250  std::lock_guard<std::mutex> guard {_currentImageMutex};
251  _turnOnClick->drawBackground(_currentImage);
252  _currentImageDirty = false;
253  }
254  }
255 }
LookAtClick
Definition: LookAtClick.h:9
visionx::ImageProviderInfo::numberImages
int numberImages
Number of images.
Definition: ImageProcessor.h:506
armarx::LookAtClickWidgetController::onConnectImageProcessor
void onConnectImageProcessor() override
Definition: LookAtClickWidgetController.cpp:142
armarx::LookAtClickWidgetController::getConfigDialog
QPointer< QDialog > getConfigDialog(QWidget *parent) override
getConfigDialog returns a pointer to the a configuration widget of this controller.
Definition: LookAtClickWidgetController.cpp:58
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
visionx::ImageProcessor::getImageProvider
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
Definition: ImageProcessor.cpp:152
ARMARX_CHECK_GREATER
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
Definition: ExpressionException.h:116
visionx::ImageProviderInfo::imageFormat
ImageFormatInfo imageFormat
Image format struct that contains all necessary image information.
Definition: ImageProcessor.h:496
armarx::RobotStateComponentPluginUser::addRobot
VirtualRobot::RobotPtr addRobot(const std::string &id, const VirtualRobot::RobotPtr &robot, const VirtualRobot::RobotNodeSetPtr &rns={}, const VirtualRobot::RobotNodePtr &node={})
Definition: RobotStateComponentPlugin.cpp:331
armarx::RobotStateComponentPluginUser::synchronizeLocalClone
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
Definition: RobotStateComponentPlugin.cpp:371
visionx::tools::createByteImage
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:125
armarx::LookAtClickWidgetController::~LookAtClickWidgetController
virtual ~LookAtClickWidgetController()
Controller destructor.
Definition: LookAtClickWidgetController.cpp:51
armarx::LookAtClickWidgetController::clickedAt
void clickedAt(const QPoint &point)
Definition: LookAtClickWidgetController.cpp:220
armarx::LookAtClickWidgetController::process
void process()
Process the vision component.
Definition: LookAtClickWidgetController.cpp:172
armarx::LookAtClickWidgetController::configured
void configured() override
This function must be implemented by the user, if he supplies a config dialog.
Definition: LookAtClickWidgetController.cpp:190
armarx::RobotStateComponentPluginUser::getRobotStateComponentPlugin
const RobotStateComponentPlugin & getRobotStateComponentPlugin() const
Definition: RobotStateComponentPlugin.cpp:307
visionx::ImageProcessor::usingImageProvider
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
Definition: ImageProcessor.cpp:117
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
visionx::ImageProcessor::getImages
int getImages(CByteImage **ppImages)
Poll images from provider.
Definition: ImageProcessor.cpp:351
armarx::LookAtClickWidgetController::loadSettings
void loadSettings(QSettings *settings) override
Definition: LookAtClickWidgetController.cpp:72
armarx::LookAtClickWidgetController::timerEvent
void timerEvent(QTimerEvent *)
Definition: LookAtClickWidgetController.cpp:243
ExpressionException.h
armarx::LookAtClickWidgetController::saveSettings
void saveSettings(QSettings *settings) override
Definition: LookAtClickWidgetController.cpp:85
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:91
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
visionx::ImageProviderInfo::proxy
ImageProviderInterfacePrx proxy
proxy to image provider
Definition: ImageProcessor.h:472
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::LookAtClickWidgetController::onInitImageProcessor
void onInitImageProcessor() override
Definition: LookAtClickWidgetController.cpp:99
IceInternal::ProxyHandle<::IceProxy::armarx::RobotStateComponentInterface >
ImageUtil.h
armarx::ArmarXWidgetController::getWidget
virtual QPointer< QWidget > getWidget()
getWidget returns a pointer to the a widget of this controller.
Definition: ArmarXWidgetController.cpp:54
armarx::LookAtClickWidgetController::LookAtClickWidgetController
LookAtClickWidgetController()
Controller Constructor.
Definition: LookAtClickWidgetController.cpp:39
LookAtClick::drawBackground
void drawBackground(QImage &image)
Definition: LookAtClick.cpp:19
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:393
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:151
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
LookAtClickWidgetController.h
visionx::ImageProcessor::waitForImages
bool waitForImages(int milliseconds=1000)
Wait for new images.
Definition: ImageProcessor.cpp:275
armarx::SimpleConfigDialog
A config-dialog containing one (or multiple) proxy finders.
Definition: SimpleConfigDialog.h:84