add Arduino part 1

This commit is contained in:
Danny
2024-08-23 22:04:09 +03:30
parent 04a575c153
commit 44ab1675fa
14 changed files with 15457 additions and 0 deletions

View File

@@ -0,0 +1,268 @@
/*
altazsearch.cpp - Don Cross - 2023-06-17
https://github.com/cosinekitty/astronomy/discussions/308
Problem: given a range of altitudes and azimuths that
form a "window" on the sky, search for when the Moon
enters/exits that window starting from a given search time.
*/
#include <cmath>
#include <cstdio>
#include <string>
#include <stdexcept>
#include "astronomy.h"
struct Event
{
astro_time_t time;
double azimuth = NAN;
double altitude = NAN;
Event()
{
time.tt = time.ut = time.eps = time.psi = time.st = NAN;
}
void Print() const
{
char text[TIME_TEXT_BYTES];
Astronomy_FormatTime(time, TIME_FORMAT_SECOND, text, sizeof(text));
Serial.printf("%s az=%0.2lf alt=%0.2lf", text, azimuth, altitude);
}
};
struct Solution
{
bool valid = false;
Event start;
Event finish;
void Print() const
{
if (valid)
{
Serial.printf("Start: ");
start.Print();
Serial.printf("; Finish: ");
finish.Print();
Serial.printf(".\n");
}
else
{
Serial.printf("No solution.\n");
}
}
};
void Verify(astro_status_t status, const char *message)
{
if (status != ASTRO_SUCCESS)
Serial.printf(message , ": error " , static_cast<int>(status));
}
class SearchProblem
{
private:
astro_body_t body;
astro_observer_t observer;
double az1;
double az2;
double alt1;
double alt2;
astro_vector_t center;
astro_horizon_t Position(astro_time_t time) const
{
// Get topocentric equatorial coordinates of body, using the Earth's equator of date.
astro_equatorial_t equ = Astronomy_Equator(body, &time, observer, EQUATOR_OF_DATE, ABERRATION);
Verify(equ.status, "Equator");
// Convert to observer's horizontal coordinates, correcting for atmospheric refraction.
return Astronomy_Horizon(&time, observer, equ.ra, equ.dec, REFRACTION_NORMAL);
}
double AngularDistance(astro_time_t time) const
{
astro_horizon_t hor = Position(time);
// Translate angular horizontal coordinates to a vector.
// Do NOT remove the refraction from the vector (REFRACTION_NONE).
astro_spherical_t sphere;
sphere.status = ASTRO_SUCCESS;
sphere.dist = 1.0;
sphere.lat = hor.altitude;
sphere.lon = hor.azimuth;
astro_vector_t vec = Astronomy_VectorFromHorizon(sphere, time, REFRACTION_NONE);
Verify(vec.status, "VectorFromHorizon");
// Calculate the angle in degrees between the body and the center of the window.
astro_angle_result_t result = Astronomy_AngleBetween(center, vec);
Verify(result.status, "AngleBetween");
return result.angle;
}
static astro_func_result_t DistanceSlopeCallback(void *context, astro_time_t time)
{
const SearchProblem& p = *static_cast<const SearchProblem *>(context);
astro_func_result_t result;
result.value = p.DistanceSlope(time);
result.status = ASTRO_SUCCESS;
return result;
}
double DistanceSlope(astro_time_t time) const
{
const double dt = 0.1 / 86400.0;
astro_time_t t1 = Astronomy_AddDays(time, -dt);
astro_time_t t2 = Astronomy_AddDays(time, +dt);
double a1 = AngularDistance(t1);
double a2 = AngularDistance(t2);
return (a2 - a1) / (2 * dt);
}
bool IsInsideWindow(astro_time_t time) const
{
astro_horizon_t hor = Position(time);
bool insideAzimuthLimits;
if (az1 <= az2)
insideAzimuthLimits = (az1 <= hor.azimuth && hor.azimuth <= az2);
else
insideAzimuthLimits = (az1 <= hor.azimuth || hor.azimuth <= az2);
return insideAzimuthLimits && alt1 <= hor.altitude && hor.altitude <= alt2;
}
Solution FindBracket(astro_time_t closestTime) const
{
Solution solution;
// If the closestTime is inside the window, we can find a bracket.
// Otherwise, there is no bracket here.
if (IsInsideWindow(closestTime))
{
const double dt = 10.0 / (24.0 * 60.0); // 10 minutes, converted to days
// Look backwards until we find a time before entering the window.
// Do a binary search to find the moment when we enter the window.
solution.start = FindTransition(closestTime, -dt);
// Look forward until we find a time after leaving the window.
// Do a binary search to find the moment we leave the window.
solution.finish = FindTransition(closestTime, +dt);
solution.valid = true;
}
return solution;
}
Event FindTransition(astro_time_t closestTime, double dt) const
{
// Find a bracket [t1, t2] that straddles being inside/outside the window.
astro_time_t t1 = closestTime;
astro_time_t t2 = Astronomy_AddDays(closestTime, dt);
while (IsInsideWindow(t2))
{
t1 = t2;
t2 = Astronomy_AddDays(t2, dt);
}
// Do a binary search to find the moment of transition, within tolerance.
const double tolerance = 0.1 / (3600.0 * 24.0); // one tenth of a second, expressed in days
astro_time_t tm = Astronomy_TimeFromDays((t1.ut + t2.ut) / 2);
while (fabs(t2.ut - t1.ut) > tolerance)
{
if (IsInsideWindow(tm))
t1 = tm;
else
t2 = tm;
tm = Astronomy_TimeFromDays((t1.ut + t2.ut) / 2);
}
astro_horizon_t hor = Position(tm);
Event event;
event.time = tm;
event.altitude = hor.altitude;
event.azimuth = hor.azimuth;
return event;
}
public:
SearchProblem(astro_body_t _body, astro_observer_t _observer, double _az1, double _az2, double _alt1, double _alt2)
: body(_body)
, observer(_observer)
, az1(_az1)
, az2(_az2)
, alt1(_alt1)
, alt2(_alt2)
{
astro_time_t dummyTime = Astronomy_TimeFromDays(0.0);
astro_spherical_t sphere;
sphere.status = ASTRO_SUCCESS;
sphere.dist = 1.0;
sphere.lat = (_alt1 + _alt2) / 2;
sphere.lon = (_az1 + _az2) / 2;
center = Astronomy_VectorFromHorizon(sphere, dummyTime, REFRACTION_NONE);
}
Solution FindNext(astro_time_t startTime, double limitDays)
{
astro_time_t stopTime = Astronomy_AddDays(startTime, limitDays);
const double stepDays = 1.0 / 24.0; // one hour
astro_time_t t1 = startTime;
double m1 = DistanceSlope(t1);
while (t1.ut < stopTime.ut)
{
astro_time_t t2 = Astronomy_AddDays(t1, stepDays);
double m2 = DistanceSlope(t2);
if (m1 <= 0.0 && m2 >= 0.0)
{
astro_search_result_t result = Astronomy_Search(DistanceSlopeCallback, this, t1, t2, 0.1);
if (result.status == ASTRO_SUCCESS)
{
// We found a time bracket [t1, t2] where the body passes closest to
// the center of the target window. Now search nearby for when the
// body enters and exits the window.
Solution solution = FindBracket(result.time);
if (solution.valid)
return solution;
}
}
t1 = t2;
m1 = m2;
}
// We could not find a solution.
// Return a default-constructed Solution, which indicates failure.
return Solution();
}
};
void setup()
{
Serial.begin(9600);
}
void loop()
{
// 2023-06-17T12:00:00Z Moon AZ = 74.03 ALT = 27.44
// 2023-06-17T13:00:00Z Moon AZ = 79.22 ALT = 39.74
astro_observer_t observer = Astronomy_MakeObserver(30.0, -80.0, 0.0);
SearchProblem problem(BODY_MOON, observer, 74.0, 78.0, 25.0, 40.0);
astro_time_t startTime = Astronomy_MakeTime(2023, 6, 17, 0, 0, 0.0);
Solution solution = problem.FindNext(startTime, 2.0);
solution.Print();
}

