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 
25 #include <algorithm>
26 #include <iostream>
27 #include <string>
28 
29 #include <QImage>
30 
32 
33 #include <RobotAPI/interface/core/RobotState.h>
34 
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(
47  _turnOnClick, SIGNAL(clickedAt(const QPoint&)), this, SLOT(clickedAt(const QPoint&)));
48  startTimer(10);
49  }
50 
52  {
53  }
54 
55  QPointer<QDialog>
57  {
58  if (!_dialog)
59  {
60  _dialog = new SimpleConfigDialog(parent);
61  _dialog->addProxyFinder<visionx::ImageProviderInterfacePrx>(
62  "ImageProvider", "ImageProvider", "Image*|*Provider");
63  _dialog->addProxyFinder<RobotStateComponentInterfacePrx>(
64  "rsc", "Robot State Component", "*Component");
65  _dialog->addProxyFinder<KinematicUnitInterfacePrx>(
66  "KinematicUnitInterface", "Kinematic Unit Interface", "*KinematicUnit");
67  _dialog->addLineEdit("pitch", "Pitch Joint (empty = autodetect)", "");
68  _dialog->addLineEdit("yaw", "Yaw Joint (empty = autodetect)", "");
69  }
70  return qobject_cast<SimpleConfigDialog*>(_dialog);
71  }
72 
73  void
75  {
76  _imageProviderName = settings->value("_imageProviderName").toString().toStdString();
77  _robotStateUnitComponentName = settings->value("rsc").toString().toStdString();
78  _kinematicUnitInterfaceName =
79  settings->value("KinematicUnitInterface").toString().toStdString();
80  _pitchJointName = settings->value("pitch").toString().toStdString();
81  _yawJointName = settings->value("yaw").toString().toStdString();
82  _inverseYaw = settings->value("inverseYaw").toFloat();
83 
84  widget.doubleSpinBoxFactorPitch->setValue(settings->value("pitchFactor").toDouble());
85  widget.doubleSpinBoxFactorYaw->setValue(settings->value("yawFactor").toDouble());
86  }
87 
88  void
90  {
91  settings->setValue("_imageProviderName", QString::fromStdString(_imageProviderName));
92  settings->setValue(
93  "rsc",
94  QString::fromStdString(getRobotStateComponentPlugin().getRobotStateComponentName()));
95  settings->setValue("KinematicUnitInterface",
96  QString::fromStdString(_kinematicUnitInterfaceName));
97  settings->setValue("pitch", QString::fromStdString(_pitchJointName));
98  settings->setValue("yaw", QString::fromStdString(_yawJointName));
99  settings->setValue("inverseYaw", _inverseYaw);
100 
101  settings->setValue("pitchFactor", widget.doubleSpinBoxFactorPitch->value());
102  settings->setValue("yawFactor", widget.doubleSpinBoxFactorPitch->value());
103  }
104 
105  void
107  {
108  usingImageProvider(_imageProviderName);
109  usingProxy(_kinematicUnitInterfaceName);
110  }
111 
112  void
113  LookAtClickWidgetController::autoDetectRobotSpecificVariables()
114  {
115  synchronizeLocalClone(_robot);
116  if (_yawJointName == "")
117  {
118  if (_robot->getName() == "Armar6")
119  {
120  _inverseYaw = -1;
121  _yawJointName = "Neck_1_Yaw";
122  }
123  else if (_robot->getName() == "Armar3")
124  {
125  _inverseYaw = 1;
126  _yawJointName = "Neck_3_Yaw";
127  }
128  else
129  {
130  throw std::invalid_argument("Could not autodetect yaw!");
131  }
132  }
133  if (_pitchJointName == "")
134  {
135  if (_robot->getName() == "Armar6")
136  {
137  _pitchJointName = "Neck_2_Pitch";
138  }
139  else if (_robot->getName() == "Armar3")
140  {
141  _pitchJointName = "Neck_1_Pitch";
142  }
143  else
144  {
145  throw std::invalid_argument("Could not autodetect pitch!");
146  }
147  }
148  }
149 
150  void
152  {
153  _robot = addRobot("state robot", VirtualRobot::RobotIO::eStructure);
154  try
155  {
156  autoDetectRobotSpecificVariables();
157  }
158  catch (...)
159  {
160  ARMARX_ERROR << "Could not autodetect joints!";
161  }
162  getProxy(kinematicUnitInterfacePrx, _kinematicUnitInterfaceName);
163  //image provider
164  {
165  _imageProviderInfo = getImageProvider(_imageProviderName, true);
166  _imageProvider = _imageProviderInfo.proxy;
167  ARMARX_CHECK_GREATER(_imageProviderInfo.numberImages, 0);
168  ARMARX_CHECK_EQUAL(_imageProviderInfo.imageFormat.type, visionx::ImageType::eRgb);
169  //reserve buffers
170  _providerImagesOwner.reserve(_imageProviderInfo.numberImages);
171  _providerImages.reserve(_imageProviderInfo.numberImages);
172  for (int i = 0; i < _imageProviderInfo.numberImages; ++i)
173  {
174  _providerImagesOwner.emplace_back(
175  visionx::tools::createByteImage(_imageProviderInfo));
176  _providerImages.emplace_back(
177  static_cast<void*>(_providerImagesOwner.back()->pixels));
178  }
179  _numberOfImages = _imageProviderInfo.numberImages;
180  }
181  }
182 
183  void
185  {
186  if (!waitForImages(_imageProviderName, 1000))
187  {
188  return;
189  }
190  getImages(_providerImages.data());
191  const CByteImage& img = *(_providerImagesOwner.at(_imageIndex));
192  {
193  std::lock_guard<std::mutex> guard{_currentImageMutex};
194  _currentImage = QImage(img.width, img.height, QImage::Format_RGB888);
195  ARMARX_CHECK_NOT_NULL(_currentImage.bits());
196  ARMARX_CHECK_NOT_NULL(img.pixels);
197  std::memcpy(_currentImage.bits(), img.pixels, 3 * img.width * img.height);
198  _currentImageDirty = true;
199  }
200  }
201 
202  void
204  {
205  _imageProviderName = _dialog->getProxyName("ImageProvider");
206  _pitchJointName = _dialog->getLineEditText("pitch");
207  _yawJointName = _dialog->getLineEditText("yaw");
208  _kinematicUnitInterfaceName = _dialog->getProxyName("KinematicUnitInterface");
209  }
210 
211  void
212  LookAtClickWidgetController::refreshWidgetData(float* factorPitch, float* factorYaw)
213  {
214  *factorPitch = widget.doubleSpinBoxFactorPitch->value();
215  *factorYaw = widget.doubleSpinBoxFactorYaw->value();
216  }
217 
218  void
219  LookAtClickWidgetController::determineNewAngles(const QPoint& offset,
221  NameControlModeMap& jointModes,
222  float factorPitch,
223  float factorYaw)
224  {
225  jointModes[_pitchJointName] = ePositionControl;
226  jointModes[_yawJointName] = ePositionControl;
227  ARMARX_INFO << _robot->getRobotNode(_pitchJointName)->getJointValue();
228  ARMARX_INFO << _robot->getRobotNode(_yawJointName)->getJointValue();
229  auto pitch = _robot->getRobotNode(_pitchJointName);
230  auto yaw = _robot->getRobotNode(_yawJointName);
231  const float pitchValue = offset.y() * factorPitch + pitch->getJointValue();
232  const float yawValue = _inverseYaw * offset.x() * factorYaw + yaw->getJointValue();
233  jointAngles[_pitchJointName] =
234  std::clamp(pitchValue, pitch->getJointLimitLo(), pitch->getJointLimitHi());
235  jointAngles[_yawJointName] =
236  std::clamp(yawValue, yaw->getJointLimitLo(), yaw->getJointLimitHi());
237  ARMARX_INFO << "pitch value: " << jointAngles[_pitchJointName]
238  << "yaw value: " << jointAngles[_yawJointName];
239  }
240 
241  void
243  {
244  ARMARX_INFO << "ClickedAt called!";
245  float factorPitch, factorYaw;
247  NameControlModeMap jointModes;
248 
249  refreshWidgetData(&factorPitch, &factorYaw);
250  synchronizeLocalClone(_robot);
251  determineNewAngles(offset, jointAngles, jointModes, factorPitch, factorYaw);
252  try
253  {
254  kinematicUnitInterfacePrx->switchControlMode(jointModes);
255  kinematicUnitInterfacePrx->setJointAngles(jointAngles);
256  }
257  catch (...)
258  {
259  ARMARX_ERROR << "Error occurred in clickedAt";
260  }
261  ARMARX_INFO << "after setjointangles";
262  }
263 
264  void
266  {
267  if (!_currentImageDirty)
268  {
269  return;
270  }
271  {
272  std::lock_guard<std::mutex> guard{_currentImageMutex};
273  _turnOnClick->drawBackground(_currentImage);
274  _currentImageDirty = false;
275  }
276  }
277 } // namespace armarx
LookAtClick
Definition: LookAtClick.h:8
visionx::ImageProviderInfo::numberImages
int numberImages
Number of images.
Definition: ImageProcessor.h:519
armarx::LookAtClickWidgetController::onConnectImageProcessor
void onConnectImageProcessor() override
Definition: LookAtClickWidgetController.cpp:151
armarx::LookAtClickWidgetController::getConfigDialog
QPointer< QDialog > getConfigDialog(QWidget *parent) override
getConfigDialog returns a pointer to the a configuration widget of this controller.
Definition: LookAtClickWidgetController.cpp:56
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:167
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:509
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:405
armarx::RobotStateComponentPluginUser::synchronizeLocalClone
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
Definition: RobotStateComponentPlugin.cpp:470
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:136
armarx::LookAtClickWidgetController::~LookAtClickWidgetController
virtual ~LookAtClickWidgetController()
Controller destructor.
Definition: LookAtClickWidgetController.cpp:51
armarx::LookAtClickWidgetController::clickedAt
void clickedAt(const QPoint &point)
Definition: LookAtClickWidgetController.cpp:242
armarx::LookAtClickWidgetController::process
void process()
Process the vision component.
Definition: LookAtClickWidgetController.cpp:184
armarx::LookAtClickWidgetController::configured
void configured() override
This function must be implemented by the user, if he supplies a config dialog.
Definition: LookAtClickWidgetController.cpp:203
armarx::RobotStateComponentPluginUser::getRobotStateComponentPlugin
const RobotStateComponentPlugin & getRobotStateComponentPlugin() const
Definition: RobotStateComponentPlugin.cpp:375
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:128
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
visionx::ImageProcessor::getImages
int getImages(CByteImage **ppImages)
Poll images from provider.
Definition: ImageProcessor.cpp:395
armarx::LookAtClickWidgetController::loadSettings
void loadSettings(QSettings *settings) override
Definition: LookAtClickWidgetController.cpp:74
armarx::LookAtClickWidgetController::timerEvent
void timerEvent(QTimerEvent *)
Definition: LookAtClickWidgetController.cpp:265
ExpressionException.h
armarx::LookAtClickWidgetController::saveSettings
void saveSettings(QSettings *settings) override
Definition: LookAtClickWidgetController.cpp:89
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:88
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
visionx::ImageProviderInfo::proxy
ImageProviderInterfacePrx proxy
proxy to image provider
Definition: ImageProcessor.h:485
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::LookAtClickWidgetController::onInitImageProcessor
void onInitImageProcessor() override
Definition: LookAtClickWidgetController.cpp:106
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:20
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:407
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:154
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
LookAtClickWidgetController.h
visionx::ImageProcessor::waitForImages
bool waitForImages(int milliseconds=1000)
Wait for new images.
Definition: ImageProcessor.cpp:309
armarx::SimpleConfigDialog
A config-dialog containing one (or multiple) proxy finders.
Definition: SimpleConfigDialog.h:84