30 #include <VirtualRobot/math/Helpers.h>
41 using namespace ProsthesisKinestheticTeachIn;
55 void CyberGloveProsthesisControl::shapeHand(
float fingers,
float thumb)
57 getHandUnit()->setJointAngles({{
"Fingers", fingers}, {
"Thumb", thumb}});
118 .
addChild(
new RemoteGui::VSpacer());
120 getRemoteGui()->createTab(
"CyberGloveProsthesisControl", rootLayoutBuilder);
126 std::filesystem::path myPath = std::filesystem::current_path();
127 std::string dataDir = myPath.string() +
"/prosthesisKinestheticTeaching/recordings/";
130 std::ofstream logger;
131 std::string timestamp =
"";
132 std::string latest_timestamp =
"";
136 int lastClickCountCalibrateCyberGlove = guiTab.
getValue<
int>(
"calibrate_cyber_glove").get();
137 int lastClickCountRecordOn = guiTab.
getValue<
int>(
"start_recording").get();
138 int lastClickCountRecordOff = guiTab.
getValue<
int>(
"stop_recording").get();
139 int lastClickCountLatestTimestamp = guiTab.
getValue<
int>(
"set_latest_timestamp").get();
145 bool storeCalibrationValuesForCyberGlove =
false;
147 std::chrono::time_point<std::chrono::system_clock> start, end;
151 while (!isRunningTaskStopped())
159 int calibrateCyberGloveClickCount = guiTab.
getValue<
int>(
"calibrate_cyber_glove").get();
160 bool calibrateCyberGloveButtonWasClicked = calibrateCyberGloveClickCount > lastClickCountCalibrateCyberGlove;
161 lastClickCountCalibrateCyberGlove = calibrateCyberGloveClickCount;
163 int startRecordingClickCount = guiTab.
getValue<
int>(
"start_recording").get();
164 bool startRecordingButtonClicked = startRecordingClickCount > lastClickCountRecordOn;
165 lastClickCountRecordOn = startRecordingClickCount;
167 int stopRecordingClickCount = guiTab.
getValue<
int>(
"stop_recording").get();
168 bool stopRecordingButtonClicked = stopRecordingClickCount > lastClickCountRecordOff;
169 lastClickCountRecordOff = stopRecordingClickCount;
171 int setLatestTimestampClickCount = guiTab.
getValue<
int>(
"set_latest_timestamp").get();
172 bool setLatestTimeStampButtonClicked = setLatestTimestampClickCount > lastClickCountLatestTimestamp;
173 lastClickCountLatestTimestamp = setLatestTimestampClickCount;
174 ARMARX_IMPORTANT <<
"Timestamp click count: " << setLatestTimestampClickCount;
176 CyberGloveValues currentValues = getCyberGloveObserver()->getLatestValues();
178 float thumbValue = 0;
179 float indexValue = 0;
183 return v.thumbAbd +
v.thumbCMC +
v.thumbIP +
v.thumbMCP;
187 return v.indexDIP +
v.indexMCP +
v.indexPIP;
190 if (setLatestTimeStampButtonClicked)
192 if (!latest_timestamp.empty())
194 timestamp = latest_timestamp;
196 getMessageDisplay()->setMessage(
"Resume latest timestamp",
"Latest timestamp is " + latest_timestamp);
201 getMessageDisplay()->setMessage(
"No timestamp stored.",
"Take a point cloud to generate a timestamp.");
205 if (startRecordingButtonClicked)
207 if (timestamp.empty())
210 time_t timer = now.toSeconds();
213 ts = localtime(&timer);
214 strftime(buffer, 80,
"%Y-%m-%d-%H-%M-%S", ts);
215 std::string
str(buffer);
217 latest_timestamp = timestamp;
219 std::string fileName = guiTab.
getValue<std::string>(
"file_name").get();
221 logger.open(dataDir + fileName +
"-temp-" + timestamp +
".csv");
222 start = std::chrono::system_clock::now();
223 logger <<
"Timestamp, indexTarget, thumbTarget, indexActual, thumbActual" << std::endl;
225 storeCalibrationValuesForCyberGlove =
true;
226 getMessageDisplay()->setMessage(
"Start Recording Trajectory",
"");
229 if (stopRecordingButtonClicked)
236 getMessageDisplay()->setMessage(
"Stop Recording Trajectory",
"");
241 getMessageDisplay()->setMessage(
"Calibrating open hand",
"");
242 guiTab.
getValue<std::string>(
"message").
set(
"Put your hand flat on the table!");
243 if (calibrateCyberGloveButtonWasClicked)
245 openValues = currentValues;
251 getMessageDisplay()->setMessage(
"Calibrating closed hand",
"");
252 guiTab.
getValue<std::string>(
"message").
set(
"Make a fist!");
253 if (calibrateCyberGloveButtonWasClicked)
255 closedValues = currentValues;
261 guiTab.
getValue<std::string>(
"message").
set(
"Teach-In!");
262 thumbValue = math::Helpers::Clamp(0, 1, math::Helpers::ILerp(calcThumbSum(openValues), calcThumbSum(closedValues), calcThumbSum(currentValues)));
263 indexValue = math::Helpers::Clamp(0, 1, math::Helpers::ILerp(calcIndexSum(openValues), calcIndexSum(closedValues), calcIndexSum(currentValues)));
275 shapeHand(indexValue, thumbValue);
278 NameValueMap handMotorValues = getHandUnit()->getCurrentJointValues();
287 end = std::chrono::system_clock::now();
288 double elapsed_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>
289 (end - start).count();
290 logger << elapsed_milliseconds <<
"," << indexValue <<
"," << thumbValue <<
"," << handMotorValues[
"Fingers"] <<
"," << handMotorValues[
"Thumb"] << std::endl;
307 std::stringstream ss;
308 ss <<
"index: " << currentValues.
indexMCP <<
" " << currentValues.
indexPIP <<
" " << currentValues.
indexDIP <<
"\n";
310 ss << std::floor(indexValue * 100) <<
"% " << std::floor(thumbValue * 100) <<
"%\n";
311 guiTab.
getValue<std::string>(
"status").
set(ss.str());
317 currentPhase = nextPhase;