View File

@@ -0,0 +1,154 @@
/*
camera.c - Don Cross - 2021-03-21
Example C program for Astronomy Engine:
https://github.com/cosinekitty/astronomy
Suppose you want to photograph the Moon,
and you want to know what it will look like in the photo.
Given a location on the Earth, and a date/time,
this program calculates the orientation of the sunlit
side of the Moon with respect to the top of your
photo image. It assumes the camera faces directly
toward the Moon's azimuth and tilts upward to its
altitude angle above the horizon.
*/
#include <stdio.h>
#include <math.h>
#include "astro_demo_common.h"
#define FAIL(...) do{fprintf(stderr, __VA_ARGS__); error = 1; goto fail;}while(0)
static int CameraImage(astro_observer_t observer, astro_time_t time);
void setup()
{
Serial.begin(9600);
}
void loop()
{
int error;
astro_observer_t observer;
astro_time_t time;
observer.height = 22.2;
observer.latitude = 33.33;
observer.longitude = 88.8;
// time = "1988-02-02T12:55:33Z";
// const char *argvs[] = {"22.2","11.8","1988-02-02T12:55:33Z"};
const char *argvs[] = {"22.2","33.8","2023-10-07T00:38:57+03:30"};
int argcs = 3;
error = ParseArgs(argcs, argvs, &observer, &time);
if (error)
Serial.println("error.......");
CameraImage(observer, time);
}
static int CameraImage(astro_observer_t observer, astro_time_t time)
{
int error;
astro_equatorial_t moon_equ;
astro_equatorial_t sun_equ;
astro_horizon_t moon_hor;
astro_rotation_t rot;
astro_vector_t vec;
astro_illum_t illum;
astro_angle_result_t angle;
double radius;
double tilt;
const double tolerance = 1.0e-15;
/* Calculate the topocentric equatorial coordinates of date for the Moon. */
/* Assume aberration does not matter because the Moon is so close and has such a small relative velocity. */
moon_equ = Astronomy_Equator(BODY_MOON, &time, observer, EQUATOR_OF_DATE, NO_ABERRATION);
if (moon_equ.status != ASTRO_SUCCESS)
FAIL("Error %d calculating Moon position.\n", moon_equ.status);
/* Also calculate the Sun's topocentric position in the same coordinate system. */
sun_equ = Astronomy_Equator(BODY_SUN, &time, observer, EQUATOR_OF_DATE, NO_ABERRATION);
if (sun_equ.status != ASTRO_SUCCESS)
FAIL("Error %d calculating Sun position.\n", sun_equ.status);
/* Get the Moon's horizontal coordinates, so we know how much to pivot azimuth and altitude. */
moon_hor = Astronomy_Horizon(&time, observer, moon_equ.ra, moon_equ.dec, REFRACTION_NONE);
Serial.printf("Moon horizontal position: azimuth = %0.3lf, altitude = %0.3lf\n", moon_hor.azimuth, moon_hor.altitude);
/* Get the rotation matrix that converts equatorial to horizontal coordintes for this place and time. */
rot = Astronomy_Rotation_EQD_HOR(&time, observer);
/*
Modify the rotation matrix in two steps:
First, rotate the orientation so we are facing the Moon's azimuth.
We do this by pivoting around the zenith axis.
Horizontal axes are: 0 = north, 1 = west, 2 = zenith.
Tricky: because the pivot angle increases counterclockwise, and azimuth
increases clockwise, we undo the azimuth by adding the positive value.
*/
rot = Astronomy_Pivot(rot, 2, moon_hor.azimuth);
if (rot.status != ASTRO_SUCCESS)
FAIL("Error %d in Astronomy_Pivot(azimuth)\n", rot.status);
/*
Second, pivot around the leftward axis to bring the Moon to the camera's altitude level.
From the point of view of the leftward axis, looking toward the camera,
adding the angle is the correct sense for subtracting the altitude.
*/
rot = Astronomy_Pivot(rot, 1, moon_hor.altitude);
if (rot.status != ASTRO_SUCCESS)
FAIL("Error %d in Astronomy_Pivot(altitude)\n", rot.status);
/* As a sanity check, apply this rotation to the Moon's equatorial (EQD) coordinates and verify x=0, y=0. */
vec = Astronomy_RotateVector(rot, moon_equ.vec);
if (vec.status != ASTRO_SUCCESS)
FAIL("Error %d in Astronomy_RotateVector(moon)\n", vec.status);
/* Convert to unit vector. */
radius = Astronomy_VectorLength(vec);
vec.x /= radius;
vec.y /= radius;
vec.z /= radius;
Serial.printf("Moon check: x = %0.6lf, y = %0.6lf, z = %0.6lf\n", vec.x, fabs(vec.y), fabs(vec.z));
if (!isfinite(vec.x) || fabs(vec.x - 1.0) > tolerance)
FAIL("Excessive error in moon check (x)\n");
if (!isfinite(vec.y) || fabs(vec.y) > tolerance)
FAIL("Excessive error in moon check (y)\n");
if (!isfinite(vec.z) || fabs(vec.z) > tolerance)
FAIL("Excessive error in moon check (z)\n");
/* Apply the same rotation to the Sun's equatorial vector. */
/* The x- and y-coordinates now tell us which side appears sunlit in the camera! */
vec = Astronomy_RotateVector(rot, sun_equ.vec);
if (vec.status != ASTRO_SUCCESS)
FAIL("Error %d in Astronomy_RotateVector(sun)\n", vec.status);
/* Don't bother normalizing the Sun vector, because in AU it will be close to unit anyway. */
Serial.printf("Sun vector: x = %0.6lf, y = %0.6lf, z = %0.6lf\n", vec.x, vec.y, vec.z);
/* Calculate the tilt angle of the sunlit side, as seen by the camera. */
/* The x-axis is now pointing directly at the object, z is up in the camera image, y is to the left. */
tilt = RAD2DEG * atan2(vec.y, vec.z);
Serial.printf("Tilt angle of sunlit side of the Moon = %0.3lf degrees counterclockwise from up.\n", tilt);
illum = Astronomy_Illumination(BODY_MOON, time);
if (illum.status != ASTRO_SUCCESS)
FAIL("Error %d trying to calculate Moon illumination.\n", illum.status);
Serial.printf("Moon magnitude = %0.2lf, phase angle = %0.2lf degrees.\n", illum.mag, illum.phase_angle);
angle = Astronomy_AngleFromSun(BODY_MOON, time);
if (angle.status != ASTRO_SUCCESS)
FAIL("Error %d trying to calculate angle between Moon and Sun\n", angle.status);
Serial.printf("Angle between Moon and Sun as seen from Earth = %0.2lf degrees.\n", angle.angle);
error = 0;
fail:
return error;
}

