why isnt this working its not outputting anything class SimpleTimeToReachCalculator {
public:
	static float calculateTimeToReach(float xyDist, float zDist, float velToTarget, float rotTime, float surfaceTime) {
		float dist = std::sqrt(xyDist * xyDist + zDist * zDist);
		float vel = velToTarget;

		// Determine whether to use aerial acceleration
		float aerialTime = 0;
		float aerialDist = dist;
		float aerialVel = vel;
		while (aerialDist > DIST_REACH_THRESH && aerialTime < surfaceTime) {
			aerialVel += (AIR_ACCEL + BOOST_ACCEL_AIR) * STEP_INTERVAL;
			if (aerialVel > MAX_TOTAL_SPEED) aerialVel = MAX_TOTAL_SPEED;
			aerialDist -= aerialVel * STEP_INTERVAL;
			aerialTime += STEP_INTERVAL;
		}
		bool useAerial = aerialTime < surfaceTime;

		float t = 0;
		for (float curDist = dist, curVel = vel; curDist > DIST_REACH_THRESH; t += STEP_INTERVAL, curDist -= curVel * STEP_INTERVAL) {
			bool hasRotated = t >= rotTime;
			if (curVel < MAX_TOTAL_SPEED && t == 0) {
				// Flip force
				curVel += FLIP_FORCE;
			}
			if (useAerial) {
				// Aerial acceleration
				if (curVel < MAX_DRIVE_SPEED) {
					curVel += (AIR_ACCEL + BOOST_ACCEL_AIR * hasRotated) * STEP_INTERVAL;
				}
				else if (curVel < MAX_TOTAL_SPEED) {
					curVel += BOOST_ACCEL_AIR * hasRotated * STEP_INTERVAL;
				}
			}
			else {
				// Ground acceleration
				if (curVel < 0) {
					curVel += (BRAKE_ACCEL + BOOST_ACCEL_GROUND * hasRotated) * STEP_INTERVAL;
				}
				else if (curVel < MAX_DRIVE_SPEED) {
					curVel += (DRIVE_ACCEL + BOOST_ACCEL_GROUND * hasRotated) * STEP_INTERVAL;
				}
				else if (curVel < MAX_TOTAL_SPEED) {
					curVel += BOOST_ACCEL_GROUND * hasRotated * STEP_INTERVAL;
				}
			}
			if (curVel >= MAX_TOTAL_SPEED) {
				return t + (curDist / MAX_TOTAL_SPEED);
			}
		}
		return t;
	}
	static float calculateTimeToReach(const PlayerData& player, const Vec& targetPos) {
		Vec deltaPos = targetPos - player.phys.pos;
		float xyDist = deltaPos.To2D().Length();
		float zDist = std::abs(deltaPos.z);
		float velToTarget = player.phys.vel.Dot(deltaPos.Normalized());
		float rotTime = calculateRotationTime(player, targetPos);
		float surfaceTime = calculateTimeToReachAnySurface(player);

		return calculateTimeToReach(xyDist, zDist, velToTarget, rotTime, surfaceTime);
	}

	static float calculateRotationTime(const PlayerData& player, const Vec& targetPos) {

		constexpr float MAX_ANG_VEL = 5.5f * 0.9f;

		Vec playerForward = player.phys.rotMat.forward;
		Vec dirToTarget = (targetPos - player.phys.pos).Normalized();
		float dotProduct = RS_CLAMP(playerForward.Dot(dirToTarget), -1.0f, 1.0f);
		float angleDiff = std::acos(dotProduct);
		return angleDiff / MAX_ANG_VEL;
	}

	static float calculateTimeToReachAnySurface(const PlayerData& player) {
		float timeToSideWalls = calculateTimeToSideWalls(player);
		float timeToBackWalls = calculateTimeToBackWalls(player);
		float timeToFloor = calculateTimeToFloor(player);

		float minTimeBetweenBackWallsAndFloor = RS_MIN(timeToBackWalls, timeToFloor);
		float minTime = RS_MIN(timeToSideWalls, minTimeBetweenBackWallsAndFloor);

		return minTime;
	}



private:
	static constexpr float DIST_REACH_THRESH = 80.0f;
	static constexpr float STEP_INTERVAL = 1.0f / 60.0f;
	static constexpr float FLIP_FORCE = 495.0f;
	static constexpr float AIR_ACCEL = 133.334f;
	static constexpr float BOOST_ACCEL_AIR = 2116.666f;
	static constexpr float MAX_TOTAL_SPEED = 2300.0f;
	static constexpr float BRAKE_ACCEL = 3500.0f;
	static constexpr float BOOST_ACCEL_GROUND = 1983.332f;
	static constexpr float MAX_DRIVE_SPEED = 1410.0f;

	// Constants for surface calculations
	static constexpr float SIDE_WALL_X = 4096.0f;
	static constexpr float NEAR_WALL_DISTANCE = 4077.0f;
	static constexpr float EPSILON = 1e-3f;
	static constexpr float BACK_WALL_Y = 5120.0f;
	static constexpr float NEG_BACK_WALL_Y = -5120.0f;
	static constexpr float MAX_BACKWALL_Y = 5100.0f;
	static constexpr float BOOST_ACCEL_POS = 1000.0f;
	static constexpr float BOOST_ACCEL_NEG = -1000.0f;
	static constexpr float FLOOR_Z = 18.0f;
	static constexpr float GRAVITY_Z = -650.0f;
	static constexpr float BOOST_ACCEL_DOWN = -1000.0f;
	static constexpr float DRIVE_ACCEL = 1600.0f;

	

	static float calculateTimeToSideWalls(const PlayerData& player) {
		const Vec& pos = player.phys.pos;
		const Vec& vel = player.phys.vel;

		float minTime = std::numeric_limits<float>::infinity();

		if (std::abs(pos.x) >= NEAR_WALL_DISTANCE && std::abs(pos.x) <= SIDE_WALL_X) {
			return 0.0f;
		}

		if (vel.x > EPSILON) {
			float a = 0.5f * DRIVE_ACCEL;
			float b = vel.x;
			float c = pos.x - SIDE_WALL_X;

			float discriminant = b * b - 4.0f * a * c;

			if (discriminant >= 0.0f) {
				float sqrtD = std::sqrt(discriminant);
				float t1 = (-b + sqrtD) / (2.0f * a);
				float t2 = (-b - sqrtD) / (2.0f * a);

				if (t1 > EPSILON && t1 < minTime) {
					minTime = t1;
				}
				if (t2 > EPSILON && t2 < minTime) {
					minTime = t2;
				}
			}
		}

		if (vel.x < -EPSILON) {
			float a = 0.5f * (-DRIVE_ACCEL);
			float b = vel.x;
			float c = pos.x + SIDE_WALL_X;

			float discriminant = b * b - 4.0f * a * c;

			if (discriminant >= 0.0f) {
				float sqrtD = std::sqrt(discriminant);
				float t1 = (-b + sqrtD) / (2.0f * a);
				float t2 = (-b - sqrtD) / (2.0f * a);

				if (t1 > EPSILON && t1 < minTime) {
					minTime = t1;
				}
				if (t2 > EPSILON && t2 < minTime) {
					minTime = t2;
				}
			}
		}

		return minTime;
	}

	static float calculateTimeToBackWalls(const PlayerData& player) {
		const Vec& pos = player.phys.pos;
		const Vec& vel = player.phys.vel;

		float minTime = std::numeric_limits<float>::infinity();

		if (pos.y >= MAX_BACKWALL_Y || pos.y <= -MAX_BACKWALL_Y) {
			return 0.0f;
		}

		if (pos.y >= BACK_WALL_Y || pos.y <= NEG_BACK_WALL_Y) {
			return 0.0f;
		}

		if (vel.y > EPSILON) {
			float a = 0.5f * BOOST_ACCEL_POS;
			float b = vel.y;
			float c = pos.y - BACK_WALL_Y;

			float discriminant = b * b - 4.0f * a * c;

			if (discriminant >= 0.0f) {
				float sqrtD = std::sqrt(discriminant);
				float t1 = (-b + sqrtD) / (2.0f * a);
				float t2 = (-b - sqrtD) / (2.0f * a);

				if (t1 > EPSILON && t1 < minTime) {
					minTime = t1;
				}
				if (t2 > EPSILON && t2 < minTime) {
					minTime = t2;
				}
			}
		}

		if (vel.y < -EPSILON) {
			float a = 0.5f * BOOST_ACCEL_NEG;
			float b = vel.y;
			float c = pos.y - NEG_BACK_WALL_Y;

			float discriminant = b * b - 4.0f * a * c;

			if (discriminant >= 0.0f) {
				float sqrtD = std::sqrt(discriminant);
				float t1 = (-b + sqrtD) / (2.0f * a);
				float t2 = (-b - sqrtD) / (2.0f * a);

				if (t1 > EPSILON && t1 < minTime) {
					minTime = t1;
				}
				if (t2 > EPSILON && t2 < minTime) {
					minTime = t2;
				}
			}
		}

		return minTime;
	}

	static float calculateTimeToFloor(const PlayerData& player) {
		const Vec& pos = player.phys.pos;
		const Vec& vel = player.phys.vel;

		if (pos.z <= FLOOR_Z) {
			return 0.0f;
		}

		float totalAccel = GRAVITY_Z + BOOST_ACCEL_DOWN;

		float a = 0.5f * totalAccel;
		float b = vel.z;
		float c = pos.z - FLOOR_Z;

		float discriminant = b * b - 4.0f * a * c;

		if (discriminant < 0.0f) {
			return std::numeric_limits<float>::infinity();
		}

		float sqrtD = std::sqrt(discriminant);
		float t1 = (-b - sqrtD) / (2.0f * a);
		float t2 = (-b + sqrtD) / (2.0f * a);

		float timeToFloor = std::numeric_limits<float>::infinity();

		if (t1 > 0.0f) {
			timeToFloor = t1;
		}
		if (t2 > 0.0f && t2 < timeToFloor) {
			timeToFloor = t2;
		}

		return timeToFloor;
	}
};

