File: object_tracker.h

package info (click to toggle)
satdump 1.2.2%2Bgb79af48-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 81,648 kB
  • sloc: cpp: 276,768; ansic: 164,598; lisp: 1,219; sh: 283; xml: 106; makefile: 7
file content (177 lines) | stat: -rw-r--r-- 5,930 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#pragma once

#include <vector>
#include <string>
#include <mutex>
#include "libs/predict/predict.h"
#include <thread>
#include "common/tracking/rotator/rotator_handler.h"
#include "common/geodetic/geodetic_coordinates.h"
#include "common/image/image.h"

namespace satdump
{
    class ObjectTracker
    {
    public:
        enum TrackingMode
        {
            TRACKING_SATELLITE,
            TRACKING_HORIZONS,
            TRACKING_NONE,
        };

        struct SatAzEl
        {
            float az = 0;
            float el = 0;
            NLOHMANN_DEFINE_TYPE_INTRUSIVE(SatAzEl, az, el);
        };

    private: // QTH Config
        double qth_lon = 0;
        double qth_lat = 0;
        double qth_alt = 0;

    private: // General configs/utils
        TrackingMode tracking_mode = TRACKING_NONE;
        bool has_tle = false, is_gui;
        std::mutex general_mutex;

        inline float az_el_to_plot_x(float plot_size, float radius, float az, float el) { return sin(az * DEG_TO_RAD) * plot_size * radius * ((90.0 - el) / 90.0); }
        inline float az_el_to_plot_y(float plot_size, float radius, float az, float el) { return cos(az * DEG_TO_RAD) * plot_size * radius * ((90.0 - el) / 90.0); }

    private: // Satellite Tracking (libpredict)
        std::vector<std::string> satoptions;
        int current_satellite_id = 0;
        std::string satellite_searchstr;

        predict_orbital_elements_t *satellite_object = nullptr;
        predict_position satellite_orbit;
        predict_observer_t *satellite_observer_station = nullptr;
        predict_observation satellite_observation_pos;

    private: // Horizons Tracking (horizons)
        struct HorizonsV
        {
            double timestamp;
            float az, el;
        };

        std::vector<std::pair<int, std::string>> horizonsoptions = {{-234, "STEREO-A"}};
        int current_horizons_id = 0;
        std::vector<HorizonsV> horizons_data;
        std::string horizons_searchstr;

        inline void horizons_interpolate(double xvalue, float *az_out, float *el_out)
        {
            int start_pos = 0;
            while (start_pos < (int)horizons_data.size() && xvalue > horizons_data[start_pos].timestamp)
                start_pos++;

            if (start_pos + 1 == (int)horizons_data.size())
                start_pos--;
            if (start_pos == 0)
                start_pos++;

            double x1 = horizons_data[start_pos].timestamp;
            double x2 = horizons_data[start_pos + 1].timestamp;
            double az_y1 = horizons_data[start_pos].az;
            double az_y2 = horizons_data[start_pos + 1].az;
            double el_y1 = horizons_data[start_pos].el;
            double el_y2 = horizons_data[start_pos + 1].el;

            // printf("%d - %f %f %f - %f %f\n", start_pos, x1, xvalue, x2, y1, y2);

            double x_len = x2 - x1;
            xvalue -= x1;

            double az_y_len = az_y2 - az_y1;
            double el_y_len = el_y2 - el_y1;

            *az_out = az_y1 + (xvalue / x_len) * az_y_len;
            *el_out = el_y1 + (xvalue / x_len) * el_y_len;
        }

        double last_horizons_fetch_time = 0;

        std::vector<std::pair<int, std::string>> pullHorizonsList();
        void loadHorizons(double curr_time);
        std::vector<HorizonsV> pullHorizonsData(double start_time, double stop_time, int num_points);

    private: // Internal threads
        bool backend_should_run = true;
        std::thread backend_thread;
        void backend_run();
        bool backend_needs_update = true;

        bool rotatorth_should_run = true;
        std::thread rotatorth_thread;
        void rotatorth_run();

    private: // Current satellite
        SatAzEl sat_current_pos;

        std::mutex upcoming_passes_mtx;
        std::vector<SatAzEl> upcoming_pass_points;
        void updateNextPass(double current_time);
        float correctRotatorAzimuth(const float az);

        double next_aos_time = -1, next_los_time = -1;
        SatAzEl sat_next_aos_pos;
        SatAzEl sat_next_los_pos;

    private: // Rotator control
        bool rotator_engaged = false;
        bool rotator_tracking = false;
        bool northbound_cross = false;
        bool southbound_cross = false;
        SatAzEl rot_current_pos;
        SatAzEl rot_current_req_pos;
        SatAzEl rot_current_reqlast_pos;

        std::mutex rotator_handler_mtx;
        std::shared_ptr<rotator::RotatorHandler> rotator_handler;

        double rotator_update_period = 1;
        bool rotator_park_while_idle = false;
        bool rotator_rounding = false;
        int rotator_decimal_multiplier = 1000;
        int rotator_decimal_precision = 3;
        SatAzEl rotator_park_position;
        double rotator_unpark_at_minus = 60;
        bool meridian_flip_correction = false;
        int rotator_az_min = 0;
        int rotator_az_max = 360;

        bool rotator_arrowkeys_enable = false;
        double rotator_arrowkeys_increment = 0.1;

    public: // Handlers
        std::function<void(double, double)> rotator_target_pos_updated_callback; //Todo: this calls from rotatorth_thread

    public: // Functions
        nlohmann::json getStatus();
        image::Image getPolarPlotImg(int size = 256);

        void setQTH(double qth_lon, double qth_lat, double qth_alt);
        void setObject(TrackingMode mode, int objid);
        void setRotator(std::shared_ptr<rotator::RotatorHandler> rot);
        void setRotatorEngaged(bool v);
        void setRotatorTracking(bool v);
        void setRotatorReqPos(float az, float el);

        void renderPolarPlot();
        void renderSelectionMenu();
        void renderObjectStatus();
        void renderRotatorStatus();
        void renderRotatorConfig();

        nlohmann::json getRotatorConfig();
        void setRotatorConfig(nlohmann::json v);

    public:
        ObjectTracker(bool is_gui = false);
        ~ObjectTracker();
    };
}