View File

@@ -0,0 +1,80 @@
/*
culminate.c - by Don Cross - 2019-06-18
Example C program for Astronomy Engine:
https://github.com/cosinekitty/astronomy
This example program shows how to calculate the time
the Sun, Moon, and planets will next reach their highest point in the sky
as seen by an observer at a given location on the Earth.
This is called culmination, and is found by finding when
each body's "hour angle" is 0.
Having an hour angle of 0 is another way of saying that the body is
crossing the meridian, the imaginary semicircle in the sky that passes
from due north on the horizon, through the zenith (straight up),
toward due south on the horizon. At this moment the body appears to
have an azimuth of either 180 degrees (due south) or 0 (due north).
*/
#include <stdio.h>
#include "astro_demo_common.h"
int PrintEvent(const char *name, astro_hour_angle_t evt)
{
Serial.printf("%-8s : ", name);
if (evt.status == ASTRO_SUCCESS)
{
PrintTime(evt.time);
Serial.printf(" altitude=%6.2lf azimuth=%6.2lf\n", evt.hor.altitude, evt.hor.azimuth);
return 0;
}
else
{
Serial.printf("ERROR %d\n", evt.status);
return 1;
}
}
void setup()
{
Serial.begin(9600);
}
void loop()
{
static const astro_body_t bodies[] =
{
BODY_SUN, BODY_MOON, BODY_MERCURY, BODY_VENUS, BODY_MARS,
BODY_JUPITER, BODY_SATURN, BODY_URANUS, BODY_NEPTUNE, BODY_PLUTO
};
static const int nbodies = sizeof(bodies) / sizeof(bodies[0]);
astro_observer_t observer;
astro_time_t time;
astro_hour_angle_t evt;
int i;
// if (ParseArgs(argc, argv, &observer, &time))
// return 1;
// const char *argvs[] = {"22.2","11.8","1988-02-02T12:55:33Z"};
const char *argvs[] = {"22.2","33.8","2023-10-07T00:38:57+03:30"};
int argcs = 3;
int error;
error = ParseArgs(argcs, argvs, &observer, &time);
if (error)
Serial.println("error.......");
Serial.printf("search : ");
PrintTime(time);
Serial.printf("\n");
for (i=0; i < nbodies; ++i)
{
evt = Astronomy_SearchHourAngleEx(bodies[i], observer, 0.0, time, +1);
PrintEvent(Astronomy_BodyName(bodies[i]), evt);
}
delay(1000);
// return 0;
}

