mirror of
https://github.com/eddyem/small_tel.git
synced 2026-09-30 22:00:37 +03:00
503 lines
27 KiB
Markdown
503 lines
27 KiB
Markdown
# mountdaemon_10micron
|
||
|
||
A daemon for controlling 10Micron equatorial mounts (e.g. GM4000HPS) over a serial port. It exposes
|
||
a text command interface for local clients, a binary Stellarium-protocol interface for planetarium
|
||
software, and periodically publishes the current telescope state into a FITS-header file for
|
||
downstream acquisition software.
|
||
|
||
The daemon is written in C (C23), uses [ERFA](https://github.com/liberfa/erfa) for all astronomical
|
||
computations, [usefull_macros](https://github.com/eddyem/snippets_library) for utility routines,
|
||
and optionally [weather
|
||
proxy](https://github.com/eddyem/small_tel/tree/master/Daemons/weather_proxy) for getting meteo data.
|
||
|
||
---
|
||
|
||
## Table of contents
|
||
|
||
1. [Overview](#overview)
|
||
2. [Building and installation](#building-and-installation)
|
||
3. [Running the daemon](#running-the-daemon)
|
||
4. [Command-line options and configuration file](#command-line-options-and-configuration-file)
|
||
5. [Astronomical parameters](#astronomical-parameters)
|
||
6. [Coordinate systems](#coordinate-systems)
|
||
7. [Network interfaces](#network-interfaces)
|
||
- [Command socket](#command-socket)
|
||
- [Stellarium socket](#stellarium-socket)
|
||
8. [Command reference](#command-reference)
|
||
9. [FITS-header file](#fits-header-file)
|
||
10. [Emulation mode](#emulation-mode)
|
||
11. [Signals and process management](#signals-and-process-management)
|
||
12. [Architecture](#architecture)
|
||
13. [Known limitations](#known-limitations)
|
||
|
||
---
|
||
|
||
## Overview
|
||
|
||
`mountdaemon_10micron` connects to a 10Micron mount over a serial line (default `/dev/ttyUSB0` at
|
||
115200 baud) and performs three independent jobs:
|
||
|
||
1. **Serves a local text command interface** — clients send newline-terminated commands (`tagra`,
|
||
`gotord`, `park`, …) over a TCP or UNIX socket and receive plain `key=value` replies. This is the
|
||
primary interface for an observatory control system.
|
||
2. **Serves a Stellarium-compatible binary protocol** — a planetarium program (Stellarium, Cartes
|
||
du Ciel, etc.) can connect to a second TCP socket, read the current telescope position, and issue
|
||
goto commands. This allows visual pointing with the planetarium.
|
||
3. **Writes a FITS-header file** — at least every `MOUNT_CHECK_T` seconds the daemon writes a fresh
|
||
FITS-header block with the current telescope position, sidereal time, MJD and place data.
|
||
The file is atomically replaced so a downstream acquisition program can read it at any moment.
|
||
|
||
Additionally, the daemon:
|
||
- corrects the mount's internal clock and refraction model once per hour from local weather data;
|
||
- parks the mount automatically if the weather feed is lost while tracking;
|
||
- reconnects to the mount if the serial link drops;
|
||
- supports an **emulation mode**, in which the mount is simulated locally — useful for testing
|
||
clients without hardware.
|
||
|
||
The daemon is built around the ERFA library, so coordinates are rigorously converted between ICRS
|
||
(J2000), CIRS, observed, and horizontal systems, and refraction is accounted for using the current
|
||
pressure and temperature.
|
||
|
||
---
|
||
|
||
## Building and installation
|
||
|
||
### Dependencies
|
||
|
||
- a C23-capable compiler (GCC 13+ or Clang 16+);
|
||
- CMake ≥ 4.0;
|
||
- **pkg-config**;
|
||
- **liberfa** ≥ 2.0.0;
|
||
- **usefull_macros** ≥ 0.3.5;
|
||
- **libweather** (linked with `-lweather`);
|
||
- `libm`.
|
||
|
||
### Build
|
||
|
||
```sh
|
||
git clone --depth=1 https://github.com/eddyem/small_tel
|
||
cd Daemons/10micron_stellarium
|
||
mkdir build && cd build
|
||
cmake ..
|
||
make
|
||
```
|
||
|
||
Options recognised by CMake:
|
||
|
||
| Option | Default | Meaning |
|
||
|----------|---------|---------------------------------------------------|
|
||
| `DEBUG` | `OFF` | Build in debug mode (`-Og -g3 -Werror`, no fork). |
|
||
|
||
### Install
|
||
|
||
```sh
|
||
su -c "make install"
|
||
```
|
||
|
||
The binary is installed to `<prefix>/bin/mountdaemon_10micron`. The default prefix is `/usr/local`.
|
||
|
||
---
|
||
|
||
## Running the daemon
|
||
|
||
```sh
|
||
mountdaemon_10micron -d /dev/ttyS0 -S 9600 \
|
||
--latitude 43.65:39:00 --longitude 41.44:06:00 --altitude 2070 \
|
||
--dut1 0.1 -p :10000 -P localhost:10001 -v
|
||
```
|
||
|
||
The daemon forks a supervisor process that re-spawns the working process if it crashes. It writes a
|
||
PID-file (`/tmp/mountdaemon_10micron.pid` by default), which is removed on clean exit.
|
||
|
||
Stopping the daemon: send `SIGTERM` (or `SIGINT`, `SIGQUIT`) to the supervisor PID from
|
||
the PID-file. The supervisor kills its child and exits.
|
||
|
||
---
|
||
|
||
## Command-line options and configuration file
|
||
|
||
All options may be given either on the command line or in a configuration file passed with `-c
|
||
<file>`. Command-line values always take precedence over the configuration file. The config file
|
||
uses `key = value` lines — key names are the long option names below without the leading `--`.
|
||
|
||
| Long option | Short | Argument | Default | Description |
|
||
|--------------------|-------|----------|----------------------------------|------------------------------------------------------------------------|
|
||
| `--device` | `-d` | string | `/dev/ttyUSB0` | Serial device connected to the mount. |
|
||
| `--emulation` | `-e` | — | `0` | Run in emulation mode (no hardware needed). |
|
||
| `--logfile` | `-l` | string | no | Redirect log output to this file. |
|
||
| `--hdrfile` | `-o` | string | `/tmp/10micron.fitsheader` | File to write the FITS-header into. |
|
||
| `--pidfile` | | string | `/tmp/mountdaemon_10micron.pid` | PID-file path. |
|
||
| `--port` | `-p` | string | `:10000` | Port (or `host:port`) for the Stellarium server. |
|
||
| `--cmdport` | `-P` | string | `localhost:10001` | Port (or UNIX-socket path) for the command console. |
|
||
| `--sleept` | `-t` | int | `100` | Main-loop sleep, µs. |
|
||
| `--isunix` | `-U` | — | `0` | Use a UNIX-domain socket for `cmdport`. |
|
||
| `--sertmout` | `-T` | double | `1.0` | Serial answer timeout, seconds. |
|
||
| `--serspeed` | `-S` | int | `115200` | Serial speed. |
|
||
| `--maxclients` | | int | `5` | Max clients per socket. |
|
||
| `--mountname` | | string | `"10Micron GM4000HPS"` | Mount name for the FITS header. |
|
||
| `--verbose` | `-v` | — | `0` | Increase verbosity (each `-v` adds a level). |
|
||
| `--parka` | `-A` | string | built-in | Parking azimuth, degrees or `DD:MM:SS`. |
|
||
| `--parkz` | `-Z` | string | built-in | Parking zenith distance. |
|
||
| `--dut1` | | double | `0` | UT1 − UTC, seconds. |
|
||
| `--polarx` | | double | `0` | IERS polar-motion X, arcsec. |
|
||
| `--polary` | | double | `0` | IERS polar-motion Y, arcsec. |
|
||
| `--latitude` | | string | built-in | Site latitude (degrees, `DD:MM:SS`, or decimal). |
|
||
| `--longitude` | | string | built-in | Site longitude (degrees, positive east). |
|
||
| `--altitude` | | string | built-in | Site altitude, metres. |
|
||
| `--help` | `-h` | — | — | Show help. |
|
||
| `--config` | `-c` | string | — | Read options from this file. |
|
||
|
||
### Example configuration file
|
||
|
||
```ini
|
||
device = /dev/serial/by-id/usb-FTDI_USB-RS232-if00-port0
|
||
serspeed = 115200
|
||
sertmout = 1.5
|
||
port = :10000
|
||
cmdport = /tmp/mountdaemon.sock
|
||
isunix = 1
|
||
sleept = 200
|
||
maxclients = 10
|
||
latitude = 43.65:39:00
|
||
longitude = 41.44:06:00
|
||
altitude = 2070
|
||
dut1 = 0.1
|
||
polarx = 0.05
|
||
polary = 0.12
|
||
mountname = "10Micron GM4000HPS"
|
||
logfile = /var/log/mountdaemon.log
|
||
```
|
||
|
||
---
|
||
|
||
## Astronomical parameters
|
||
|
||
The following parameters influence pointing accuracy and FITS-header content. They may be set at
|
||
start-up via CLI/config, and (except place data) also at runtime via network commands.
|
||
|
||
| Parameter | Runtime command | Units | Typical range | Notes |
|
||
|-----------------|-----------------|----------|--------------------|-----------------------------------------------------------|
|
||
| Site latitude | — | degrees | −90 … +90 | Set at start-up only. |
|
||
| Site longitude | — | degrees | −180 … +180 (E+) | Set at start-up only. |
|
||
| Site altitude | — | metres | −500 … +9000 | Set at start-up only. |
|
||
| DUT1 | `dut1` | seconds | −1 … +1 | UT1 − UTC. Affects LST by up to ±15″, affecting pointing. |
|
||
| Polar motion X | `polarx` | arcsec | ±1000 | IERS X coordinate of celestial pole. |
|
||
| Polar motion Y | `polary` | arcsec | ±1000 | IERS Y coordinate of celestial pole. |
|
||
|
||
If not set, the daemon uses internal defaults (site: SAO RAS, altitude 2070 m). DUT1 and polar
|
||
motion default to 0.
|
||
|
||
---
|
||
|
||
## Coordinate systems
|
||
|
||
The daemon distinguishes the following frames:
|
||
|
||
| Frame | Notation | Units | Notes |
|
||
|-----------------------------|------------|----------|----------------------------------------------------------|
|
||
| Catalog (ICRS / J2000) | `J2000` | RA: hours, Dec: degrees | Coordinates entered by the user via `tagra/tagdec`. |
|
||
| Epoch of date (mean equinox)| `Jnow` | RA: hours, Dec: degrees | Used internally for pointing. |
|
||
| CIRS (geocentric apparent) | — | radians | Result of `eraAtci13`. |
|
||
| Observed (with refraction) | — | radians | Result of `eraAtco13`. |
|
||
| Horizontal | `Az/Zd` | degrees | Azimuth, clockwise from North. ZD = 90° − altitude. |
|
||
|
||
- **Target epoch** is stored as an MJD. By default it is J2000 (`ERFA_DJM00` = 51544.5). It can be
|
||
set to any epoch via the `tagmjd` command.
|
||
- The command `gotord` converts the input coordinates from the target epoch to *Jnow* using
|
||
`JXtoJnow()` before sending to the mount.
|
||
- The command `gotorh` interprets the input as an **hour angle** and converts to RA using the
|
||
current LST.
|
||
- The current telescope position returned by the mount is in *Jnow*, and the FITS-header records it
|
||
under `RA`, `HA`, `DEC`, `AZ`, `ZD`.
|
||
|
||
---
|
||
|
||
## Network interfaces
|
||
|
||
### Command socket
|
||
|
||
Default address: `localhost:10001` (TCP) or a UNIX socket if `--isunix` is set.
|
||
|
||
Protocol: **line-oriented text**. A client sends one command per line, optionally with a value:
|
||
|
||
```
|
||
tagra = 12.345
|
||
tagdec = +45:30:00
|
||
gotord
|
||
```
|
||
|
||
The daemon replies with `key=value` (newline-terminated) for getters, or nothing (only implicit
|
||
success/failure) for setters/actions. Commands may be issued one at a time or in a stream. All
|
||
sockets are multiplexed by a thread-per-client model inside `usefull_macros`'s `sl_sock`
|
||
infrastructure.
|
||
|
||
Up to `--maxclients` simultaneous clients are accepted. If more try to connect, they receive `Try
|
||
later: too much clients connected` and the connection is closed.
|
||
|
||
Values may be given either as a decimal number (`12.345`, `-26.5`) or as `DD:MM:SS` / `HH:MM:SS`
|
||
(sexagesimal). Angles are interpreted as degrees unless the field name (RA, HA, LST) explicitly
|
||
implies hours.
|
||
|
||
### Stellarium socket
|
||
|
||
Default address: `:10000` (all interfaces, port 10000). Protocol: **binary little-endian**,
|
||
according to Stellarium's "Telescope Control" plugin specification.
|
||
|
||
Incoming (client → server) message, 20 bytes:
|
||
|
||
| Field | Type | Meaning |
|
||
|--------|-----------|--------------------------------------------------------|
|
||
| `len` | `uint16` | Total message length (`20`). |
|
||
| `type` | `uint16` | `0`. |
|
||
| `time` | `uint64` | µs since epoch (unused). |
|
||
| `RA` | `uint32` | Target RA. `0` = 0h, `0x80000000` = 12h, `0x100000000` = 24h. |
|
||
| `DEC` | `int32` | Target Dec. `-0x40000000` = −90°, `0x40000000` = +90°. |
|
||
|
||
Outgoing (server → client) message, 24 bytes: same fields plus a trailing `int32 status` (0 = ok,
|
||
other = error).
|
||
|
||
The daemon treats incoming messages as `tagra`/`tagdec` in the current epoch (which for Stellarium
|
||
is normally J2000). It does **not** automatically start a slew — the client must send `gotord` on
|
||
the command socket.
|
||
|
||
---
|
||
|
||
## Command reference
|
||
|
||
All commands are case-sensitive. Getter command names are typically used without an argument;
|
||
setter commands require an argument of the indicated type.
|
||
|
||
### Target coordinates (input)
|
||
|
||
| Command | Type | Units | Description |
|
||
|-----------|--------|--------------------|------------------------------------------------------------------|
|
||
| `tagra` | get/set| hours (0…24) | Target right ascension. |
|
||
| `tagdec` | get/set| degrees (−90…+90) | Target declination. |
|
||
| `tagha` | get/set| hours | Target hour angle (alternative to RA). |
|
||
| `tagaz` | get/set| degrees (0…360) | Target azimuth (clock from North). |
|
||
| `tagzd` | get/set| degrees (0…90) | Target zenith distance. |
|
||
| `tagmjd` | get/set| MJD or `J<year>` | Epoch of the input coordinates. `J2050` = 2050.0, `51544.5` = J2000. |
|
||
|
||
### Pointing
|
||
|
||
| Command | Description |
|
||
|-----------|---------------------------------------------------------------------------------------------|
|
||
| `gotord` | Slew to the input RA/Dec (converted from target epoch to Jnow) and start tracking. |
|
||
| `gotorh` | Slew using the stored hour angle: RA = LST − HA, then track. |
|
||
| `gotoaz` | Slew to the input Az/ZD and stop. |
|
||
| `stop` | Stop any motion (emergency stop). |
|
||
| `stoptrk` | Stop tracking but leave the mount in place. |
|
||
| `track` | Start tracking from the current position. |
|
||
| `park` | Slew to the parking position (see `parkaz`/`parkzd`). |
|
||
| `shutdown`| Power off the mount. Requires a numeric key to confirm (see below). |
|
||
|
||
### State queries
|
||
|
||
| Command | Units | Description |
|
||
|-----------|----------|-----------------------------------------------------------------|
|
||
| `status` | — | Human-readable mount status. |
|
||
| `telra` | hours | Current telescope RA (Jnow). |
|
||
| `telha` | hours | Current telescope hour angle. |
|
||
| `teldec` | degrees | Current telescope declination (Jnow). |
|
||
| `telaz` | degrees | Current telescope azimuth. |
|
||
| `telzd` | degrees | Current telescope zenith distance. |
|
||
| `lst` | hours | Local sidereal time. |
|
||
| `unixt` | seconds | Server UNIX time. |
|
||
|
||
`tel*` commands return `RESULT_FAIL` if the weather feed is lost or the mount is in `Error` state —
|
||
this prevents a client from acting on stale coordinates.
|
||
|
||
### Place and almanac data
|
||
|
||
| Command | Type | Description |
|
||
|-----------|--------|-----------------------------------------------------------------|
|
||
| `place` | get | Site latitude, longitude, altitude. |
|
||
| `dut1` | get/set| UT1 − UTC, seconds. |
|
||
| `polarx` | get/set| IERS X pole coordinate, arcsec. |
|
||
| `polary` | get/set| IERS Y pole coordinate, arcsec. |
|
||
|
||
Place data can only be set at start-up (via CLI/config).
|
||
|
||
### Parking
|
||
|
||
| Command | Type | Description |
|
||
|-----------|--------|--------------------------------------|
|
||
| `parkaz` | get/set| Parking azimuth, degrees. |
|
||
| `parkzd` | get/set| Parking zenith distance, degrees. |
|
||
|
||
### Sending custom command
|
||
|
||
The `raw` command allows to send any unsupported command string directly to mount.
|
||
E.g. to set lunar tracking rate send `raw = :TL#`. If mount gives no answer for command, you will
|
||
get message "No answer", otherwise you'll get this answer.
|
||
|
||
### Shutdown
|
||
|
||
The `shutdown` command implements a simple confirmation handshake:
|
||
|
||
1. A client sends `shutdown` **without** an argument. The daemon generates a random key, stores it
|
||
with a timestamp, and returns `shutdown=<key>`.
|
||
2. Within 5 minutes, a client must send `shutdown = <key>`. If the key matches, the mount is powered
|
||
off.
|
||
|
||
This protects against accidental shutdown commands.
|
||
|
||
---
|
||
|
||
## FITS-header file
|
||
|
||
Every `MOUNT_CHECK_T` (0.5 s) the daemon collects the current state and writes a complete
|
||
FITS-header block into the file given by `--hdrfile`. The write is atomic: a temporary file is
|
||
created with `mkstemp()` and `rename()`d over the destination, so a reader never sees a partial
|
||
block.
|
||
|
||
The following keywords are written (only if meaningful):
|
||
|
||
| Keyword | Comment |
|
||
|------------------|----------------------------------------------------------------------|
|
||
| `TIMESYS` | `'UTC'`. |
|
||
| `ORIGIN` | `'SAO RAS'`. |
|
||
| `MOUNTNAM` | Mount name (from `--mountname`). |
|
||
| `POLARX` | X pole coordinate, arcsec (if non-zero). |
|
||
| `POLARY` | Y pole coordinate, arcsec (if non-zero). |
|
||
| `DUT1` | UT1 − UTC, seconds (if non-zero). |
|
||
| `INPRA`,`INPDEC` | Input target RA/Dec, if the last input was celestial. |
|
||
| `INPAZ`,`INPZD` | Input target Az/ZD, if the last input was horizontal. |
|
||
| `TAGRA`,`TAGDEC` | Last **slewed-to** target, always celestial. |
|
||
| `RA`,`HA`,`DEC` | Current telescope position in *Jnow*. |
|
||
| `AZ`,`ZD` | Current telescope position in the horizontal frame. |
|
||
| `TELSTAT` | Human-readable mount status. |
|
||
| `INPEQUIN` | Epoch (year) of the input coordinates. |
|
||
| `EQUINOX` | Epoch (year) of the current telescope coordinates. |
|
||
| `MJD` | MJD of the header. |
|
||
| `PIERSIDE` | Pier side of the mount (`'E'`/`'W'`). |
|
||
| `ELEVAT` | Site altitude, m. |
|
||
| `LONGITUD` | Site longitude, degrees east. |
|
||
| `LATITUDE` | Site latitude, degrees north. |
|
||
| `LSTEND` | Local sidereal time, hours. |
|
||
|
||
Weather keywords (`HUMIDITY`, `PRESSURE`, `EXTTEMP`, `RAIN`, `SKYQUAL`, `WINDSPD`, `WINDMAX`,
|
||
`WEATTIME`) are intentionally **not** written by this daemon — the weather data is expected to be
|
||
merged by the weather daemon's own header writer.
|
||
|
||
---
|
||
|
||
## Emulation mode
|
||
|
||
Started with `-e`/`--emulation`, the daemon does not open the serial port and instead simulates a
|
||
mount with the following behaviour:
|
||
|
||
- Start-up position: Az = 180°, ZD = 80°.
|
||
- Slew rates: 5°/s in RA, 8°/s in Dec.
|
||
- Slew completes when the angular distance is below 1″ or when the modelled time has elapsed.
|
||
- `ZD_LIMIT = 80°` — slews beyond this limit are refused or stopped.
|
||
- **Meridian flip** is simulated: if reaching the target from the "flipped" side is faster, the
|
||
mount will go through a flipped state (Dec > 90°, RA += 12h).
|
||
- Statuses `Stopped`, `Slewing`, `Tracking` are fully modelled; the others are not.
|
||
|
||
This is useful for developing clients (control-system, planetarium) without access to real
|
||
hardware. All command-socket and Stellarium-socket behaviour is identical to the real-mount mode.
|
||
|
||
---
|
||
|
||
## Signals and process management
|
||
|
||
The daemon runs as a supervisor + worker pair:
|
||
|
||
- The **supervisor** (`main()` before `fork()`) watches the child, re-spawns it after a crash, and
|
||
holds the PID-file.
|
||
- The **worker** is the actual server: it opens the serial port, listens on sockets, and processes
|
||
commands.
|
||
|
||
Signals handled:
|
||
|
||
| Signal | Action |
|
||
|-------------|-----------------------------------------------------------------------|
|
||
| `SIGTERM` | Remove PID-file, kill worker, exit. |
|
||
| `SIGINT` | Same as `SIGTERM`. |
|
||
| `SIGQUIT` | Same as `SIGTERM`. |
|
||
| `SIGHUP` | Ignored (may be used later for config-file re-reading) |
|
||
| `SIGTSTP` | Ignored (so the daemon can survive `Ctrl-Z` from a shell session). |
|
||
|
||
If the worker dies with a non-zero exit status, the supervisor logs the event. If the worker dies
|
||
within 10 minutes of the previous restart, this is treated as a crash-loop and logged with a
|
||
warning.
|
||
|
||
---
|
||
|
||
## Architecture
|
||
|
||
```
|
||
┌─────────────────────────┐
|
||
│ supervisor (fork) │
|
||
└────────────┬────────────┘
|
||
│ fork + waitpid
|
||
┌────────────▼────────────┐
|
||
cmd clients ──►│ worker process │◄── Stellarium clients
|
||
│ │
|
||
│ ┌───────────────────┐ │
|
||
│ │ cmd_socket (TCP │ │
|
||
│ │ or UNIX, thread │ │
|
||
│ │ per client) │ │
|
||
│ └───────────────────┘ │
|
||
│ ┌───────────────────┐ │
|
||
│ │ stellarium_sock │ │
|
||
│ │ (TCP, thread │ │
|
||
│ │ per client) │ │
|
||
│ └───────────────────┘ │
|
||
│ ┌───────────────────┐ │
|
||
│ │ main loop │ │
|
||
│ │ (0.5 s tick) │ │
|
||
│ └────────┬──────────┘ │
|
||
│ │ │
|
||
└───────────┼─────────────┘
|
||
│ serial (mutex-protected)
|
||
▼
|
||
┌──────────────┐
|
||
│ 10Micron │
|
||
│ mount │
|
||
└──────────────┘
|
||
```
|
||
|
||
Threading model:
|
||
|
||
- The **main thread** runs the state-collection loop: every `MOUNT_CHECK_T` seconds it queries
|
||
mount status, coordinates, azimuth, pier side, weather, and updates the FITS header.
|
||
- The **command socket** is served by `sl_sock` which spawns one thread per connected client. All
|
||
command handlers run in those threads; access to the serial device is serialised by `mntdev_mutex`.
|
||
- The **Stellarium socket** spawns one thread per connected client, with each thread performing a
|
||
bidirectional exchange with the client.
|
||
- Shared state (`HDR`, mount status, input coordinates) is protected implicitly — all updates go
|
||
through accessor functions, and the serial port is guarded by `mntdev_mutex`.
|
||
|
||
Synchronisation primitives:
|
||
|
||
- `pthread_mutex_t mntdev_mutex` — serialises access to the mount device.
|
||
- `atomic_int mountstatus` — cached mount status visible from any thread.
|
||
- `atomic_int emul_status` — emulation-mode status.
|
||
|
||
---
|
||
|
||
## Known limitations
|
||
|
||
- The daemon assumes a well-behaved serial link; there is no protocol-level retry for corrupted
|
||
responses beyond 3 immediate retries on `mount_status()`.
|
||
- Weather data is read via `libweather`; the format is expected to be stable. If `libweather` is
|
||
unavailable at build time, the code will not build.
|
||
- Emulation mode does not model all mount statuses and does not implement true dual-axis motion; it
|
||
is a kinematic approximation suitable for client development.
|
||
- `mount_corrdata()` uses **local** time for the `:SLDT` command, which matches the 10Micron
|
||
firmware convention; this is intentional and differs from the rest of the daemon, which works in
|
||
UTC.
|
||
- The Stellarium protocol implementation uses JNow coordinates (the DAEMON does not perform the
|
||
JNow→J2000 conversion that some clients expect). Planetarium programs that assume J2000 output may
|
||
show a small offset; this is acceptable for visual pointing but should be considered if used for
|
||
astrometric work.
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
All source files are licensed under **GNU General Public License v3.0** unless stated otherwise...
|
||
|