Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update Autostory tools. added UnexpectedBattleException. #493

Merged
merged 4 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions SerialPrograms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ file(GLOB MAIN_SOURCES
Source/CommonFramework/Exceptions/ProgramFinishedException.h
Source/CommonFramework/Exceptions/ScreenshotException.cpp
Source/CommonFramework/Exceptions/ScreenshotException.h
Source/CommonFramework/Exceptions/UnexpectedBattleException.cpp
Source/CommonFramework/Exceptions/UnexpectedBattleException.h
Source/CommonFramework/GlobalServices.cpp
Source/CommonFramework/GlobalServices.h
Source/CommonFramework/GlobalSettingsPanel.cpp
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/SerialPrograms.pro
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ SOURCES += \
Source/CommonFramework/Exceptions/OperationFailedException.cpp \
Source/CommonFramework/Exceptions/ProgramFinishedException.cpp \
Source/CommonFramework/Exceptions/ScreenshotException.cpp \
Source/CommonFramework/Exceptions/UnexpectedBattleException.cpp \
Source/CommonFramework/GlobalServices.cpp \
Source/CommonFramework/GlobalSettingsPanel.cpp \
Source/CommonFramework/Globals.cpp \
Expand Down Expand Up @@ -1230,6 +1231,7 @@ HEADERS += \
Source/CommonFramework/Exceptions/OperationFailedException.h \
Source/CommonFramework/Exceptions/ProgramFinishedException.h \
Source/CommonFramework/Exceptions/ScreenshotException.h \
Source/CommonFramework/Exceptions/UnexpectedBattleException.h \
Source/CommonFramework/GlobalServices.h \
Source/CommonFramework/GlobalSettingsPanel.h \
Source/CommonFramework/Globals.h \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* Unexpected Battle Exception
*
* From: https://github.com/PokemonAutomation/Arduino-Source
*
*/

#include "CommonFramework/ImageTypes/ImageRGB32.h"
#include "CommonFramework/Notifications/ProgramNotifications.h"
#include "CommonFramework/Tools/ErrorDumper.h"
#include "CommonFramework/Tools/ProgramEnvironment.h"
#include "CommonFramework/Tools/ConsoleHandle.h"
#include "UnexpectedBattleException.h"

namespace PokemonAutomation{


UnexpectedBattleException::UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this, there will be 4 exception classes with near identical implementations. I'll probably revisit this in future to try to merge away some of this duplicate code.

: ScreenshotException(error_report, std::move(message))
{
logger.log(std::string(UnexpectedBattleException::name()) + ": " + m_message, COLOR_RED);
}
UnexpectedBattleException::UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message, std::shared_ptr<const ImageRGB32> screenshot)
: ScreenshotException(error_report, std::move(message), std::move(screenshot))
{
logger.log(std::string(UnexpectedBattleException::name()) + ": " + m_message, COLOR_RED);
}
UnexpectedBattleException::UnexpectedBattleException(ErrorReport error_report, ConsoleHandle& console, std::string message, bool take_screenshot)
: ScreenshotException(error_report, console, std::move(message), take_screenshot)
{
console.log(std::string(UnexpectedBattleException::name()) + ": " + m_message, COLOR_RED);
}


void UnexpectedBattleException::send_notification(ProgramEnvironment& env, EventNotificationOption& notification) const{
std::vector<std::pair<std::string, std::string>> embeds;
if (!m_message.empty()){
embeds.emplace_back(std::pair<std::string, std::string>("Message:", m_message));
}
if (m_send_error_report == ErrorReport::SEND_ERROR_REPORT && m_screenshot){
std::string label = name();
std::string filename = dump_image_alone(env.logger(), env.program_info(), label, *m_screenshot);
send_program_telemetry(
env.logger(), true, COLOR_RED,
env.program_info(),
label,
embeds,
filename
);
}
send_program_notification(
env, notification,
COLOR_RED,
"Program Error",
std::move(embeds), "",
screenshot()
);
}





}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* Unexpected Battle Exception
*
* From: https://github.com/PokemonAutomation/Arduino-Source
*
*/

#ifndef PokemonAutomation_UnexpectedBattleException_H
#define PokemonAutomation_UnexpectedBattleException_H

#include <memory>
#include "ScreenshotException.h"

namespace PokemonAutomation{

class FatalProgramException;


// Thrown by subroutines if caught in an wild battle in-game unexpectedly.
// These include recoverable errors which can be consumed by the program.
class UnexpectedBattleException : public ScreenshotException{
public:
explicit UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message);
explicit UnexpectedBattleException(ErrorReport error_report, Logger& logger, std::string message, std::shared_ptr<const ImageRGB32> screenshot);
explicit UnexpectedBattleException(ErrorReport error_report, ConsoleHandle& console, std::string message, bool take_screenshot);

virtual const char* name() const override{ return "UnexpectedBattleException"; }
virtual std::string message() const override{ return m_message; }

virtual void send_notification(ProgramEnvironment& env, EventNotificationOption& notification) const override;
};





}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,32 @@ class DestinationMarkerMatcher : public ImageMatch::WaterfillTemplateMatcher{
}
};