View File

@@ -0,0 +1,124 @@
/*
astro_demo_common.h - by Don Cross <cosinekitty@gmail.com>
https://github.com/cosinekitty/astronomy
Helper code for Astronomy Engine demo programs.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "Arduino.h"
#include "astro_demo_common.h"
static const char ObserverVarName[] = "ASTRONOMY_ENGINE_OBSERVER";
static int IsValid(double x, double lo, double hi)
{
return isfinite(x) && (x >= lo) && (x <= hi);
}
int ParseArgs(int argc, const char *argv[], astro_observer_t *observer, astro_time_t *time)
{
int time_arg = 0;
observer->height = 0.0;
if ((argc==2 || argc==3) && !strcmp(argv[1], "-e"))
{
/* Use an environment variable to specify the observer's location. */
const char *obstext = getenv(ObserverVarName);
if (obstext == NULL)
{
fprintf(stderr, "ERROR: The -e option was specified but environment variable %s is not defined.\n", ObserverVarName);
return 1;
}
if (2 != sscanf(obstext, "%lf %lf", &observer->latitude, &observer->longitude) ||
!IsValid(observer->latitude, -90.0, +90.0) ||
!IsValid(observer->longitude, -180.0, +180.0))
{
fprintf(stderr, "ERROR: Invalid geographic coordinates in environment variable %s.\n", ObserverVarName);
return 1;
}
time_arg = 2;
}
else if (argc==3 || argc==4)
{
/* The observer's location must appear in the command line. */
if (1 != sscanf(argv[1], "%lf", &observer->latitude) ||
!IsValid(observer->latitude, -90.0, +90.0))
{
fprintf(stderr, "ERROR: Invalid latitude '%s' on command line\n", argv[1]);
return 1;
}
if (1 != sscanf(argv[2], "%lf", &observer->longitude) ||
!IsValid(observer->longitude, -180.0, +180.0))
{
fprintf(stderr, "ERROR: Invalid longitude '%s' on command line\n", argv[2]);
return 1;
}
time_arg = 3;
}
if (time_arg && argc == 1+time_arg)
{
/* Time is present on command line, so use it. */
return ParseTime(argv[time_arg], time);
}
if (time_arg && argc == time_arg)
{
/* Time is absent on command line, so use current time. */
*time = Astronomy_CurrentTime();
return 0;
}
fprintf(stderr, "USAGE: %s [-e | latitude longitude] [yyyy-mm-ddThh:mm:ssZ]\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "If '-e' is specified, an environment variable must be set as follows:\n");
fprintf(stderr, "%s='latitude longitude'\n", ObserverVarName);
fprintf(stderr, "Otherwise, the latitude and longitude must appear in the command line.\n");
fprintf(stderr, "\n");
return 1;
}
int ParseTime(const char *text, astro_time_t *time)
{
astro_utc_t utc;
int nscanned = sscanf(text, "%d-%d-%dT%d:%d:%lfZ",
&utc.year, &utc.month, &utc.day,
&utc.hour, &utc.minute, &utc.second);
if (nscanned != 6)
{
fprintf(stderr, "ERROR: Invalid date/time format in '%s'\n", text);
return 1;
}
*time = Astronomy_TimeFromUtc(utc);
return 0;
}
void PrintTime(astro_time_t time)
{
astro_status_t status;
char text[TIME_TEXT_BYTES];
status = Astronomy_FormatTime(time, TIME_FORMAT_SECOND, text, sizeof(text));
if (status != ASTRO_SUCCESS)
{
Serial.printf(stderr, "\nFATAL(PrintTime): status %d\n", status);
// exit(1);
}
// printf("%s", text);
}

