Drift support (#926)

* upgrading drift support

* updated showports

* typos
This commit is contained in:
Peli de Halleux 2019-09-29 09:49:13 -07:00 committed by GitHub
parent 07504027f9
commit 7581b5af9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 174 additions and 38 deletions

View File

@ -10,12 +10,12 @@ You can find out what's connected to the ports on the brick and show its status.
## Example ## Example
Show the status of the ports on the brick when the ``enter`` button is pressed. Show the status of the ports on the brick. Resets all motors when ENTER is pressed.
```blocks ```blocks
brick.showString("Press ENTER for port status", 1) brick.showPorts()
brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () { brick.buttonEnter.onEvent(ButtonEvent.Pressed, function () {
brick.showPorts() motors.resetAll()
}) })
``` ```

View File

@ -0,0 +1,25 @@
# reset All Motors
Reset all motors currently running on the brick.
```sig
motors.resetAll();
```
The motors counters are resetted.
## Example
Tank the EV3 Brick forward at half speed for 5 seconds and then stop.
```blocks
motors.largeAB.tank(50, 50);
pause(5000);
motors.stopAll();
motors.resetAll();
```
## See also
[stop all](/reference/motors/motor/stop-all),
[reset](/reference/motors/motor/reset)

View File

@ -22,4 +22,5 @@ motors.stopAll();
[stop](/reference/motors/motor/stop), [stop](/reference/motors/motor/stop),
[reset](/reference/motors/motor/reset), [reset](/reference/motors/motor/reset),
[reset-all](/reference/motors/motor/reset-all),
[set brake](/reference/motors/motor/set-brake) [set brake](/reference/motors/motor/set-brake)

View File

