Refactored controller

Esse commit está contido em:
Laurent Eschenauer
2013-06-22 21:31:18 +02:00
commit 1d0b4ce59f
+33 -48
Ver Arquivo
@@ -23,10 +23,10 @@ function Controller(client, options) {
this._tag = options.tag || {x: 0, y: 0, yaw: 0}; this._tag = options.tag || {x: 0, y: 0, yaw: 0};
// Configure the four PID required to control the drone // Configure the four PID required to control the drone
this._pid_x = new PID(0.5, 0, 0.35); this._pid_x = new PID(0.3, 0, 0.1);
this._pid_y = new PID(0.5, 0, 0.35); this._pid_y = new PID(0.3, 0, 0.1);
this._pid_z = new PID(0.6, 0, 0.15); this._pid_z = new PID(0.5, 0, 0.1);
this._pid_yaw = new PID(1.0, 0, 0.5); this._pid_yaw = new PID(1.0, 0, 0.3);
// kalman filter is used for the drone state estimation // kalman filter is used for the drone state estimation
this._ekf = new EKF(options); this._ekf = new EKF(options);
@@ -174,9 +174,6 @@ Controller.prototype._control = function(d) {
// Do not control if no known state or no goal defines // Do not control if no known state or no goal defines
if (this._goal == null || this._state == null) return; if (this._goal == null || this._state == null) return;
// Initialize control commands to zero
var ux = uy = uz = uyaw = 0;
// Compute error between current state and goal // Compute error between current state and goal
var ex = (this._goal.x != undefined) ? this._goal.x - this._state.x : 0 var ex = (this._goal.x != undefined) ? this._goal.x - this._state.x : 0
, ey = (this._goal.y != undefined) ? this._goal.y - this._state.y : 0 , ey = (this._goal.y != undefined) ? this._goal.y - this._state.y : 0
@@ -184,31 +181,13 @@ Controller.prototype._control = function(d) {
, eyaw = (this._goal.yaw != undefined) ? this._goal.yaw - this._state.yaw : 0 , eyaw = (this._goal.yaw != undefined) ? this._goal.yaw - this._state.yaw : 0
; ;
// Compute control commands // Check if we are within the target area
if (Math.abs(ex) > EPS_LIN) { if ((Math.abs(ex) < EPS_LIN) && (Math.abs(ey) < EPS_LIN) && (Math.abs(ez) < EPS_LIN) && (Math.abs(eyaw) < EPS_ANG)) {
ux = this._pid_x.getCommand(ex); // Have we been here before ?
} if (!this._goal.reached && this._last_ok != 0) {
if (Math.abs(ey) > EPS_LIN) { // And for long enough ?
uy = this._pid_y.getCommand(ey); if ((Date.now() - this._last_ok) > STABLE_DELAY) {
} // Mark the goal has reached
if (Math.abs(ez) > EPS_LIN) {
uz = this._pid_z.getCommand(ez);
}
if (Math.abs(eyaw) > EPS_ANG) {
uyaw = this._pid_yaw.getCommand(eyaw);
}
// If all commands are zero, we have reached our destination;
// we go into hover mode and trigger the callback if defined.
var now = Date.now();
if (ux == 0 && uy == 0 && uz == 0 && uyaw == 0) {
// If we have been in this position long enough we consider the target reached
if (this._goal.reached) {
// do nothing
} else if (this._last_ok != 0) {
if ((now - this._last_ok) > STABLE_DELAY) {
// Set the drone in hover mode
this._client.stop();
this._goal.reached = true; this._goal.reached = true;
// We schedule the callback in the near future. This is to make // We schedule the callback in the near future. This is to make
@@ -222,22 +201,9 @@ Controller.prototype._control = function(d) {
this.emit('goalReached', this._state); this.emit('goalReached', this._state);
} }
} else { } else {
this._last_ok = now; this._last_ok = Date.now();
} }
} } else {
// Else map controller commands to drone commands
else {
var yaw = this._state.yaw;
var cx = within(Math.cos(yaw) * ux - Math.sin(yaw) * uy, -1, 1);
var cy = within(-Math.sin(yaw) * ux + Math.cos(yaw) * uy, -1, 1);
var cz = within(uz, -1, 1);
var cyaw = within(uyaw, -1, 1);
this._client.front(cx);
this._client.right(cy);
this._client.up(cz);
this._client.clockwise(cyaw);
// If we just left the goal, we notify // If we just left the goal, we notify
if (this._last_ok != 0) { if (this._last_ok != 0) {
// Reset last ok since we are in motion // Reset last ok since we are in motion
@@ -247,7 +213,26 @@ Controller.prototype._control = function(d) {
} }
} }
// Emit the control data for others // Get Raw command from PID
var ux = this._pid_x.getCommand(ex);
var uy = this._pid_y.getCommand(ey);
var uz = this._pid_z.getCommand(ez);
var uyaw = this._pid_yaw.getCommand(eyaw);
// Ceil commands and map them to drone orientation
var yaw = this._state.yaw;
var cx = within(Math.cos(yaw) * ux - Math.sin(yaw) * uy, -1, 1);
var cy = within(-Math.sin(yaw) * ux + Math.cos(yaw) * uy, -1, 1);
var cz = within(uz, -1, 1);
var cyaw = within(uyaw, -1, 1);
// Send commands to drone
this._client.front(cx);
this._client.right(cy);
this._client.up(cz);
this._client.clockwise(cyaw);
// Emit the control data for auditing
this.emit('controlData', { this.emit('controlData', {
state: this._state, state: this._state,
goal: this._goal, goal: this._goal,