class TimeToReachLUT {
public:
	static constexpr int XY_DIST_STEPS = 100;
	static constexpr int Z_DIST_STEPS = 50;
	static constexpr int VEL_STEPS = 50;
	static constexpr int ROT_TIME_STEPS = 20;
	static constexpr int SURFACE_TIME_STEPS = 20;

	static constexpr float MAX_XY_DIST = 10000.0f;
	static constexpr float MAX_Z_DIST = 2000.0f;
	static constexpr float MAX_VEL = 2300.0f;
	static constexpr float MAX_ROT_TIME = 2.0f;
	static constexpr float MAX_SURFACE_TIME = 5.0f;

	TimeToReachLUT() {
		precomputeLUT();
	}

	float getTimeToReach(float xyDist, float zDist, float velToTarget, float rotTime, float surfaceTime) const {
		int xyIndex = static_cast<int>(xyDist / (MAX_XY_DIST / XY_DIST_STEPS));
		int zIndex = static_cast<int>(zDist / (MAX_Z_DIST / Z_DIST_STEPS));
		int velIndex = static_cast<int>((velToTarget + MAX_VEL) / (2 * MAX_VEL / VEL_STEPS));
		int rotIndex = static_cast<int>(rotTime / (MAX_ROT_TIME / ROT_TIME_STEPS));
		int surfaceIndex = static_cast<int>(surfaceTime / (MAX_SURFACE_TIME / SURFACE_TIME_STEPS));

		xyIndex = std::clamp(xyIndex, 0, XY_DIST_STEPS - 1);
		zIndex = std::clamp(zIndex, 0, Z_DIST_STEPS - 1);
		velIndex = std::clamp(velIndex, 0, VEL_STEPS - 1);
		rotIndex = std::clamp(rotIndex, 0, ROT_TIME_STEPS - 1);
		surfaceIndex = std::clamp(surfaceIndex, 0, SURFACE_TIME_STEPS - 1);

		return lut[xyIndex][zIndex][velIndex][rotIndex][surfaceIndex];
	}

private:
	std::array<std::array<std::array<std::array<std::array<float, SURFACE_TIME_STEPS>, ROT_TIME_STEPS>, VEL_STEPS>, Z_DIST_STEPS>, XY_DIST_STEPS> lut;

