commit
6a4e64eac0
@ -52,17 +52,32 @@
|
|||||||
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
|
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
|
||||||
"motors.Motor.clearCount": "Clears the motor count",
|
"motors.Motor.clearCount": "Clears the motor count",
|
||||||
"motors.Motor.count": "Gets motor step count.",
|
"motors.Motor.count": "Gets motor step count.",
|
||||||
"motors.Motor.move": "Moves the motor by a number of degrees",
|
"motors.Motor.move": "Moves the motor by a number of rotations, degress or seconds",
|
||||||
"motors.Motor.move|param|angle": "the degrees to rotate, eg: 360",
|
"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.port": "Gets the port where this motor is connected",
|
||||||
"motors.Motor.reset": "Resets the motor.",
|
"motors.Motor.reset": "Resets the motor.",
|
||||||
"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",
|
||||||
"motors.Motor.setReversed": "Reverses the motor polarity",
|
"motors.Motor.setReversed": "Reverses the motor polarity",
|
||||||
"motors.Motor.setSpeed": "Sets the motor speed level from ``-100`` to ``100``.",
|
"motors.Motor.setSpeed": "Sets the speed of the motor.",
|
||||||
"motors.Motor.setSpeed|param|speed": "the power from ``100`` full forward to ``-100`` full backward, eg: 50",
|
"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.speed": "Gets motor actual speed.",
|
||||||
"motors.Motor.stop": "Stops the motor",
|
|
||||||
"motors.Motor.tachoCount": "Gets motor tacho count.",
|
"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",
|
"motors.stopAllMotors": "Stops all motors",
|
||||||
"output.createBuffer": "Create a new zero-initialized buffer.",
|
"output.createBuffer": "Create a new zero-initialized buffer.",
|
||||||
"output.createBuffer|param|size": "number of bytes in the buffer",
|
"output.createBuffer|param|size": "number of bytes in the buffer",
|
||||||
|
@ -12,9 +12,16 @@
|
|||||||
"LightsPattern.RedFlash|block": "Flashing Red",
|
"LightsPattern.RedFlash|block": "Flashing Red",
|
||||||
"LightsPattern.RedPulse|block": "Pulsing Red",
|
"LightsPattern.RedPulse|block": "Pulsing Red",
|
||||||
"LightsPattern.Red|block": "Red",
|
"LightsPattern.Red|block": "Red",
|
||||||
|
"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.ALL|block": "All",
|
||||||
"Output.A|block": "A",
|
"Output.A|block": "A",
|
||||||
|
"Output.BC|block": "B+C",
|
||||||
"Output.B|block": "B",
|
"Output.B|block": "B",
|
||||||
|
"Output.CD|block": "C+D",
|
||||||
"Output.C|block": "C",
|
"Output.C|block": "C",
|
||||||
"Output.D|block": "D",
|
"Output.D|block": "D",
|
||||||
"brick.Button.isPressed|block": "`icons.brickButtons` %button|is pressed",
|
"brick.Button.isPressed|block": "`icons.brickButtons` %button|is pressed",
|
||||||
@ -36,22 +43,30 @@
|
|||||||
"control.raiseEvent|block": "raise event|from %src|with value %value",
|
"control.raiseEvent|block": "raise event|from %src|with value %value",
|
||||||
"control|block": "control",
|
"control|block": "control",
|
||||||
"motors.Motor.count|block": "`icons.motorLarge` %motor|count",
|
"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|at %speed|%",
|
||||||
|
"motors.Motor.reset|block": "reset `icons.motorLarge` %motor",
|
||||||
"motors.Motor.setBrake|block": "set `icons.motorLarge` %motor|brake %brake",
|
"motors.Motor.setBrake|block": "set `icons.motorLarge` %motor|brake %brake",
|
||||||
"motors.Motor.setReversed|block": "set `icons.motorLarge` %motor|reversed %reversed",
|
"motors.Motor.setReversed|block": "set `icons.motorLarge` %motor|reversed %reversed",
|
||||||
"motors.Motor.setSpeed|block": "set speed `icons.motorLarge` %motor|to %speed|%",
|
"motors.Motor.setSpeed|block": "set speed of `icons.motorLarge` %motor|to %speed|%",
|
||||||
"motors.Motor.speed|block": "`icons.motorLarge` %motor|speed",
|
"motors.Motor.speed|block": "`icons.motorLarge` %motor|speed",
|
||||||
"motors.Motor.stop|block": "stop `icons.motorLarge` %motor",
|
|
||||||
"motors.Motor.tachoCount|block": "`icons.motorLarge` %motor|tacho count",
|
"motors.Motor.tachoCount|block": "`icons.motorLarge` %motor|tacho count",
|
||||||
"motors.largeMotorA|block": "large A",
|
"motors.SynchedMotorPair.moveSteering|block": "move steering %chassis|at %speed|%|steer %turnRadio|%|by %value|%unit",
|
||||||
"motors.largeMotorB|block": "large B",
|
"motors.SynchedMotorPair.moveTank|block": "move tank %chassis|left %speedLeft|%|right %speedRight|%|by %value|%unit",
|
||||||
"motors.largeMotorC|block": "large C",
|
"motors.SynchedMotorPair.setBrake|block": "set `icons.motorLarge` %chassis|brake %brake",
|
||||||
"motors.largeMotorD|block": "large D",
|
"motors.SynchedMotorPair.setSpeed|block": "set speed of `icons.motorLarge` %motor|to %speed|%",
|
||||||
"motors.mediumMotorA|block": "medium A",
|
"motors.largeAB|block": "large A+B",
|
||||||
"motors.mediumMotorB|block": "medium B",
|
"motors.largeAD|block": "large A+D",
|
||||||
"motors.mediumMotorC|block": "medium C",
|
"motors.largeA|block": "large A",
|
||||||
"motors.mediumMotorD|block": "medium D",
|
"motors.largeBC|block": "large B+C",
|
||||||
"motors.stopAllMotors|block": "stop all `icons.motorLarge`",
|
"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",
|
"motors|block": "motors",
|
||||||
"output|block": "output",
|
"output|block": "output",
|
||||||
"screen|block": "screen",
|
"screen|block": "screen",
|
||||||
@ -66,7 +81,9 @@
|
|||||||
"{id:category}Screen": "Screen",
|
"{id:category}Screen": "Screen",
|
||||||
"{id:category}Serial": "Serial",
|
"{id:category}Serial": "Serial",
|
||||||
"{id:group}Buttons": "Buttons",
|
"{id:group}Buttons": "Buttons",
|
||||||
|
"{id:group}Chassis": "Chassis",
|
||||||
"{id:group}Light": "Light",
|
"{id:group}Light": "Light",
|
||||||
"{id:group}Motors": "Motors",
|
"{id:group}Motion": "Motion",
|
||||||
"{id:group}Screen": "Screen"
|
"{id:group}Screen": "Screen",
|
||||||
|
"{id:group}Sensors": "Sensors"
|
||||||
}
|
}
|
@ -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 {
|
|
||||||
}
|
|
||||||
|
@ -7,6 +7,14 @@ enum Output {
|
|||||||
C = 0x04,
|
C = 0x04,
|
||||||
//% block="D"
|
//% block="D"
|
||||||
D = 0x08,
|
D = 0x08,
|
||||||
|
//% block="B+C"
|
||||||
|
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"
|
//% block="All"
|
||||||
ALL = 0x0f
|
ALL = 0x0f
|
||||||
}
|
}
|
||||||
@ -17,6 +25,15 @@ enum OutputType {
|
|||||||
MiniTacho = 8,
|
MiniTacho = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MoveUnit {
|
||||||
|
//% block="rotations"
|
||||||
|
Rotations,
|
||||||
|
//% block="degrees"
|
||||||
|
Degrees,
|
||||||
|
//% block="seconds"
|
||||||
|
Seconds
|
||||||
|
}
|
||||||
|
|
||||||
namespace motors {
|
namespace motors {
|
||||||
let pwmMM: MMap
|
let pwmMM: MMap
|
||||||
let motorMM: MMap
|
let motorMM: MMap
|
||||||
@ -67,8 +84,9 @@ namespace motors {
|
|||||||
/**
|
/**
|
||||||
* Stops all motors
|
* Stops all motors
|
||||||
*/
|
*/
|
||||||
//% blockId=motorStopAll block="stop all `icons.motorLarge`"
|
//% blockId=motorStopAll block="stop all motors"
|
||||||
//% weight=10 group="Motors" blockGap=8
|
//% weight=97
|
||||||
|
//% group="Motion"
|
||||||
export function stopAllMotors() {
|
export function stopAllMotors() {
|
||||||
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
|
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
@ -76,72 +94,113 @@ namespace motors {
|
|||||||
|
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class Motor extends control.Component {
|
export class Motor extends control.Component {
|
||||||
private port: Output;
|
private _port: Output;
|
||||||
private large: boolean;
|
private _large: boolean;
|
||||||
private brake: boolean;
|
|
||||||
|
private _initialized: boolean;
|
||||||
|
private _brake: boolean;
|
||||||
|
|
||||||
constructor(port: Output, large: boolean) {
|
constructor(port: Output, large: boolean) {
|
||||||
super();
|
super();
|
||||||
this.port = port;
|
this._port = port;
|
||||||
this.large = large;
|
this._large = large;
|
||||||
this.brake = false;
|
this._brake = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private __init() {
|
||||||
* Sets the motor speed level from ``-100`` to ``100``.
|
if (!this._initialized) {
|
||||||
* @param motor the output connection that the motor is connected to
|
// specify motor size on this port
|
||||||
* @param speed the power from ``100`` full forward to ``-100`` full backward, eg: 50
|
const b = mkCmd(this._port, DAL.opOutputSetType, 1)
|
||||||
*/
|
b.setNumber(NumberFormat.Int8LE, 2, this._large ? 0x07 : 0x08)
|
||||||
//% blockId=motorSetSpeed block="set speed `icons.motorLarge` %motor|to %speed|%"
|
writePWM(b)
|
||||||
//% 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) {
|
|
||||||
const b = mkCmd(this.port, DAL.opOutputStart, 0)
|
|
||||||
writePWM(b);
|
|
||||||
} else {
|
|
||||||
this.stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the motor by a number of degrees
|
* Gets the port where this motor is connected
|
||||||
* @param degrees the angle to turn the motor
|
*/
|
||||||
* @param angle the degrees to rotate, eg: 360
|
//%
|
||||||
|
//% 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
|
* @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|%"
|
//% blockId=motorSetSpeed block="set speed of `icons.motorLarge` %motor|to %speed|%"
|
||||||
//% weight=98 group="Motors" blockGap=8
|
//% on.fieldEditor=toggleonoff
|
||||||
|
//% weight=99 blockGap=8
|
||||||
//% speed.min=-100 speed.max=100
|
//% speed.min=-100 speed.max=100
|
||||||
move(angle: number, power: number) {
|
//% group="Motion"
|
||||||
angle = angle >> 0;
|
setSpeed(speed: number) {
|
||||||
power = Math.clamp(-100, 100, power >> 0);
|
this.__init();
|
||||||
|
speed = Math.clamp(-100, 100, speed >> 0);
|
||||||
|
if (!speed) { // always stop
|
||||||
|
this.stop();
|
||||||
|
} else {
|
||||||
|
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
|
||||||
|
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
||||||
|
writePWM(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
step(this.port, {
|
/**
|
||||||
speed: power,
|
* 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|for %value|%unit|at %speed|%"
|
||||||
|
//% 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);
|
||||||
|
if (!speed) {
|
||||||
|
this.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
turnRatio = Math.clamp(-200, 200, turnRatio >> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
step(this._port, {
|
||||||
|
useSteps: useSteps,
|
||||||
step1: 0,
|
step1: 0,
|
||||||
step2: angle,
|
step2: stepsOrTime,
|
||||||
step3: 0,
|
step3: 0,
|
||||||
useSteps: true,
|
speed: speed,
|
||||||
useBrake: this.brake
|
useBrake: this._brake
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the motor
|
* Stops the motor
|
||||||
*/
|
*/
|
||||||
//% blockId=motorStop block="stop `icons.motorLarge` %motor"
|
private stop() {
|
||||||
//% weight=97 group="Motors"
|
this.__init();
|
||||||
stop() {
|
stop(this._port);
|
||||||
const b = mkCmd(this.port, DAL.opOutputStop, 1)
|
|
||||||
b.setNumber(NumberFormat.UInt8LE, 2, this.brake ? 1 : 0)
|
|
||||||
writePWM(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,9 +209,11 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//% blockId=outputMotorSetBrakeMode block="set `icons.motorLarge` %motor|brake %brake"
|
//% blockId=outputMotorSetBrakeMode block="set `icons.motorLarge` %motor|brake %brake"
|
||||||
//% brake.fieldEditor=toggleonoff
|
//% brake.fieldEditor=toggleonoff
|
||||||
//% weight=60 group="Motors" blockGap=8
|
//% weight=60 blockGap=8
|
||||||
|
//% group="Motion"
|
||||||
setBrake(brake: boolean) {
|
setBrake(brake: boolean) {
|
||||||
this.brake = brake;
|
this.__init();
|
||||||
|
this._brake = brake;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,9 +221,11 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//% blockId=motorSetReversed block="set `icons.motorLarge` %motor|reversed %reversed"
|
//% blockId=motorSetReversed block="set `icons.motorLarge` %motor|reversed %reversed"
|
||||||
//% reversed.fieldEditor=toggleonoff
|
//% reversed.fieldEditor=toggleonoff
|
||||||
//% weight=59 group="Motors"
|
//% weight=59
|
||||||
|
//% group="Motion"
|
||||||
setReversed(reversed: boolean) {
|
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);
|
b.setNumber(NumberFormat.Int8LE, 2, reversed ? -1 : 1);
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
}
|
}
|
||||||
@ -172,9 +235,11 @@ namespace motors {
|
|||||||
* @param motor the port which connects to the motor
|
* @param motor the port which connects to the motor
|
||||||
*/
|
*/
|
||||||
//% blockId=motorSpeed block="`icons.motorLarge` %motor|speed"
|
//% blockId=motorSpeed block="`icons.motorLarge` %motor|speed"
|
||||||
//% weight=72 group="Motors" blockGap=8
|
//% weight=72 blockGap=8
|
||||||
|
//% group="Sensors"
|
||||||
speed(): number {
|
speed(): number {
|
||||||
return getMotorData(this.port).actualSpeed;
|
this.__init();
|
||||||
|
return getMotorData(this._port).actualSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,9 +247,11 @@ namespace motors {
|
|||||||
* @param motor the port which connects to the motor
|
* @param motor the port which connects to the motor
|
||||||
*/
|
*/
|
||||||
//% blockId=motorCount block="`icons.motorLarge` %motor|count"
|
//% blockId=motorCount block="`icons.motorLarge` %motor|count"
|
||||||
//% weight=71 group="Motors" blockGap=8
|
//% weight=71 blockGap=8
|
||||||
|
//% group="Sensors"
|
||||||
count(): number {
|
count(): number {
|
||||||
return getMotorData(this.port).count;
|
this.__init();
|
||||||
|
return getMotorData(this._port).count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,19 +259,23 @@ namespace motors {
|
|||||||
* @param motor the port which connects to the motor
|
* @param motor the port which connects to the motor
|
||||||
*/
|
*/
|
||||||
//% blockId=motorTachoCount block="`icons.motorLarge` %motor|tacho count"
|
//% blockId=motorTachoCount block="`icons.motorLarge` %motor|tacho count"
|
||||||
//% weight=70 group="Motors"
|
//% weight=70
|
||||||
|
//% group="Sensors"
|
||||||
tachoCount(): number {
|
tachoCount(): number {
|
||||||
return getMotorData(this.port).tachoCount;
|
this.__init();
|
||||||
|
return getMotorData(this._port).tachoCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the motor count
|
* Clears the motor count
|
||||||
*/
|
*/
|
||||||
|
//% group="Motion"
|
||||||
clearCount() {
|
clearCount() {
|
||||||
const b = mkCmd(this.port, DAL.opOutputClearCount, 0)
|
this.__init();
|
||||||
|
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) {
|
||||||
if (this.port & (1 << i)) {
|
if (this._port & (1 << i)) {
|
||||||
motorMM.setNumber(NumberFormat.Int32LE, i * MotorDataOff.Size + MotorDataOff.TachoSensor, 0)
|
motorMM.setNumber(NumberFormat.Int32LE, i * MotorDataOff.Size + MotorDataOff.TachoSensor, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,34 +284,166 @@ namespace motors {
|
|||||||
/**
|
/**
|
||||||
* Resets the motor.
|
* Resets the motor.
|
||||||
*/
|
*/
|
||||||
|
//% blockId=motorReset block="reset `icons.motorLarge` %motor"
|
||||||
|
//% weight=20
|
||||||
|
//% group="Motion"
|
||||||
reset() {
|
reset() {
|
||||||
reset(this.port);
|
this.__init();
|
||||||
|
reset(this._port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="large A"
|
//% whenUsed fixedInstance block="large A"
|
||||||
export const largeMotorA = new Motor(Output.A, true);
|
export const largeA = new Motor(Output.A, true);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="large B"
|
//% whenUsed fixedInstance block="large B"
|
||||||
export const largeMotorB = new Motor(Output.B, true);
|
export const largeB = new Motor(Output.B, true);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="large C"
|
//% whenUsed fixedInstance block="large C"
|
||||||
export const largeMotorC = new Motor(Output.C, true);
|
export const largeC = new Motor(Output.C, true);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="large D"
|
//% whenUsed fixedInstance block="large D"
|
||||||
export const largeMotorD = new Motor(Output.D, true);
|
export const largeD = new Motor(Output.D, true);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="medium A"
|
//% whenUsed fixedInstance block="medium A"
|
||||||
export const mediumMotorA = new Motor(Output.A, false);
|
export const mediumA = new Motor(Output.A, false);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="medium B"
|
//% whenUsed fixedInstance block="medium B"
|
||||||
export const mediumMotorB = new Motor(Output.B, false);
|
export const mediumB = new Motor(Output.B, false);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="medium C"
|
//% whenUsed fixedInstance block="medium C"
|
||||||
export const mediumMotorC = new Motor(Output.C, false);
|
export const mediumC = new Motor(Output.C, false);
|
||||||
|
|
||||||
//% whenUsed fixedInstance block="medium D"
|
//% whenUsed fixedInstance block="medium D"
|
||||||
export const mediumMotorD = new Motor(Output.D, false);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the speed of the motor.
|
||||||
|
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
||||||
|
*/
|
||||||
|
//% 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 steering the ratio of power sent to the follower motor, from ``-100`` to ``100``
|
||||||
|
*/
|
||||||
|
//% 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) {
|
||||||
|
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,
|
||||||
|
* 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=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;
|
||||||
|
this.moveSteering(speedLeft, steering, value, unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//% whenUsed fixedInstance block="large B+C"
|
||||||
|
export const largeBC = new SynchedMotorPair(Output.BC);
|
||||||
|
|
||||||
|
//% whenUsed fixedInstance block="large A+D"
|
||||||
|
export const largeAD = new SynchedMotorPair(Output.AD);
|
||||||
|
|
||||||
|
//% whenUsed fixedInstance block="large A+B"
|
||||||
|
export const largeAB = new SynchedMotorPair(Output.AB);
|
||||||
|
|
||||||
|
//% whenUsed fixedInstance block="large C+D"
|
||||||
|
export const largeCD = new SynchedMotorPair(Output.CD);
|
||||||
|
|
||||||
function reset(out: Output) {
|
function reset(out: Output) {
|
||||||
let b = mkCmd(out, DAL.opOutputReset, 0)
|
let b = mkCmd(out, DAL.opOutputReset, 0)
|
||||||
@ -272,6 +475,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 {
|
interface StepOptions {
|
||||||
power?: number;
|
power?: number;
|
||||||
speed?: number; // either speed or power has to be present
|
speed?: number; // either speed or power has to be present
|
||||||
@ -282,6 +508,17 @@ namespace motors {
|
|||||||
useBrake?: boolean;
|
useBrake?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function start(out: Output) {
|
||||||
|
const b = mkCmd(out, DAL.opOutputStart, 0)
|
||||||
|
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) {
|
function step(out: Output, opts: StepOptions) {
|
||||||
let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed
|
let op = opts.useSteps ? DAL.opOutputStepSpeed : DAL.opOutputTimeSpeed
|
||||||
let speed = opts.speed
|
let speed = opts.speed
|
||||||
|
@ -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 {
|
namespace sensors {
|
||||||
}
|
}
|
||||||
|
|
||||||
//% color="#A5CA18" weight=90 icon="\uf185"
|
//% color="#A5CA18" weight=90 icon="\uf185"
|
||||||
|
//% groups='["Motion", "Sensors", "Chassis"]'
|
||||||
namespace motors {
|
namespace motors {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user