View File

@@ -0,0 +1,9 @@
#ifndef __ASTRONOMY_DEMO_COMMON_H
#define __ASTRONOMY_DEMO_COMMON_H
#include "astronomy.h"
int ParseArgs(int argc, const char *argv[], astro_observer_t *observer, astro_time_t *time);
int ParseTime(const char *text, astro_time_t *time);
void PrintTime(astro_time_t time);
#endif /* __ASTRONOMY_DEMO_COMMON_H */

View File

@@ -0,0 +1,58 @@
#include "stdio.h"
#include "astro_demo_common.h"
void setup()
{
Serial.begin(9600);
// setSyncProvider(syncProvider);//sets internal clock
// if(timeStatus() != timeSet)
// Serial.println("Unable to sync with the unixTimeStamp");
// else
// Serial.println("unixTimeStamp has set the system time");
}
void loop()
{
static const astro_body_t body[] = {
BODY_SUN, BODY_MERCURY, BODY_VENUS, BODY_EARTH, BODY_MOON, BODY_MARS,
BODY_JUPITER, BODY_SATURN, BODY_URANUS, BODY_NEPTUNE, BODY_PLUTO
};
int i;
int num_bodies;
astro_time_t time;
astro_rotation_t rot;
astro_time_t time2;
num_bodies = sizeof(body) / sizeof(body[0]);;
const char *argv[] = {"123","2023-10-07T00:38:57+03:30"};
if (0 == ParseTime(argv[1], &time))
{
rot = Astronomy_Rotation_EQJ_ECL();
// Serial.println("BODY X Y Z\n");
for (i=0; i < num_bodies; ++i)
{
astro_vector_t eqj = Astronomy_HelioVector(body[i], time);
astro_vector_t ecl = Astronomy_RotateVector(rot, eqj);
const char *name = Astronomy_BodyName(body[i]);
if (ecl.status != ASTRO_SUCCESS)
{
Serial.println( "ERROR %d calculating vector for %s.\n");
Serial.println((int)ecl.status);
Serial.println(name);
}
Serial.printf("%-8s %11.6lf %11.6lf %11.6lf\n", name, ecl.x, ecl.y, ecl.z);
}
}
delay(1000);
}

