@@ -350,22 +350,56 @@ bool move_then_recover_sandwich_hand_position(
350350 );
351351}
352352
353+ // return true if the current plate is empty.
354+ // i.e. the current plate label is not yellow.
355+ // Assumes that we are in a grabbing state.
356+ bool check_plate_empty (VideoStream& stream, SandwichPlateDetector::Side target_plate_label, Language language){
357+ auto screen = stream.video ().snapshot ();
358+ // screen.frame->save("test.png");
359+
360+ // switch(target_plate_label){
361+ // case SandwichPlateDetector::Side::LEFT:
362+ // cout << "left" << endl;
363+ // break;
364+ // case SandwichPlateDetector::Side::MIDDLE:
365+ // cout << "middle" << endl;
366+ // break;
367+ // case SandwichPlateDetector::Side::RIGHT:
368+ // cout << "right" << endl;
369+ // break;
370+ // default:
371+ // break;
372+ // }
373+
374+ SandwichPlateDetector plate_detector = SandwichPlateDetector (stream.logger (), COLOR_RED, language, target_plate_label);
375+
376+ return !plate_detector.is_label_yellow (screen);
377+ }
378+
379+ struct HandMoveData {
380+ ImageFloatBox end_box;
381+ bool plate_empty;
382+ };
383+
384+
353385/*
354386- moves the sandwich hand from start_box to end_box
355387- It detects the location of the sandwich hand, from within the bounds of the last frame's
356388expanded_hand_bb (i.e. m_box field in SandwichHandLocator).
357389Then updates the current location of expanded_hand_bb.
358390Then moves the sandwich hand closer towards end_box.
359391 */
360- ImageFloatBox move_sandwich_hand (
392+ HandMoveData move_sandwich_hand_and_check_if_plates_empty (
361393 const ProgramInfo& info,
362394 AsyncDispatcher& dispatcher,
363395 VideoStream& stream,
364396 ProControllerContext& context,
365397 SandwichHandType hand_type,
366398 bool pressing_A,
367399 const ImageFloatBox& start_box,
368- const ImageFloatBox& end_box
400+ const ImageFloatBox& end_box,
401+ SandwichPlateDetector::Side target_plate_label = SandwichPlateDetector::Side::NOT_APPLICABLE,
402+ Language language = Language::None
369403){
370404 context.wait_for_all_requests ();
371405 stream.log (" Start moving sandwich hand: " + SANDWICH_HAND_TYPE_NAMES (hand_type)
@@ -457,14 +491,24 @@ ImageFloatBox move_sandwich_hand(
457491
458492 std::pair<double , double > dif (target_loc.first - cur_loc.first , target_loc.second - cur_loc.second );
459493 // console.log("float diff to target: " + std::to_string(dif.first) + ", " + std::to_string(dif.second));
494+
495+
496+ // Reached the Target
460497 if (std::fabs (dif.first ) < end_box.width /2 && std::fabs (dif.second ) < end_box.height /2 ){
461498 stream.log (SANDWICH_HAND_TYPE_NAMES (hand_type) + " hand reached target." );
499+ bool plate_empty = false ;
500+
501+ // check if the plate is empty. but only if the target_plate_label isn't NOT_APPLICABLE.
502+ if (target_plate_label != SandwichPlateDetector::Side::NOT_APPLICABLE){
503+ plate_empty = check_plate_empty (stream, target_plate_label, language);
504+ }
505+
462506 move_session.stop_session_and_rethrow (); // Stop the commands
463507 if (hand_type == SandwichHandType::GRABBING){
464508 // wait for some time to let hand release ingredient
465509 context.wait_for (std::chrono::milliseconds (100 ));
466510 }
467- return hand_bb;
511+ return { hand_bb, plate_empty} ;
468512 }
469513
470514 // Assume screen width is 16.0, then the screen height is 9.0
@@ -520,6 +564,19 @@ ImageFloatBox move_sandwich_hand(
520564 }
521565}
522566
567+ ImageFloatBox move_sandwich_hand (
568+ const ProgramInfo& info,
569+ AsyncDispatcher& dispatcher,
570+ VideoStream& stream,
571+ ProControllerContext& context,
572+ SandwichHandType hand_type,
573+ bool pressing_A,
574+ const ImageFloatBox& start_box,
575+ const ImageFloatBox& end_box
576+ ){
577+ return move_sandwich_hand_and_check_if_plates_empty (info, dispatcher, stream, context, hand_type, pressing_A, start_box, end_box, SandwichPlateDetector::Side::NOT_APPLICABLE, Language::None).end_box ;
578+ }
579+
523580} // end anonymous namespace
524581
525582void finish_sandwich_eating (
@@ -1169,15 +1226,18 @@ void run_sandwich_maker(ProgramEnvironment& env, VideoStream& stream, ProControl
11691226 // cout << "Target plate: " << plate_index.at(j) << endl;
11701227 stream.log (" Target plate: " + std::to_string (plate_index.at (j)), COLOR_WHITE);
11711228 stream.overlay ().add_log (" Target plate: " + std::to_string (plate_index.at (j)), COLOR_WHITE);
1229+ SandwichPlateDetector::Side target_plate_label = SandwichPlateDetector::Side::MIDDLE;
11721230 switch (plate_index.at (j)){
11731231 case 0 :
11741232 target_plate = center_plate;
11751233 break ;
11761234 case 1 :
11771235 target_plate = left_plate;
1236+ target_plate_label = SandwichPlateDetector::Side::LEFT;
11781237 break ;
11791238 case 2 :
11801239 target_plate = right_plate;
1240+ target_plate_label = SandwichPlateDetector::Side::RIGHT;
11811241 break ;
11821242 case 3 : case 4 : case 5 : case 6 :
11831243 // Press R the appropriate number of times
@@ -1190,10 +1250,11 @@ void run_sandwich_maker(ProgramEnvironment& env, VideoStream& stream, ProControl
11901250 break ;
11911251 }
11921252
1253+ // place down all the ingredients for the current plate.
11931254 // Place the fillings until label does not light up yellow on grab/the piece count is not hit
11941255 while (true ){
11951256 // Break out after placing all pieces of the filling
1196- if (placement_number == times_to_place){ // todo: maybe swap to piecesPerServing?
1257+ if (placement_number == times_to_place){ // todo: maybe swap to current_plate_placement_number == piecesPerServing?
11971258 break ;
11981259 }
11991260
@@ -1211,34 +1272,26 @@ void run_sandwich_maker(ProgramEnvironment& env, VideoStream& stream, ProControl
12111272 ImageFloatBox placement_target = FillingsCoordinates::instance ().get_filling_information (i).placementCoordinates .at (
12121273 (int )fillings.find (i)->second ).at (placement_number);
12131274
1214- end_box = move_sandwich_hand (
1275+ HandMoveData hand_move_data = move_sandwich_hand_and_check_if_plates_empty (
12151276 env.program_info (), env.realtime_dispatcher (),
12161277 stream, context,
12171278 SandwichHandType::GRABBING,
12181279 true ,
12191280 expand_box (end_box),
1220- placement_target
1281+ placement_target,
1282+ target_plate_label
12211283 );
1284+ end_box = hand_move_data.end_box ;
12221285 context.wait_for_all_requests ();
12231286
1224- // If any of the labels are yellow continue. Otherwise assume plate is empty move on to the next.
1225- auto screen = stream.video ().snapshot ();
1226-
1227- // The label check is needed for ingredients with multiple plates as we don't know which plate has what amount
1228- // ensure the plates aren't absent to minimize false positives.
1229- bool is_left_plate_yellow = !left_plate_absent && left_plate_detector.is_label_yellow (screen);
1230- bool is_middle_plate_yellow = middle_plate_detector.is_label_yellow (screen);
1231- bool is_right_plate_yellow = !right_plate_absent && right_plate_detector.is_label_yellow (screen);
1232- // cout << "is_left_plate_yellow: " << is_left_plate_yellow << endl;
1233- // cout << "is_middle_plate_yellow: " << is_middle_plate_yellow << endl;
1234- // cout << "is_right_plate_yellow: " << is_right_plate_yellow << endl;
1235- if (!is_left_plate_yellow && !is_middle_plate_yellow && !is_right_plate_yellow){
1287+ // If the current plate is empty, break out of the loop and move on to the next plate.
1288+ if (hand_move_data.plate_empty ){
12361289 context.wait_for_all_requests ();
1237- stream.log (" None of the labels are yellow, so we assume our current plate is empty and move on to the next plate." , COLOR_WHITE );
1290+ stream.log (" Our current plate label is NOT yellow, so we assume our current plate is empty. Move on to the next plate." , COLOR_YELLOW );
12381291 break ;
12391292 }
12401293
1241- stream.log (" One of the labels are yellow, so we assume our current plate is not empty and we continue the current plate." , COLOR_WHITE );
1294+ stream.log (" Our current plate label is yellow, so we assume our current plate is NOT empty. Continue with the current plate." , COLOR_YELLOW );
12421295
12431296 // If the plate is empty the increment is skipped using the above break
12441297 placement_number++;
@@ -1252,7 +1305,7 @@ void run_sandwich_maker(ProgramEnvironment& env, VideoStream& stream, ProControl
12521305 }
12531306
12541307 context.wait_for_all_requests ();
1255- context.wait_for (Milliseconds (1000 ));
1308+ context.wait_for (Milliseconds (500 ));
12561309 stream.log (" All ingredients should now be empty. Wait for upper bread." , COLOR_YELLOW);
12571310 // Handle top slice by tossing it away
12581311 SandwichHandWatcher grabbing_hand (SandwichHandType::GRABBING, { 0 , 0 , 1.0 , 1.0 });
0 commit comments