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
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
38using namespace armarx;
39using namespace ScanLocationGroup;
40
41namespace fs = std::filesystem;
42
43// DO NOT EDIT NEXT LINE
44NameRecognizedObjects::SubClassRegistry
45 NameRecognizedObjects::Registry(NameRecognizedObjects::GetName(),
47
48class InterruptedException : std::exception
49{
50};
51
52void
53NameRecognizedObjects::waitForSpeechFinished()
54{
55 ARMARX_INFO << "Starting to wait for speech to finish";
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
78void
82
83static std::vector<std::string>
84getNamesFromChannels(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
120void
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
218void
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
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
Used to find objects in the ArmarX objects repository [1] (formerly [2]).
std::vector< std::string > loadSpokenNames(const ObjectID &objectID, bool includeClassName=false) const
Load names to use when verbalizing an object name.
NameRecognizedObjects(const XMLStateConstructorParams &stateData)
static XMLStateFactoryBasePtr CreateInstance(XMLStateConstructorParams stateData)
static void SleepMS(float milliseconds)
Definition TimeUtil.h:203
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
std::vector< ObjectPose > ObjectPoseSeq
void fromIce(const Box &box, simox::OrientedBox< float > &oobb)
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< ChannelRef > ChannelRefPtr
Definition ChannelRef.h:40
IceInternal::Handle< XMLStateFactoryBase > XMLStateFactoryBasePtr
Definition XMLState.h:64
An object pose as stored by the ObjectPoseStorage.
Definition ObjectPose.h:34