NameRecognizedObjects.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 RobotSkillTemplates::ScanLocationGroup
17  * @author Markus Grotz ( markus dot grotz at kit dot edu )
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "NameRecognizedObjects.h"
24 
25 #include <filesystem>
26 
27 #include <boost/regex.hpp>
28 
29 #include <SimoxUtility/algorithm/string.h>
30 #include <SimoxUtility/json.h>
31 
33 
36 
37 
38 using namespace armarx;
39 using namespace ScanLocationGroup;
40 
41 namespace fs = std::filesystem;
42 
43 // DO NOT EDIT NEXT LINE
44 NameRecognizedObjects::SubClassRegistry
45  NameRecognizedObjects::Registry(NameRecognizedObjects::GetName(),
47 
48 class InterruptedException : std::exception
49 {
50 };
51 
52 void
53 NameRecognizedObjects::waitForSpeechFinished()
54 {
55  ARMARX_INFO << "Starting to wait for speech to finish";
56  TimeUtil::SleepMS(200);
57  while (!isRunningTaskStopped())
58  {
60  << deactivateSpam(1) << "Speech observer status: "
61  << getSpeechObserver()->getDatafieldByName("TextToSpeech", "State")->getString();
62  if (getSpeechObserver()->getDatafieldByName("TextToSpeech", "State")->getString() ==
63  "FinishedSpeaking")
64  {
66  << "Speech observer status: "
67  << getSpeechObserver()->getDatafieldByName("TextToSpeech", "State")->getString();
68  break;
69  }
71  }
72  if (isRunningTaskStopped())
73  {
74  throw InterruptedException();
75  }
76 }
77 
78 void
80 {
81 }
82 
83 static std::vector<std::string>
84 getNamesFromChannels(std::vector<ChannelRefPtr> const& channels,
85  std::map<std::string, std::string> const& humanObjectNameMap)
86 {
87  boost::regex re("[^a-zA-Z0-9]+");
88 
89  auto resolveObjectName = [&](ChannelRefPtr channelRef)
90  {
91  std::string memoryName = channelRef->getDataField("className")->getString();
92  if (humanObjectNameMap.count(memoryName))
93  {
94  return humanObjectNameMap.at(memoryName);
95  }
96  else
97  {
98  return boost::regex_replace(memoryName, re, std::string(" "));
99  }
100  };
101 
102  std::vector<ChannelRefPtr> const& objectInstanceChannels = channels;
103  std::vector<std::string> objectNames;
104 
105  std::set<std::string> uniqueObjectNames;
106  for (ChannelRefPtr const& p : objectInstanceChannels)
107  {
108  auto resolvedName = resolveObjectName(p);
109  if (uniqueObjectNames.count(resolvedName))
110  {
111  continue;
112  }
113  uniqueObjectNames.insert(resolvedName);
114  objectNames.push_back(resolvedName);
115  }
116 
117  return objectNames;
118 }
119 
120 void
122 {
123  std::map<std::string, std::string> humanObjectNameMap = in.getHumanObjectNameMap();
124 
125  std::vector<std::string> recognizedObjectsVec =
126  getNamesFromChannels(in.getObjectInstanceChannels(), humanObjectNameMap);
127 
128  if (in.getUseObjectPoseStorage())
129  {
130  // Also get the object names from the ObjectPoseStorage
131  const objpose::ObjectPoseStorageInterfacePrx objectPoseStorage = getObjectPoseStorage();
132  const std::vector<std::string> objPoseProviderNames = in.getObjectPoseProviderNames();
133  const std::set<std::string> objPoseProviderNamesSet(objPoseProviderNames.begin(),
134  objPoseProviderNames.end());
135  const objpose::ObjectPoseSeq objectPoses =
136  objpose::fromIce(getObjectPoseStorage()->getObjectPoses());
137  ARMARX_INFO << "Got " << objectPoses.size() << " object poses.";
138 
139  ObjectFinder finder;
140  for (objpose::ObjectPose const& objectPose : objectPoses)
141  {
142  if (objPoseProviderNamesSet.count(objectPose.providerName))
143  {
144  const static bool includeClassName = false;
145  const std::vector<std::string> names =
146  finder.loadSpokenNames(objectPose.objectID, includeClassName);
147  ARMARX_IMPORTANT << "Loaded names for object " << objectPose.objectID << ": "
148  << names;
149 
150  const std::string objectName =
151  names.size() > 0 ? names.front() : objectPose.objectID.className();
152  recognizedObjectsVec.push_back(objectName);
153  }
154  }
155  }
156  std::set<std::string> recognizedObjects;
157  for (const std::string& name : recognizedObjectsVec)
158  {
159  recognizedObjects.insert(simox::alg::to_lower(name));
160  }
161 
162  std::vector<std::string> display = in.getDisplay_Text();
163  if (display.size() != 2)
164  {
165  display.resize(2);
166  }
167 
168  std::vector<std::string> ttsSeq;
169  if (recognizedObjects.empty())
170  {
171  ttsSeq.push_back("I cannot see any objects that I know.");
172  display[1] = "I did not find any objects.";
173  }
174  else if (recognizedObjects.size() == 1)
175  {
176  const std::string resolvedName = *recognizedObjects.begin();
177  ttsSeq.push_back("I can see " + resolvedName);
178  display[1] = "I can see the " + resolvedName;
179  }
180  else
181  {
182  ttsSeq.push_back("I can see the following objects: ");
183  for (const std::string& objectName : recognizedObjects)
184  {
185  ttsSeq.push_back(" a " + objectName + "");
186  }
187 
188  display[1] = "I found " + std::to_string(recognizedObjects.size()) + " objects.";
189  }
190 
191  getMessageDisplay()->setMessage(display[0], display[1]);
192 
193  if (in.getReportObjectsWithSpeech())
194  {
195  for (auto tts : ttsSeq)
196  {
197  getTextToSpeech()->reportText(tts);
198  if (in.getWaitForSpeechToFinish())
199  {
200  waitForSpeechFinished();
201  }
202  else
203  {
204  ARMARX_INFO << deactivateSpam(5) << "Not waiting for speech";
205  }
206  }
207  }
208 
209  emitSuccess();
210 }
211 
212 //void NameRecognizedObjects::onBreak()
213 //{
214 // // put your user code for the breaking point here
215 // // execution time should be short (<100ms)
216 //}
217 
218 void
220 {
221  // put your user code for the exit point here
222  // execution time should be short (<100ms)
223 }
224 
225 // DO NOT EDIT NEXT FUNCTION
228 {
229  return XMLStateFactoryBasePtr(new NameRecognizedObjects(stateData));
230 }
armarx::ObjectPoseStorageInterfacePrx
::IceInternal::ProxyHandle<::IceProxy::armarx::objpose::ObjectPoseStorageInterface > ObjectPoseStorageInterfacePrx
Definition: ObjectPoseClientWidget.h:57
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
armarx::objpose::ObjectPoseSeq
std::vector< ObjectPose > ObjectPoseSeq
Definition: forward_declarations.h:20
armarx::XMLStateConstructorParams
Definition: XMLState.h:49
armarx::objpose::fromIce
void fromIce(const Box &box, simox::OrientedBox< float > &oobb)
display
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this display
Definition: license.txt:11
armarx::ScanLocationGroup::NameRecognizedObjects::CreateInstance
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
Definition: NameRecognizedObjects.cpp:227
armarx::XMLStateFactoryBasePtr
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition: XMLState.h:64
IceInternal::Handle< ChannelRef >
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
armarx::ScanLocationGroup::NameRecognizedObjects::onEnter
void onEnter() override
Definition: NameRecognizedObjects.cpp:79
armarx::ObjectFinder
Used to find objects in the ArmarX objects repository [1] (formerly [2]).
Definition: ObjectFinder.h:22
armarx::ScanLocationGroup::NameRecognizedObjects::Registry
static SubClassRegistry Registry
Definition: NameRecognizedObjects.h:47
NameRecognizedObjects.h
armarx::ObjectFinder::loadSpokenNames
std::vector< std::string > loadSpokenNames(const ObjectID &objectID, bool includeClassName=false) const
Load names to use when verbalizing an object name.
Definition: ObjectFinder.cpp:388
ObjectPose.h
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::TimeUtil::SleepMS
static void SleepMS(float milliseconds)
Definition: TimeUtil.h:203
armarx::viz::data::ElementFlags::names
const simox::meta::IntEnumNames names
Definition: json_elements.cpp:13
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::ScanLocationGroup::NameRecognizedObjects::onExit
void onExit() override
Definition: NameRecognizedObjects.cpp:219
armarx::armem::laser_scans::constants::memoryName
const std::string memoryName
Definition: constants.h:28
armarx::ScanLocationGroup::NameRecognizedObjects::run
void run() override
Definition: NameRecognizedObjects.cpp:121
InterruptedException
Definition: NameRecognizedObjects.cpp:48
armarx::ScanLocationGroup::NameRecognizedObjects::NameRecognizedObjects
NameRecognizedObjects(const XMLStateConstructorParams &stateData)
Definition: NameRecognizedObjects.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::objpose::ObjectPose
An object pose as stored by the ObjectPoseStorage.
Definition: ObjectPose.h:33
ObjectFinder.h