Merge branch 'master' into initial_sim
This commit is contained in:
commit
5be3b31e00
66
docs/tests/motors.ts
Normal file
66
docs/tests/motors.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
let errors: string[] = [];
|
||||||
|
let tachoB = 0;
|
||||||
|
let tachoC = 0;
|
||||||
|
|
||||||
|
function assert(name: string, condition: boolean) {
|
||||||
|
if (!condition) {
|
||||||
|
errors.push(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertClose(name: string, expected: number, actual: number, tolerance = 10) {
|
||||||
|
assert(name + ` ${expected}/${actual}`, Math.abs(expected - actual) < tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test(name: string, f: () => void, check?: () => void) {
|
||||||
|
motors.stopAllMotors();
|
||||||
|
loops.pause(500);
|
||||||
|
tachoB = motors.largeB.tachoCount()
|
||||||
|
tachoC = motors.largeB.tachoCount()
|
||||||
|
brick.clearScreen()
|
||||||
|
brick.print(name, 0, 0)
|
||||||
|
f();
|
||||||
|
loops.pause(3000);
|
||||||
|
motors.stopAllMotors();
|
||||||
|
motors.largeB.setReversed(false);
|
||||||
|
motors.largeC.setReversed(false);
|
||||||
|
motors.mediumA.setReversed(false);
|
||||||
|
loops.pause(1000);
|
||||||
|
if (check)
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
test("lgB set speed 100", () => {
|
||||||
|
motors.largeB.setSpeed(100)
|
||||||
|
});
|
||||||
|
test("lgB set speed (reversed)", () => {
|
||||||
|
motors.largeB.setReversed(true)
|
||||||
|
motors.largeB.setSpeed(100)
|
||||||
|
})
|
||||||
|
test("lgBC set speed 100", () => {
|
||||||
|
motors.largeBC.setSpeed(100)
|
||||||
|
})
|
||||||
|
test("lgBC steer 50% 2x", () => {
|
||||||
|
motors.largeBC.steer(50, 50, 2, MoveUnit.Rotations)
|
||||||
|
}, () => {
|
||||||
|
assertClose("largeB", 720, motors.largeB.tachoCount() - tachoB)
|
||||||
|
});
|
||||||
|
test("lgBC steer 50% 500deg", () => {
|
||||||
|
motors.largeBC.steer(50, 50, 500, MoveUnit.Degrees)
|
||||||
|
}, () => {
|
||||||
|
assertClose("largeB", 500, motors.largeB.tachoCount() - tachoB)
|
||||||
|
});
|
||||||
|
test("lgBC steer 50% 2s", () => {
|
||||||
|
motors.largeBC.steer(50, 50, 2, MoveUnit.Seconds)
|
||||||
|
})
|
||||||
|
test("lgBC tank 50% 2s", () => {
|
||||||
|
motors.largeBC.tank(50, 50, 720, MoveUnit.Degrees)
|
||||||
|
})
|
||||||
|
|
||||||
|
brick.clearScreen()
|
||||||
|
brick.print(`${errors.length} errors`, 0, 0)
|
||||||
|
let l = 1;
|
||||||
|
for(const error of errors)
|
||||||
|
brick.print(`error: ${error}`, 0, l++ * 12)
|
||||||
|
})
|
@ -55,7 +55,6 @@
|
|||||||
"motors.Motor.move|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
|
"motors.Motor.move|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
|
||||||
"motors.Motor.move|param|unit": "the meaning of the value",
|
"motors.Motor.move|param|unit": "the meaning of the value",
|
||||||
"motors.Motor.move|param|value": "the move quantity, eg: 2",
|
"motors.Motor.move|param|value": "the move quantity, eg: 2",
|
||||||
"motors.Motor.port": "Gets the port where this motor is connected",
|
|
||||||
"motors.Motor.reset": "Resets the motor(s).",
|
"motors.Motor.reset": "Resets the motor(s).",
|
||||||
"motors.Motor.setBrake": "Sets the automatic brake on or off when the motor is off",
|
"motors.Motor.setBrake": "Sets the automatic brake on or off when the motor is off",
|
||||||
"motors.Motor.setBrake|param|brake": "a value indicating if the motor should break when off",
|
"motors.Motor.setBrake|param|brake": "a value indicating if the motor should break when off",
|
||||||
|
@ -96,31 +96,31 @@ namespace motors {
|
|||||||
export class Motor extends control.Component {
|
export class Motor extends control.Component {
|
||||||
protected _port: Output;
|
protected _port: Output;
|
||||||
protected _brake: boolean;
|
protected _brake: boolean;
|
||||||
|
private _initialized: boolean;
|
||||||
constructor(port: Output) {
|
private _init: () => void;
|
||||||
|
private _setSpeed: (speed: number) => void;
|
||||||
|
private _move: (steps: boolean, stepsOrTime: number, speed: number) => void;
|
||||||
|
|
||||||
|
constructor(port: Output, init: () => void, setSpeed: (speed: number) => void, move: (steps: boolean, stepsOrTime: number, speed: number) => void) {
|
||||||
super();
|
super();
|
||||||
this._port = port;
|
this._port = port;
|
||||||
this._brake = false;
|
this._brake = false;
|
||||||
|
this._initialized = false;
|
||||||
|
this._init = init;
|
||||||
|
this._setSpeed = setSpeed;
|
||||||
|
this._move = move;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazy initialization code
|
* Lazy initialization code
|
||||||
*/
|
|
||||||
protected __init() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the port where this motor is connected
|
|
||||||
*/
|
*/
|
||||||
//%
|
protected init() {
|
||||||
//% group="Motion"
|
if (!this._initialized) {
|
||||||
port(): Output {
|
this._initialized = true;
|
||||||
this.__init();
|
this._init();
|
||||||
return this._port;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the automatic brake on or off when the motor is off
|
* Sets the automatic brake on or off when the motor is off
|
||||||
* @param brake a value indicating if the motor should break when off
|
* @param brake a value indicating if the motor should break when off
|
||||||
@ -130,9 +130,9 @@ namespace motors {
|
|||||||
//% weight=60 blockGap=8
|
//% weight=60 blockGap=8
|
||||||
//% group="Motion"
|
//% group="Motion"
|
||||||
setBrake(brake: boolean) {
|
setBrake(brake: boolean) {
|
||||||
this.__init();
|
this.init();
|
||||||
this._brake = brake;
|
this._brake = brake;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverses the motor polarity
|
* Reverses the motor polarity
|
||||||
@ -142,18 +142,18 @@ namespace motors {
|
|||||||
//% weight=59
|
//% weight=59
|
||||||
//% group="Motion"
|
//% group="Motion"
|
||||||
setReversed(reversed: boolean) {
|
setReversed(reversed: boolean) {
|
||||||
this.__init();
|
this.init();
|
||||||
const b = mkCmd(this._port, DAL.opOutputPolarity, 1)
|
const b = mkCmd(this._port, DAL.opOutputPolarity, 1)
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, reversed ? -1 : 1);
|
b.setNumber(NumberFormat.Int8LE, 2, reversed ? 0 : 1);
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the motor(s).
|
* Stops the motor(s).
|
||||||
*/
|
*/
|
||||||
//%
|
//%
|
||||||
stop() {
|
stop() {
|
||||||
this.__init();
|
this.init();
|
||||||
stop(this._port, this._brake);
|
stop(this._port, this._brake);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//%
|
//%
|
||||||
reset() {
|
reset() {
|
||||||
this.__init();
|
this.init();
|
||||||
reset(this._port);
|
reset(this._port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,17 +176,14 @@ namespace motors {
|
|||||||
//% speed.min=-100 speed.max=100
|
//% speed.min=-100 speed.max=100
|
||||||
//% group="Motion"
|
//% group="Motion"
|
||||||
setSpeed(speed: number) {
|
setSpeed(speed: number) {
|
||||||
this.__init();
|
this.init();
|
||||||
speed = Math.clamp(-100, 100, speed >> 0);
|
speed = Math.clamp(-100, 100, speed >> 0);
|
||||||
if (!speed) // always stop
|
if (!speed) // always stop
|
||||||
this.stop();
|
this.stop();
|
||||||
else
|
else
|
||||||
this.__setSpeed(speed);
|
this._setSpeed(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __setSpeed(speed: number) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the motor by a number of rotations, degress or seconds
|
* Moves the motor by a number of rotations, degress or seconds
|
||||||
* @param value the move quantity, eg: 2
|
* @param value the move quantity, eg: 2
|
||||||
@ -198,7 +195,7 @@ namespace motors {
|
|||||||
//% speed.min=-100 speed.max=100
|
//% speed.min=-100 speed.max=100
|
||||||
//% group="Motion"
|
//% group="Motion"
|
||||||
move(value: number, unit: MoveUnit, speed: number) {
|
move(value: number, unit: MoveUnit, speed: number) {
|
||||||
this.__init();
|
this.init();
|
||||||
speed = Math.clamp(-100, 100, speed >> 0);
|
speed = Math.clamp(-100, 100, speed >> 0);
|
||||||
if (!speed) {
|
if (!speed) {
|
||||||
this.stop();
|
this.stop();
|
||||||
@ -221,20 +218,16 @@ namespace motors {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__move(useSteps, stepsOrTime, speed);
|
this._move(useSteps, stepsOrTime, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __move(steps: boolean, stepsOrTime: number, speed: number) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class SingleMotor extends Motor {
|
export class SingleMotor extends Motor {
|
||||||
private _large: boolean;
|
private _large: boolean;
|
||||||
private _initialized: boolean;
|
|
||||||
|
|
||||||
constructor(port: Output, large: boolean) {
|
constructor(port: Output, large: boolean) {
|
||||||
super(port);
|
super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
||||||
this._large = large;
|
this._large = large;
|
||||||
this.markUsed();
|
this.markUsed();
|
||||||
}
|
}
|
||||||
@ -243,23 +236,23 @@ namespace motors {
|
|||||||
motors.__motorUsed(this._port, this._large);
|
motors.__motorUsed(this._port, this._large);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __init() {
|
private __init() {
|
||||||
if (!this._initialized) {
|
// specify motor size on this port
|
||||||
this._initialized = true;
|
const b = mkCmd(outOffset(this._port), DAL.opOutputSetType, 1)
|
||||||
// specify motor size on this port
|
b.setNumber(NumberFormat.Int8LE, 2, this._large ? 0x07 : 0x08)
|
||||||
const b = mkCmd(this._port, DAL.opOutputSetType, 1)
|
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, this._large ? 0x07 : 0x08)
|
|
||||||
writePWM(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected __setSpeed(speed: number) {
|
|
||||||
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
|
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __move(steps: boolean, stepsOrTime: number, speed: number) {
|
private __setSpeed(speed: number) {
|
||||||
|
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
||||||
|
writePWM(b)
|
||||||
|
if (speed) {
|
||||||
|
writePWM(mkCmd(this._port, DAL.opOutputStart, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private __move(steps: boolean, stepsOrTime: number, speed: number) {
|
||||||
step(this._port, {
|
step(this._port, {
|
||||||
useSteps: steps,
|
useSteps: steps,
|
||||||
step1: 0,
|
step1: 0,
|
||||||
@ -278,7 +271,7 @@ namespace motors {
|
|||||||
//% weight=72 blockGap=8
|
//% weight=72 blockGap=8
|
||||||
//% group="Sensors"
|
//% group="Sensors"
|
||||||
speed(): number {
|
speed(): number {
|
||||||
this.__init();
|
this.init();
|
||||||
return getMotorData(this._port).actualSpeed;
|
return getMotorData(this._port).actualSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +283,7 @@ namespace motors {
|
|||||||
//% weight=71 blockGap=8
|
//% weight=71 blockGap=8
|
||||||
//% group="Sensors"
|
//% group="Sensors"
|
||||||
count(): number {
|
count(): number {
|
||||||
this.__init();
|
this.init();
|
||||||
return getMotorData(this._port).count;
|
return getMotorData(this._port).count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +295,7 @@ namespace motors {
|
|||||||
//% weight=70
|
//% weight=70
|
||||||
//% group="Sensors"
|
//% group="Sensors"
|
||||||
tachoCount(): number {
|
tachoCount(): number {
|
||||||
this.__init();
|
this.init();
|
||||||
return getMotorData(this._port).tachoCount;
|
return getMotorData(this._port).tachoCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +304,7 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//% group="Motion"
|
//% group="Motion"
|
||||||
clearCount() {
|
clearCount() {
|
||||||
this.__init();
|
this.init();
|
||||||
const b = mkCmd(this._port, DAL.opOutputClearCount, 0)
|
const b = mkCmd(this._port, DAL.opOutputClearCount, 0)
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
||||||
@ -348,10 +341,9 @@ namespace motors {
|
|||||||
|
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class SynchedMotorPair extends Motor {
|
export class SynchedMotorPair extends Motor {
|
||||||
private _initialized: boolean;
|
|
||||||
|
|
||||||
constructor(ports: Output) {
|
constructor(ports: Output) {
|
||||||
super(ports);
|
super(ports, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
||||||
this.markUsed();
|
this.markUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,16 +351,17 @@ namespace motors {
|
|||||||
motors.__motorUsed(this._port, true);
|
motors.__motorUsed(this._port, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __init() {
|
private __init() {
|
||||||
if (!this._initialized) {
|
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
||||||
this._initialized = true;
|
if (this._port & (1 << i)) {
|
||||||
const b = mkCmd(this._port, DAL.opOutputSetType, 1)
|
const b = mkCmd(outOffset(1 << i), DAL.opOutputSetType, 1)
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, 0x07) // large motor
|
b.setNumber(NumberFormat.Int8LE, 2, 0x07) // large motor
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __setSpeed(speed: number) {
|
private __setSpeed(speed: number) {
|
||||||
syncMotors(this._port, {
|
syncMotors(this._port, {
|
||||||
speed: speed,
|
speed: speed,
|
||||||
turnRatio: 0,
|
turnRatio: 0,
|
||||||
@ -376,7 +369,7 @@ namespace motors {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
protected __move(steps: boolean, stepsOrTime: number, speed: number) {
|
private __move(steps: boolean, stepsOrTime: number, speed: number) {
|
||||||
syncMotors(this._port, {
|
syncMotors(this._port, {
|
||||||
useSteps: steps,
|
useSteps: steps,
|
||||||
speed: speed,
|
speed: speed,
|
||||||
@ -384,7 +377,7 @@ namespace motors {
|
|||||||
stepsOrTime: stepsOrTime,
|
stepsOrTime: stepsOrTime,
|
||||||
useBrake: this._brake
|
useBrake: this._brake
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns the motor and the follower motor by a number of rotations
|
* Turns the motor and the follower motor by a number of rotations
|
||||||
@ -399,6 +392,7 @@ namespace motors {
|
|||||||
//% inlineInputMode=inline
|
//% inlineInputMode=inline
|
||||||
//% group="Chassis"
|
//% group="Chassis"
|
||||||
steer(steering: number, speed: number, value: number, unit: MoveUnit) {
|
steer(steering: number, speed: number, value: number, unit: MoveUnit) {
|
||||||
|
this.init();
|
||||||
speed = Math.clamp(-100, 100, speed >> 0);
|
speed = Math.clamp(-100, 100, speed >> 0);
|
||||||
if (!speed) {
|
if (!speed) {
|
||||||
stop(this._port, this._brake);
|
stop(this._port, this._brake);
|
||||||
|
Loading…
Reference in New Issue
Block a user