49 #define WLS_VERBOSE FALSE
54 static void print_final_values(
struct WLS_t* WLS_p,
float **
B);
55 static void print_in_and_outputs(
int n_c,
int n_free,
float **A_free_ptr,
float *d,
float *p_free);
59 #if PERIODIC_TELEMETRY
61 void send_wls_v(
char *name,
struct WLS_t *WLS_p,
struct transport_tx *trans,
struct link_device *
dev)
64 pprz_msg_send_WLS_V(trans,
dev, AC_ID,
69 WLS_p->
nv, WLS_p->
Wv);
71 void send_wls_u(
char *name,
struct WLS_t *WLS_p,
struct transport_tx *trans,
struct link_device *
dev)
73 pprz_msg_send_WLS_U(trans,
dev, AC_ID,
96 for (
int j = 0; j < n; j++) {
97 for (
int i = 0; i <
m; i++) {
119 void wls_alloc(
struct WLS_t* WLS_p,
float **
B,
float *u_guess,
float *W_init,
int imax) {
122 if (!imax) imax = 100;
124 int n_c = WLS_p->
nu + WLS_p->
nv;
126 float A[n_c][WLS_p->
nu];
127 float A_free[n_c][WLS_p->
nu];
131 float *A_free_ptr[n_c];
132 for(
int i = 0; i < n_c; i++)
133 A_free_ptr[i] = A_free[i];
138 int free_index[WLS_p->
nu];
139 int free_index_lookup[WLS_p->
nu];
144 float p_free[WLS_p->
nu];
146 float u_opt[WLS_p->
nu];
147 int infeasible_index[WLS_p->
nu]
UNUSED;
148 int n_infeasible = 0;
154 for (
int i = 0; i < WLS_p->
nu; i++) {
155 WLS_p->
u[i] = (WLS_p->
u_max[i] + WLS_p->
u_min[i]) * 0.5;
158 for (
int i = 0; i < WLS_p->
nu; i++) {
159 WLS_p->
u[i] = u_guess[i];
162 W_init ? memcpy(W, W_init, WLS_p->
nu *
sizeof(
float))
163 : memset(W, 0, WLS_p->
nu *
sizeof(
float));
165 memset(free_index_lookup, -1, WLS_p->
nu *
sizeof(
float));
168 for (
int i = 0; i < WLS_p->
nu; i++) {
170 free_index_lookup[i] = n_free;
171 free_index[n_free++] = i;
176 for (
int i = 0; i < WLS_p->
nv; i++) {
179 for (
int j = 0; j < WLS_p->
nu; j++) {
182 d[i] -=
A[i][j] * WLS_p->
u[j];
185 for (
int i = WLS_p->
nv; i < n_c; i++) {
186 memset(
A[i], 0, WLS_p->
nu *
sizeof(
float));
187 A[i][i - WLS_p->
nv] = WLS_p->
Wu[i - WLS_p->
nv];
188 b[i] = WLS_p->
Wu[i - WLS_p->
nv] * WLS_p->
u_pref[i - WLS_p->
nv];
189 d[i] =
b[i] -
A[i][i - WLS_p->
nv] * WLS_p->
u[i - WLS_p->
nv];
193 while (iter++ < imax) {
195 memset(
p, 0, WLS_p->
nu *
sizeof(
float));
196 memcpy(u_opt, WLS_p->
u, WLS_p->
nu *
sizeof(
float));
199 if (free_chk != n_free) {
200 for (
int i = 0; i < n_c; i++) {
201 for (
int j = 0; j < n_free; j++) {
202 A_free[i][j] =
A[i][free_index[j]];
220 print_in_and_outputs(n_c, n_free, A_free_ptr, d, p_free);
224 for (
int i = 0; i < n_free; i++) {
225 p[free_index[i]] = p_free[i];
226 u_opt[free_index[i]] += p_free[i];
229 if ((u_opt[free_index[i]] > WLS_p->
u_max[free_index[i]] || u_opt[free_index[i]] < WLS_p->
u_min[free_index[i]])) {
230 infeasible_index[n_infeasible++] = free_index[i];
236 if (n_infeasible == 0) {
238 memcpy(WLS_p->
u, u_opt, WLS_p->
nu *
sizeof(
float));
239 memset(
lambda, 0, WLS_p->
nu *
sizeof(
float));
242 for (
int i = 0; i < n_c; i++) {
243 for (
int k = 0; k < n_free; k++) {
244 d[i] -= A_free[i][k] * p_free[k];
246 for (
int k = 0; k < WLS_p->
nu; k++) {
250 bool break_flag =
true;
253 for (
int i = 0; i < WLS_p->
nu; i++) {
256 if (
lambda[i] < -FLT_EPSILON) {
260 if (free_index_lookup[i] < 0) {
261 free_index_lookup[i] = n_free;
262 free_index[n_free++] = i;
269 print_final_values(WLS_p,
B);
279 int id_alpha = free_index[0];
282 for (
int i = 0; i < n_free; i++) {
283 int id = free_index[i];
285 alpha_tmp = (
p[id] < 0) ? (WLS_p->
u_min[
id] - WLS_p->
u[
id]) /
p[id]
286 : (WLS_p->
u_max[id] - WLS_p->
u[id]) /
p[
id];
288 if (isnan(alpha_tmp) || alpha_tmp < 0.f) {
291 if (alpha_tmp <
alpha) {
298 for (
int i = 0; i < WLS_p->
nu; i++) {
300 Bound(WLS_p->
u[i], WLS_p->
u_min[i], WLS_p->
u_max[i]);
303 for (
int i = 0; i < n_c; i++) {
304 for (
int k = 0; k < n_free; k++) {
305 d[i] -= A_free[i][k] *
alpha * p_free[k];
309 W[id_alpha] = (
p[id_alpha] > 0) ? 1.0 : -1.0;
311 free_index[free_index_lookup[id_alpha]] = free_index[--n_free];
312 free_index_lookup[free_index[free_index_lookup[id_alpha]]] =
313 free_index_lookup[id_alpha];
314 free_index_lookup[id_alpha] = -1;
321 static void print_in_and_outputs(
int n_c,
int n_free,
float **A_free_ptr,
float *d,
float *p_free) {
322 printf(
"n_c = %d n_free = %d\n", n_c, n_free);
324 printf(
"A_free =\n");
325 for (
int i = 0; i < n_c; i++) {
326 for (
int j = 0; j < n_free; j++) {
327 printf(
"%f ", A_free_ptr[i][j]);
333 for (
int j = 0; j < n_c; j++) {
337 printf(
"\noutput = ");
338 for (
int j = 0; j < n_free; j++) {
339 printf(
"%f ", p_free[j]);
344 static void print_final_values(
struct WLS_t* WLS_p,
float **
B) {
345 printf(
"n_u = %d n_v = %d\n", WLS_p->
nu, WLS_p->
nv);
348 for (
int i = 0; i < WLS_p->
nv; i++) {
349 for (
int j = 0; j < WLS_p->
nu; j++) {
350 printf(
"%f ",
B[i][j]);
356 for (
int j = 0; j < WLS_p->
nv; j++) {
357 printf(
"%f ", WLS_p->
v[j]);
361 for (
int j = 0; j < WLS_p->
nu; j++) {
367 for (
int j = 0; j < WLS_p->
nu; j++) {
368 printf(
"%f ", WLS_p->
u_min[j]);
373 for (
int j = 0; j < WLS_p->
nu; j++) {
374 printf(
"%f ", WLS_p->
u_max[j]);
void qr_solve(int m, int n, float a[], float b[], float x[])
static const struct usb_device_descriptor dev
Periodic telemetry system header (includes downlink utility and generated code).
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
static void qr_solve_wrapper(int m, int n, float **A, float *b, float *x)
Wrapper for qr solve.
void send_wls_v(char *name, struct WLS_t *WLS_p, struct transport_tx *trans, struct link_device *dev)
void wls_alloc(struct WLS_t *WLS_p, float **B, float *u_guess, float *W_init, int imax)
active set algorithm for control allocation
void send_wls_u(char *name, struct WLS_t *WLS_p, struct transport_tx *trans, struct link_device *dev)
float u_pref[WLS_N_U_MAX]