View File

@@ -0,0 +1,117 @@
/*
galactic.c - Don Cross - 2021-06-10
Example C program for Astronomy Engine:
https://github.com/cosinekitty/astronomy
This program illustrates how to convert a location
in the sky expressed in IAU 1958 galactic coordinates
into the local altitude and azimuth of someone wanting
to aim a radio dish at it.
*/
#include <stdio.h>
#include <math.h>
#include "astro_demo_common.h"
int GalaticToHorizontal(
astro_time_t time,
astro_observer_t observer,
double glat,
double glon,
double *altitude,
double *azimuth) {
astro_rotation_t rot, adjust_rot;
astro_spherical_t gsphere, hsphere;
astro_vector_t gvec, hvec;
/*
Calculate a rotation matrix that converts
galactic coordinates to J2000 equatorial coordinates.
*/
rot = Astronomy_Rotation_GAL_EQJ();
/*
Adjust the rotation matrix to convert galatic to horizontal (HOR).
*/
adjust_rot = Astronomy_Rotation_EQJ_HOR(&time, observer);
rot = Astronomy_CombineRotation(rot, adjust_rot);
/*
Convert the galactic coordinates from angles to a unit vector.
*/
gsphere.status = ASTRO_SUCCESS;
gsphere.lat = glat;
gsphere.lon = glon;
gsphere.dist = 1.0;
gvec = Astronomy_VectorFromSphere(gsphere, time);
if (gvec.status != ASTRO_SUCCESS) {
Serial.printf("Astronomy_VectorFromSphere returned error %d\n", gvec.status);
return 1;
}
/*
Use the rotation matrix to convert the galactic vector to a horizontal vector.
*/
hvec = Astronomy_RotateVector(rot, gvec);
if (hvec.status != ASTRO_SUCCESS) {
Serial.printf("Astronomy_RotateVector returned error %d\n", hvec.status);
return 1;
}
/*
Convert the horizontal vector back to angular coordinates: altitude and azimuth.
Assuming this is a radio source (not optical), do not correct for refraction.
*/
hsphere = Astronomy_HorizonFromVector(hvec, REFRACTION_NONE);
if (hsphere.status != ASTRO_SUCCESS) {
Serial.printf("Astronomy_HorizonFromVector returned error %d\n", hsphere.status);
return 1;
}
*altitude = hsphere.lat;
*azimuth = hsphere.lon;
return 0;
}
void setup() {
Serial.begin(9600);
}
void loop() {
astro_observer_t observer;
astro_time_t time;
double glat, glon;
double azimuth, altitude;
const char *argvs[] = { "22.2", "33.8", "2023-10-07T00:38:57+03:30" };
glat = 23.3; //-90.0 to 90.0
glon = 17.6; //-90.0 to 90.0
int argcs = 3;
int error;
error = ParseArgs(argcs, argvs, &observer, &time);
if (glat < -90.0 || glat > +90.0) {
Serial.printf("ERROR: Invalid galatic latitude '%s' on command line\n", glat);
error = 1;
}
if (glon <= -360.0 || glon >= +360.0) {
Serial.printf("ERROR: Invalid galatic longitude '%s' on command line\n", glon);
error = 1;
}
if (GalaticToHorizontal(time, observer, glat, glon, &altitude, &azimuth)) {
Serial.println("error.......");
}
if (error) {
Serial.println("error.......");
}
Serial.printf("altitude = %10.3lf, azimuth = %10.3lf\n", altitude, azimuth);
delay(1000);
}

