From 755738072256fee800815f7678c5e15b146026a3 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Tue, 12 Dec 2017 13:20:25 -0800 Subject: [PATCH 1/9] adding sync command --- libs/core/output.ts | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/libs/core/output.ts b/libs/core/output.ts index 7f982cb8..fe605900 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -75,7 +75,7 @@ namespace motors { //% fixedInstances export class Motor extends control.Component { - private port: Output; + public port: Output; private large: boolean; private brake: boolean; @@ -270,6 +270,29 @@ namespace motors { } } + interface SyncOptions { + useSteps?: boolean; + speed: number; + turnRatio: number; + stepsOrTime: number; + useBrake?: boolean; + } + + function syncMotors(out: Output, opts: SyncOptions) { + const cmd = opts.useSteps ? DAL.opOutputStepSync : DAL.opOutputTimeSync; + const b = mkCmd(out, cmd, 11); + const speed = Math.clamp(-100, 100, opts.speed); + const turnRatio = Math.clamp(-200, 200, opts.turnRatio); + + b.setNumber(NumberFormat.Int8LE, 2, speed) + // note that b[3] is padding + b.setNumber(NumberFormat.Int16LE, 4 + 4 * 0, turnRatio) + // b[6], b[7] is padding + b.setNumber(NumberFormat.Int32LE, 4 + 4 * 1, opts.stepsOrTime || 0) + b.setNumber(NumberFormat.Int8LE, 4 + 4 * 2, opts.useBrake ? 1 : 0) + writePWM(b) + } + interface StepOptions { power?: number; speed?: number; // either speed or power has to be present From 113b42656c39b1af595ea6dab177e4e58cd30945 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Tue, 12 Dec 2017 14:08:45 -0800 Subject: [PATCH 2/9] sync command working --- libs/core/_locales/core-jsdoc-strings.json | 3 ++ libs/core/_locales/core-strings.json | 2 ++ libs/core/output.ts | 34 ++++++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 3b1aa9e7..b2bdb5dc 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -63,6 +63,9 @@ "motors.Motor.speed": "Gets motor actual speed.", "motors.Motor.stop": "Stops the motor", "motors.Motor.tachoCount": "Gets motor tacho count.", + "motors.setSyncSpeed": "Synchronizes this motor with another motor.", + "motors.setSyncSpeed|param|speed": "the power applied to the motor, eg: 50", + "motors.setSyncSpeed|param|turnRatio": "the ratio of the master power applied to this motor, eg: 100", "motors.stopAllMotors": "Stops all motors", "output.createBuffer": "Create a new zero-initialized buffer.", "output.createBuffer|param|size": "number of bytes in the buffer", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 132ddeca..f3e8cf34 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -14,6 +14,7 @@ "LightsPattern.Red|block": "Red", "Output.ALL|block": "All", "Output.A|block": "A", + "Output.BC|block": "B+C", "Output.B|block": "B", "Output.C|block": "C", "Output.D|block": "D", @@ -51,6 +52,7 @@ "motors.mediumMotorB|block": "medium B", "motors.mediumMotorC|block": "medium C", "motors.mediumMotorD|block": "medium D", + "motors.setSyncSpeed|block": "set sync speed B+C with %turnRatio|turn ratio at %speed|% speed", "motors.stopAllMotors|block": "stop all `icons.motorLarge`", "motors|block": "motors", "output|block": "output", diff --git a/libs/core/output.ts b/libs/core/output.ts index fe605900..0ffdb8e2 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -7,6 +7,8 @@ enum Output { C = 0x04, //% block="D" D = 0x08, + //% block="B+C" + BC = 0x06, //% block="All" ALL = 0x0f } @@ -75,7 +77,7 @@ namespace motors { //% fixedInstances export class Motor extends control.Component { - public port: Output; + private port: Output; private large: boolean; private brake: boolean; @@ -102,8 +104,7 @@ namespace motors { b.setNumber(NumberFormat.Int8LE, 2, speed) writePWM(b) if (speed) { - const b = mkCmd(this.port, DAL.opOutputStart, 0) - writePWM(b); + start(this.port); } else { this.stop(); } @@ -241,6 +242,28 @@ namespace motors { //% whenUsed fixedInstance block="medium D" export const mediumMotorD = new Motor(Output.D, false); + + /** + * Synchronizes this motor with another motor. + * @param motor the controlled motor, eg: motors.largeB + * @param other the motor that will control this motor, eg: motors.largeC + * @param turnRatio the ratio of the master power applied to this motor, eg: 100 + * @param speed the power applied to the motor, eg: 50 + */ + //% blockId=motorSync block="set sync speed B+C with %turnRatio|turn ratio at %speed|% speed" + //% turnRatio.min=-200 turnRatio.max=200 + //% speed.min=-100 speed.max=100 + export function setSyncSpeed(turnRatio: number, speed: number) { + syncMotors(Output.BC, { + useSteps: true, + speed: speed, + turnRatio: turnRatio, + stepsOrTime: 0, + useBrake: false + }) + start(Output.BC); + } + function reset(out: Output) { let b = mkCmd(out, DAL.opOutputReset, 0) writePWM(b) @@ -303,6 +326,11 @@ namespace motors { useBrake?: boolean; } + function start(out: Output) { + const b = mkCmd(out, DAL.opOutputStart, 0) + writePWM(b); + } + function step(out: Output, opts: StepOptions) { let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed let speed = opts.speed From 3c86ae286fbb66ccc85e80b460d3a5bccaaa226c Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Wed, 13 Dec 2017 22:40:40 -0800 Subject: [PATCH 3/9] more work on motors --- libs/core/_locales/core-jsdoc-strings.json | 21 +- libs/core/_locales/core-strings.json | 13 +- libs/core/output.ts | 257 ++++++++++++++------- 3 files changed, 191 insertions(+), 100 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index e496c9f0..1056d98f 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -52,20 +52,23 @@ "control.raiseEvent|param|value": "Component specific code indicating the cause of the event.", "motors.Motor.clearCount": "Clears the motor count", "motors.Motor.count": "Gets motor step count.", - "motors.Motor.move": "Moves the motor by a number of degrees", - "motors.Motor.move|param|angle": "the degrees to rotate, eg: 360", - "motors.Motor.reset": "Resets the motor.", + "motors.Motor.move": "Moves the motor by a number of rotations, degress or seconds", + "motors.Motor.move|param|unit": "the meaning of the value", + "motors.Motor.move|param|value": "the move quantity, eg: 2", + "motors.Motor.power": "Turns the motor on or off at the current speed", + "motors.Motor.power|param|on": "true if the motor should be on", + "motors.Motor.reset": "Resets the motor and clears any synchronization", "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.setReversed": "Reverses the motor polarity", - "motors.Motor.setSpeed": "Sets the motor speed level from ``-100`` to ``100``.", - "motors.Motor.setSpeed|param|speed": "the power from ``100`` full forward to ``-100`` full backward, eg: 50", "motors.Motor.speed": "Gets motor actual speed.", - "motors.Motor.stop": "Stops the motor", + "motors.Motor.sync": "Synchronizes a follower motor to this motor", + "motors.Motor.sync|param|follower": "the motor that follows this motor commands, eg: motors.largeC", "motors.Motor.tachoCount": "Gets motor tacho count.", - "motors.setSyncSpeed": "Synchronizes this motor with another motor.", - "motors.setSyncSpeed|param|speed": "the power applied to the motor, eg: 50", - "motors.setSyncSpeed|param|turnRatio": "the ratio of the master power applied to this motor, eg: 100", + "motors.Motor.turn": "Turns the motor and the follower motor by a number of rotations", + "motors.Motor.turn|param|turnRatio": "the ratio of power sent to the follower motor, from -200 to 200", + "motors.Motor.turn|param|unit": "the meaning of the value", + "motors.Motor.turn|param|value": "the move quantity, eg: 2", "motors.stopAllMotors": "Stops all motors", "output.createBuffer": "Create a new zero-initialized buffer.", "output.createBuffer|param|size": "number of bytes in the buffer", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 747bea17..4e152d05 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -12,6 +12,9 @@ "LightsPattern.RedFlash|block": "Flashing Red", "LightsPattern.RedPulse|block": "Pulsing Red", "LightsPattern.Red|block": "Red", + "MoveUnit.Degrees|block": "degrees", + "MoveUnit.Rotations|block": "rotations", + "MoveUnit.Seconds|block": "seconds", "Output.ALL|block": "All", "Output.A|block": "A", "Output.BC|block": "B+C", @@ -37,13 +40,15 @@ "control.raiseEvent|block": "raise event|from %src|with value %value", "control|block": "control", "motors.Motor.count|block": "`icons.motorLarge` %motor|count", - "motors.Motor.move|block": "move `icons.motorLarge` %motor|by %angle|degrees at %speed|%", + "motors.Motor.move|block": "move `icons.motorLarge` %motor|for %value|%unit", + "motors.Motor.power|block": "power `icons.motorLarge` %motor|%on", + "motors.Motor.reset|block": "reset `icons.motorLarge` %motor", "motors.Motor.setBrake|block": "set `icons.motorLarge` %motor|brake %brake", "motors.Motor.setReversed|block": "set `icons.motorLarge` %motor|reversed %reversed", - "motors.Motor.setSpeed|block": "set speed `icons.motorLarge` %motor|to %speed|%", "motors.Motor.speed|block": "`icons.motorLarge` %motor|speed", - "motors.Motor.stop|block": "stop `icons.motorLarge` %motor", + "motors.Motor.sync|block": "sync `icons.motorLarge` %motor|with `icons.motorLarge` %follower", "motors.Motor.tachoCount|block": "`icons.motorLarge` %motor|tacho count", + "motors.Motor.turn|block": "turn `icons.motorLarge` %motor|by %value|%unit|turn %turnRadio", "motors.largeMotorA|block": "large A", "motors.largeMotorB|block": "large B", "motors.largeMotorC|block": "large C", @@ -52,7 +57,6 @@ "motors.mediumMotorB|block": "medium B", "motors.mediumMotorC|block": "medium C", "motors.mediumMotorD|block": "medium D", - "motors.setSyncSpeed|block": "set sync speed B+C with %turnRatio|turn ratio at %speed|% speed", "motors.stopAllMotors|block": "stop all `icons.motorLarge`", "motors|block": "motors", "output|block": "output", @@ -69,6 +73,5 @@ "{id:category}Serial": "Serial", "{id:group}Buttons": "Buttons", "{id:group}Light": "Light", - "{id:group}Motors": "Motors", "{id:group}Screen": "Screen" } \ No newline at end of file diff --git a/libs/core/output.ts b/libs/core/output.ts index 3301fa88..902b3b93 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -19,6 +19,15 @@ enum OutputType { MiniTacho = 8, } +enum MoveUnit { + //% block="rotations" + Rotations, + //% block="degrees" + Degrees, + //% block="seconds" + Seconds +} + namespace motors { let pwmMM: MMap let motorMM: MMap @@ -70,7 +79,7 @@ namespace motors { * Stops all motors */ //% blockId=motorStopAll block="stop all `icons.motorLarge`" - //% weight=10 group="Motors" blockGap=8 + //% weight=10 blockGap=8 export function stopAllMotors() { const b = mkCmd(Output.ALL, DAL.opOutputStop, 0) writePWM(b) @@ -78,71 +87,127 @@ namespace motors { //% fixedInstances export class Motor extends control.Component { - private port: Output; - private large: boolean; - private brake: boolean; + private _port: Output; + private _large: boolean; + + private _initialized: boolean; + private _speed: number; + private _brake: boolean; + private _follower: Motor; // constructor(port: Output, large: boolean) { super(); - this.port = port; - this.large = large; - this.brake = false; + this._port = port; + this._large = large; + this._brake = false; + this._speed = 50; } - /** - * Sets the motor speed level from ``-100`` to ``100``. - * @param motor the output connection that the motor is connected to - * @param speed the power from ``100`` full forward to ``-100`` full backward, eg: 50 - */ - //% blockId=motorSetSpeed block="set speed `icons.motorLarge` %motor|to %speed|%" - //% weight=99 group="Motors" blockGap=8 - //% speed.min=-100 speed.max=100 - setSpeed(speed: number) { - speed = Math.clamp(-100, 100, speed >> 0); - - // per LEGO: call it power, use speed - const b = mkCmd(this.port, DAL.opOutputSpeed, 1) - b.setNumber(NumberFormat.Int8LE, 2, speed) - writePWM(b) - if (speed) { - start(this.port); - } else { - this.stop(); + private __init() { + if (!this._initialized) { + // specify motor size on this port + const b = mkCmd(this._port, DAL.opOutputSetType, 1) + b.setNumber(NumberFormat.Int8LE, 2, this._large ? 0x07 : 0x08) + writePWM(b) } } /** - * Moves the motor by a number of degrees - * @param degrees the angle to turn the motor - * @param angle the degrees to rotate, eg: 360 + * Turns the motor on or off at the current speed + * @param on true if the motor should be on + */ + //% blockId=motorPower block="power `icons.motorLarge` %motor|%on" + //% on.fieldEditor=toggleonoff + //% weight=99 blockGap=8 + power(on: boolean) { + if (!this._speed || !on) { // always stop + this.stop(); + } else { + if (this._follower) this.setSpeedSync(this._speed); + else this.setSpeedSingle(this._speed); + } + } + + 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 + * @param unit the meaning of the value * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 */ - //% blockId=motorMove block="move `icons.motorLarge` %motor|by %angle|degrees at %speed|%" - //% weight=98 group="Motors" blockGap=8 - //% speed.min=-100 speed.max=100 - move(angle: number, power: number) { - angle = angle >> 0; - power = Math.clamp(-100, 100, power >> 0); + //% blockId=motorMove block="move `icons.motorLarge` %motor|for %value|%unit" + //% weight=98 + //% speed.min=-100 speed.max=100 + move(value: number, unit: MoveUnit) { + this.output(value, unit, 0); + } + + private output(value: number, unit: MoveUnit, turnRatio: number) { + this.__init(); + if (!this._speed) { + this.stop(); + return; + } + turnRatio = Math.clamp(-200, 200, turnRatio >> 0); - step(this.port, { - speed: power, - step1: 0, - step2: angle, - step3: 0, - useSteps: true, - useBrake: this.brake - }) + 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; + } + + if (this._follower) { + syncMotors(this._port | this._follower._port, { + useSteps: useSteps, + stepsOrTime: stepsOrTime, + speed: this._speed, + turnRatio: turnRatio, + useBrake: this._brake + }) + } else { + step(this._port, { + useSteps: useSteps, + step1: 0, + step2: stepsOrTime, + step3: 0, + speed: this._speed, + useBrake: this._brake + }) + } } /** * Stops the motor */ - //% blockId=motorStop block="stop `icons.motorLarge` %motor" - //% weight=97 group="Motors" - stop() { - const b = mkCmd(this.port, DAL.opOutputStop, 1) - b.setNumber(NumberFormat.UInt8LE, 2, this.brake ? 1 : 0) - writePWM(b); + private stop() { + this.__init(); + if (this._follower) stop(this._port | this._follower._port); + else stop(this._port); } /** @@ -151,9 +216,9 @@ namespace motors { */ //% blockId=outputMotorSetBrakeMode block="set `icons.motorLarge` %motor|brake %brake" //% brake.fieldEditor=toggleonoff - //% weight=60 group="Motors" blockGap=8 + //% weight=60 blockGap=8 setBrake(brake: boolean) { - this.brake = brake; + this._brake = brake; } /** @@ -161,9 +226,10 @@ namespace motors { */ //% blockId=motorSetReversed block="set `icons.motorLarge` %motor|reversed %reversed" //% reversed.fieldEditor=toggleonoff - //% weight=59 group="Motors" + //% weight=59 setReversed(reversed: boolean) { - const b = mkCmd(this.port, DAL.opOutputPolarity, 1) + this.__init(); + const b = mkCmd(this._port, DAL.opOutputPolarity, 1) b.setNumber(NumberFormat.Int8LE, 2, reversed ? -1 : 1); writePWM(b) } @@ -173,9 +239,10 @@ namespace motors { * @param motor the port which connects to the motor */ //% blockId=motorSpeed block="`icons.motorLarge` %motor|speed" - //% weight=72 group="Motors" blockGap=8 + //% weight=72 blockGap=8 speed(): number { - return getMotorData(this.port).actualSpeed; + this.__init(); + return getMotorData(this._port).actualSpeed; } /** @@ -183,9 +250,10 @@ namespace motors { * @param motor the port which connects to the motor */ //% blockId=motorCount block="`icons.motorLarge` %motor|count" - //% weight=71 group="Motors" blockGap=8 + //% weight=71 blockGap=8 count(): number { - return getMotorData(this.port).count; + this.__init(); + return getMotorData(this._port).count; } /** @@ -193,30 +261,63 @@ namespace motors { * @param motor the port which connects to the motor */ //% blockId=motorTachoCount block="`icons.motorLarge` %motor|tacho count" - //% weight=70 group="Motors" + //% weight=70 tachoCount(): number { - return getMotorData(this.port).tachoCount; + this.__init(); + return getMotorData(this._port).tachoCount; } /** * Clears the motor count */ clearCount() { - const b = mkCmd(this.port, DAL.opOutputClearCount, 0) + this.__init(); + const b = mkCmd(this._port, DAL.opOutputClearCount, 0) writePWM(b) for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) { - if (this.port & (1 << i)) { + if (this._port & (1 << i)) { motorMM.setNumber(NumberFormat.Int32LE, i * MotorDataOff.Size + MotorDataOff.TachoSensor, 0) } } } /** - * Resets the motor. + * Resets the motor and clears any synchronization */ + //% blockId=motorReset block="reset `icons.motorLarge` %motor" + //% weight=1 reset() { - reset(this.port); + this.__init(); + reset(this._port); + delete this._follower; } + + /** + * 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 + */ + //% 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; + } + + /** + * Turns the motor and the follower motor by a number of rotations + * @param value the move quantity, eg: 2 + * @param unit the meaning of the value + * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 + * @param turnRatio the ratio of power sent to the follower motor, from -200 to 200 + */ + //% blockId=motorTurn block="turn `icons.motorLarge` %motor|by %value|%unit|turn %turnRadio" + //% weight=9 blockGap=8 + //% turnRatio.min=-200 turnRatio=200 + turn(value: number, unit: MoveUnit, turnRatio: number) { + this.output(value, unit, turnRatio); + } } //% whenUsed fixedInstance block="large A" @@ -243,28 +344,6 @@ namespace motors { //% whenUsed fixedInstance block="medium D" export const mediumMotorD = new Motor(Output.D, false); - - /** - * Synchronizes this motor with another motor. - * @param motor the controlled motor, eg: motors.largeB - * @param other the motor that will control this motor, eg: motors.largeC - * @param turnRatio the ratio of the master power applied to this motor, eg: 100 - * @param speed the power applied to the motor, eg: 50 - */ - //% blockId=motorSync block="set sync speed B+C with %turnRatio|turn ratio at %speed|% speed" - //% turnRatio.min=-200 turnRatio.max=200 - //% speed.min=-100 speed.max=100 - export function setSyncSpeed(turnRatio: number, speed: number) { - syncMotors(Output.BC, { - useSteps: true, - speed: speed, - turnRatio: turnRatio, - stepsOrTime: 0, - useBrake: false - }) - start(Output.BC); - } - function reset(out: Output) { let b = mkCmd(out, DAL.opOutputReset, 0) writePWM(b) @@ -299,7 +378,7 @@ namespace motors { useSteps?: boolean; speed: number; turnRatio: number; - stepsOrTime: number; + stepsOrTime?: number; useBrake?: boolean; } @@ -333,6 +412,12 @@ namespace motors { writePWM(b); } + function stop(out: Output) { + const b = mkCmd(out, DAL.opOutputStop, 1) + b.setNumber(NumberFormat.UInt8LE, 2, this.brake ? 1 : 0) + writePWM(b); + } + function step(out: Output, opts: StepOptions) { let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed let speed = opts.speed From 92178f3371edf9a3855a6bda088c03de922aa4c0 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Wed, 13 Dec 2017 22:54:08 -0800 Subject: [PATCH 4/9] bring back speed --- libs/core/_locales/core-jsdoc-strings.json | 6 ++-- libs/core/_locales/core-strings.json | 6 ++-- libs/core/output.ts | 42 +++++++++++----------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 1056d98f..25e0f3b5 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -53,19 +53,21 @@ "motors.Motor.clearCount": "Clears the motor count", "motors.Motor.count": "Gets motor step count.", "motors.Motor.move": "Moves the motor by a number of rotations, degress or seconds", + "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|value": "the move quantity, eg: 2", - "motors.Motor.power": "Turns the motor on or off at the current speed", - "motors.Motor.power|param|on": "true if the motor should be on", "motors.Motor.reset": "Resets the motor and clears any synchronization", "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.setReversed": "Reverses the motor polarity", + "motors.Motor.setSpeed": "Sets the speed of the motor.", + "motors.Motor.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", "motors.Motor.speed": "Gets motor actual speed.", "motors.Motor.sync": "Synchronizes a follower motor to this motor", "motors.Motor.sync|param|follower": "the motor that follows this motor commands, eg: motors.largeC", "motors.Motor.tachoCount": "Gets motor tacho count.", "motors.Motor.turn": "Turns the motor and the follower motor by a number of rotations", + "motors.Motor.turn|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", "motors.Motor.turn|param|turnRatio": "the ratio of power sent to the follower motor, from -200 to 200", "motors.Motor.turn|param|unit": "the meaning of the value", "motors.Motor.turn|param|value": "the move quantity, eg: 2", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 4e152d05..4a8cd96c 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -40,15 +40,15 @@ "control.raiseEvent|block": "raise event|from %src|with value %value", "control|block": "control", "motors.Motor.count|block": "`icons.motorLarge` %motor|count", - "motors.Motor.move|block": "move `icons.motorLarge` %motor|for %value|%unit", - "motors.Motor.power|block": "power `icons.motorLarge` %motor|%on", + "motors.Motor.move|block": "move `icons.motorLarge` %motor|for %value|%unit|at %speed|%", "motors.Motor.reset|block": "reset `icons.motorLarge` %motor", "motors.Motor.setBrake|block": "set `icons.motorLarge` %motor|brake %brake", "motors.Motor.setReversed|block": "set `icons.motorLarge` %motor|reversed %reversed", + "motors.Motor.setSpeed|block": "set speed of `icons.motorLarge` %motor|to %speed|%", "motors.Motor.speed|block": "`icons.motorLarge` %motor|speed", "motors.Motor.sync|block": "sync `icons.motorLarge` %motor|with `icons.motorLarge` %follower", "motors.Motor.tachoCount|block": "`icons.motorLarge` %motor|tacho count", - "motors.Motor.turn|block": "turn `icons.motorLarge` %motor|by %value|%unit|turn %turnRadio", + "motors.Motor.turn|block": "turn `icons.motorLarge` %motor|by %value|%unit|at %speed|% turn %turnRadio", "motors.largeMotorA|block": "large A", "motors.largeMotorB|block": "large B", "motors.largeMotorC|block": "large C", diff --git a/libs/core/output.ts b/libs/core/output.ts index 902b3b93..4a0b5126 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -91,7 +91,6 @@ namespace motors { private _large: boolean; private _initialized: boolean; - private _speed: number; private _brake: boolean; private _follower: Motor; // @@ -100,7 +99,6 @@ namespace motors { this._port = port; this._large = large; this._brake = false; - this._speed = 50; } private __init() { @@ -113,18 +111,21 @@ namespace motors { } /** - * Turns the motor on or off at the current speed - * @param on true if the motor should be on + * Sets the speed of the motor. + * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 */ - //% blockId=motorPower block="power `icons.motorLarge` %motor|%on" + //% blockId=motorPower block="set speed of `icons.motorLarge` %motor|to %speed|%" //% on.fieldEditor=toggleonoff //% weight=99 blockGap=8 - power(on: boolean) { - if (!this._speed || !on) { // always stop + //% speed.min=-100 speed.max=100 + setSpeed(speed: number) { + this.__init(); + speed = Math.clamp(-100, 100, speed >> 0); + if (!speed) { // always stop this.stop(); } else { - if (this._follower) this.setSpeedSync(this._speed); - else this.setSpeedSingle(this._speed); + if (this._follower) this.setSpeedSync(speed); + else this.setSpeedSingle(speed); } } @@ -149,21 +150,21 @@ namespace motors { * @param unit the meaning of the value * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 */ - //% blockId=motorMove block="move `icons.motorLarge` %motor|for %value|%unit" + //% blockId=motorMove block="move `icons.motorLarge` %motor|for %value|%unit|at %speed|%" //% weight=98 //% speed.min=-100 speed.max=100 - move(value: number, unit: MoveUnit) { - this.output(value, unit, 0); + move(value: number, unit: MoveUnit, speed: number) { + this.output(value, unit, speed, 0); } - private output(value: number, unit: MoveUnit, turnRatio: number) { + private output(value: number, unit: MoveUnit, speed: number, turnRatio: number) { this.__init(); - if (!this._speed) { + speed = Math.clamp(-100, 100, speed >> 0); + if (!speed) { this.stop(); return; } turnRatio = Math.clamp(-200, 200, turnRatio >> 0); - let useSteps: boolean; let stepsOrTime: number; switch (unit) { @@ -185,7 +186,7 @@ namespace motors { syncMotors(this._port | this._follower._port, { useSteps: useSteps, stepsOrTime: stepsOrTime, - speed: this._speed, + speed: speed, turnRatio: turnRatio, useBrake: this._brake }) @@ -195,7 +196,7 @@ namespace motors { step1: 0, step2: stepsOrTime, step3: 0, - speed: this._speed, + speed: speed, useBrake: this._brake }) } @@ -218,6 +219,7 @@ namespace motors { //% brake.fieldEditor=toggleonoff //% weight=60 blockGap=8 setBrake(brake: boolean) { + this.__init(); this._brake = brake; } @@ -312,11 +314,11 @@ namespace motors { * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 * @param turnRatio the ratio of power sent to the follower motor, from -200 to 200 */ - //% blockId=motorTurn block="turn `icons.motorLarge` %motor|by %value|%unit|turn %turnRadio" + //% blockId=motorTurn block="turn `icons.motorLarge` %motor|by %value|%unit|at %speed|% turn %turnRadio" //% weight=9 blockGap=8 //% turnRatio.min=-200 turnRatio=200 - turn(value: number, unit: MoveUnit, turnRatio: number) { - this.output(value, unit, turnRatio); + turn(value: number, unit: MoveUnit, speed: number, turnRatio: number) { + this.output(value, unit, speed, turnRatio); } } From 11a88a9d944625376ce16ed4f7f703af9b7663a4 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Wed, 13 Dec 2017 23:00:37 -0800 Subject: [PATCH 5/9] updated signatures --- libs/core/_locales/core-jsdoc-strings.json | 2 +- libs/core/output.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 25e0f3b5..a496592b 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -68,7 +68,7 @@ "motors.Motor.tachoCount": "Gets motor tacho count.", "motors.Motor.turn": "Turns the motor and the follower motor by a number of rotations", "motors.Motor.turn|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", - "motors.Motor.turn|param|turnRatio": "the ratio of power sent to the follower motor, from -200 to 200", + "motors.Motor.turn|param|turnRatio": "the ratio of power sent to the follower motor, from ``-200`` to ``200``", "motors.Motor.turn|param|unit": "the meaning of the value", "motors.Motor.turn|param|value": "the move quantity, eg: 2", "motors.stopAllMotors": "Stops all motors", diff --git a/libs/core/output.ts b/libs/core/output.ts index 4a0b5126..9b7fd2c0 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -312,7 +312,7 @@ namespace motors { * @param value the move quantity, eg: 2 * @param unit the meaning of the value * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 - * @param turnRatio the ratio of power sent to the follower motor, from -200 to 200 + * @param turnRatio the ratio of power sent to the follower motor, from ``-200`` to ``200`` */ //% blockId=motorTurn block="turn `icons.motorLarge` %motor|by %value|%unit|at %speed|% turn %turnRadio" //% weight=9 blockGap=8 From 81fcbb69164e92779779c12847664b36c4722319 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Thu, 14 Dec 2017 13:07:10 -0800 Subject: [PATCH 6/9] tweaks of blocks --- libs/core/_locales/core-strings.json | 2 +- libs/core/output.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index 4a8cd96c..bf557bb5 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -57,7 +57,7 @@ "motors.mediumMotorB|block": "medium B", "motors.mediumMotorC|block": "medium C", "motors.mediumMotorD|block": "medium D", - "motors.stopAllMotors|block": "stop all `icons.motorLarge`", + "motors.stopAllMotors|block": "stop all motors", "motors|block": "motors", "output|block": "output", "screen|block": "screen", diff --git a/libs/core/output.ts b/libs/core/output.ts index 9b7fd2c0..f95b6a33 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -78,8 +78,8 @@ namespace motors { /** * Stops all motors */ - //% blockId=motorStopAll block="stop all `icons.motorLarge`" - //% weight=10 blockGap=8 + //% blockId=motorStopAll block="stop all motors" + //% weight=19 export function stopAllMotors() { const b = mkCmd(Output.ALL, DAL.opOutputStop, 0) writePWM(b) @@ -272,6 +272,7 @@ namespace motors { /** * Clears the motor count */ + //% clearCount() { this.__init(); const b = mkCmd(this._port, DAL.opOutputClearCount, 0) @@ -287,12 +288,12 @@ namespace motors { * Resets the motor and clears any synchronization */ //% blockId=motorReset block="reset `icons.motorLarge` %motor" - //% weight=1 + //% weight=20 reset() { this.__init(); reset(this._port); delete this._follower; - } + } /** * Synchronizes a follower motor to this motor @@ -317,6 +318,7 @@ namespace motors { //% blockId=motorTurn block="turn `icons.motorLarge` %motor|by %value|%unit|at %speed|% turn %turnRadio" //% weight=9 blockGap=8 //% turnRatio.min=-200 turnRatio=200 + //% inlineInputMode=inline turn(value: number, unit: MoveUnit, speed: number, turnRatio: number) { this.output(value, unit, speed, turnRatio); } From 124d8a0fd83fc581688a40a4dc952f50b4f7fe3f Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Thu, 14 Dec 2017 13:25:27 -0800 Subject: [PATCH 7/9] tank support --- libs/core/_locales/core-jsdoc-strings.json | 13 ++++---- libs/core/_locales/core-strings.json | 3 +- libs/core/output.ts | 35 ++++++++++++++++++---- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index a496592b..45879b14 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -53,6 +53,14 @@ "motors.Motor.clearCount": "Clears the motor count", "motors.Motor.count": "Gets motor step count.", "motors.Motor.move": "Moves the motor by a number of rotations, degress or seconds", + "motors.Motor.moveSteering": "Turns the motor and the follower motor by a number of rotations", + "motors.Motor.moveSteering|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", + "motors.Motor.moveSteering|param|steering": "the ratio of power sent to the follower motor, from ``-100`` to ``100``", + "motors.Motor.moveSteering|param|unit": "the meaning of the value", + "motors.Motor.moveSteering|param|value": "the move quantity, eg: 2", + "motors.Motor.moveTank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.", + "motors.Motor.moveTank|param|unit": "@param speedLeft ", + "motors.Motor.moveTank|param|value": "the amount of movement, eg: 2", "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|value": "the move quantity, eg: 2", @@ -66,11 +74,6 @@ "motors.Motor.sync": "Synchronizes a follower motor to this motor", "motors.Motor.sync|param|follower": "the motor that follows this motor commands, eg: motors.largeC", "motors.Motor.tachoCount": "Gets motor tacho count.", - "motors.Motor.turn": "Turns the motor and the follower motor by a number of rotations", - "motors.Motor.turn|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", - "motors.Motor.turn|param|turnRatio": "the ratio of power sent to the follower motor, from ``-200`` to ``200``", - "motors.Motor.turn|param|unit": "the meaning of the value", - "motors.Motor.turn|param|value": "the move quantity, eg: 2", "motors.stopAllMotors": "Stops all motors", "output.createBuffer": "Create a new zero-initialized buffer.", "output.createBuffer|param|size": "number of bytes in the buffer", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index bf557bb5..a2f44b08 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -40,6 +40,8 @@ "control.raiseEvent|block": "raise event|from %src|with value %value", "control|block": "control", "motors.Motor.count|block": "`icons.motorLarge` %motor|count", + "motors.Motor.moveSteering|block": "move steering `icons.motorLarge` %motor|at %speed|%|steer %turnRadio|%|by %value|%unit", + "motors.Motor.moveTank|block": "move tank `icons.motorLarge` %motor|left %speedLeft|%|right %speedRight|%|by %value|%unit", "motors.Motor.move|block": "move `icons.motorLarge` %motor|for %value|%unit|at %speed|%", "motors.Motor.reset|block": "reset `icons.motorLarge` %motor", "motors.Motor.setBrake|block": "set `icons.motorLarge` %motor|brake %brake", @@ -48,7 +50,6 @@ "motors.Motor.speed|block": "`icons.motorLarge` %motor|speed", "motors.Motor.sync|block": "sync `icons.motorLarge` %motor|with `icons.motorLarge` %follower", "motors.Motor.tachoCount|block": "`icons.motorLarge` %motor|tacho count", - "motors.Motor.turn|block": "turn `icons.motorLarge` %motor|by %value|%unit|at %speed|% turn %turnRadio", "motors.largeMotorA|block": "large A", "motors.largeMotorB|block": "large B", "motors.largeMotorC|block": "large C", diff --git a/libs/core/output.ts b/libs/core/output.ts index f95b6a33..1255a52a 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -313,15 +313,38 @@ namespace motors { * @param value the move quantity, eg: 2 * @param unit the meaning of the value * @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50 - * @param turnRatio the ratio of power sent to the follower motor, from ``-200`` to ``200`` + * @param steering the ratio of power sent to the follower motor, from ``-100`` to ``100`` */ - //% blockId=motorTurn block="turn `icons.motorLarge` %motor|by %value|%unit|at %speed|% turn %turnRadio" + //% blockId=motorTurn block="move steering `icons.motorLarge` %motor|at %speed|%|steer %turnRadio|%|by %value|%unit" //% weight=9 blockGap=8 - //% turnRatio.min=-200 turnRatio=200 + //% steering.min=-100 steering=100 //% inlineInputMode=inline - turn(value: number, unit: MoveUnit, speed: number, turnRatio: number) { - this.output(value, unit, speed, turnRatio); - } + moveSteering(steering: number, speed: number, value: number, unit: MoveUnit) { + this.output(value, unit, speed, steering + 100); + } + + /** + * 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, + * with one motor driving the left side of the vehicle and the other the right side. + * You can make the two motors go at different speeds or in different directions + * to make your robot turn. + * @param value the amount of movement, eg: 2 + * @param unit + * @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" + //% weight=9 blockGap=8 + //% speedLeft.min=-100 speedLeft=100 + //% speedRight.min=-100 speedRight=100 + //% inlineInputMode=inline + 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; + this.moveSteering(speedLeft, steering, value, unit); + } } //% whenUsed fixedInstance block="large A" From 9dedbeae1b341467dd718bb23306660b5092336a Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Thu, 14 Dec 2017 13:26:04 -0800 Subject: [PATCH 8/9] updated parameters --- libs/core/_locales/core-jsdoc-strings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 45879b14..dfe9c5e8 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -59,7 +59,8 @@ "motors.Motor.moveSteering|param|unit": "the meaning of the value", "motors.Motor.moveSteering|param|value": "the move quantity, eg: 2", "motors.Motor.moveTank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.", - "motors.Motor.moveTank|param|unit": "@param speedLeft ", + "motors.Motor.moveTank|param|speedRight": "the speed on the right motor, eg: 50", + "motors.Motor.moveTank|param|unit": "@param speedLeft the speed on the left motor, eg: 50", "motors.Motor.moveTank|param|value": "the amount of movement, eg: 2", "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", From fcdc350e4027b143aa1290941b267f6449d07b45 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Thu, 14 Dec 2017 17:01:23 -0800 Subject: [PATCH 9/9] more motor work --- libs/core/_locales/core-jsdoc-strings.json | 27 +-- libs/core/_locales/core-strings.json | 35 +-- libs/core/ns.ts | 8 - libs/core/output.ts | 238 ++++++++++++++------- libs/ev3/ns.ts | 4 +- 5 files changed, 197 insertions(+), 115 deletions(-) diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index dfe9c5e8..b3dc1c6d 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -53,28 +53,31 @@ "motors.Motor.clearCount": "Clears the motor count", "motors.Motor.count": "Gets motor step count.", "motors.Motor.move": "Moves the motor by a number of rotations, degress or seconds", - "motors.Motor.moveSteering": "Turns the motor and the follower motor by a number of rotations", - "motors.Motor.moveSteering|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", - "motors.Motor.moveSteering|param|steering": "the ratio of power sent to the follower motor, from ``-100`` to ``100``", - "motors.Motor.moveSteering|param|unit": "the meaning of the value", - "motors.Motor.moveSteering|param|value": "the move quantity, eg: 2", - "motors.Motor.moveTank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.", - "motors.Motor.moveTank|param|speedRight": "the speed on the right motor, eg: 50", - "motors.Motor.moveTank|param|unit": "@param speedLeft the speed on the left motor, eg: 50", - "motors.Motor.moveTank|param|value": "the amount of movement, eg: 2", "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|value": "the move quantity, eg: 2", - "motors.Motor.reset": "Resets the motor and clears any synchronization", + "motors.Motor.port": "Gets the port where this motor is connected", + "motors.Motor.reset": "Resets the motor.", "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.setReversed": "Reverses the motor polarity", "motors.Motor.setSpeed": "Sets the speed of the motor.", "motors.Motor.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", "motors.Motor.speed": "Gets motor actual speed.", - "motors.Motor.sync": "Synchronizes a follower motor to this motor", - "motors.Motor.sync|param|follower": "the motor that follows this motor commands, eg: motors.largeC", "motors.Motor.tachoCount": "Gets motor tacho count.", + "motors.SynchedMotorPair.moveSteering": "Turns the motor and the follower motor by a number of rotations", + "motors.SynchedMotorPair.moveSteering|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", + "motors.SynchedMotorPair.moveSteering|param|steering": "the ratio of power sent to the follower motor, from ``-100`` to ``100``", + "motors.SynchedMotorPair.moveSteering|param|unit": "the meaning of the value", + "motors.SynchedMotorPair.moveSteering|param|value": "the move quantity, eg: 2", + "motors.SynchedMotorPair.moveTank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.", + "motors.SynchedMotorPair.moveTank|param|speedRight": "the speed on the right motor, eg: 50", + "motors.SynchedMotorPair.moveTank|param|unit": "@param speedLeft the speed on the left motor, eg: 50", + "motors.SynchedMotorPair.moveTank|param|value": "the amount of movement, eg: 2", + "motors.SynchedMotorPair.setBrake": "Sets the automatic brake on or off when the motor is off", + "motors.SynchedMotorPair.setBrake|param|brake": "a value indicating if the motor should break when off", + "motors.SynchedMotorPair.setSpeed": "Sets the speed of the motor.", + "motors.SynchedMotorPair.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50", "motors.stopAllMotors": "Stops all motors", "output.createBuffer": "Create a new zero-initialized buffer.", "output.createBuffer|param|size": "number of bytes in the buffer", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index a2f44b08..4fc48b38 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -15,10 +15,13 @@ "MoveUnit.Degrees|block": "degrees", "MoveUnit.Rotations|block": "rotations", "MoveUnit.Seconds|block": "seconds", + "Output.AB|block": "A+B", + "Output.AD|block": "A+D", "Output.ALL|block": "All", "Output.A|block": "A", "Output.BC|block": "B+C", "Output.B|block": "B", + "Output.CD|block": "C+D", "Output.C|block": "C", "Output.D|block": "D", "brick.Button.isPressed|block": "`icons.brickButtons` %button|is pressed", @@ -40,24 +43,29 @@ "control.raiseEvent|block": "raise event|from %src|with value %value", "control|block": "control", "motors.Motor.count|block": "`icons.motorLarge` %motor|count", - "motors.Motor.moveSteering|block": "move steering `icons.motorLarge` %motor|at %speed|%|steer %turnRadio|%|by %value|%unit", - "motors.Motor.moveTank|block": "move tank `icons.motorLarge` %motor|left %speedLeft|%|right %speedRight|%|by %value|%unit", "motors.Motor.move|block": "move `icons.motorLarge` %motor|for %value|%unit|at %speed|%", "motors.Motor.reset|block": "reset `icons.motorLarge` %motor", "motors.Motor.setBrake|block": "set `icons.motorLarge` %motor|brake %brake", "motors.Motor.setReversed|block": "set `icons.motorLarge` %motor|reversed %reversed", "motors.Motor.setSpeed|block": "set speed of `icons.motorLarge` %motor|to %speed|%", "motors.Motor.speed|block": "`icons.motorLarge` %motor|speed", - "motors.Motor.sync|block": "sync `icons.motorLarge` %motor|with `icons.motorLarge` %follower", "motors.Motor.tachoCount|block": "`icons.motorLarge` %motor|tacho count", - "motors.largeMotorA|block": "large A", - "motors.largeMotorB|block": "large B", - "motors.largeMotorC|block": "large C", - "motors.largeMotorD|block": "large D", - "motors.mediumMotorA|block": "medium A", - "motors.mediumMotorB|block": "medium B", - "motors.mediumMotorC|block": "medium C", - "motors.mediumMotorD|block": "medium D", + "motors.SynchedMotorPair.moveSteering|block": "move steering %chassis|at %speed|%|steer %turnRadio|%|by %value|%unit", + "motors.SynchedMotorPair.moveTank|block": "move tank %chassis|left %speedLeft|%|right %speedRight|%|by %value|%unit", + "motors.SynchedMotorPair.setBrake|block": "set `icons.motorLarge` %chassis|brake %brake", + "motors.SynchedMotorPair.setSpeed|block": "set speed of `icons.motorLarge` %motor|to %speed|%", + "motors.largeAB|block": "large A+B", + "motors.largeAD|block": "large A+D", + "motors.largeA|block": "large A", + "motors.largeBC|block": "large B+C", + "motors.largeB|block": "large B", + "motors.largeCD|block": "large C+D", + "motors.largeC|block": "large C", + "motors.largeD|block": "large D", + "motors.mediumA|block": "medium A", + "motors.mediumB|block": "medium B", + "motors.mediumC|block": "medium C", + "motors.mediumD|block": "medium D", "motors.stopAllMotors|block": "stop all motors", "motors|block": "motors", "output|block": "output", @@ -73,6 +81,9 @@ "{id:category}Screen": "Screen", "{id:category}Serial": "Serial", "{id:group}Buttons": "Buttons", + "{id:group}Chassis": "Chassis", "{id:group}Light": "Light", - "{id:group}Screen": "Screen" + "{id:group}Motion": "Motion", + "{id:group}Screen": "Screen", + "{id:group}Sensors": "Sensors" } \ No newline at end of file diff --git a/libs/core/ns.ts b/libs/core/ns.ts index 6d583a36..8b137891 100644 --- a/libs/core/ns.ts +++ b/libs/core/ns.ts @@ -1,9 +1 @@ -//% weight=100 -namespace brick { -} - -//% color="#B4009E" weight=98 icon="\uf192" -//% groups='["Ultrasonic Sensor", "Touch Sensor", "Color Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Gyro Sensor"]' -namespace sensors { -} diff --git a/libs/core/output.ts b/libs/core/output.ts index 1255a52a..72b3526b 100644 --- a/libs/core/output.ts +++ b/libs/core/output.ts @@ -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) diff --git a/libs/ev3/ns.ts b/libs/ev3/ns.ts index 839da544..18f414f1 100644 --- a/libs/ev3/ns.ts +++ b/libs/ev3/ns.ts @@ -5,11 +5,13 @@ namespace brick { } -//% color="#C8509B" weight=95 +//% color="#C8509B" weight=95 icon="\uf192" +//% groups='["Ultrasonic Sensor", "Touch Sensor", "Color Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Gyro Sensor"]' namespace sensors { } //% color="#A5CA18" weight=90 icon="\uf185" +//% groups='["Motion", "Sensors", "Chassis"]' namespace motors { }