1 /*
2 * Copyright (c) 2021 Kevin Townsend (KTOWN)
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include <zephyr/shell/shell.h>
10 #include <zsl/orientation/orientation.h>
11
12 #if CONFIG_ZSL_SHELL_ORIENT
13
14 static int
zsl_orient_shell_invalid_arg(const struct shell * shell,char * arg_name)15 zsl_orient_shell_invalid_arg(const struct shell *shell, char *arg_name)
16 {
17 shell_print(shell, "Error: invalid argument \"%s\"\n", arg_name);
18
19 return -EINVAL;
20 }
21
22 static int
zsl_orient_shell_missing_arg(const struct shell * shell,char * arg_name)23 zsl_orient_shell_missing_arg(const struct shell *shell, char *arg_name)
24 {
25 shell_print(shell, "Error: missing argument: \"%s\"\n", arg_name);
26
27 return -EINVAL;
28 }
29
30 static int
zsl_orient_shell_rc_code(const struct shell * shell,int rc)31 zsl_orient_shell_rc_code(const struct shell *shell, int rc)
32 {
33 shell_print(shell, "Error: unexpected return code: \"%d\"\n", rc);
34
35 return -EINVAL;
36 }
37
38 static int
zsl_orient_shell_cmd_lat2g(const struct shell * shell,size_t argc,char ** argv)39 zsl_orient_shell_cmd_lat2g(const struct shell *shell, size_t argc, char **argv)
40 {
41 int rc;
42 zsl_real_t lat = 0.0;
43 zsl_real_t alt = 0.0;
44 zsl_real_t g = 0.0;
45
46 if ((argc == 1) || (strcmp(argv[1], "help") == 0)) {
47 shell_print(shell, "Latitude and altitude to gravity (m/s^2)");
48 shell_print(shell, " $ %s <lat> <altitude>\n", argv[0]);
49 shell_print(shell, "Ex. (Barcelona, ES):");
50 shell_print(shell, " $ %s 41.3851 12.0", argv[0]);
51 shell_print(shell, " 9.794146 m/s^2");
52 return 0;
53 }
54
55 /* Missing argument. */
56 if (argc == 2) {
57 return zsl_orient_shell_missing_arg(shell, "altitude");
58 }
59
60 /* Too many arguments. */
61 if (argc > 3) {
62 return zsl_orient_shell_invalid_arg(shell, argv[3]);
63 }
64
65 /* Invalid latitude. */
66 lat = strtof(argv[1], NULL);
67 if (lat <= 0.0) {
68 return zsl_orient_shell_invalid_arg(shell, argv[1]);
69 }
70
71 /* Invalid altitude. Use sensible Earth limits for validation. */
72 alt = strtof(argv[2], NULL);
73 if ((alt > 10000.0) || (alt < -500.0)) {
74 return zsl_orient_shell_invalid_arg(shell, argv[2]);
75 }
76
77 rc = zsl_grav_lat_alt(lat, alt, &g);
78 if (rc) {
79 return zsl_orient_shell_rc_code(shell, rc);
80 }
81
82 shell_print(shell, "%f m/s^2", g);
83
84 return 0;
85 }
86
87 /* Subcommand array for "orient" (level 1). */
88 SHELL_STATIC_SUBCMD_SET_CREATE(
89 sub_orient,
90 /* 'lat2g' command handler. */
91 SHELL_CMD_ARG(lat2g, NULL, "Latitude and altitude to gravity",
92 zsl_orient_shell_cmd_lat2g, 1, 4),
93
94 /* Array terminator. */
95 SHELL_SUBCMD_SET_END
96 );
97
98 /* Root command "orient" (level 0). */
99 SHELL_CMD_REGISTER(orient, &sub_orient, "Orientation commands", NULL);
100
101 #endif
102