View File

@@ -0,0 +1,123 @@
/*
astro_demo_common.h - by Don Cross <cosinekitty@gmail.com>
https://github.com/cosinekitty/astronomy
Helper code for Astronomy Engine demo programs.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "astro_demo_common.h"
static const char ObserverVarName[] = "ASTRONOMY_ENGINE_OBSERVER";
static int IsValid(double x, double lo, double hi)
{
return isfinite(x) && (x >= lo) && (x <= hi);
}
int ParseArgs(int argc, const char *argv[], astro_observer_t *observer, astro_time_t *time)
{
int time_arg = 0;
observer->height = 0.0;
if ((argc==2 || argc==3) && !strcmp(argv[1], "-e"))
{
/* Use an environment variable to specify the observer's location. */
const char *obstext = getenv(ObserverVarName);
if (obstext == NULL)
{
fprintf(stderr, "ERROR: The -e option was specified but environment variable %s is not defined.\n", ObserverVarName);
return 1;
}
if (2 != sscanf(obstext, "%lf %lf", &observer->latitude, &observer->longitude) ||
!IsValid(observer->latitude, -90.0, +90.0) ||
!IsValid(observer->longitude, -180.0, +180.0))
{
fprintf(stderr, "ERROR: Invalid geographic coordinates in environment variable %s.\n", ObserverVarName);
return 1;
}
time_arg = 2;
}
else if (argc==3 || argc==4)
{
/* The observer's location must appear in the command line. */
if (1 != sscanf(argv[1], "%lf", &observer->latitude) ||
!IsValid(observer->latitude, -90.0, +90.0))
{
fprintf(stderr, "ERROR: Invalid latitude '%s' on command line\n", argv[1]);
return 1;
}
if (1 != sscanf(argv[2], "%lf", &observer->longitude) ||
!IsValid(observer->longitude, -180.0, +180.0))
{
fprintf(stderr, "ERROR: Invalid longitude '%s' on command line\n", argv[2]);
return 1;
}
time_arg = 3;
}
if (time_arg && argc == 1+time_arg)
{
/* Time is present on command line, so use it. */
return ParseTime(argv[time_arg], time);
}
if (time_arg && argc == time_arg)
{
/* Time is absent on command line, so use current time. */
*time = Astronomy_CurrentTime();
return 0;
}
fprintf(stderr, "USAGE: %s [-e | latitude longitude] [yyyy-mm-ddThh:mm:ssZ]\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "If '-e' is specified, an environment variable must be set as follows:\n");
fprintf(stderr, "%s='latitude longitude'\n", ObserverVarName);
fprintf(stderr, "Otherwise, the latitude and longitude must appear in the command line.\n");
fprintf(stderr, "\n");
return 1;
}
int ParseTime(const char *text, astro_time_t *time)
{
astro_utc_t utc;
int nscanned = sscanf(text, "%d-%d-%dT%d:%d:%lfZ",
&utc.year, &utc.month, &utc.day,
&utc.hour, &utc.minute, &utc.second);
if (nscanned != 6)
{
fprintf(stderr, "ERROR: Invalid date/time format in '%s'\n", text);
return 1;
}
*time = Astronomy_TimeFromUtc(utc);
return 0;
}
void PrintTime(astro_time_t time)
{
astro_status_t status;
char text[TIME_TEXT_BYTES];
status = Astronomy_FormatTime(time, TIME_FORMAT_SECOND, text, sizeof(text));
if (status != ASTRO_SUCCESS)
{
fprintf(stderr, "\nFATAL(PrintTime): status %d\n", status);
exit(1);
}
printf("%s", text);
}

