more motor work
This commit is contained in:
@ -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)
|
||||
|
Reference in New Issue
Block a user