Skip to content

Commit dc6549f

Browse files
first geometric controller working (badly tuned)
1 parent c819ea9 commit dc6549f

File tree

5 files changed

+42
-17
lines changed

5 files changed

+42
-17
lines changed

blob

Submodule blob updated 1 file

controller.js

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { vec3, mat3, vec4, mat4, quat } from 'https://esm.sh/gl-matrix';
22

33
export default class Controller {
4-
constructor() { }
4+
constructor() {
5+
this.k_p = 1.0;
6+
this.k_d = 1.0;
7+
this.k_R = 0.001;
8+
this.k_omega = 0.001;
9+
}
510

611
evaluate_step(state) {
712
const stateDict = JSON.parse(state.get_state());
@@ -23,11 +28,6 @@ export default class Controller {
2328
const k_q = params['dynamics']['rotor_torque_constants'][0];
2429
const [a, b, c] = params['dynamics']['rotor_thrust_coefficients'][0];
2530

26-
const k_p = 3.0;
27-
const k_d = 2.0;
28-
const k_R = 1.0;
29-
const k_omega = 0.1;
30-
3131
const p_des = vec3.fromValues(0, 0, 0);
3232
const v_des = vec3.fromValues(0, 0, 0);
3333
const q_des = quat.fromValues(0, 0, 0, 1);
@@ -37,25 +37,33 @@ export default class Controller {
3737

3838
const a_fb = vec3.add(
3939
vec3.create(),
40-
vec3.scale(vec3.create(), e_p, -k_p),
41-
vec3.scale(vec3.create(), e_v, -k_d)
40+
vec3.scale(vec3.create(), e_p, -this.k_p),
41+
vec3.scale(vec3.create(), e_v, -this.k_d)
4242
);
4343

4444
const F_des = vec3.fromValues(0, 0, m * g);
4545
vec3.add(F_des, F_des, vec3.scale(vec3.create(), a_fb, m));
4646

47-
const A = mat4.fromValues(
47+
// note: gl-matrix uses a column-major layout
48+
const A = mat4.transpose(mat4.create(), mat4.fromValues(
4849
1, 1, 1, 1,
4950
-l, -l, l, l,
5051
-l, l, l, -l,
5152
-k_q, k_q, -k_q, k_q
52-
);
53+
));
5354
const A_inv = mat4.invert(mat4.create(), A);
5455

5556
const T = vec3.dot(F_des, vec3.transformQuat(vec3.create(), [0, 0, 1], q));
5657

5758
const R = mat3.fromQuat(mat3.create(), q);
58-
const R_des = mat3.fromQuat(mat3.create(), q_des);
59+
const R_des_z = vec3.normalize(vec3.create(), F_des)
60+
const R_des_y = vec3.cross(vec3.create(), R_des_z, vec3.fromValues(1, 0, 0));
61+
const R_des_x = vec3.cross(vec3.create(), R_des_y, R_des_z);
62+
const R_des = mat3.fromValues(
63+
R_des_x[0], R_des_x[1], R_des_x[2],
64+
R_des_y[0], R_des_y[1], R_des_y[2],
65+
R_des_z[0], R_des_z[1], R_des_z[2]
66+
);
5967

6068
const R_err = mat3.create();
6169
mat3.multiply(R_err, mat3.transpose(mat3.create(), R_des), R);
@@ -66,9 +74,9 @@ export default class Controller {
6674
);
6775

6876
const tau = vec3.create();
69-
vec3.scale(tau, e_R, -k_R);
77+
vec3.scale(tau, e_R, -this.k_R);
7078
const temp = vec3.create();
71-
vec3.scale(temp, omega, -k_omega);
79+
vec3.scale(temp, omega, -this.k_omega);
7280
vec3.add(tau, tau, temp);
7381

7482
const controlInputs = vec4.fromValues(T, tau[0], tau[1], tau[2]);
@@ -82,8 +90,24 @@ export default class Controller {
8290
const rpm = (-b + Math.sqrt(discriminant)) / (2 * a);
8391
return Math.max(0.0, Math.min(1.0, rpm));
8492
}
93+
94+
function solveRPM(fi){
95+
// a + b*rpm + c*rpm^2 = fi
96+
// c*rpm^2 + b*rpm + (a - fi) = 0
97+
const b_new = b/c
98+
const a_new = (a - fi)/c
99+
const d = b_new*b_new/4 - a_new
100+
if (d < 0) return 0.0;
101+
let rpm = -b_new/2 + Math.sqrt(d);
102+
if (rpm < 0){
103+
rpm = -b_new/2 - Math.sqrt(d);
104+
};
105+
return rpm
106+
}
85107

86-
return f_clipped.map(solveRPM);
108+
const rpms = f_clipped.map(solveRPM);
109+
const rpms_clipped = rpms.map(x=> x > 1 ? 1 : (x < -1 ? -1 : x))
110+
return rpms_clipped.map(x => x * 2 - 1)
87111
}
88112

89113
reset() { }

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
<input id="perturbation-id-max" class="perturbation-id-minmax" type="text" disabled></input>
123123
⬆️
124124
<span style="margin-left: 5px;">Transform:</span>
125-
<input id="perturbation-transform" type="text" value="(id, o, p, x) => o/2 + p*o/20 * id" title="id = id of the quadrotor, o = original value, p = percentage of the slider, x: resulting value {slider x range}"></input>
125+
<input id="perturbation-transform" type="text" value="(id, o, p, x) => 1" title="id = id of the quadrotor, o = original value, p = percentage of the slider, x: resulting value {slider x range}"></input>
126126
</div>
127127
</span>
128128
</div>

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ async function main(){
187187
// const Controller = (await import(url)).default
188188
// URL.revokeObjectURL(url);
189189
proxy_controller.policy = new Controller()
190+
window.controller = proxy_controller.policy
190191
}
191192
})
192193
controller_code_loaded.then(() => {

parameter_manager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ export class ParameterManager{
218218
})
219219

220220
l2f.initialized.then(() => {
221-
perturbation_id_input.value = "parameters.dynamics.mass"
221+
perturbation_id_input.value = "parameters.mdp.init.guidance"
222222
perturbation_id_input.dispatchEvent(new Event("input"))
223223
const event = new Event('keydown')
224224
event.key = "Enter"

0 commit comments

Comments
 (0)