View File

@@ -0,0 +1,9 @@
#ifndef __ASTRONOMY_DEMO_COMMON_H
#define __ASTRONOMY_DEMO_COMMON_H
#include "astronomy.h"
int ParseArgs(int argc, const char *argv[], astro_observer_t *observer, astro_time_t *time);
int ParseTime(const char *text, astro_time_t *time);
void PrintTime(astro_time_t time);
#endif /* __ASTRONOMY_DEMO_COMMON_H */

View File

@@ -0,0 +1,31 @@
#include <stdio.h>
#include <math.h>
#include "astronomy.h"
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
const double MAX_HEIGHT_METERS = 100000.0;
double latitude, height, gravity;
latitude = 23.3;
height = 1000;
gravity = Astronomy_ObserverGravity(latitude, height);
// printf("latitude = %8.4lf, height = %6.0lf, gravity = %8.6lf\n", latitude, height, gravity);
Serial.printf("latitude = %8.4lf, height = %6.0lf, gravity = %8.6lf\n", latitude, height, gravity);
// Serial.println(gravity,6);
delay(500);
}
//--->ASTRONOMY_ENGINE_WHOLE_SECOND

View File

@@ -0,0 +1,75 @@
/*
astro_demo_common.h - by Don Cross <cosinekitty@gmail.com>
https://github.com/cosinekitty/astronomy
Helper code for Astronomy Engine demo programs.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "astro_demo_common.h"
static const char ObserverVarName[] = "ASTRONOMY_ENGINE_OBSERVER";
static int IsValid(double x, double lo, double hi)
{
return isfinite(x) && (x >= lo) && (x <= hi);
}
int ParseArgs(int argc, const char *argv[], astro_observer_t *observer, astro_time_t *time)
{
int time_arg = 2;
observer->height = 0.0;
// fprintf(stderr, "USAGE: %s [0 first]\n", argv[0]);
// fprintf(stderr, "USAGE: %s [2 doo]\n", argv[1]);
// fprintf(stderr, "USAGE: %s [3 se]\n", argv[2]);
// fprintf(stderr, "%s='asdasd asdasd'\n", argv[2]);
observer->latitude = atof(argv[0]);
observer->longitude = atof(argv[1]);
// time_arg = 2;
if (!IsValid(observer->latitude, -90.0, +90.0) || !IsValid(observer->longitude, -180.0, +180.0))
{
fprintf(stderr, "ERROR: Invalid geographic coordinates in environment variable %s.\n", ObserverVarName);
return 1;
}
time_arg = 2;
return ParseTime(argv[time_arg], time);
return 0;
}
int ParseTime(const char *text, astro_time_t *time)
{
astro_utc_t utc;
int nscanned = sscanf(text, "%d-%d-%dT%d:%d:%lfZ",
&utc.year, &utc.month, &utc.day,
&utc.hour, &utc.minute, &utc.second);
if (nscanned != 6)
{
fprintf(stderr, "ERROR: Invalid date/time format in '%s'\n", text);
return 1;
}
*time = Astronomy_TimeFromUtc(utc);
return 0;
}
void PrintTime(astro_time_t time)
{
astro_status_t status;
char text[TIME_TEXT_BYTES];
status = Astronomy_FormatTime(time, TIME_FORMAT_SECOND, text, sizeof(text));
if (status != ASTRO_SUCCESS)
{
fprintf(stderr, "\nFATAL(PrintTime): status %d\n", status);
exit(1);
}
printf("%s", text);
}

View File

@@ -0,0 +1,9 @@
#ifndef __ASTRONOMY_DEMO_COMMON_H
#define __ASTRONOMY_DEMO_COMMON_H
#include "astronomy.h"
int ParseArgs(int argc, const char *argv[], astro_observer_t *observer, astro_time_t *time);
int ParseTime(const char *text, astro_time_t *time);
void PrintTime(astro_time_t time);
#endif /* __ASTRONOMY_DEMO_COMMON_H */

12969
source/arduino/astronomy.cpp Normal file
View File

File diff suppressed because it is too large Load Diff

1431
source/arduino/astronomy.h Normal file
View File

File diff suppressed because it is too large Load Diff