Add laser_tracking_cli_tool/src/main.c
This commit is contained in:
commit
8adac2f6db
1 changed files with 288 additions and 0 deletions
288
laser_tracking_cli_tool/src/main.c
Normal file
288
laser_tracking_cli_tool/src/main.c
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* W A R N U N G – K I – G E N E R I E R T E S P R O G R A M M
|
||||
*
|
||||
* Dieses Kommandozeilenprogramm wurde vollständig von einer KI generiert.
|
||||
* Es ist rein experimentell und wurde in KEINER Weise auf Sicherheit, Korrektheit
|
||||
* oder Robustheit geprüft.
|
||||
*
|
||||
* - KEIN PRODUKTIVEINSATZ!
|
||||
* - KEINE GARANTIE FÜR FUNKTIONALITÄT ODER SICHERHEIT!
|
||||
* - Kann Abstürze, Speicherfehler, undefiniertes Verhalten oder Sicherheitslücken verursachen
|
||||
* - Nur für Lern-, Demonstrations- und Forschungszwecke gedacht
|
||||
*
|
||||
* Sprache: C
|
||||
*/
|
||||
|
||||
/*
|
||||
* laser_tracking_cli_tool
|
||||
*
|
||||
* Einfaches, simuliertes CLI-Tool zur Steuerung eines (fiktiven) Laser-Tracking-Systems
|
||||
* für Satelliten. Es bietet Befehle zum Starten des Trackings und zum Abfragen des
|
||||
* aktuellen Tracking-Status.
|
||||
*
|
||||
* WICHTIG: Dieses Programm steuert KEINE echte Hardware und führt KEINE
|
||||
* Netzwerkoperationen durch. Alle Werte sind simuliert.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "tracking.h"
|
||||
|
||||
#define TOOL_VERSION "0.1.0-experimental"
|
||||
|
||||
static void print_usage(const char *progname)
|
||||
{
|
||||
if (progname == NULL) {
|
||||
progname = "laser_tracking";
|
||||
}
|
||||
|
||||
printf("Usage: %s [OPTION]... COMMAND [ARGS]\n", progname);
|
||||
printf("Simuliertes CLI-Tool zur Steuerung eines Laser-Tracking-Systems für Satelliten.\n");
|
||||
printf("KEIN PRODUKTIVEINSATZ – NUR DEMO!\n\n");
|
||||
|
||||
printf("Globale Optionen:\n");
|
||||
printf(" -h, --help diese Hilfe anzeigen\n");
|
||||
printf(" -v, --version Versionsinformationen ausgeben\n");
|
||||
printf(" -q, --quiet weniger Ausgaben\n");
|
||||
printf(" --debug Debug-Informationen\n");
|
||||
printf(" --seed=N Zufalls-Seed setzen (Reproduzierbarkeit)\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Befehle:\n");
|
||||
printf(" start Tracking für einen Satelliten starten\n");
|
||||
printf(" status aktuellen Tracking-Status anzeigen\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Beispiele:\n");
|
||||
printf(" %s start --sat COMM-SAT-RX --elev 67\n", progname);
|
||||
printf(" %s status\n", progname);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void print_version(void)
|
||||
{
|
||||
printf("laser_tracking_cli_tool %s\n", TOOL_VERSION);
|
||||
}
|
||||
|
||||
static void print_start_usage(const char *progname)
|
||||
{
|
||||
printf("Usage: %s [GLOBAL-OPTION]... start --sat NAME --elev WINKEL\n", progname);
|
||||
printf("Startet ein simuliertes Laser-Tracking auf einen Satelliten.\n\n");
|
||||
printf("Optionen für 'start':\n");
|
||||
printf(" --sat NAME Name/ID des Ziel-Satelliten (z.B. COMM-SAT-RX)\n");
|
||||
printf(" --elev WINKEL Elevationswinkel in Grad (0.0–90.0)\n");
|
||||
printf("\nBeispiel:\n");
|
||||
printf(" %s start --sat COMM-SAT-RX --elev 67\n", progname);
|
||||
}
|
||||
|
||||
static void print_status_usage(const char *progname)
|
||||
{
|
||||
printf("Usage: %s [GLOBAL-OPTION]... status\n", progname);
|
||||
printf("Zeigt den aktuellen simulierten Tracking-Status an.\n");
|
||||
}
|
||||
|
||||
static void print_tracking_status(const tracking_status *st, int quiet)
|
||||
{
|
||||
if (st == NULL) {
|
||||
fprintf(stderr, "[ERROR] tracking_status ist NULL.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char timebuf[64];
|
||||
struct tm tm_info;
|
||||
|
||||
if (localtime_r(&st->last_update, &tm_info) != NULL) {
|
||||
if (strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S %Z", &tm_info) == 0) {
|
||||
strncpy(timebuf, "<time-format-error>", sizeof(timebuf) - 1);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
}
|
||||
} else {
|
||||
strncpy(timebuf, "<time-error>", sizeof(timebuf) - 1);
|
||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
printf("Tracking-Status:\n");
|
||||
}
|
||||
|
||||
printf(" active : %s\n", st->active ? "yes" : "no");
|
||||
printf(" last_update : %s\n", timebuf);
|
||||
printf(" deviation : %.4f deg\n", st->deviation);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int quiet = 0;
|
||||
int debug = 0;
|
||||
unsigned int seed = 0;
|
||||
int seed_set = 0;
|
||||
|
||||
static struct option long_opts[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version",no_argument, 0, 'v'},
|
||||
{"quiet", no_argument, 0, 'q'},
|
||||
{"debug", no_argument, 0, 1 },
|
||||
{"seed", required_argument, 0, 2 },
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int opt;
|
||||
int opt_index = 0;
|
||||
|
||||
/* Nur globale Optionen bis zum ersten Nicht-Options-Argument parsen */
|
||||
while ((opt = getopt_long(argc, argv, "hvq", long_opts, &opt_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
case 'v':
|
||||
print_version();
|
||||
return 0;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 1: /* --debug */
|
||||
debug = 1;
|
||||
break;
|
||||
case 2: /* --seed */
|
||||
{
|
||||
char *endptr = NULL;
|
||||
seed = (unsigned int)strtoul(optarg, &endptr, 10);
|
||||
if (endptr == optarg || *endptr != '\0') {
|
||||
fprintf(stderr, "Ungueltiger Seed-Wert: '%s'\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
seed_set = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (seed_set) {
|
||||
if (!quiet) {
|
||||
printf("[INFO] Seed gesetzt auf %u\n", seed);
|
||||
}
|
||||
srand(seed);
|
||||
} else {
|
||||
/* Reproduzierbarkeit ist nicht notwendig, aber wir initialisieren */
|
||||
srand((unsigned int)time(NULL));
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
/* Kein Kommando angegeben */
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *command = argv[optind];
|
||||
|
||||
if (debug) {
|
||||
printf("[DEBUG] Global quiet=%d, debug=%d, command='%s'\n", quiet, debug, command);
|
||||
}
|
||||
|
||||
if (strcmp(command, "start") == 0) {
|
||||
/* Subkommando 'start' */
|
||||
const char *sat_name = NULL;
|
||||
double elev = -1.0;
|
||||
|
||||
/* Einfache Sub-Argumentverarbeitung: --sat NAME --elev WINKEL */
|
||||
int i = optind + 1;
|
||||
while (i < argc) {
|
||||
const char *arg = argv[i];
|
||||
if (strcmp(arg, "--sat") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "Fehlender Wert für --sat.\n");
|
||||
print_start_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
sat_name = argv[i + 1];
|
||||
i += 2;
|
||||
} else if (strcmp(arg, "--elev") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "Fehlender Wert für --elev.\n");
|
||||
print_start_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
char *endptr = NULL;
|
||||
elev = strtod(argv[i + 1], &endptr);
|
||||
if (endptr == argv[i + 1] || *endptr != '\0') {
|
||||
fprintf(stderr, "Ungueltiger Elevationswinkel: '%s'\n", argv[i + 1]);
|
||||
return 1;
|
||||
}
|
||||
i += 2;
|
||||
} else if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
|
||||
print_start_usage(argv[0]);
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "Unbekanntes Argument fuer 'start': %s\n", arg);
|
||||
print_start_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sat_name == NULL || elev < 0.0) {
|
||||
fprintf(stderr, "Fehlende oder ungueltige Parameter fuer 'start'.\n");
|
||||
print_start_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (elev < 0.0 || elev > 90.0) {
|
||||
fprintf(stderr, "Elevation muss zwischen 0.0 und 90.0 Grad liegen.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
printf("tracking – target=%s, elev=%.2fdeg\n", sat_name, elev);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
printf("[DEBUG] Aufruf start_tracking(""%s"", %.2f)\n", sat_name, elev);
|
||||
}
|
||||
|
||||
tracking_status st;
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
bool ok = start_tracking(sat_name, elev, &st, debug);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Start des Trackings fehlgeschlagen (Simulation).\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
printf("Tracking simuliert gestartet. Status:\n");
|
||||
}
|
||||
|
||||
print_tracking_status(&st, quiet);
|
||||
return 0;
|
||||
|
||||
} else if (strcmp(command, "status") == 0) {
|
||||
/* Subkommando 'status' – hier nur aktuelles (simuliertes) Statusobjekt
|
||||
* aus der Library abfragen. In dieser einfachen Demo generieren wir es
|
||||
* bei jedem Aufruf neu. */
|
||||
tracking_status st;
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
if (!get_status(&st)) {
|
||||
fprintf(stderr, "Konnte Tracking-Status nicht abrufen (Simulation).\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_tracking_status(&st, quiet);
|
||||
return 0;
|
||||
} else if (strcmp(command, "help") == 0) {
|
||||
print_usage(argv[0]);
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "Unbekanntes Kommando: %s\n\n", command);
|
||||
print_usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue