more motor work

This commit is contained in:
Peli de Halleux
2017-12-14 17:01:23 -08:00
parent 9dedbeae1b
commit fcdc350e40
5 changed files with 197 additions and 115 deletions

View File

@ -8,7 +8,13 @@ enum Output {
//% block="D"
D = 0x08,
//% block="B+C"
BC = 0x06,
BC = Output.B | Output.C,
//% block="A+B"
AB = Output.A | Output.B,
//% block="C+D"
CD = Output.C | Output.D,
//% block="A+D"
AD = Output.B | Output.C,
//% block="All"
ALL = 0x0f
}
@ -79,7 +85,8 @@ namespace motors {
* Stops all motors
*/
//% blockId=motorStopAll block="stop all motors"
//% weight=19
//% weight=97
//% group="Motion"
export function stopAllMotors() {
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
writePWM(b)
@ -92,7 +99,6 @@ namespace motors {
private _initialized: boolean;
private _brake: boolean;
private _follower: Motor; //
constructor(port: Output, large: boolean) {
super();
@ -110,40 +116,36 @@ namespace motors {
}
}
/**
* Gets the port where this motor is connected
*/
//%
//% group="Motion"
port(): Output {
return this._port;
}
/**
* Sets the speed of the motor.
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
*/
//% blockId=motorPower block="set speed of `icons.motorLarge` %motor|to %speed|%"
//% blockId=motorSetSpeed block="set speed of `icons.motorLarge` %motor|to %speed|%"
//% on.fieldEditor=toggleonoff
//% weight=99 blockGap=8
//% speed.min=-100 speed.max=100
//% group="Motion"
setSpeed(speed: number) {
this.__init();
speed = Math.clamp(-100, 100, speed >> 0);
if (!speed) { // always stop
this.stop();
} else {
if (this._follower) this.setSpeedSync(speed);
else this.setSpeedSingle(speed);
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
b.setNumber(NumberFormat.Int8LE, 2, speed)
writePWM(b)
}
}
private setSpeedSingle(speed: number) {
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
b.setNumber(NumberFormat.Int8LE, 2, speed)
writePWM(b)
}
private setSpeedSync(speed: number) {
const out = this._port | this._follower._port;
syncMotors(out, {
speed: speed,
turnRatio: 0,
useBrake: !!this._brake
})
}
/**
* Moves the motor by a number of rotations, degress or seconds
* @param value the move quantity, eg: 2
@ -151,12 +153,13 @@ namespace motors {
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
*/
//% blockId=motorMove block="move `icons.motorLarge` %motor|for %value|%unit|at %speed|%"
//% weight=98
//% weight=98 blockGap=8
//% speed.min=-100 speed.max=100
//% group="Motion"
move(value: number, unit: MoveUnit, speed: number) {
this.output(value, unit, speed, 0);
}
private output(value: number, unit: MoveUnit, speed: number, turnRatio: number) {
this.__init();
speed = Math.clamp(-100, 100, speed >> 0);
@ -182,24 +185,14 @@ namespace motors {
break;
}
if (this._follower) {
syncMotors(this._port | this._follower._port, {
useSteps: useSteps,
stepsOrTime: stepsOrTime,
speed: speed,
turnRatio: turnRatio,
useBrake: this._brake
})
} else {
step(this._port, {
useSteps: useSteps,
step1: 0,
step2: stepsOrTime,
step3: 0,
speed: speed,
useBrake: this._brake
})
}
step(this._port, {
useSteps: useSteps,
step1: 0,
step2: stepsOrTime,
step3: 0,
speed: speed,
useBrake: this._brake
})
}
/**
@ -207,8 +200,7 @@ namespace motors {
*/
private stop() {
this.__init();
if (this._follower) stop(this._port | this._follower._port);
else stop(this._port);
stop(this._port);
}
/**
@ -218,6 +210,7 @@ namespace motors {
//% blockId=outputMotorSetBrakeMode block="set `icons.motorLarge` %motor|brake %brake"
//% brake.fieldEditor=toggleonoff
//% weight=60 blockGap=8
//% group="Motion"
setBrake(brake: boolean) {
this.__init();
this._brake = brake;
@ -229,6 +222,7 @@ namespace motors {
//% blockId=motorSetReversed block="set `icons.motorLarge` %motor|reversed %reversed"
//% reversed.fieldEditor=toggleonoff
//% weight=59
//% group="Motion"
setReversed(reversed: boolean) {
this.__init();
const b = mkCmd(this._port, DAL.opOutputPolarity, 1)
@ -242,6 +236,7 @@ namespace motors {
*/
//% blockId=motorSpeed block="`icons.motorLarge` %motor|speed"
//% weight=72 blockGap=8
//% group="Sensors"
speed(): number {
this.__init();
return getMotorData(this._port).actualSpeed;
@ -253,6 +248,7 @@ namespace motors {
*/
//% blockId=motorCount block="`icons.motorLarge` %motor|count"
//% weight=71 blockGap=8
//% group="Sensors"
count(): number {
this.__init();
return getMotorData(this._port).count;
@ -264,6 +260,7 @@ namespace motors {
*/
//% blockId=motorTachoCount block="`icons.motorLarge` %motor|tacho count"
//% weight=70
//% group="Sensors"
tachoCount(): number {
this.__init();
return getMotorData(this._port).tachoCount;
@ -272,7 +269,7 @@ namespace motors {
/**
* Clears the motor count
*/
//%
//% group="Motion"
clearCount() {
this.__init();
const b = mkCmd(this._port, DAL.opOutputClearCount, 0)
@ -285,27 +282,84 @@ namespace motors {
}
/**
* Resets the motor and clears any synchronization
* Resets the motor.
*/
//% blockId=motorReset block="reset `icons.motorLarge` %motor"
//% weight=20
//% group="Motion"
reset() {
this.__init();
reset(this._port);
delete this._follower;
}
}
}
//% whenUsed fixedInstance block="large A"
export const largeA = new Motor(Output.A, true);
//% whenUsed fixedInstance block="large B"
export const largeB = new Motor(Output.B, true);
//% whenUsed fixedInstance block="large C"
export const largeC = new Motor(Output.C, true);
//% whenUsed fixedInstance block="large D"
export const largeD = new Motor(Output.D, true);
//% whenUsed fixedInstance block="medium A"
export const mediumA = new Motor(Output.A, false);
//% whenUsed fixedInstance block="medium B"
export const mediumB = new Motor(Output.B, false);
//% whenUsed fixedInstance block="medium C"
export const mediumC = new Motor(Output.C, false);
//% whenUsed fixedInstance block="medium D"
export const mediumD = new Motor(Output.D, false);
//% fixedInstances
export class SynchedMotorPair extends control.Component {
private _ports: Output;
private _brake: boolean;
constructor(ports: Output) {
super();
this._ports = ports;
this._brake = false;
}
/**
* Synchronizes a follower motor to this motor
* @param motor the leader motor, eg: motors.largeB
* @param follower the motor that follows this motor commands, eg: motors.largeC
* Sets the speed of the motor.
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
*/
//% blockId=motorSync block="sync `icons.motorLarge` %motor|with `icons.motorLarge` %follower"
//% weight=10 blockGap=8
sync(follower: Motor) {
this.__init();
if (this == follower) return; // can't sync with self
this._follower = follower;
//% blockId=motorPairSetSpeed block="set speed of `icons.motorLarge` %motor|to %speed|%"
//% on.fieldEditor=toggleonoff
//% weight=99 blockGap=8
//% speed.min=-100 speed.max=100
//% group="Chassis"
setSpeed(speed: number) {
speed = Math.clamp(speed >> 0, -100, 100);
if (!speed) {
stop(this._ports);
return;
}
syncMotors(this._ports, {
speed: speed,
turnRatio: 0,
useBrake: !!this._brake
})
}
/**
* Sets the automatic brake on or off when the motor is off
* @param brake a value indicating if the motor should break when off
*/
//% blockId=motorPairSetBrakeMode block="set `icons.motorLarge` %chassis|brake %brake"
//% brake.fieldEditor=toggleonoff
//% weight=60 blockGap=8
//% group="Chassis"
setBrake(brake: boolean) {
this._brake = brake;
}
/**
@ -315,14 +369,45 @@ namespace motors {
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
* @param steering the ratio of power sent to the follower motor, from ``-100`` to ``100``
*/
//% blockId=motorTurn block="move steering `icons.motorLarge` %motor|at %speed|%|steer %turnRadio|%|by %value|%unit"
//% blockId=motorPairTurn block="move steering %chassis|at %speed|%|steer %turnRadio|%|by %value|%unit"
//% weight=9 blockGap=8
//% steering.min=-100 steering=100
//% inlineInputMode=inline
//% group="Chassis"
moveSteering(steering: number, speed: number, value: number, unit: MoveUnit) {
this.output(value, unit, speed, steering + 100);
}
speed = Math.clamp(-100, 100, speed >> 0);
if (!speed) {
stop(this._ports);
return;
}
const turnRatio = Math.clamp(-200, 200, steering + 100 >> 0);
let useSteps: boolean;
let stepsOrTime: number;
switch (unit) {
case MoveUnit.Rotations:
stepsOrTime = (value * 360) >> 0;
useSteps = true;
break;
case MoveUnit.Degrees:
stepsOrTime = value >> 0;
useSteps = true;
break;
default:
stepsOrTime = value;
useSteps = false;
break;
}
syncMotors(this._ports, {
useSteps: useSteps,
speed: speed,
turnRatio: turnRatio,
stepsOrTime: stepsOrTime,
useBrake: this._brake
});
}
/**
* The Move Tank block can make a robot drive forward, backward, turn, or stop.
* Use the Move Tank block for robot vehicles that have two Large Motors,
@ -334,42 +419,31 @@ namespace motors {
* @param speedLeft the speed on the left motor, eg: 50
* @param speedRight the speed on the right motor, eg: 50
*/
//% blockId=motorTank block="move tank `icons.motorLarge` %motor|left %speedLeft|%|right %speedRight|%|by %value|%unit"
//% blockId=motorPairTank block="move tank %chassis|left %speedLeft|%|right %speedRight|%|by %value|%unit"
//% weight=9 blockGap=8
//% speedLeft.min=-100 speedLeft=100
//% speedRight.min=-100 speedRight=100
//% inlineInputMode=inline
//% group="Chassis"
moveTank(speedLeft: number, speedRight: number, value: number, unit: MoveUnit) {
speedLeft = Math.clamp(speedLeft >> 0, -100, 100);
speedRight = Math.clamp(speedRight >> 0, -100, 100);
const steering =(speedRight * 100 / speedLeft) >> 0;
const steering = (speedRight * 100 / speedLeft) >> 0;
this.moveSteering(speedLeft, steering, value, unit);
}
}
//% whenUsed fixedInstance block="large A"
export const largeMotorA = new Motor(Output.A, true);
//% whenUsed fixedInstance block="large B+C"
export const largeBC = new SynchedMotorPair(Output.BC);
//% whenUsed fixedInstance block="large B"
export const largeMotorB = new Motor(Output.B, true);
//% whenUsed fixedInstance block="large A+D"
export const largeAD = new SynchedMotorPair(Output.AD);
//% whenUsed fixedInstance block="large C"
export const largeMotorC = new Motor(Output.C, true);
//% whenUsed fixedInstance block="large A+B"
export const largeAB = new SynchedMotorPair(Output.AB);
//% whenUsed fixedInstance block="large D"
export const largeMotorD = new Motor(Output.D, true);
//% whenUsed fixedInstance block="medium A"
export const mediumMotorA = new Motor(Output.A, false);
//% whenUsed fixedInstance block="medium B"
export const mediumMotorB = new Motor(Output.B, false);
//% whenUsed fixedInstance block="medium C"
export const mediumMotorC = new Motor(Output.C, false);
//% whenUsed fixedInstance block="medium D"
export const mediumMotorD = new Motor(Output.D, false);
//% whenUsed fixedInstance block="large C+D"
export const largeCD = new SynchedMotorPair(Output.CD);
function reset(out: Output) {
let b = mkCmd(out, DAL.opOutputReset, 0)