<commit_before>#include "Observer.h"
#include "SGP4.h"

#include <cmath>
#include <iostream>

Julian FindCrossingPoint(const CoordGeodetic& user_geo, SGP4& sgp4, const Julian& initial_time1, const Julian& initial_time2, bool finding_aos) {

    Observer obs(user_geo);
    Eci eci;

    bool searching = true;
    unsigned int loop_count = 0;

    Julian time1 = initial_time1;
    Julian time2 = initial_time2;

    Julian middle_time = time1 + (time2.GetDate() - time1.GetDate()) / 2.0;

    while (searching && loop_count < 25) {

        /*
         * find position
         */
        sgp4.FindPosition(&eci, middle_time);
        CoordTopographic topo = obs.GetLookAngle(eci);

        if (topo.elevation > 0.0) {

            if (finding_aos) {
                time2 = middle_time;
            } else {
                time1 = middle_time;
            }
        } else {

            if (finding_aos) {
                time1 = middle_time;
            } else {
                time2 = middle_time;
            }
        }

        /*
         * when two times are within a second, stop
         */
        if (((time2.GetDate() - time1.GetDate()) * kSECONDS_PER_DAY) < 1.0) {
            searching = false;
        }

        middle_time = time1 + (time2.GetDate() - time1.GetDate()) / 2.0;
        loop_count++;
    };

    return middle_time;
}

void AOSLOS(const CoordGeodetic& user_geo, SGP4& sgp4, const Julian& start_time, const Julian& end_time) {

    Observer obs(user_geo);
    Eci eci;

    bool first_run = true;
    Julian previous_time = start_time;

    Julian aos_time;
    Julian los_time;
    bool found_aos = false;
    bool found_los = false;

    for (Julian current_time = start_time; current_time <= end_time; current_time.AddMin(1.0)) {

        sgp4.FindPosition(&eci, current_time);
        CoordTopographic topo = obs.GetLookAngle(eci);

        if (topo.elevation > 0.0) {
            /*
             * satellite is above horizon
             * and its the first run, so just use start_time
             */
            if (first_run) {

                aos_time = start_time;
                found_aos = true;
                found_los = false;

                /*
                 * not the first iteration and satellite has
                 * gone above horizon, so find AOS
                 */
            } else if (!found_aos) {

                aos_time = FindCrossingPoint(user_geo, sgp4, previous_time, current_time, true);
                found_aos = true;
                found_los = false;
            }
        } else {
            /*
             * if satellite now below horizon and have previously
             * found AOS, find LOS
             */
            if (found_aos) {

                los_time = FindCrossingPoint(user_geo, sgp4, previous_time, current_time, false);
                found_aos = false;
                found_los = false;
                std::cout << "AOS: " << aos_time << ", LOS: " << los_time << std::endl;
            }
        }

        first_run = false;
        previous_time = current_time;
    }

    /*
     * is satellite still above horizon at end of search period
     */
    if (found_aos && !found_los) {

        los_time = end_time;
        std::cout << "AOS: " << aos_time << ", LOS: " << los_time << std::endl;
    }
}

int main() {

    CoordGeodetic geo(51.37322, 0.089607, 0.05);
    Tle tle("STS 134                 ",
            "1 37577U 11020A   11146.50425755  .00016213  00000-0  10821-3 0   213",
            "2 37577  51.6484 271.9502 0003400 321.9646 127.1023 15.75523823  1551");
    SGP4 sgp4(tle);

    Julian start_date;
    Julian end_date(start_date);
    end_date.AddDay(10.0);

    /*
     * generate 10 day schedule
     */
    AOSLOS(geo, sgp4, start_date, end_date);

    /*
     * convert time to whole seconds
     */
    //if(finding_aos)
    //    middle_time = floor(middle_time.GetDate() * kSECONDS_PER_DAY) / kSECONDS_PER_DAY;
    //else
    //    middle_time = ceil(middle_time.GetDate() * kSECONDS_PER_DAY) / kSECONDS_PER_DAY;

    return 0;
#if 0
    Eci eci;

    while (1) {
        Julian now;
        sgp4.FindPosition(&eci, now);
        CoordTopographic topo = obs.GetLookAngle(eci);
        CoordGeodetic geo = eci.ToGeodetic();
        std::cout << now << " ";
        std::cout << topo << " ";
        std::cout << geo << std::endl;
    };

    return 0;
#endif
}<commit_msg>Added max elevation calculation<commit_after>#include "Observer.h"
#include "SGP4.h"

#include <cmath>
#include <iostream>

