1 /*
2 * Copyright (c) 2019 Kevin Townsend (KTOWN)
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <math.h>
8 #include <errno.h>
9 #include <zsl/zsl.h>
10 #include <zsl/physics/kinematics.h>
11
12 int
zsl_phy_kin_dist(zsl_real_t vi,zsl_real_t time,zsl_real_t accel,zsl_real_t * dist)13 zsl_phy_kin_dist(zsl_real_t vi, zsl_real_t time, zsl_real_t accel,
14 zsl_real_t *dist)
15 {
16 if (time < 0) {
17 *dist = NAN;
18 return -EINVAL;
19 }
20
21 *dist = vi * time + 0.5 * accel * time * time;
22
23 return 0;
24 }
25
26 int
zsl_phy_kin_init_pos(zsl_real_t vi,zsl_real_t t,zsl_real_t a,zsl_real_t xf,zsl_real_t * xi)27 zsl_phy_kin_init_pos(zsl_real_t vi, zsl_real_t t, zsl_real_t a, zsl_real_t xf,
28 zsl_real_t *xi)
29 {
30 if (t < 0) {
31 *xi = NAN;
32 return -EINVAL;
33 }
34
35 zsl_real_t dist;
36
37 zsl_phy_kin_dist(vi, t, a, &dist);
38
39 *xi = xf - dist;
40
41 return 0;
42 }
43
44 int
zsl_phy_kin_init_pos2(zsl_real_t vi,zsl_real_t vf,zsl_real_t a,zsl_real_t xf,zsl_real_t * xi)45 zsl_phy_kin_init_pos2(zsl_real_t vi, zsl_real_t vf, zsl_real_t a, zsl_real_t xf,
46 zsl_real_t *xi)
47 {
48 if (a == 0) {
49 *xi = NAN;
50 return -EINVAL;
51 }
52
53 *xi = xf - ((vf * vf - vi * vi) / (2.0 * a));
54
55 return 0;
56 }
57
58 int
zsl_phy_kin_time(zsl_real_t vi,zsl_real_t vf,zsl_real_t accel,zsl_real_t * time)59 zsl_phy_kin_time(zsl_real_t vi, zsl_real_t vf, zsl_real_t accel,
60 zsl_real_t *time)
61 {
62 *time = (vf - vi) / accel;
63
64 if (*time < 0 || accel == 0) {
65 *time = NAN;
66 return -EINVAL;
67 }
68
69 return 0;
70 }
71
72 int
zsl_phy_kin_vel(zsl_real_t vi,zsl_real_t time,zsl_real_t accel,zsl_real_t * vf)73 zsl_phy_kin_vel(zsl_real_t vi, zsl_real_t time, zsl_real_t accel,
74 zsl_real_t *vf)
75 {
76 *vf = vi + time * accel;
77
78 if (time < 0) {
79 *vf = NAN;
80 return -EINVAL;
81 }
82
83 return 0;
84 }
85
86 int
zsl_phy_kin_vel2(zsl_real_t vi,zsl_real_t dist,zsl_real_t accel,zsl_real_t * vf)87 zsl_phy_kin_vel2(zsl_real_t vi, zsl_real_t dist, zsl_real_t accel,
88 zsl_real_t *vf)
89 {
90 zsl_real_t vf2 = vi * vi + 2 * accel * dist;
91
92 if (vf2 < 0) {
93 *vf = NAN;
94 return -EINVAL;
95 }
96
97 *vf = ZSL_SQRT(vf2);
98
99 return 0;
100 }
101
102 int
zsl_phy_kin_init_vel(zsl_real_t vf,zsl_real_t a,zsl_real_t t,zsl_real_t * vi)103 zsl_phy_kin_init_vel(zsl_real_t vf, zsl_real_t a, zsl_real_t t, zsl_real_t *vi)
104 {
105 if (t < 0) {
106 *vi = NAN;
107 return -EINVAL;
108 }
109
110 *vi = vf - a * t;
111
112 return 0;
113 }
114
115 int
zsl_phy_kin_init_vel2(zsl_real_t dist,zsl_real_t a,zsl_real_t t,zsl_real_t * vi)116 zsl_phy_kin_init_vel2(zsl_real_t dist, zsl_real_t a, zsl_real_t t,
117 zsl_real_t *vi)
118 {
119 if (t <= 0) {
120 *vi = NAN;
121 return -EINVAL;
122 }
123
124 *vi = (dist - 0.5 * a * t * t) / t;
125
126 return 0;
127 }
128
129 int
zsl_phy_kin_init_vel3(zsl_real_t vf,zsl_real_t a,zsl_real_t dist,zsl_real_t * vi)130 zsl_phy_kin_init_vel3(zsl_real_t vf, zsl_real_t a, zsl_real_t dist,
131 zsl_real_t *vi)
132 {
133 zsl_real_t sq = vf * vf - 2 * a * dist;
134
135 if (sq < 0) {
136 *vi = NAN;
137 return -EINVAL;
138 }
139
140 *vi = ZSL_SQRT(sq);
141
142 return 0;
143 }
144
145 int
zsl_phy_kin_av_vel(zsl_real_t dist,zsl_real_t time,zsl_real_t * vel)146 zsl_phy_kin_av_vel(zsl_real_t dist, zsl_real_t time, zsl_real_t *vel)
147 {
148 if (time <= 0) {
149 *vel = NAN;
150 return -EINVAL;
151 }
152
153 *vel = dist / time;
154
155 return 0;
156 }
157
158 int
zsl_phy_kin_accel(zsl_real_t vi,zsl_real_t vf,zsl_real_t time,zsl_real_t * accel)159 zsl_phy_kin_accel(zsl_real_t vi, zsl_real_t vf, zsl_real_t time,
160 zsl_real_t *accel)
161 {
162 if (time <= 0) {
163 *accel = NAN;
164 return -EINVAL;
165 }
166
167 *accel = (vf - vi) / time;
168
169 return 0;
170 }
171
172 int
zsl_phy_kin_ener(zsl_real_t v,zsl_real_t m,zsl_real_t * ke)173 zsl_phy_kin_ener(zsl_real_t v, zsl_real_t m, zsl_real_t *ke)
174 {
175 if (m < 0) {
176 *ke = NAN;
177 return -EINVAL;
178 }
179
180 *ke = 0.5 * m * v * v;
181
182 return 0;
183 }
184