File: SerialCommand.hpp

package info (click to toggle)
indi-bresserexos2 1.0%2B20221223130124-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, trixie
  • size: 3,136 kB
  • sloc: cpp: 2,317; makefile: 2
file content (218 lines) | stat: -rw-r--r-- 8,010 bytes parent folder | download | duplicates (2)
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
 * SerialCommand.hpp
 *
 * Copyright 2020 Kevin Krüger <kkevin@gmx.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 *
 */

#ifndef _SERIALCOMMAND_H_INCLUDED_
#define _SERIALCOMMAND_H_INCLUDED_

#include <cstdint>
#include <vector>
#include <chrono>
#include <cmath>
#include <ctime>
#include <libnova/julian_day.h>
#include "config.h"

#define MESSAGE_FRAME_SIZE (13)

namespace SerialDeviceControl
{
//After determining the message frame size and structure,
//these commands where found to affect the telescope controller (Handbox + Motors).
//If an invalid command is issued the telescope controller stops reporting its status,
//until another valid command is issued.
//Command IDs which did not stop the report messages are considered effective and are listed below:
enum SerialCommandID
{
    //a null command message.
    NULL_COMMAND_ID = (uint8_t) 0x00,

    //these command IDs move the telescope in certain direction while tracking:
    //move the telescope "east".
    MOVE_EAST_COMMAND_ID  = (uint8_t)0x01,

    //move the telescope "west".
    MOVE_WEST_COMMAND_ID  = (uint8_t)0x02,

    //move the telescope "north".
    MOVE_NORTH_COMMAND_ID = (uint8_t)0x04,

    //move the telescope "south".
    MOVE_SOUTH_COMMAND_ID = (uint8_t)0x08,

    //immediatly stops slewing the telescope.
    STOP_MOTION_COMMAND_ID = (uint8_t)0x1D,

    //slews the telescope back into the park/initial position.
    PARK_COMMAND_ID = (uint8_t)0x1E,

    //Requests the site location geodesic coordinates from the controller.
    GET_SITE_LOCATION_COMMAND_ID = (uint8_t)0x1f,

    //Tell the mount to gracefully disconnect the driver from the serial protocol. Stops the mount from sending status reports.
    DISCONNET_COMMAND_ID = (uint8_t) 0x22,

    //Slews the telescope to the equatorial coordinates provided.
    GOTO_COMMAND_ID = (uint8_t)0x23,

    //Tell the controller to match/align to the delivered coordinates. This updates the scope alignment.
    SYNC_COMMAND_ID = (uint8_t)0x24,

    //sets the site location on the telescope controller.
    SET_SITE_LOCATION_COMMAND_ID = (uint8_t)0x25,

    //sets time and date on the telescope controller.
    SET_DATE_TIME_COMMAND_ID = (uint8_t)0x26,

    //If the GET_SITE_LOCATION message was sent, the controller responds with this message, along side the Geo-Coordinates.
    TELESCOPE_SITE_LOCATION_REPORT_COMMAND_ID = (uint8_t)0xfe,
    
    //This id is used when the telescope is in an untracked state. Found in the C# implementation but apparently not used.
    TELESCOPE_POSITION_REPORT_UNTRACKED_COMMAND_ID = (uint8_t)0xf0,

    //This id is used by the telescope controller to announce its pointing coordinates.
    TELESCOPE_POSITION_REPORT_COMMAND_ID = (uint8_t)0xff
};

//Simple data structure for a coordinate pair.
struct EquatorialCoordinates
{
    //The time stamp when this coordinates where received.
    std::chrono::time_point<std::chrono::system_clock> TimeStamp;

    //decimal value of the right ascension.
    float RightAscension;

    //decimal value of the declination.
    float Declination;

    static EquatorialCoordinates Delta(EquatorialCoordinates &first, EquatorialCoordinates &second)
    {
        EquatorialCoordinates result;

        result.RightAscension = first.RightAscension - second.RightAscension;
        result.Declination = first.RightAscension - second.RightAscension;

        return result;
    }

    static float Absolute(EquatorialCoordinates &deltaCoordinates)
    {
        float a = deltaCoordinates.RightAscension;
        float b = deltaCoordinates.Declination;

        float abs = std::fabs(a * a + b * b);

        return abs;
    }
};

//Enum with month names for easy legibility.
enum DateMonths
{
    January = 1,
    February = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12,
};

//helper union to read out float bytes without the hazzle with pointers
union FloatByteConverter
{
    uint8_t bytes[4];
    float decimal_number;
};

//Simple static class providing the message generation mechanisms.
//The message frame size is 13 bytes, a 4 byte header/preamble,
//a one byte command followed by 2 to 6 arguments,
//distributed over the 8 remaining bytes.
//see the Get...Message() implementations for details.
//Since the serial protocol is faily simple, a lot of the error handling is on the client side to avoid the controller to go haywire.
class SerialCommand
{
    private:


        //helper function pushing a number of bytes into the buffer, for padding.
        static void push_bytes(std::vector<uint8_t> &buffer, uint8_t byte, size_t count);

        //simple constant containing the message header as of firmware V2.3.
        static uint8_t MessageHeader[4];

        //helper function to push the float values into the buffer
        static void push_float_bytes(std::vector<uint8_t> &buffer, FloatByteConverter &values);

    public:
        //Gracefully disconnect from the GoTo Controller.
        //returns false if an error occurs.
        static bool GetDisconnectCommandMessage(std::vector<uint8_t> &buffer);

        //put the stop message into the buffer provided.
        //returns false if an error occurs.
        static bool GetStopMotionCommandMessage(std::vector<uint8_t> &buffer);

        //put the park message into the buffer provided.
        //returns false if an error occurs.
        static bool GetParkCommandMessage(std::vector<uint8_t> &buffer);

        //put the get site location message into the buffer provided.
        //returns false if an error occurs.
        static bool GetGetSiteLocationCommandMessage(std::vector<uint8_t> &buffer);

        //put the goto message corresponding to the coordinates provided into the buffer provided.
        //returns false if an error occurs.
        static bool GetGotoCommandMessage(std::vector<uint8_t> &buffer, float decimal_right_ascension, float decimal_declination);

        //put the sync message corresponding to the coordinates provided into the buffer provided.
        //This function is used when plate solving.
        //returns false if an error occurs.
        static bool GetSyncCommandMessage(std::vector<uint8_t> &buffer, float decimal_right_ascension, float decimal_declination);

        //put the set site location message corresponding the coordinates provided into the buffer provided
        //returns false if an error occurs.
        static bool GetSetSiteLocationCommandMessage(std::vector<uint8_t> &buffer, float decimal_latitude, float decimal_longitude);

        //put the date time message corresponding to the time/date provided into the buffer provided.
        //returns false if an error occurs.
        static bool GetSetDateTimeCommandMessage(std::vector<uint8_t> &buffer, uint16_t year, uint8_t month, uint8_t day,
                uint8_t hour, uint8_t minute, uint8_t second, int8_t utc_offset);

        //move the telescope in a certain direction. Use the first 4 command IDs for a particular direction.
        static bool GetMoveWhileTrackingCommandMessage(std::vector<uint8_t> &buffer, SerialCommandID direction);

        //helper function pushing the header into the buffer.
        static void PushHeader(std::vector<uint8_t> &buffer);


};
}

#endif