class DestinationMarkerYellowMatcher : public ImageMatch::WaterfillTemplateMatcher{
public:

DestinationMarkerYellowMatcher() : WaterfillTemplateMatcher(
"PokemonSV/Map/DestinationMarkerIcon-Yellow.png", Color(180,80,0), Color(255, 200, 50), 50
){
m_aspect_ratio_lower = 0.8;
m_aspect_ratio_upper = 1.2;
m_area_ratio_lower = 0.8;
m_area_ratio_upper = 1.2;

}

static const ImageMatch::WaterfillTemplateMatcher& instance(){
static DestinationMarkerYellowMatcher matcher;
return matcher;
}
};


DestinationMarkerDetector::~DestinationMarkerDetector() = default;

DestinationMarkerDetector::DestinationMarkerDetector(Color color, const ImageFloatBox& box)
DestinationMarkerDetector::DestinationMarkerDetector(Color color, const ImageFloatBox& box, bool check_yellow)
: m_color(color)
, m_box(box)
, m_check_yellow(check_yellow)
{}

void DestinationMarkerDetector::make_overlays(VideoOverlaySet& items) const{
Expand All @@ -53,7 +73,12 @@ void DestinationMarkerDetector::make_overlays(VideoOverlaySet& items) const{

bool DestinationMarkerDetector::detect(const ImageViewRGB32& screen) const{
std::vector<ImageFloatBox> hits = detect_all(screen);
return !hits.empty();
if (!m_check_yellow){
return !hits.empty();
}else{
std::vector<ImageFloatBox> hits_yellow = detect_all_yellow(screen);
return !hits.empty() || !hits_yellow.empty();
}
}

std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all(const ImageViewRGB32& screen) const{
Expand All @@ -64,7 +89,6 @@ std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all(const ImageView


const double rmsd_threshold = 80.0; // from my testing: RMSD is 15 at 1080p, 60 at 720p

const double min_object_size = 150.0;

const double screen_rel_size = (screen.height() / 1080.0);
Expand Down Expand Up @@ -93,6 +117,48 @@ std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all(const ImageView



std::vector<ImageFloatBox> DestinationMarkerDetector::detect_all_yellow(const ImageViewRGB32& screen) const{
const std::vector<std::pair<uint32_t, uint32_t>> filters = {
{combine_rgb(180, 100, 0), combine_rgb(255, 190, 50)}, // to detect the marker within the minimap, when the radar beam is covering the marker
};


const double rmsd_threshold = 80.0; // from my testing, RMSD ranges from 15-50, even at 720p
/*
- min object size restrictions also helps to filter out false positives
at pokemon centers
*/
const double min_object_size = 150.0;

const double screen_rel_size = (screen.height() / 1080.0);
const size_t min_size = size_t(screen_rel_size * screen_rel_size * min_object_size);

std::vector<ImageFloatBox> found_locations;

ImagePixelBox pixel_search_area = floatbox_to_pixelbox(screen.width(), screen.height(), m_box);
match_template_by_waterfill(
extract_box_reference(screen, m_box),
DestinationMarkerYellowMatcher::instance(),
filters,
{min_size, SIZE_MAX},
rmsd_threshold,
[&](Kernels::Waterfill::WaterfillObject& object) -> bool {
ImagePixelBox found_box(
object.min_x + pixel_search_area.min_x, object.min_y + pixel_search_area.min_y,
object.max_x + pixel_search_area.min_x, object.max_y + pixel_search_area.min_y);
found_locations.emplace_back(pixelbox_to_floatbox(screen.width(), screen.height(), found_box));
return true;
}
);

return found_locations;
}






}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,22 @@ namespace PokemonSV{

class DestinationMarkerDetector : public StaticScreenDetector{
public:
DestinationMarkerDetector(Color color, const ImageFloatBox& box);
DestinationMarkerDetector(Color color, const ImageFloatBox& box, bool check_yellow);
virtual ~DestinationMarkerDetector();

virtual void make_overlays(VideoOverlaySet& items) const override;
virtual bool detect(const ImageViewRGB32& screen) const override;

std::vector<ImageFloatBox> detect_all(const ImageViewRGB32& screen) const;

// for detecting the marker within the minimap
// ImageFloatBox for detecting within the minimap {0.815, 0.645, 0.180, 0.320}. needs to be slightly higher up than the minimap since the marker will stick up past the minimap
std::vector<ImageFloatBox> detect_all_yellow(const ImageViewRGB32& screen) const;

protected:
Color m_color;
ImageFloatBox m_box;
bool m_check_yellow;
};


Expand All @@ -45,9 +50,10 @@ class DestinationMarkerWatcher : public DetectorToFinder<DestinationMarkerDetect
DestinationMarkerWatcher(
Color color,
const ImageFloatBox& box,
bool check_yellow = false,
std::chrono::milliseconds duration = std::chrono::milliseconds(250)
)
: DetectorToFinder("DestinationMarkerWatcher", std::chrono::milliseconds(250), color, box)
: DetectorToFinder("DestinationMarkerWatcher", std::chrono::milliseconds(250), color, box, check_yellow)
{}
};

Expand Down
Loading
Loading