double FindMaxElevation(const CoordGeodetic& user_geo, SGP4& sgp4, const Julian& aos, const Julian& los) {

    Observer obs(user_geo);
    Eci eci;

    double max_elevation = -99.9;
    /*
     * time step in seconds
     */
    double time_step = 180.0;
    /*
     * still searching for max elevation
     */
    bool searching = true;
    /*
     * fine tune the max elevation value
     */
    bool fine_tune = false;

    Julian current_time = aos;
    while (current_time < los && searching) {

        /*
         * find position
         */
        sgp4.FindPosition(&eci, current_time);
        CoordTopographic topo = obs.GetLookAngle(eci);

        /*
         * keep updating max elevation
         */
        if (topo.elevation > max_elevation) {

            max_elevation = topo.elevation;
        } else if (!fine_tune) {
            /*
             * passed max elevation
             * max elevation happened in the last 6 minutes
             * go back and fine tune max elevation value
             */
            current_time.AddSec(-2.0 * time_step);
            /*
             * dont go back before aos
             */
            if (current_time < aos)
                current_time = aos;

            /*
             * 1 second increment
             */
            time_step = 1.0;
            fine_tune = true;

            /*
             * reset elevation
             */
            max_elevation = -99.9;
            
        } else {
            /*
             * found max elevation
             */

            searching = false;
        }

        if (searching) {
            current_time.AddSec(time_step);
            if (current_time > los)
                current_time = los;
        }
    };

    return max_elevation;
}

Julian FindCrossingPoint(const CoordGeodetic& user_geo, SGP4& sgp4, const Julian& initial_time1, const Julian& initial_time2, bool finding_aos) {

    Observer obs(user_geo);
    Eci eci;

    bool searching = true;
    unsigned int loop_count = 0;

    Julian time1 = initial_time1;
    Julian time2 = initial_time2;

    Julian middle_time = time1 + (time2.GetDate() - time1.GetDate()) / 2.0;

    while (searching && loop_count < 25) {

        /*
         * find position
         */
        sgp4.FindPosition(&eci, middle_time);
        CoordTopographic topo = obs.GetLookAngle(eci);

        if (topo.elevation > 0.0) {

            if (finding_aos) {
                time2 = middle_time;
            } else {
                time1 = middle_time;
            }
        } else {

            if (finding_aos) {
                time1 = middle_time;
            } else {
                time2 = middle_time;
            }
        }

        /*
         * when two times are within a second, stop
         */
        if (((time2.GetDate() - time1.GetDate()) * kSECONDS_PER_DAY) < 1.0) {
            searching = false;
        }

        middle_time = time1 + (time2.GetDate() - time1.GetDate()) / 2.0;
        loop_count++;
    };

    return middle_time;
}

void AOSLOS(const CoordGeodetic& user_geo, SGP4& sgp4, const Julian& start_time, const Julian& end_time) {

    Observer obs(user_geo);
    Eci eci;

    bool first_run = true;
    Julian previous_time = start_time;

    Julian aos_time;
    Julian los_time;
    bool found_aos = false;
    bool found_los = false;

    Julian current_time = start_time;
    while (current_time < end_time) {

        sgp4.FindPosition(&eci, current_time);
        CoordTopographic topo = obs.GetLookAngle(eci);

        if (topo.elevation > 0.0) {
            /*
             * satellite is above horizon
             * and its the first run, so just use start_time
             */
            if (first_run) {

                aos_time = start_time;
                found_aos = true;
                found_los = false;

                /*
                 * not the first iteration and satellite has
                 * gone above horizon, so find AOS
                 */
            } else if (!found_aos) {

                aos_time = FindCrossingPoint(user_geo, sgp4, previous_time, current_time, true);
                found_aos = true;
                found_los = false;
            }
        } else {
            /*
             * if satellite now below horizon and have previously
             * found AOS, find LOS
             */
            if (found_aos) {

                los_time = FindCrossingPoint(user_geo, sgp4, previous_time, current_time, false);
                found_aos = false;
                found_los = false;
                double max_elevation = FindMaxElevation(user_geo, sgp4, aos_time, los_time);
                std::cout << "AOS: " << aos_time << ", LOS: " << los_time << ", Max El: " << RadiansToDegrees(max_elevation) << std::endl;
            }
        }

        first_run = false;
        previous_time = current_time;

        current_time.AddMin(1.0);
        if (current_time > end_time)
            current_time = end_time;
    };

    /*
     * is satellite still above horizon at end of search period
     */
    if (found_aos && !found_los) {

        los_time = end_time;
        double max_elevation = FindMaxElevation(user_geo, sgp4, aos_time, los_time);
        std::cout << "AOS: " << aos_time << ", LOS: " << los_time << ", Max El: " << RadiansToDegrees(max_elevation) << std::endl;
    }
}

int main() {

    CoordGeodetic geo(51.37322, 0.089607, 0.05);
    Tle tle("GIOVE-B                 ",
            "1 32781U 08020A   11158.03814084  .00000088  00000-0  10000-3 0  4620",
            "2 32781  55.9142 172.9458 0022365 228.3743 131.4697  1.70953903 19437");
    SGP4 sgp4(tle);

    Julian start_date;
    Julian end_date(start_date);
    end_date.AddDay(10.0);

    /*
     * generate 10 day schedule
     */
    AOSLOS(geo, sgp4, start_date, end_date);

    return 0;
}
{'fraction_non_alphanumeric': 0.10230228301705038, 'fraction_numerical': 0.035545708505924284, 'mean_word_length': 1.6283544303797468, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3572615', 'n_tokens_mistral': 3570, 'n_tokens_neox': 3222, 'n_words': 775}