@ -111,6 +111,9 @@ namespace sensors {
"red", "red",
"white", "white",
"brown"][this._query()]; "brown"][this._query()];
case ColorSensorMode.AmbientLightIntensity:
case ColorSensorMode.ReflectedLightIntensity:
return `${this._query()}%`;
default: default:
return this._query().toString(); return this._query().toString();
} }
@ -253,7 +256,7 @@ namespace sensors {
light(mode: LightIntensityMode) { light(mode: LightIntensityMode) {
this.poke(); this.poke();
this.setMode(<ColorSensorMode><number>mode) this.setMode(<ColorSensorMode><number>mode)
switch(mode) { switch (mode) {
case LightIntensityMode.ReflectedRaw: case LightIntensityMode.ReflectedRaw:
return this.reflectedLightRaw(); return this.reflectedLightRaw();
default: default:

View File

@ -62,7 +62,7 @@ namespace motors {
motorMM = control.mmap("/dev/lms_motor", MotorDataOff.Size * DAL.NUM_OUTPUTS, 0) motorMM = control.mmap("/dev/lms_motor", MotorDataOff.Size * DAL.NUM_OUTPUTS, 0)
if (!motorMM) control.fail("no motor file") if (!motorMM) control.fail("no motor file")
resetAllMotors() resetAll()
const buf = output.createBuffer(1) const buf = output.createBuffer(1)
buf[0] = DAL.opProgramStart buf[0] = DAL.opProgramStart
@ -118,7 +118,7 @@ namespace motors {
* Stops all motors * Stops all motors
*/ */
//% blockId=motorStopAll block="stop all motors" //% blockId=motorStopAll block="stop all motors"
//% weight=1 //% weight=2
//% group="Move" //% group="Move"
//% help=motors/stop-all //% help=motors/stop-all
export function stopAll() { export function stopAll() {
@ -130,8 +130,11 @@ namespace motors {
/** /**
* Resets all motors * Resets all motors
*/ */
//% blockId=motorResetAll block="reset all motors"
//% weight=1
//% group="Move" //% group="Move"
export function resetAllMotors() { //% help=motors/reset-all
export function resetAll() {
reset(Output.ALL) reset(Output.ALL)
pause(1); pause(1);
} }

View File

@ -0,0 +1,37 @@
# compute Drift
Called when the sensor is completely still, computes the current rate drift
```sig
sensors.gyro2.computeDrift()
```
The gyroscope sensor is subject to rate drifting. This means that the measurement reported by the sensor is off by a few degrees per second over time: it is drifting.
To counter the effect of drifting, call the ``||sensors:compute drift||`` block when the sensor is still to compute the current drift. The rate meansurements will automatically be corrected based on that drift.
## Example
This example uses a gyro sensor to
```blocks
let error = 0
sensors.gyro2.computeDrift()
while (sensors.color3.color() != ColorSensorColor.White) {
error = sensors.gyro2.rate() * -1
motors.largeBC.steer(error, 50)
}
motors.stopAll()
pause(1000)
sensors.gyro2.computeDrift()
while (sensors.color3.color() != ColorSensorColor.Blue) {
error = sensors.gyro2.rate() * -1
motors.largeBC.steer(error, 50)
}
motors.stopAll()
```
## See Also
[rate](/reference/sensors/gyro/rate),
[compute drift](/reference/sensors/gyro/compute-drift)

View File

@ -0,0 +1,39 @@
# drift
Get the computed rate drift
```sig
sensors.gyro2.drift()
```
The gyroscope sensor is subject to rate drifting. This means that the measurement reported by the sensor is off by a few degrees per second over time: it is drifting.
To counter the effect of drifting, call the ``||sensors:compute drift||`` block when the sensor is still to compute the current drift. The rate meansurements will automatically be corrected based on that drift.
## Example
This example uses a gyro sensor to drive straight until while color is detected.
The robot is stopped, the drift is computed and another movement is done.
```blocks
let error = 0
sensors.gyro2.computeDrift()
while (sensors.color3.color() != ColorSensorColor.White) {
error = sensors.gyro2.rate() * -1
motors.largeBC.steer(error, 50)
}
motors.stopAll()
pause(1000)
sensors.gyro2.computeDrift()
while (sensors.color3.color() != ColorSensorColor.Blue) {
error = sensors.gyro2.rate() * -1
motors.largeBC.steer(error, 50)
}
motors.stopAll()
```
## See Also
[rate](/reference/sensors/gyro/rate),
[compute drift](/reference/sensors/gyro/compute-drift)

View File

@ -9,12 +9,10 @@ namespace sensors {
export class GyroSensor extends internal.UartSensor { export class GyroSensor extends internal.UartSensor {
private calibrating: boolean; private calibrating: boolean;
private _drift: number; private _drift: number;
private _driftCorrection: boolean;
constructor(port: number) { constructor(port: number) {
super(port) super(port)
this.calibrating = false; this.calibrating = false;
this._drift = 0; this._drift = 0;
this._driftCorrection = false;
this.setMode(GyroSensorMode.Rate); this.setMode(GyroSensorMode.Rate);
} }
@ -42,7 +40,7 @@ namespace sensors {
//% parts="gyroscope" //% parts="gyroscope"
//% blockNamespace=sensors //% blockNamespace=sensors
//% this.fieldEditor="ports" //% this.fieldEditor="ports"
//% weight=64 blockGap=8 //% weight=64
//% group="Gyro Sensor" //% group="Gyro Sensor"
angle(): number { angle(): number {
this.poke(); this.poke();
@ -71,13 +69,7 @@ namespace sensors {
pauseUntil(() => !this.calibrating, 2000); pauseUntil(() => !this.calibrating, 2000);
this.setMode(GyroSensorMode.Rate); this.setMode(GyroSensorMode.Rate);
let curr = this._query(); return this._query() - this._drift;
if (Math.abs(curr) < 4 && this._driftCorrection) {
const p = 0.01;
this._drift = (1 - p) * this._drift + p * curr;
curr = Math.round(curr - this._drift);
}
return curr;
} }
/** /**
@ -113,8 +105,6 @@ namespace sensors {
// mode toggling // mode toggling
this.setMode(GyroSensorMode.Rate); this.setMode(GyroSensorMode.Rate);
this.setMode(GyroSensorMode.Angle); this.setMode(GyroSensorMode.Angle);
// switch back to the desired mode
this.setMode(this.mode);
// check sensor is ready // check sensor is ready
if (!this.isActive()) { if (!this.isActive()) {
@ -125,17 +115,12 @@ namespace sensors {
return; return;
} }
// compute drift // switch to rate mode
this._drift = 0; this.computeDriftNoCalibration();
if (this._driftCorrection && this.mode == GyroSensorMode.Rate) { // switch back to the desired mode
const n = 100; this.setMode(this.mode);
for (let i = 0; i < n; ++i) {
this._drift += this._query();
pause(4);
}
this._drift /= n;
}
// and done
brick.setStatusLight(StatusLight.Green); // success brick.setStatusLight(StatusLight.Green); // success
pause(1000); pause(1000);
brick.setStatusLight(statusLight); // resture previous light brick.setStatusLight(statusLight); // resture previous light
@ -153,7 +138,7 @@ namespace sensors {
//% parts="gyroscope" //% parts="gyroscope"
//% blockNamespace=sensors //% blockNamespace=sensors
//% this.fieldEditor="ports" //% this.fieldEditor="ports"
//% weight=50 //% weight=50 blockGap=8
//% group="Gyro Sensor" //% group="Gyro Sensor"
reset(): void { reset(): void {
if (this.calibrating) return; // already in calibration mode if (this.calibrating) return; // already in calibration mode
@ -168,19 +153,62 @@ namespace sensors {
/** /**
* Gets the computed rate drift * Gets the computed rate drift
*/ */
//% //% help=sensors/gyro/drift
//% block="**gyro** %this|drift"
//% blockId=gyroDrift
//% parts="gyroscope"
//% blockNamespace=sensors
//% this.fieldEditor="ports"
//% weight=9 blockGap=8
//% group="Gyro Sensor"
drift(): number { drift(): number {
return this._drift; return this._drift;
} }
/** /**
* Enables or disable drift correction * Computes the current sensor drift when using rate measurements.
* @param enabled
*/ */
//% //% help=sensors/gyro/compute-drift
setDriftCorrection(enabled: boolean) { //% block="compute **gyro** %this|drift"
this._driftCorrection = enabled; //% blockId=gyroComputeDrift
//% parts="gyroscope"
//% blockNamespace=sensors
//% this.fieldEditor="ports"
//% weight=10 blockGap=8
//% group="Gyro Sensor"
computeDrift() {
if (this.calibrating)
pauseUntil(() => !this.calibrating, 2000);
this.computeDriftNoCalibration();
}
private computeDriftNoCalibration() {
// clear drift
this.setMode(GyroSensorMode.Rate);
this._drift = 0; this._drift = 0;
const n = 100;
let d = 0;
for (let i = 0; i < n; ++i) {
d += this._query();
pause(4);
}
this._drift = d / n;
}
_info(): string {
if (this.calibrating)
return "cal...";
switch (this.mode) {
case GyroSensorMode.Angle:
return `${this._query()}>`;
case GyroSensorMode.Rate:
let r = `${this._query()}>/s`;
if (this._drift)
r += `-${this._drift | 0}`;
return r;
}
return "";
} }
} }

View File

@ -4,9 +4,9 @@ tests.onEvent(TestEvent.RunSetUp, function() {
}) })
tests.onEvent(TestEvent.TestSetUp, function() { tests.onEvent(TestEvent.TestSetUp, function() {
motors.stopAll(); motors.stopAll();
motors.resetAllMotors(); motors.resetAll();
}) })
tests.onEvent(TestEvent.TestTearDown, function() { tests.onEvent(TestEvent.TestTearDown, function() {
motors.stopAll(); motors.stopAll();
motors.resetAllMotors(); motors.resetAll();
}) })