Skip to content

Commit 813ace3

Browse files
committed
ensure we check for yellow labels before we drop the ingredient, not after
1 parent ea1ef3c commit 813ace3

File tree

2 files changed

+76
-22
lines changed

2 files changed

+76
-22
lines changed

SerialPrograms/Source/PokemonSV/Inference/Picnics/PokemonSV_SandwichPlateDetector.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class SandwichPlateDetector : public StaticScreenDetector{
3232
enum class Side{
3333
LEFT,
3434
MIDDLE,
35-
RIGHT
35+
RIGHT,
36+
NOT_APPLICABLE,
3637
};
3738
SandwichPlateDetector(Logger& logger, Color color, Language language, Side side);
3839
virtual ~SandwichPlateDetector();

SerialPrograms/Source/PokemonSV/Programs/Sandwiches/PokemonSV_SandwichRoutines.cpp

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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
356388
expanded_hand_bb (i.e. m_box field in SandwichHandLocator).
357389
Then updates the current location of expanded_hand_bb.
358390
Then 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

525582
void 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

Comments
 (0)