	void precomputeLUT() {
		for (int xy = 0; xy < XY_DIST_STEPS; ++xy) {
			for (int z = 0; z < Z_DIST_STEPS; ++z) {
				for (int v = 0; v < VEL_STEPS; ++v) {
					for (int r = 0; r < ROT_TIME_STEPS; ++r) {
						for (int s = 0; s < SURFACE_TIME_STEPS; ++s) {
							float xyDist = xy * (MAX_XY_DIST / XY_DIST_STEPS);
							float zDist = z * (MAX_Z_DIST / Z_DIST_STEPS);
							float velToTarget = v * (2 * MAX_VEL / VEL_STEPS) - MAX_VEL;
							float rotTime = r * (MAX_ROT_TIME / ROT_TIME_STEPS);
							float surfaceTime = s * (MAX_SURFACE_TIME / SURFACE_TIME_STEPS);

							lut[xy][z][v][r][s] = SimpleTimeToReachCalculator::calculateTimeToReach(
								xyDist, zDist, velToTarget, rotTime, surfaceTime);
						}
					}
				}
			}
		}
	}
};
 rlbot::Controller RLBotBot::GetOutput(rlbot::GameTickPacket gameTickPacket) {
    float curTime = gameTickPacket->gameInfo()->secondsElapsed();
    float deltaTime = curTime - prevTime;
    prevTime = curTime;
    int ticksElapsed = roundf(deltaTime * 120);
    ticks += ticksElapsed;

    std::vector<RocketSim::Car*> rocketSimCars;
    if (predictionArena != nullptr) {
        auto cars = predictionArena->GetCars();
        rocketSimCars.assign(cars.begin(), cars.end());
    }

    GameState gs = ToGameState(gameTickPacket, ticksElapsed, params.tickSkip, rocketSimCars, ticks, controls);
    auto& localPlayer = gs.players[index];
    // Update BallPred
    BallPred::getInstance().UpdateIfNeeded(predictionArena);
    //RenderGlobalBallPred(gs);

   

     // Calculate time to reach the ball
    Vec ballPos = gs.ball.pos;
    //float timeToReachBall = TimeToReachCalculatorv2::calculateTimeToReach(localPlayer, ballPos);
    //RG_LOG("Time to reach ball: " << timeToReachBall);

    // Render the time to reach ball using RenderText
    //std::stringstream ss;
    //ss << std::fixed << std::setprecision(2) << timeToReachBall << "s";
    //rlbot::flat::Vector3 textPosition{
   //     static_cast<float>(ballPos.x),
    //    static_cast<float>(ballPos.y),
    //    static_cast<float>(ballPos.z + CommonValues::BALL_RADIUS + 10)  // Position text just above the ball's surface
   // };
   // RenderText(ss.str(), textPosition, 1.0f, rlbot::Color::white);

    //RenderPossession(gs);
    //RenderTimeToSurface(gs);
    //RenderPossessionPrediction(gs);
     //RenderCarInfo(gs);
     //RenderTimeToSurface(gs);
     // **Integrate DistToClosestWall Function Here**
     //RenderGlobalBallPred(gs);
    //RG_LOG(TimeToground);

    //timewallexsrap(gs);
    //RenderArenaRamps(gs);
    //Vec ballPos = gs.ball.pos;
    Vec deltaPos = ballPos - localPlayer.phys.pos;
    float xyDist = deltaPos.To2D().Length();
    float zDist = std::abs(deltaPos.z);
    float velToTarget = localPlayer.phys.vel.Dot(deltaPos.Normalized());

    float rotTime = SimpleTimeToReachCalculator::calculateRotationTime(localPlayer, ballPos);
    float surfaceTime = SimpleTimeToReachCalculator::calculateTimeToReachAnySurface(localPlayer);

    // Use the LUT to get the time to reach
    float timeToReach = timeToReachLUT.getTimeToReach(xyDist, zDist, velToTarget, rotTime, surfaceTime);

    RG_LOG("LUT Time to Reach: " + std::to_string(timeToReach));

    // For comparison, you can keep the original calculation
    float timeToReach2 = SimpleTimeToReachCalculator::calculateTimeToReach(xyDist, zDist, velToTarget, rotTime, surfaceTime);
    RG_LOG("Original Time to Reach: " + std::to_string(timeToReach2));

    // Calculate and log the time to reach any surface
    //auto timeToReachSurface = calculateMinAirTime2(localPlayer, gs);
    //RG_LOG(timeToReachSurface);

    //float timeToReach = calculateTimeToReach(gs);
    //RG_LOG(timeToReach);

    //float RotTime = calculateRotationTime(gs);
    //RG_LOG(RotTime);

    //float TotalTime = calculateTotalTimeToBall(gs);
    //RG_LOG(TotalTime);

    ListenAndPrintKeys();

    //RenderTimeToReachBall2(gs);

    //ResetToDefaultKickoff();  // Call the reset function

    //RenderBallInfo(gs);

    //RenderCarInfo(gs);

    if (renderRewardEnabled) {
        RenderReward(gs);
    }
    if (renderCarStateTableEnabled) {
        //RenderCarStateTable(gs);
        //RenderCarStateTable(gs);
    }
    if (renderBallPredictionsEnabled) {
        //RenderBallPredictions(gs);
    }
    if (updatePredictionArenaEnabled) {
        UpdatePredictionArena(gs);
    }
    if (renderTimeToReachBallEnabled) {
        //RenderTimeToReachBall(gs);
        //RenderTimeToReachBall2(gs);
    }
    gs.lastArena = predictionArena;

    if (g_RLBotParams.userInputMode) {
        controls = ConvertToAction(g_RLBotParams.userControls);
    }
    else {
        if (updateAction) {
            updateAction = false;
            action = policyInferUnit->InferPolicySingle(localPlayer, gs, controls, true);
        }
        if (ticks >= params.tickSkip || ticks == -1) {
            controls = action;
            ticks = 0;
            updateAction = true;
        }
    }

    auto rc = rlbot::Controller();
    rc.throttle = controls.throttle;
    rc.steer = controls.steer;
    rc.pitch = controls.pitch;
    rc.yaw = controls.yaw;
    rc.roll = controls.roll;
    rc.boost = controls.boost;
    rc.jump = controls.jump;
    rc.handbrake = controls.handbrake;

    return rc;
}