KITHandUnit.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 RobotAPI::ArmarXObjects::KITHandUnit
17  * @author Stefan Reither ( stefan dot reither at kit dot edu )
18  * @date 2019
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "KITHandUnit.h"
26 
27 #include <algorithm>
28 
29 using namespace KITHand;
30 
31 namespace armarx
32 {
33  KITHandUnitPropertyDefinitions::KITHandUnitPropertyDefinitions(std::string prefix) :
35  {
36  defineOptionalProperty<KITHandCommunicationDriver::ScanMode>("ConnectionType", KITHandCommunicationDriver::ScanMode::Bluetooth, "Type of the connection to the hand, either Bluetooth or Serial")
37  .map("Bluetooth", KITHandCommunicationDriver::ScanMode::Bluetooth)
38  .map("Serial", KITHandCommunicationDriver::ScanMode::Serial);
39  defineRequiredProperty<std::string>("MAC-Address", "MAC-Address of the hand to connect to.");
40  defineOptionalProperty<bool>("AutomaticReconnectActive", false, "Whether the hand unit should try to reconnect after the connection is lost.");
41  defineOptionalProperty<bool>("ScanUntilHandFound", true, "Wheather to keep scanning until the hand with the given MAC-Address is found.");
42  defineOptionalProperty<int>("ScanTimeout", 5, "Timeout for scanning repeatedly.");
43  }
44 
45 
46  std::string KITHandUnit::getDefaultName() const
47  {
48  return "KITHandUnit";
49  }
50 
52  {
53  //addShapeName("Open"); //is added by something else already
54  addShapeName("Close");
55  addShapeName("G0");
56  addShapeName("G1");
57  addShapeName("G2");
58  addShapeName("G3");
59  addShapeName("G4");
60  addShapeName("G5");
61  addShapeName("G6");
62  addShapeName("G7");
63  addShapeName("G8");
64 
65  _driver = std::make_unique<KITHandCommunicationDriver>();
66  _driver->registerConnectionStateChangedCallback(std::bind(&KITHandUnit::connectionStateChangedCallback, this, std::placeholders::_1));
67  }
68 
70  {
71  std::string macAddress = getProperty<std::string>("MAC-Address");
72  KITHandCommunicationDriver::ScanMode mode = getProperty<KITHandCommunicationDriver::ScanMode>("ConnectionType").getValue();
73  bool found = false;
74  auto start = std::chrono::system_clock::now();
75  do
76  {
77  std::vector<HandDevice> devices = _driver->scanForDevices(mode);
78  for (HandDevice& d : devices)
79  {
80  if (mode == KITHandCommunicationDriver::ScanMode::Bluetooth)
81  {
82  ARMARX_INFO << "Found device with MAC-Address: " << d.macAdress;
83  }
84  else if (mode == KITHandCommunicationDriver::ScanMode::Serial)
85  {
86  ARMARX_INFO << "Found device at serial port: " << d.serialDeviceFile;
87  }
88  else
89  {
90  ARMARX_INFO << "Found hand"; //TODO
91  }
92  if (d.macAdress == macAddress || (mode == KITHandCommunicationDriver::ScanMode::Serial))
93  {
94  d.hardwareTarget = mode == KITHandCommunicationDriver::ScanMode::Bluetooth ? KITHand::HardwareTarget::Bluetooth : KITHand::HardwareTarget::Serial;
95  _driver->connect(d);
96  while (!_driver->connected())
97  {
98  std::this_thread::sleep_for(std::chrono::milliseconds(100));
99  }
100  found = true;
101 
102  //gui
104  {
105  processGui(prx);
106  });
107  return;
108  }
109  }
110  }
111  while (getProperty<bool>("ScanUntilHandFound").getValue()
112  && !found
113  && std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start).count() < getProperty<int>("ScanTimeout").getValue());
114 
115  if (mode == KITHandCommunicationDriver::ScanMode::Bluetooth)
116  {
117  ARMARX_WARNING << "Could not find hand with the given MAC-Address: " << macAddress << " Shutting down this KITHandUnit.";
118  }
119  else
120  {
121  ARMARX_WARNING << "Could not find hand ove serial ports. Shutting down this KITHHandUnit";
122  }
123  getArmarXManager()->asyncShutdown();
124  }
125 
127  {
128  ARMARX_IMPORTANT << "Calling driver disconnect";
129  _driver->disconnect();
130  _driver.reset();
131  }
132 
133  void KITHandUnit::setShape(const std::string& shapeName, const Ice::Current&)
134  {
135  if (std::regex_match(shapeName, std::regex{"[gG](0|[1-9][0-9]*)"}) && _driver->getCurrentConnectedDevice()->abilities.receivesAdditionalGraspCommands)
136  {
137  _driver->sendGrasp(std::stoul(shapeName.substr(1)));
138  }
139  else if (shapeName == "Open")
140  {
141  _driver->sendGrasp(0);
142  }
143  else if (shapeName == "Close")
144  {
145  _driver->sendGrasp(1);
146  }
147  else if (!_shapes.count(shapeName))
148  {
149  ARMARX_WARNING << "Unknown shape name '" << shapeName
150  << "'\nKnown shapes: " << _shapes;
151  }
152  else
153  {
154  setJointAngles(_shapes.at(shapeName));
155  }
156  }
157 
158  void KITHandUnit::setJointAngles(const NameValueMap& targetJointAngles, const Ice::Current&)
159  {
160  ARMARX_CHECK_NOT_NULL(_driver);
161 
162  for (const std::pair<std::string, float>& pair : targetJointAngles)
163  {
164  if (pair.first == "Fingers")
165  {
166  const std::uint64_t pos = std::clamp(
167  static_cast<std::uint64_t>(pair.second * KITHand::ControlOptions::maxPosFingers),
168  static_cast<std::uint64_t>(0),
169  KITHand::ControlOptions::maxPosFingers);
170  ARMARX_DEBUG << deactivateSpam(1, std::to_string(pos)) << "set fingers " << pos;
171  _driver->sendFingersPosition(pos);
172  }
173  else if (pair.first == "Thumb")
174  {
175  const std::uint64_t pos = std::clamp(
176  static_cast<std::uint64_t>(pair.second * KITHand::ControlOptions::maxPosThumb),
177  static_cast<std::uint64_t>(0),
178  KITHand::ControlOptions::maxPosThumb);
179  ARMARX_DEBUG << deactivateSpam(1, std::to_string(pos)) << "set thumb " << pos;
180  _driver->sendThumbPosition(pos);
181  }
182  else
183  {
184  ARMARX_WARNING << "Invalid HandJointName '" << pair.first << "', ignoring.";
185  }
186  _driver->waitForCommunicationMedium();
187  }
188  }
189 
191  {
192  NameValueMap jointValues;
193  jointValues["Fingers"] = _driver->getFingersPos() * 1.f / KITHand::ControlOptions::maxPosFingers;
194  jointValues["Thumb"] = _driver->getThumbPos() * 1.f / KITHand::ControlOptions::maxPosThumb;
195  return jointValues;
196  }
197 
198  void KITHandUnit::addShape(const std::string& name, const std::map<std::string, float>& shape)
199  {
200  _shapes[name] = shape;
201  addShapeName(name);
202  }
203 
204  void KITHandUnit::addShapeName(const std::string& name)
205  {
206  Variant currentPreshape;
207  currentPreshape.setString(name);
208  shapeNames->addVariant(currentPreshape);
209  }
210 
211 
213  {
216  }
217 
219  {
220  if (state == State::DeviceLost)
221  {
222  getArmarXManager()->asyncShutdown();
223  }
224  }
225 
227  {
229  .addTextLabel("Fingers")
231  .min(0).max(1).value(0))
232  .addChild(new RemoteGui::HSpacer)
233 
234  .addTextLabel("Thumb")
236  .min(0).max(1).value(0))
237  .addChild(new RemoteGui::HSpacer)
238 
239  .addChild(RemoteGui::makeCheckBox("AutoSendValues").value(false).label("Auto send"))
240  .addChild(RemoteGui::makeButton("SendValues").label("Send"))
241  .addChild(new RemoteGui::HSpacer)
242 
243  .addChild(RemoteGui::makeLineEdit("Raw").value("M2,1000,1000,100000"))
244  .addChild(RemoteGui::makeButton("SendRaw").label("Send Raw"))
245  .addChild(new RemoteGui::HSpacer);
246  }
247 
249  {
250  prx.receiveUpdates();
251  if (prx.getValue<bool>("AutoSendValues").get() || prx.getButtonClicked("SendValues"))
252  {
253  const auto fingers = prx.getValue<float>("Fingers").get();
254  const auto thumb = prx.getValue<float>("Thumb").get();
255  ARMARX_INFO << "setting Fingers " << fingers << " and Thumb " << thumb;
256  setJointAngles({{"Fingers", fingers}, {"Thumb", thumb}});
257  }
258  if (prx.getButtonClicked("SendRaw") && _driver)
259  {
260  _driver->sendRaw(prx.getValue<std::string>("Raw").get());
261  }
262  }
263 }
armarx::KITHandUnit::addShape
void addShape(const std::string &name, const std::map< std::string, float > &shape)
Definition: KITHandUnit.cpp:198
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::HandUnit::shapeNames
SingleTypeVariantListPtr shapeNames
List containing the names of all valid shapes.
Definition: HandUnit.h:158
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
armarx::KITHandUnit::processGui
void processGui(RemoteGui::TabProxy &prx)
Definition: KITHandUnit.cpp:248
armarx::RemoteGui::makeButton
detail::ButtonBuilder makeButton(std::string const &name)
Definition: IntegerWidgets.h:48
ArmarXManager.h
armarx::SensorActorUnit::start
void start(const Ice::Current &c=Ice::emptyCurrent) override
Set execution state to eStarted.
Definition: SensorActorUnit.cpp:66
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
WidgetBuilder.h
armarx::Variant::setString
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
Definition: Variant.cpp:340
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:267
armarx::RemoteGui::makeLineEdit
detail::LineEditBuilder makeLineEdit(std::string const &name)
Definition: StringWidgets.h:53
armarx::RemoteGui::detail::SimpleGridLayoutBuilder::addChild
SimpleGridLayoutBuilder & addChild(WidgetPtr const &child, int colspan)
Definition: LayoutWidgets.h:121
armarx::KITHandUnit::connectionStateChangedCallback
void connectionStateChangedCallback(const KITHand::State state)
Definition: KITHandUnit.cpp:218
armarx::RemoteGui::makeSimpleGridLayout
detail::SimpleGridLayoutBuilder makeSimpleGridLayout(std::string const &name="")
Definition: LayoutWidgets.h:235
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:125
armarx::KITHandUnitPropertyDefinitions
Definition: KITHandUnit.h:40
armarx::RemoteGui::TabProxy
Definition: WidgetProxy.h:17
armarx::KITHandUnit::setJointAngles
void setJointAngles(const NameValueMap &targetJointAngles, const Ice::Current &=Ice::emptyCurrent) override
Definition: KITHandUnit.cpp:158
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::RemoteGui::TabProxy::receiveUpdates
void receiveUpdates()
Definition: WidgetProxy.h:131
armarx::RemoteGui::makeCheckBox
detail::CheckBoxBuilder makeCheckBox(std::string const &name)
Definition: BoolWidgets.h:26
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::KITHandUnit::getCurrentJointValues
NameValueMap getCurrentJointValues(const Ice::Current &=Ice::emptyCurrent) override
Definition: KITHandUnit.cpp:190
armarx::KITHandUnit::getDefaultName
virtual std::string getDefaultName() const override
Definition: KITHandUnit.cpp:46
armarx::RemoteGui::detail::SimpleGridLayoutBuilder::addTextLabel
SimpleGridLayoutBuilder & addTextLabel(std::string const &text, int colspan)
Definition: LayoutWidgets.h:130
armarx::HandUnitPropertyDefinitions
Defines all necessary properties for armarx::HandUnit.
Definition: HandUnit.h:44
armarx::State
Definition: State.h:54
armarx::KITHandUnit::setShape
void setShape(const std::string &shapeName, const Ice::Current &=Ice::emptyCurrent) override
Definition: KITHandUnit.cpp:133
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::KITHandUnit::onStartHandUnit
void onStartHandUnit() override
Definition: KITHandUnit.cpp:69
armarx::WidgetDescription::WidgetPtr
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
Definition: NJointControllerBase.h:66
armarx::RemoteGui::TabProxy::getValue
ValueProxy< T > getValue(std::string const &name)
Definition: WidgetProxy.h:161
armarx::KITHandUnit::onExitHandUnit
void onExitHandUnit() override
Definition: KITHandUnit.cpp:126
armarx::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:91
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
armarx::RemoteGui::TabProxy::getButtonClicked
bool getButtonClicked(std::string const &name)
Definition: WidgetProxy.cpp:11
armarx::KITHandUnit::buildGui
RemoteGui::WidgetPtr buildGui()
Definition: KITHandUnit.cpp:226
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::RemoteGui::detail::SimpleGridLayoutBuilder::cols
SimpleGridLayoutBuilder & cols(int n)
Definition: LayoutWidgets.h:108
armarx::min
std::vector< T > min(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:294
KITHandUnit.h
armarx::KITHandUnit::onInitHandUnit
void onInitHandUnit() override
Definition: KITHandUnit.cpp:51
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::RemoteGuiComponentPluginUser::createOrUpdateRemoteGuiTab
void createOrUpdateRemoteGuiTab(Ts &&...ts)
Definition: RemoteGuiComponentPlugin.h:255
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::PropertyDefinitionsPtr
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
Definition: forward_declarations.h:34
armarx::KITHandUnit::createPropertyDefinitions
virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: KITHandUnit.cpp:212
armarx::RemoteGui::makeFloatSpinBox
detail::FloatSpinBoxBuilder makeFloatSpinBox(std::string const &name)
Definition: FloatWidgets.h:52
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::KITHandUnit::addShapeName
void addShapeName(const std::string &name)
Definition: KITHandUnit.cpp:204