Baseball Batting Heuristic
/*
Copyright(C) 2025 Tyler Crockett | Macdaddy4sure.ai
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissionsand
limitations under the License.
*/
#include "AugmentedIntelligence.hpp"
#include "Baseball.hpp"
#include "Large Language Models.hpp"
#include "Parsers.hpp"
#include "Settings.hpp"
#include "Thought.hpp"
#include "Utilities.hpp"
#include "Working-Memory.hpp"
#include "Vision.hpp"
using namespace std;
// Define constants for arm movement
const double ARM_LENGTH = 0.7; // meters
const double ELBOW_BEND_ANGLE = M_PI / 2; // radians (90 degrees)
const double SHOULDER_ROTATION_ANGLE = M_PI / 4; // radians (45 degrees)
std::vector<BallState> trajectory;
PitchAnalyzer analyzer;
const size_t MAX_HISTORY = 30;
/*
Todo: Implement Baseball Stats Tracking from Baseball-Reference.com and MLB.com to analyze player performance and make informed decisions during the game. Use this data to adjust the AI's strategy and improve its performance over time. Additionally, consider implementing a machine learning model to predict player performance based on historical data and current game conditions.
*/
void _Baseball::Baseball()
{
TF_Status* status = TF_NewStatus();
TF_Graph* graph = TF_NewGraph();
TF_SessionOptions* options = TF_NewSessionOptions();
TF_Buffer* run_opts = nullptr;
const char* tags = "serve";
TF_Session* session = TF_LoadSessionFromSavedModel(options, nullptr, tensorflow_model.c_str(), &tags, 1, graph, nullptr, status);
bool AtBat = true;
string mode = "baseball";
string image_location;
string image_date;
ostringstream oss;
string currentTime;
Object current_object;
Object prev_object;
Object home_plate = { "0", "home plate", 0.0, 0.0, 0.0, 0.0, 0.0, nullptr, nullptr};
BallState lastState = { 0, 0, 0.0, 0, "", "" };
while (AtBat)
{
// Find the most recent frame in working memory
for (int x = 999; x >= 0; x--)
{
if (wm_vision_path_camera1[x][0] != "")
{
image_location = wm_vision_path_camera1[x][0];
image_date = wm_vision_path_camera1[x][1];
break;
}
}
cv::Mat frame = cv::imread(image_location, cv::IMREAD_COLOR);
vector<vector<string>> object_detection = _Vision::ObjectDetectionSequence(status, graph, options, run_opts, tags, session, frame);
// Read the values from the coco_ball array and store them into memory
for (int x = 0; x <= object_detection.size(); x++)
{
if (object_detection[x][1] == "sports ball")
{
current_object.unique_id = "object " + to_string(x);
current_object.class_name = object_detection[x][1];
current_object.x = stoi(object_detection[x][2]);
current_object.box_width = stoi(object_detection[x][3]);
current_object.y = stoi(object_detection[x][4]);
current_object.box_height = stoi(object_detection[x][5]);
current_object.distance = _Baseball::Math::getBallDistance(current_object, prev_object);
break;
}
}
if (current_object.class_name == "sports ball")
{
// Solve the baseball for each frame, make predictions for each frame and create swing assist
// 1. Get the position and velocity of the ball
// 2. Get the derivative of the velocity of the ball
// 3. Get the position of the ball with respect to the position on the diamond
// 4. Get the amount of time until the ball reaches the plate
// 5. Get the pitch type
// 6. Get the spin rate of the ball
// 7. Get the elbow and hand angles of the pitcher to infer the pitch type
// 8. Get the finger position of the pitcher to infer the pitch type
// 9. Get the trajectory of the ball
// 10. Get the pitch types of the current pitcher and the tendencies of the pitcher to predict the pitch type
// 11. Predict the location of the ball before it crosses the plate
// 12. Get my hot and cold zones to predict the target location
// 13. Get the angles of swing to create a swing zone
// 14. When to take and when not to take a swing based on the above solve
// 15. Get when to swing in frames
// a. Get the distance of the ball to home plate and take a swing based on angles of bat and swing zone
// 16. When to take a contact or power swing basedm on the above solve
// 17. Use previous frames for predictions
double IoU = _Baseball::Math::CalculateIoU(current_object, prev_object);
if (IoU >= iou_min && IoU <= iou_max)
{
// Get the velocity and acceleration of the ball from pixels to meters
current_object.velocity = _Baseball::Math::CalculateObjectVelocity(current_object, prev_object, 1 / camera1_fps);
current_object.acceleration = _Baseball::Math::CalculateAcceleration(current_object, prev_object, 1 / camera1_fps);
// 1. Calculate the time to cross plate
double relativeVelocity = _Baseball::Math::calculateRelativeVelocity(home_plate, current_object);
double ttc = _Baseball::Math::calculateTTC(current_object.distance, relativeVelocity);
//double probability = _Baseball::Math::calculateCollisionProbability(ttc, threshold);
// Determine by the trajectory, speed, and spin of the ball when to take a swing and when not to take a swing
BallState currentState = { current_object.x, current_object.y, (int)current_object.velocity, 0, "", currentTime };
analyzer.addState(currentState);
std::string pitch = analyzer.identifyPitch(prev_object, current_object);
auto entry = time(nullptr);
auto tm1 = *localtime(&entry);
oss << put_time(&tm1, "%d-%m-%Y_%H-%M-%S");
currentTime = oss.str();
cv::Rect currentRect(current_object.x, current_object.y, current_object.box_width, current_object.box_height);
cv::rectangle(frame, currentRect, cv::Scalar(0, 255, 0), 2);
std::string label = "Velocity: " + std::to_string((int)current_object.velocity) + " mph";
cv::putText(frame, label, cv::Point(currentRect.x, currentRect.y - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2);
lastState = currentState;
prev_object = current_object;
}
}
}
}
Filed under: Uncategorized - @ April 23, 2026 5:23 pm