Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
83793fc668 | |||
47ee87fe72 | |||
374fa36548 | |||
358ef7e19f |
@ -5,7 +5,7 @@
|
||||
This repo contains the editor target hosted at https://d541eec2-1e96-4b7b-a223-da9d01d0337a.pxt.io/
|
||||
|
||||
LEGO Auth: https://src.education.lego.com/groups/ev3-makecode (use Google Authenticator)
|
||||
LEGO Chat: https://chat.internal.education.lego.com/make-code/channels/town-square
|
||||
LEGO Chat: https://chat.internal.education.lego.com/make-code/channels/town-square
|
||||
|
||||
## Local Dev setup
|
||||
|
||||
|
@ -1,43 +1,5 @@
|
||||
# @extends
|
||||
|
||||
## Projects #projects
|
||||
|
||||
* [Maker](/maker)
|
||||
* [Sound Machine](/maker/sound-machine)
|
||||
* [Sound of Color](/maker/sound-of-color)
|
||||
* [Security Gadget](/maker/security-gadget)
|
||||
* [Intruder detector](/maker/intruder-detector)
|
||||
* [Puppet](/maker/puppet)
|
||||
|
||||
* [Coding](/coding)
|
||||
* [Three Point Turn 1](/coding/three-point-turn-1)
|
||||
* [Three Point Turn 2](/coding/three-point-turn-2)
|
||||
* [Three Point Turn 3](/coding/three-point-turn-3)
|
||||
* [Reversing the robot 1](/coding/reversing-the-robot-1)
|
||||
* [Reversing the robot 2](/coding/reversing-the-robot-2)
|
||||
* [Reversing the robot 3](/coding/reversing-the-robot-3)
|
||||
* [Light the way 1](/coding/light-the-way-1)
|
||||
* [Light the way 2](/coding/light-the-way-2)
|
||||
* [Light the way 3](/coding/light-the-way-3)
|
||||
* [Traffic Lights 1](/coding/traffic-lights-1)
|
||||
* [Traffic Lights 2](/coding/traffic-lights-2)
|
||||
* [Traffic Lights 3](/coding/traffic-lights-3)
|
||||
* [Reverse Beeper 1](/coding/reverse-beeper-1)
|
||||
* [Reverse Beeper 2](/coding/reverse-beeper-2)
|
||||
* [Reverse Beeper 3](/coding/reverse-beeper-3)
|
||||
* [Ignition 1](/coding/ignition-1)
|
||||
* [Ignition 2](/coding/ignition-2)
|
||||
* [Ignition 3](/coding/ignition-3)
|
||||
* [Cruise Control 1](/coding/cruise-control-1)
|
||||
* [Cruise Control 2](/coding/cruise-control-2)
|
||||
* [Cruise Control 3](/coding/cruise-control-3)
|
||||
* [Roaming 1](/coding/roaming-1)
|
||||
* [Roaming 2](/coding/roaming-2)
|
||||
|
||||
* [Lessons](/lessons)
|
||||
* [Make it move](/lessons/make-it-move)
|
||||
* [Line detection](/lessons/line-detection)
|
||||
|
||||
## Reference #reference
|
||||
|
||||
* [Reference](/reference)
|
||||
|
@ -6,14 +6,14 @@ Welcome to the **Microsoft MakeCode** editor for the **@boardname@**!
|
||||
|
||||
You can program the @boardname@ using [Blocks](/blocks) or [JavaScript](/javascript) in your web browser:
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Click, () => {
|
||||
motors.largeA.setSpeed(50)
|
||||
```block
|
||||
input.buttonA.onEvent(ButtonEvent.Click, () => {
|
||||
light.showRing(`blue blue blue blue blue blue blue blue blue blue`)
|
||||
})
|
||||
```
|
||||
```typescript
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Click, () => {
|
||||
motors.largeA.setSpeed(50)
|
||||
input.buttonA.onEvent(ButtonEvent.Click, () => {
|
||||
light.showRing(`blue blue blue blue blue blue blue blue blue blue`)
|
||||
})
|
||||
```
|
||||
|
||||
@ -22,10 +22,10 @@ The editor work in [most modern browsers](/browsers), work [offline](/offline) o
|
||||
## [Compile and Flash: Your Program!](/device/usb)
|
||||
|
||||
When you have your code ready, you connect your @boardname@ to a computer via a USB cable
|
||||
so it appears as a mounted drive (named **EV3**).
|
||||
**then press the reset button** so it appears as a mounted drive (named **CPLAYBOOT**).
|
||||
|
||||
Compilation to machine code from [Blocks](/blocks) or [JavaScript](/javascript) happens in the browser. You save the binary
|
||||
program to a **.uf2** file, which you then copy to the **EV3** drive, which flashes the device with the new program.
|
||||
program to a **.uf2** file, which you then copy to the **CPLAYBOOT** drive, which flashes the device with the new program.
|
||||
|
||||
## Simulator: Test Your Code
|
||||
|
||||
@ -33,7 +33,11 @@ You can run your code using the micro:bit simulator, all within the confines of
|
||||
The simulator has support for the LED screen, buttons, as well as compass, accelerometer, and digital I/O pins.
|
||||
|
||||
```sim
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Click, () => {
|
||||
motors.largeA.setSpeed(50)
|
||||
loops.forever(() => {
|
||||
light.pixels.showAnimation(light.animation(LightAnimation.Rainbow), 1000)
|
||||
})
|
||||
```
|
||||
|
||||
```package
|
||||
light
|
||||
```
|
||||
|
@ -14,7 +14,7 @@ function accelerate() {
|
||||
}
|
||||
function update() {
|
||||
brick.clearScreen()
|
||||
brick.showString("speed: " + speed, 1)
|
||||
brick.printLine("speed: " + speed, 1)
|
||||
motors.largeBC.setSpeed(speed)
|
||||
}
|
||||
sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () {
|
||||
|
@ -7,5 +7,5 @@ loops.forever(function () {
|
||||
})
|
||||
motors.largeBC.setSpeed(-20);
|
||||
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
|
||||
motors.largeBC.stop();
|
||||
motors.stopAllMotors();
|
||||
```
|
||||
|
@ -9,5 +9,5 @@ loops.forever(function () {
|
||||
})
|
||||
motors.largeBC.setSpeed(-20);
|
||||
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
|
||||
motors.largeBC.stop();
|
||||
motors.stopAllMotors();
|
||||
```
|
||||
|
@ -3,13 +3,14 @@
|
||||
```blocks
|
||||
let beep = false
|
||||
beep = true
|
||||
control.runInParallel(function () {
|
||||
motors.largeBC.setSpeed(-20)
|
||||
control.runInBackground(function () {
|
||||
motors.largeB.setSpeed(-20)
|
||||
motors.largeC.setSpeed(-20)
|
||||
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear)
|
||||
motors.largeBC.stop()
|
||||
motors.stopAllMotors()
|
||||
beep = false
|
||||
})
|
||||
control.runInParallel(function () {
|
||||
control.runInBackground(function () {
|
||||
while (beep) {
|
||||
if (sensors.ultrasonic4.distance() < 20) {
|
||||
music.playTone(440, sensors.ultrasonic4.distance())
|
||||
|
@ -3,10 +3,10 @@
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||
motors.largeBC.setSpeed(50)
|
||||
sensors.touch1.pauseUntil(TouchSensorEvent.Pressed)
|
||||
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
|
||||
motors.largeBC.setSpeed(0)
|
||||
loops.pause(1000)
|
||||
brick.setLight(BrickLight.OrangeFlash)
|
||||
brick.setLight(LightsPattern.OrangeFlash)
|
||||
motors.largeBC.setSpeed(-50)
|
||||
loops.pause(2000)
|
||||
motors.largeBC.setSpeed(0)
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||
sensors.touch1.pauseUntil(TouchSensorEvent.Pressed)
|
||||
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
|
||||
motors.largeBC.setSpeed(50)
|
||||
sensors.touch2.pauseUntil(TouchSensorEvent.Pressed)
|
||||
sensors.touchSensor2.pauseUntil(TouchSensorEvent.Pressed)
|
||||
motors.largeBC.setSpeed(0)
|
||||
loops.pause(1000)
|
||||
brick.setLight(BrickLight.OrangeFlash)
|
||||
brick.setLight(LightsPattern.OrangeFlash)
|
||||
motors.largeBC.setSpeed(-50)
|
||||
loops.pause(2000)
|
||||
motors.largeBC.setSpeed(0)
|
||||
|
@ -3,14 +3,14 @@
|
||||
```blocks
|
||||
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||
brick.showImage(images.eyesSleeping)
|
||||
sensors.touch1.pauseUntil(TouchSensorEvent.Pressed)
|
||||
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
|
||||
brick.showImage(images.eyesNeutral)
|
||||
motors.largeBC.setSpeed(50)
|
||||
sensors.touch2.pauseUntil(TouchSensorEvent.Pressed)
|
||||
sensors.touchSensor2.pauseUntil(TouchSensorEvent.Pressed)
|
||||
brick.showImage(images.eyesTiredMiddle)
|
||||
motors.largeBC.setSpeed(0)
|
||||
loops.pause(1000)
|
||||
brick.setLight(BrickLight.OrangeFlash)
|
||||
brick.setLight(LightsPattern.OrangeFlash)
|
||||
brick.showImage(images.eyesDizzy)
|
||||
motors.largeBC.setSpeed(-50)
|
||||
loops.pause(2000)
|
||||
|
@ -19,13 +19,17 @@ loops.pause(1000)
|
||||
music.playSoundEffectUntilDone(sounds.communicationGo)
|
||||
for (let d of drive) {
|
||||
if (d == 1) {
|
||||
motors.largeC.setSpeed(50, 360, MoveUnit.Degrees)
|
||||
motors.largeC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||
motors.largeC.pauseUntilReady()
|
||||
} else if (d == 3) {
|
||||
motors.largeB.setSpeed(50, 360, MoveUnit.Degrees)
|
||||
motors.largeB.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||
motors.largeB.pauseUntilReady()
|
||||
} else if (d == 4) {
|
||||
motors.largeBC.setSpeed(50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.pauseUntilReady()
|
||||
} else {
|
||||
motors.largeBC.setSpeed(-50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.setSpeedFor(-50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.pauseUntilReady()
|
||||
}
|
||||
}
|
||||
music.playSoundEffectUntilDone(sounds.communicationGameOver)
|
||||
|
@ -23,13 +23,17 @@ loops.pause(1000)
|
||||
music.playSoundEffectUntilDone(sounds.communicationGo)
|
||||
for (let d of drive) {
|
||||
if (d == 1) {
|
||||
motors.largeC.setSpeed(50, 360, MoveUnit.Degrees)
|
||||
motors.largeC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||
motors.largeC.pauseUntilReady()
|
||||
} else if (d == 3) {
|
||||
motors.largeB.setSpeed(50, 360, MoveUnit.Degrees)
|
||||
motors.largeB.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||
motors.largeB.pauseUntilReady()
|
||||
} else if (d == 4) {
|
||||
motors.largeBC.setSpeed(50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.pauseUntilReady()
|
||||
} else {
|
||||
motors.largeBC.setSpeed(-50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.setSpeedFor(-50, 360, MoveUnit.Degrees)
|
||||
motors.largeBC.pauseUntilReady()
|
||||
}
|
||||
}
|
||||
music.playSoundEffectUntilDone(sounds.communicationGameOver)
|
||||
|
@ -1,178 +0,0 @@
|
||||
# Gyroboy
|
||||
|
||||
Work in progress
|
||||
|
||||
```blocks
|
||||
let motorSpeed1 = 0
|
||||
let motorSpeed2 = 0
|
||||
let motorSpeed3 = 0
|
||||
let motorSpeed = 0
|
||||
let fallen = false
|
||||
let motorSpeed0 = 0
|
||||
let oldControlDrive = 0
|
||||
let controlDrive = 0
|
||||
let power = 0
|
||||
let motorAngle = 0
|
||||
let gyroAngle = 0
|
||||
let controlSteering = 0
|
||||
let state = 0
|
||||
let motorPosition = 0
|
||||
let temp = 0
|
||||
let gyroRate = 0
|
||||
let timestep = 0
|
||||
sensors.color1.onColorDetected(ColorSensorColor.Red, function () {
|
||||
music.playTone(2000, 100)
|
||||
controlDrive = 0
|
||||
controlSteering = 0
|
||||
})
|
||||
// reads the motor angle and computes the motor speed,
|
||||
// position
|
||||
function computeMotors() {
|
||||
temp = motorAngle
|
||||
// read angle on both motors
|
||||
motorAngle = motors.largeD.angle() + motors.largeA.angle()
|
||||
// and estimate speed as angle difference
|
||||
motorSpeed0 = motorAngle - temp
|
||||
// average last 4 speed readings
|
||||
motorSpeed = (motorSpeed0 + motorSpeed1 + motorSpeed2 + motorSpeed3) / 4 / timestep
|
||||
// shift all previous recorded speeds by one
|
||||
motorSpeed3 = motorSpeed2
|
||||
motorSpeed2 = motorSpeed1
|
||||
motorSpeed1 = motorSpeed0
|
||||
// compute position from speed
|
||||
motorPosition = motorPosition + timestep * motorSpeed
|
||||
}
|
||||
// read the gyro rate and computes the angle
|
||||
function computeGyro() {
|
||||
gyroRate = sensors.gyro2.rate()
|
||||
gyroAngle = gyroAngle + timestep * gyroRate
|
||||
}
|
||||
function reset() {
|
||||
state = 0
|
||||
// sleeping
|
||||
moods.sleeping.show();
|
||||
// reset counters
|
||||
motors.largeA.reset()
|
||||
motors.largeD.reset()
|
||||
// motors are unregulated
|
||||
motors.largeA.setRegulated(false)
|
||||
motors.largeD.setRegulated(false)
|
||||
// clear the gyro sensor to remove drift
|
||||
sensors.gyro2.reset()
|
||||
// fall detection timer
|
||||
control.timer2.reset()
|
||||
// timestep computation timer
|
||||
control.timer3.reset()
|
||||
motorAngle = 0
|
||||
motorPosition = 0
|
||||
motorSpeed = 0
|
||||
motorSpeed0 = 0
|
||||
motorSpeed1 = 0
|
||||
motorSpeed2 = 0
|
||||
motorSpeed3 = 0
|
||||
gyroRate = 0
|
||||
gyroAngle = 0
|
||||
fallen = false
|
||||
power = 0
|
||||
controlSteering = 0
|
||||
controlDrive = 0
|
||||
// awake
|
||||
moods.awake.show();
|
||||
gyroAngle = -0.25
|
||||
state = 1;
|
||||
}
|
||||
// compute set point for motor position and required
|
||||
// motor power
|
||||
function computePower() {
|
||||
// apply control and compute desired motor position
|
||||
motorPosition -= timestep * controlDrive;
|
||||
// estimate power based on sensor readings and control
|
||||
// values
|
||||
power = 0.8 * gyroRate + 15 * gyroAngle + (0.08 * motorSpeed + 0.12 * motorPosition) - 0.01 * controlDrive
|
||||
// ensure that power stays within -100, 100
|
||||
if (power > 100) {
|
||||
power = 100
|
||||
} else if (power < -100) {
|
||||
power = -100
|
||||
}
|
||||
}
|
||||
// test if the robot has fallen off
|
||||
function checkFallen() {
|
||||
if (Math.abs(power) < 100) {
|
||||
control.timer2.reset()
|
||||
}
|
||||
if (control.timer2.seconds() > 2) {
|
||||
fallen = true
|
||||
}
|
||||
}
|
||||
// stop all motors and wait for touch button to be
|
||||
// pressed
|
||||
function stop() {
|
||||
motors.stopAllMotors()
|
||||
state = 0
|
||||
moods.knockedOut.show();
|
||||
sensors.touch3.pauseUntil(TouchSensorEvent.Pressed)
|
||||
moods.neutral.show();
|
||||
}
|
||||
sensors.ultrasonic4.onEvent(UltrasonicSensorEvent.ObjectNear, function () {
|
||||
moods.dizzy.show()
|
||||
controlSteering = 0
|
||||
oldControlDrive = controlDrive
|
||||
controlDrive = -10
|
||||
motors.mediumC.setSpeed(30, 30, MoveUnit.Degrees);
|
||||
motors.mediumC.setSpeed(-30, 60, MoveUnit.Degrees);
|
||||
motors.mediumC.setSpeed(30, 30, MoveUnit.Degrees);
|
||||
if (Math.randomRange(-1, 1) >= 1) {
|
||||
controlSteering = 70
|
||||
} else {
|
||||
controlSteering = -70
|
||||
}
|
||||
loops.pause(4000)
|
||||
music.playTone(2000, 100)
|
||||
controlSteering = 0
|
||||
controlDrive = oldControlDrive
|
||||
moods.neutral.show()
|
||||
})
|
||||
// compute the elapsed time since the last iteration
|
||||
function computeTimestep() {
|
||||
timestep = control.timer3.seconds()
|
||||
control.timer3.reset()
|
||||
}
|
||||
sensors.color1.onColorDetected(ColorSensorColor.Green, function () {
|
||||
moods.winking.show()
|
||||
controlDrive = 150
|
||||
controlSteering = 0
|
||||
})
|
||||
sensors.color1.onColorDetected(ColorSensorColor.Blue, function () {
|
||||
moods.middleRight.show()
|
||||
controlSteering = 70
|
||||
})
|
||||
// apply power to motors
|
||||
function controlMotors() {
|
||||
motors.largeA.setSpeed(power + controlSteering * 0.1)
|
||||
motors.largeD.setSpeed(power - controlSteering * 0.1)
|
||||
}
|
||||
sensors.color1.onColorDetected(ColorSensorColor.Yellow, function () {
|
||||
moods.middleLeft.show()
|
||||
controlSteering = -70
|
||||
})
|
||||
sensors.color1.onColorDetected(ColorSensorColor.White, function () {
|
||||
moods.sad.show();
|
||||
controlDrive = -75
|
||||
})
|
||||
timestep = 0.014
|
||||
// main loop
|
||||
loops.forever(function () {
|
||||
reset()
|
||||
while (!fallen) {
|
||||
control.timer3.pauseUntil(5)
|
||||
computeTimestep()
|
||||
computeGyro()
|
||||
computeMotors()
|
||||
computePower()
|
||||
controlMotors()
|
||||
checkFallen()
|
||||
}
|
||||
stop()
|
||||
})
|
||||
```
|
@ -1,215 +0,0 @@
|
||||
# Gyroboy LabView
|
||||
|
||||
```typescript
|
||||
let mSum = 0;
|
||||
let mPos = 0;
|
||||
let mSpd = 0;
|
||||
let mD = 0;
|
||||
let mDP1 = 0;
|
||||
let mDP2 = 0;
|
||||
let mDP3 = 0;
|
||||
let Crdv = 0;
|
||||
let cLo = 0;
|
||||
let gAng = 0;
|
||||
let ok = false;
|
||||
let pwr = 0;
|
||||
let Cstr = 0;
|
||||
let Cdrv = 0;
|
||||
let gMn = 0;
|
||||
let gMx = 0;
|
||||
let gSum = 0;
|
||||
let gyro = 0;
|
||||
let gOS = 0;
|
||||
let gSpd = 0;
|
||||
let tInt = 0.014;
|
||||
let lpwr = 0
|
||||
let rpwr = 0
|
||||
let tStart = 0
|
||||
let st = 0
|
||||
let oldDr = 0
|
||||
|
||||
function RST() {
|
||||
motors.largeA.reset()
|
||||
motors.largeD.reset()
|
||||
motors.largeA.setRegulated(false)
|
||||
motors.largeD.setRegulated(false)
|
||||
sensors.gyro2.reset()
|
||||
sensors.gyro2.rate()
|
||||
control.timer2.reset()
|
||||
loops.pause(5000)
|
||||
mSum = 0;
|
||||
mPos = 0;
|
||||
mD = 0;
|
||||
mDP1 = 0;
|
||||
mDP2 = 0;
|
||||
mDP3 = 0;
|
||||
Crdv = 0;
|
||||
cLo = 0;
|
||||
gAng = 0;
|
||||
ok = false;
|
||||
pwr = 0;
|
||||
st = 0;
|
||||
Cstr = 0;
|
||||
Cdrv = 0;
|
||||
}
|
||||
|
||||
function OS() {
|
||||
// OSL
|
||||
do {
|
||||
gMn = 1000;
|
||||
gMx = -100;
|
||||
gSum = 0;
|
||||
// gChk
|
||||
for (let i = 0; i < 200; i++) {
|
||||
gyro = sensors.gyro2.rate()
|
||||
gSum = gyro;
|
||||
gMx = Math.max(gMx, gyro)
|
||||
gMn = Math.min(gMn, gyro)
|
||||
loops.pause(4);
|
||||
}
|
||||
} while (gMx - gMn > 2);
|
||||
gOS = gSum / 200;
|
||||
}
|
||||
|
||||
function GT() {
|
||||
if (cLo == 0) {
|
||||
tInt = 0.014;
|
||||
control.timer1.reset();
|
||||
} else {
|
||||
tInt = control.timer1.seconds() / cLo;
|
||||
}
|
||||
cLo++;
|
||||
}
|
||||
|
||||
function GG() {
|
||||
gyro = sensors.gyro2.rate();
|
||||
gOS = 0.0005 * gyro + (1 - 0.0005) * gOS
|
||||
gSpd = gyro - gOS;
|
||||
gAng = gAng + tInt * gSpd;
|
||||
}
|
||||
|
||||
function GM() {
|
||||
let temp = mSum
|
||||
mSum = motors.largeD.angle() + motors.largeA.angle();
|
||||
mD = mSum - temp;
|
||||
mPos = mPos + mD;
|
||||
mSpd = ((mDP1 + mDP2 + mDP3 + mD) / 4) / tInt;
|
||||
mDP3 = mDP2;
|
||||
mDP2 = mDP1;
|
||||
mDP1 = mD;
|
||||
}
|
||||
|
||||
function EQ() {
|
||||
mPos = mPos - Cdrv * tInt;
|
||||
pwr = (0.8 * gSpd + 15 * gAng) + (0.08 * mSpd + 0.12 * mPos) - 0.01 * Cdrv
|
||||
if (pwr > 100) pwr = 100
|
||||
else if (pwr < -100) pwr = -100
|
||||
}
|
||||
|
||||
function cntrl() {
|
||||
mPos = mPos - tInt * Cdrv
|
||||
lpwr = (pwr + Cstr * 0.1)
|
||||
rpwr = (pwr - Cstr * 0.1)
|
||||
}
|
||||
|
||||
function CHK() {
|
||||
if (Math.abs(pwr) < 100)
|
||||
control.timer2.reset();
|
||||
if (control.timer2.seconds() > 2) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// M
|
||||
loops.forever(function () {
|
||||
RST();
|
||||
brick.showImage(images.eyesSleeping)
|
||||
OS()
|
||||
gAng = -0.25;
|
||||
music.playSoundEffect(sounds.movementsSpeedUp)
|
||||
brick.showImage(images.eyesAwake)
|
||||
st = 1;
|
||||
// BALANCE
|
||||
while (!ok) {
|
||||
GT();
|
||||
let t1 = control.timer1.millis()
|
||||
GG();
|
||||
GM();
|
||||
EQ();
|
||||
cntrl();
|
||||
motors.largeA.setSpeed(lpwr)
|
||||
motors.largeD.setSpeed(rpwr)
|
||||
CHK()
|
||||
let t2 = control.timer1.millis();
|
||||
let p = 5 - (t2 - t1);
|
||||
loops.pause(Math.max(1, p))
|
||||
}
|
||||
motors.stopAllMotors()
|
||||
st = 0;
|
||||
brick.setLight(BrickLight.RedPulse);
|
||||
brick.showImage(images.eyesKnockedOut)
|
||||
music.playSoundEffect(sounds.movementsSpeedDown)
|
||||
sensors.touch3.pauseUntil(TouchSensorEvent.Pressed)
|
||||
brick.setLight(BrickLight.Off);
|
||||
})
|
||||
|
||||
// BHV
|
||||
loops.forever(function () {
|
||||
switch (st) {
|
||||
case 0:
|
||||
Cdrv = 0;
|
||||
Cstr = 0;
|
||||
break;
|
||||
case 1:
|
||||
Cdrv = 40;
|
||||
loops.pause(4000);
|
||||
Cdrv = 0;
|
||||
music.playTone(1000, 100);
|
||||
st = 2;
|
||||
break;
|
||||
case 2:
|
||||
switch (sensors.color1.color()) {
|
||||
case ColorSensorColor.Red:
|
||||
music.playTone(2000, 100);
|
||||
Cdrv = 0;
|
||||
Cstr = 0;
|
||||
break;
|
||||
case ColorSensorColor.Green:
|
||||
music.playTone(2000, 100);
|
||||
Cdrv = 150;
|
||||
Cstr = 0;
|
||||
break;
|
||||
case ColorSensorColor.Blue:
|
||||
music.playTone(2000, 100);
|
||||
Cstr = 70;
|
||||
break;
|
||||
case ColorSensorColor.Yellow:
|
||||
music.playTone(2000, 100);
|
||||
Cstr = -70;
|
||||
break;
|
||||
case ColorSensorColor.White:
|
||||
music.playTone(2000, 100);
|
||||
Cdrv = -75;
|
||||
break;
|
||||
}
|
||||
if (sensors.ultrasonic4.distance() < 25) {
|
||||
Cstr = 0;
|
||||
oldDr = Cdrv;
|
||||
Cdrv = -10;
|
||||
motors.mediumC.setSpeed(30, 30, MoveUnit.Degrees);
|
||||
motors.mediumC.setSpeed(-30, 60, MoveUnit.Degrees);
|
||||
motors.mediumC.setSpeed(30, 30, MoveUnit.Degrees);
|
||||
if (Math.randomRange(-1, 1) >= 1)
|
||||
Cstr = 70;
|
||||
else
|
||||
Cstr = -70;
|
||||
loops.pause(4000);
|
||||
music.playTone(2000, 100)
|
||||
Cstr = 0;
|
||||
Cdrv = oldDr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
loops.pause(80);
|
||||
})
|
||||
```
|
@ -1,390 +0,0 @@
|
||||
# Puppy
|
||||
|
||||
```typescript
|
||||
let P_T = 0;
|
||||
let ISS = 0;
|
||||
let F_T = 0;
|
||||
let P_C = 0;
|
||||
let F_C = 0;
|
||||
let DB_S = 0;
|
||||
let NS = false;
|
||||
let IBP = 0;
|
||||
let IAP = 0;
|
||||
let C = false;
|
||||
let TC = false;
|
||||
let OTC = false;
|
||||
let COL = 0;
|
||||
let OCOL = 0;
|
||||
let _C = false;
|
||||
let GTO = 0;
|
||||
|
||||
function DN() {
|
||||
motors.largeAD.setBrake(true);
|
||||
motors.largeAD.tank(50, 50, 1, MoveUnit.Seconds);
|
||||
loops.pause(100);
|
||||
motors.largeA.clearCounts()
|
||||
motors.largeD.clearCounts()
|
||||
}
|
||||
|
||||
function MNRH() {
|
||||
motors.mediumC.setBrake(true)
|
||||
brick.showImage(images.legoEv3icon)
|
||||
brick.setLight(BrickLight.OrangePulse)
|
||||
while (!brick.buttonEnter.wasPressed()) {
|
||||
if (brick.buttonUp.wasPressed()) {
|
||||
motors.mediumC.setSpeed(-100);
|
||||
} else if (brick.buttonDown.wasPressed()) {
|
||||
motors.mediumC.setSpeed(100);
|
||||
} else {
|
||||
motors.mediumC.stop();
|
||||
}
|
||||
}
|
||||
motors.mediumC.stop();
|
||||
motors.mediumC.clearCounts();
|
||||
brick.setLight(BrickLight.Green);
|
||||
}
|
||||
|
||||
function IS(t: number) {
|
||||
ISS = t;
|
||||
switch (t) {
|
||||
case 0:
|
||||
brick.showImage(images.eyesNeutral);
|
||||
break;
|
||||
case 1:
|
||||
brick.showImage(images.eyesSleeping);
|
||||
break;
|
||||
case 2:
|
||||
brick.showImage(images.eyesTear);
|
||||
// draw rect...
|
||||
break;
|
||||
case 3:
|
||||
brick.showImage(images.eyesHurt);
|
||||
break;
|
||||
case 4:
|
||||
brick.showImage(images.eyesAngry);
|
||||
break;
|
||||
case 5:
|
||||
brick.showImage(images.eyesTiredMiddle);
|
||||
break;
|
||||
case 6:
|
||||
brick.showImage(images.eyesTiredRight);
|
||||
break;
|
||||
case 7:
|
||||
brick.showImage(images.eyesTiredLeft);
|
||||
break;
|
||||
case 8:
|
||||
brick.showImage(images.eyesLove);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function UP() {
|
||||
if (motors.largeA.angle() > -50) {
|
||||
control.runInParallel(function () {
|
||||
motors.largeD.clearCounts()
|
||||
motors.largeD.setSpeed(-35);
|
||||
pauseUntil(() => motors.largeD.angle() < -25);
|
||||
motors.largeD.stop();
|
||||
motors.largeD.setRegulated(false)
|
||||
motors.largeD.setSpeed(-15)
|
||||
pauseUntil(() => motors.largeD.angle() < -65);
|
||||
motors.largeD.stop();
|
||||
})
|
||||
motors.largeA.clearCounts()
|
||||
motors.largeA.setSpeed(-35);
|
||||
pauseUntil(() => motors.largeA.angle() < -25);
|
||||
motors.largeA.stop();
|
||||
motors.largeA.setRegulated(false)
|
||||
motors.largeA.setSpeed(-15)
|
||||
pauseUntil(() => motors.largeA.angle() < -65);
|
||||
motors.largeA.stop();
|
||||
|
||||
loops.pause(500);
|
||||
}
|
||||
}
|
||||
|
||||
function RST() {
|
||||
P_T = Math.randomRange(3, 6);
|
||||
F_T = Math.randomRange(2, 4);
|
||||
P_C = 1;
|
||||
F_C = 1;
|
||||
control.timer1.reset();
|
||||
control.timer2.reset();
|
||||
control.timer3.reset();
|
||||
CS(0);
|
||||
}
|
||||
|
||||
function CS(db: number) {
|
||||
if (DB_S != db) {
|
||||
DB_S = db;
|
||||
NS = true;
|
||||
}
|
||||
}
|
||||
|
||||
function MON() {
|
||||
if (control.timer2.seconds() > 10) {
|
||||
control.timer2.reset();
|
||||
P_C--;
|
||||
if (P_C < 0) {
|
||||
P_C = 0;
|
||||
}
|
||||
}
|
||||
if (control.timer1.seconds() > 20) {
|
||||
control.timer1.reset()
|
||||
F_C--;
|
||||
if (F_C < 0) {
|
||||
F_C = 0;
|
||||
}
|
||||
}
|
||||
if (control.timer3.seconds() > 30) {
|
||||
control.timer3.reset();
|
||||
CS(1);
|
||||
}
|
||||
}
|
||||
|
||||
function UIS() {
|
||||
if (control.timer5.seconds() > IBP) {
|
||||
control.timer5.reset();
|
||||
if (ISS == 1) {
|
||||
ISS = 6;
|
||||
IBP = Math.randomRange(1, 5);
|
||||
} else {
|
||||
ISS = 1;
|
||||
IBP = 0.25;
|
||||
}
|
||||
IS(ISS);
|
||||
}
|
||||
if (control.timer6.seconds() > IAP) {
|
||||
if (ISS != 1) {
|
||||
control.timer6.reset();
|
||||
IAP = Math.randomRange(1, 10)
|
||||
if (ISS != 7) {
|
||||
ISS = 7
|
||||
} else {
|
||||
ISS = 6;
|
||||
}
|
||||
IS(ISS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function UPDB() {
|
||||
if ((P_T == P_C) && (F_T == F_C)) {
|
||||
CS(6);
|
||||
}
|
||||
if ((P_T > P_C) && (F_T < F_C)) {
|
||||
CS(3);
|
||||
}
|
||||
if ((P_T < P_C) && (F_T > F_C)) {
|
||||
CS(5);
|
||||
}
|
||||
if ((P_C == 0) && (F_C > 0)) {
|
||||
CS(2)
|
||||
}
|
||||
if (F_C == 0) {
|
||||
CS(4)
|
||||
}
|
||||
}
|
||||
|
||||
function PTC() {
|
||||
C = false;
|
||||
OTC = TC;
|
||||
TC = sensors.touch1.isPressed()
|
||||
if (TC != OTC && TC) {
|
||||
P_C++;
|
||||
control.timer3.reset();
|
||||
if (DB_S != 4) {
|
||||
IS(2);
|
||||
music.playSoundEffect(sounds.animalsDogSniff);
|
||||
C = true;
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
function FDC() {
|
||||
OCOL = COL;
|
||||
COL = sensors.color4.color();
|
||||
_C = false;
|
||||
if ((COL != 0) && (OCOL != COL)) {
|
||||
F_C++;
|
||||
_C = true;
|
||||
control.timer3.reset();
|
||||
IS(2);
|
||||
music.playSoundEffect(sounds.expressionsCrunching)
|
||||
}
|
||||
return _C;
|
||||
}
|
||||
|
||||
function IDL() {
|
||||
if (NS) {
|
||||
NS = false;
|
||||
UP();
|
||||
}
|
||||
UIS();
|
||||
UPDB();
|
||||
PTC();
|
||||
FDC();
|
||||
}
|
||||
|
||||
function MHT(Pos: number) {
|
||||
let _R = Pos - motors.mediumC.angle();
|
||||
if (_R >= 0) {
|
||||
motors.mediumC.setSpeed(100, _R, MoveUnit.Degrees);
|
||||
} else {
|
||||
motors.mediumC.setSpeed(-100, Math.abs(_R), MoveUnit.Degrees);
|
||||
}
|
||||
}
|
||||
|
||||
function SLP() {
|
||||
if (NS) {
|
||||
NS = false;
|
||||
IS(5)
|
||||
DN()
|
||||
MHT(3000)
|
||||
IS(1)
|
||||
music.playSoundEffect(sounds.expressionsSnoring)
|
||||
}
|
||||
if (sensors.touch1.isPressed() || brick.buttonEnter.isPressed()) {
|
||||
music.stopAllSounds();
|
||||
control.timer3.reset();
|
||||
CS(7);
|
||||
}
|
||||
}
|
||||
|
||||
function PLF() {
|
||||
if (NS) {
|
||||
NS = false
|
||||
IS(0)
|
||||
UP()
|
||||
music.playSoundEffect(sounds.animalsDogBark2)
|
||||
control.timer4.reset()
|
||||
GTO = Math.randomRange(4, 8);
|
||||
}
|
||||
if(PTC()) {
|
||||
CS(0);
|
||||
}
|
||||
if (control.timer4.seconds() > GTO) {
|
||||
music.playSoundEffect(sounds.animalsDogBark2)
|
||||
control.timer4.reset();
|
||||
GTO = Math.randomRange(4, 8);
|
||||
}
|
||||
}
|
||||
|
||||
function NGR() {
|
||||
NS = false
|
||||
IS(4)
|
||||
music.playSoundEffect(sounds.animalsDogGrowl);
|
||||
UP();
|
||||
loops.pause(1500);
|
||||
music.stopAllSounds()
|
||||
music.playSoundEffect(sounds.animalsDogBark1)
|
||||
P_C--;
|
||||
CS(0);
|
||||
}
|
||||
|
||||
function HNG() {
|
||||
if (NS) {
|
||||
NS = false;
|
||||
IS(3)
|
||||
DN();
|
||||
music.playSoundEffect(sounds.animalsDogWhine);
|
||||
}
|
||||
if(FDC()) {
|
||||
CS(0)
|
||||
}
|
||||
if (PTC()) {
|
||||
CS(3);
|
||||
}
|
||||
}
|
||||
|
||||
function PPP() {
|
||||
NS = false;
|
||||
IS(2);
|
||||
UP();
|
||||
loops.pause(100)
|
||||
motors.largeA.setSpeed(-30, 70, MoveUnit.Degrees);
|
||||
loops.pause(800);
|
||||
music.playSoundEffect(sounds.mechanicalHorn1);
|
||||
loops.pause(1000);
|
||||
for(let i = 0; i < 3; ++i) {
|
||||
motors.largeA.setSpeed(-30, 20, MoveUnit.Degrees);
|
||||
motors.largeA.setSpeed(30, 20, MoveUnit.Degrees);
|
||||
}
|
||||
motors.largeA.setSpeed(30, 70, MoveUnit.Degrees);
|
||||
F_C = 1;
|
||||
CS(0);
|
||||
}
|
||||
|
||||
function HPY() {
|
||||
IS(8)
|
||||
MHT(0);
|
||||
motors.largeAD.setSpeed(10, 0.8, MoveUnit.Seconds);
|
||||
for(let i = 0; i < 3; ++i) {
|
||||
music.playSoundEffect(sounds.animalsDogBark1);
|
||||
motors.largeAD.setSpeed(-100, 0.2, MoveUnit.Seconds);
|
||||
loops.pause(300)
|
||||
motors.largeAD.setSpeed(10, 0.3, MoveUnit.Seconds)
|
||||
}
|
||||
loops.pause(500);
|
||||
music.stopAllSounds();
|
||||
DN();
|
||||
RST();
|
||||
}
|
||||
|
||||
function STL() {
|
||||
UP();
|
||||
motors.largeAD.setSpeed(-20, 60, MoveUnit.Degrees);
|
||||
music.playSoundEffect(sounds.animalsDogWhine);
|
||||
motors.largeAD.setSpeed(20, 60, MoveUnit.Degrees);
|
||||
}
|
||||
|
||||
function WKU() {
|
||||
let stateC = false;
|
||||
IS(5);
|
||||
music.playSoundEffect(sounds.animalsDogWhine)
|
||||
MHT(0)
|
||||
DN()
|
||||
STL()
|
||||
loops.pause(1000);
|
||||
UP()
|
||||
CS(0;)
|
||||
}
|
||||
|
||||
DN();
|
||||
MNRH();
|
||||
// compare button state???
|
||||
IS(1);
|
||||
UP();
|
||||
RST();
|
||||
loops.forever(function () {
|
||||
MON();
|
||||
switch (DB_S) {
|
||||
case 0:
|
||||
IDL();
|
||||
break;
|
||||
case 1:
|
||||
SLP();
|
||||
break;
|
||||
case 2:
|
||||
PLF();
|
||||
break;
|
||||
case 3:
|
||||
NGR();
|
||||
break;
|
||||
case 4:
|
||||
HNG();
|
||||
break;
|
||||
case 5:
|
||||
PPP();
|
||||
break;
|
||||
case 6:
|
||||
HPY();
|
||||
break;
|
||||
case 7:
|
||||
WKU();
|
||||
break;
|
||||
}
|
||||
})
|
||||
```
|
@ -1,51 +0,0 @@
|
||||
# Robot Arm
|
||||
|
||||
```typescript
|
||||
function INI() {
|
||||
motors.largeB.setBrake(true)
|
||||
motors.largeC.setBrake(true)
|
||||
motors.mediumA.setBrake(true)
|
||||
motors.largeB.setSpeed(-50)
|
||||
pauseUntil(() => sensors.color3.light(LightIntensityMode.Reflected) > 25);
|
||||
motors.largeB.stop();
|
||||
motors.mediumA.setSpeed(30, 1, MoveUnit.Seconds);
|
||||
motors.mediumA.setSpeed(-50, 90, MoveUnit.Degrees);
|
||||
motors.largeC.setSpeed(50)
|
||||
sensors.touch1.pauseUntil(TouchSensorEvent.Pressed);
|
||||
motors.largeC.setSpeed(-50, 0.86, MoveUnit.Rotations);
|
||||
}
|
||||
|
||||
INI()
|
||||
|
||||
let down = false;
|
||||
loops.forever(function () {
|
||||
brick.showImage(images.informationQuestionMark)
|
||||
brick.setLight(BrickLight.OrangePulse);
|
||||
pauseUntil(() => (down = brick.buttonDown.wasPressed()) || brick.buttonUp.wasPressed())
|
||||
brick.setLight(BrickLight.Off)
|
||||
music.playSoundEffect(sounds.mechanicalAirRelease)
|
||||
brick.showImage(images.informationAccept)
|
||||
if (down) {
|
||||
brick.showImage(images.informationForward)
|
||||
motors.largeC.setSpeed(65, 0.85, MoveUnit.Rotations);
|
||||
} else {
|
||||
brick.showImage(images.informationBackward)
|
||||
motors.largeC.setSpeed(-65, 0.85, MoveUnit.Rotations);
|
||||
}
|
||||
motors.largeB.setSpeed(20, 275, MoveUnit.Degrees)
|
||||
motors.mediumA.setSpeed(30, 1, MoveUnit.Seconds)
|
||||
motors.largeB.setSpeed(-55)
|
||||
pauseUntil(() => sensors.color3.light(LightIntensityMode.Reflected) > 25);
|
||||
motors.largeB.stop();
|
||||
if (down) {
|
||||
motors.largeC.setSpeed(-65, 0.86, MoveUnit.Rotations);
|
||||
} else {
|
||||
motors.largeC.setSpeed(65, 0.85, MoveUnit.Rotations);
|
||||
}
|
||||
motors.largeB.setSpeed(20, 275, MoveUnit.Degrees);
|
||||
motors.mediumA.setSpeed(-30, 90, MoveUnit.Degrees);
|
||||
motors.largeB.setSpeed(-55)
|
||||
pauseUntil(() => sensors.color3.light(LightIntensityMode.Reflected) > 25);
|
||||
motors.largeB.stop()
|
||||
})
|
||||
```
|
@ -1,51 +0,0 @@
|
||||
# Crane LabView
|
||||
|
||||
```blocks
|
||||
function INI() {
|
||||
motors.largeB.setBrake(true)
|
||||
motors.largeC.setBrake(true)
|
||||
motors.mediumA.setBrake(true)
|
||||
motors.largeB.setSpeed(-50)
|
||||
pauseUntil(() => sensors.color3.light(LightIntensityMode.Reflected) > 25);
|
||||
motors.largeB.stop();
|
||||
motors.mediumA.setSpeed(30, 1, MoveUnit.Seconds);
|
||||
motors.mediumA.setSpeed(-50, 90, MoveUnit.Degrees);
|
||||
motors.largeC.setSpeed(50)
|
||||
sensors.touch1.pauseUntil(TouchSensorEvent.Pressed);
|
||||
motors.largeC.setSpeed(-50, 0.86, MoveUnit.Rotations);
|
||||
}
|
||||
|
||||
INI()
|
||||
|
||||
let down = false;
|
||||
loops.forever(function () {
|
||||
brick.showImage(images.informationQuestionMark)
|
||||
brick.setLight(BrickLight.OrangePulse);
|
||||
pauseUntil(() => (down = brick.buttonDown.wasPressed()) || brick.buttonUp.wasPressed())
|
||||
brick.setLight(BrickLight.Off)
|
||||
music.playSoundEffect(sounds.mechanicalAirRelease)
|
||||
brick.showImage(images.informationAccept)
|
||||
if (down) {
|
||||
brick.showImage(images.informationForward)
|
||||
motors.largeC.setSpeed(65, 0.85, MoveUnit.Rotations);
|
||||
} else {
|
||||
brick.showImage(images.informationBackward)
|
||||
motors.largeC.setSpeed(-65, 0.85, MoveUnit.Rotations);
|
||||
}
|
||||
motors.largeB.setSpeed(20, 275, MoveUnit.Degrees)
|
||||
motors.mediumA.setSpeed(30, 1, MoveUnit.Seconds)
|
||||
motors.largeB.setSpeed(-55)
|
||||
pauseUntil(() => sensors.color3.light(LightIntensityMode.Reflected) > 25);
|
||||
motors.largeB.stop();
|
||||
if (down) {
|
||||
motors.largeC.setSpeed(-65, 0.86, MoveUnit.Rotations);
|
||||
} else {
|
||||
motors.largeC.setSpeed(65, 0.85, MoveUnit.Rotations);
|
||||
}
|
||||
motors.largeB.setSpeed(20, 275, MoveUnit.Degrees);
|
||||
motors.mediumA.setSpeed(-30, 90, MoveUnit.Degrees);
|
||||
motors.largeB.setSpeed(-55)
|
||||
pauseUntil(() => sensors.color3.light(LightIntensityMode.Reflected) > 25);
|
||||
motors.largeB.stop()
|
||||
})
|
||||
```
|
@ -1,215 +0,0 @@
|
||||
# Gyro Boy LabView
|
||||
|
||||
```blocks
|
||||
let mSum = 0;
|
||||
let mPos = 0;
|
||||
let mSpd = 0;
|
||||
let mD = 0;
|
||||
let mDP1 = 0;
|
||||
let mDP2 = 0;
|
||||
let mDP3 = 0;
|
||||
let Crdv = 0;
|
||||
let cLo = 0;
|
||||
let gAng = 0;
|
||||
let ok = false;
|
||||
let pwr = 0;
|
||||
let Cstr = 0;
|
||||
let Cdrv = 0;
|
||||
let gMn = 0;
|
||||
let gMx = 0;
|
||||
let gSum = 0;
|
||||
let gyro = 0;
|
||||
let gOS = 0;
|
||||
let gSpd = 0;
|
||||
let tInt = 0.014;
|
||||
let lpwr = 0
|
||||
let rpwr = 0
|
||||
let tStart = 0
|
||||
let st = 0
|
||||
let oldDr = 0
|
||||
|
||||
function RST() {
|
||||
motors.largeA.reset()
|
||||
motors.largeD.reset()
|
||||
motors.largeA.setRegulated(false)
|
||||
motors.largeD.setRegulated(false)
|
||||
sensors.gyro2.reset()
|
||||
sensors.gyro2.rate()
|
||||
control.timer2.reset()
|
||||
loops.pause(5000)
|
||||
mSum = 0;
|
||||
mPos = 0;
|
||||
mD = 0;
|
||||
mDP1 = 0;
|
||||
mDP2 = 0;
|
||||
mDP3 = 0;
|
||||
Crdv = 0;
|
||||
cLo = 0;
|
||||
gAng = 0;
|
||||
ok = false;
|
||||
pwr = 0;
|
||||
st = 0;
|
||||
Cstr = 0;
|
||||
Cdrv = 0;
|
||||
}
|
||||
|
||||
function OS() {
|
||||
// OSL
|
||||
do {
|
||||
gMn = 1000;
|
||||
gMx = -100;
|
||||
gSum = 0;
|
||||
// gChk
|
||||
for (let i = 0; i < 200; i++) {
|
||||
gyro = sensors.gyro2.rate()
|
||||
gSum = gyro;
|
||||
gMx = Math.max(gMx, gyro)
|
||||
gMn = Math.min(gMn, gyro)
|
||||
loops.pause(4);
|
||||
}
|
||||
} while (gMx - gMn > 2);
|
||||
gOS = gSum / 200;
|
||||
}
|
||||
|
||||
function GT() {
|
||||
if (cLo == 0) {
|
||||
tInt = 0.014;
|
||||
control.timer1.reset();
|
||||
} else {
|
||||
tInt = control.timer1.seconds() / cLo;
|
||||
}
|
||||
cLo++;
|
||||
}
|
||||
|
||||
function GG() {
|
||||
gyro = sensors.gyro2.rate();
|
||||
gOS = 0.0005 * gyro + (1 - 0.0005) * gOS
|
||||
gSpd = gyro - gOS;
|
||||
gAng = gAng + tInt * gSpd;
|
||||
}
|
||||
|
||||
function GM() {
|
||||
let temp = mSum
|
||||
mSum = motors.largeD.angle() + motors.largeA.angle();
|
||||
mD = mSum - temp;
|
||||
mPos = mPos + mD;
|
||||
mSpd = ((mDP1 + mDP2 + mDP3 + mD) / 4) / tInt;
|
||||
mDP3 = mDP2;
|
||||
mDP2 = mDP1;
|
||||
mDP1 = mD;
|
||||
}
|
||||
|
||||
function EQ() {
|
||||
mPos = mPos - Cdrv * tInt;
|
||||
pwr = (0.8 * gSpd + 15 * gAng) + (0.095 * mSpd + 0.13 * mPos) - 0.01 * Cdrv
|
||||
if (pwr > 100) pwr = 100
|
||||
else if (pwr < -100) pwr = -100
|
||||
}
|
||||
|
||||
function cntrl() {
|
||||
mPos = mPos - tInt * Cdrv
|
||||
lpwr = (pwr + Cstr * 0.1)
|
||||
rpwr = (pwr - Cstr * 0.1)
|
||||
}
|
||||
|
||||
function CHK() {
|
||||
if (Math.abs(pwr) < 100)
|
||||
control.timer2.reset();
|
||||
if (control.timer2.seconds() > 2) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// M
|
||||
loops.forever(function () {
|
||||
RST();
|
||||
brick.showImage(images.eyesSleeping)
|
||||
OS()
|
||||
gAng = -0.25;
|
||||
music.playSoundEffect(sounds.movementsSpeedUp)
|
||||
brick.showImage(images.eyesAwake)
|
||||
st = 1;
|
||||
// BALANCE
|
||||
while (!ok) {
|
||||
GT();
|
||||
let t1 = control.timer1.millis()
|
||||
GG();
|
||||
GM();
|
||||
EQ();
|
||||
cntrl();
|
||||
motors.largeA.setSpeed(lpwr)
|
||||
motors.largeD.setSpeed(rpwr)
|
||||
CHK()
|
||||
let t2 = control.timer1.millis();
|
||||
let p = 5 - (t2 - t1);
|
||||
loops.pause(Math.max(1, p))
|
||||
}
|
||||
motors.stopAllMotors()
|
||||
st = 0;
|
||||
brick.setLight(BrickLight.RedPulse);
|
||||
brick.showImage(images.eyesKnockedOut)
|
||||
music.playSoundEffect(sounds.movementsSpeedDown)
|
||||
sensors.touch3.pauseUntil(TouchSensorEvent.Pressed)
|
||||
brick.setLight(BrickLight.Off);
|
||||
})
|
||||
|
||||
// BHV
|
||||
loops.forever(function () {
|
||||
switch (st) {
|
||||
case 0:
|
||||
Cdrv = 0;
|
||||
Cstr = 0;
|
||||
break;
|
||||
case 1:
|
||||
Cdrv = 40;
|
||||
loops.pause(4000);
|
||||
Cdrv = 0;
|
||||
music.playTone(1000, 100);
|
||||
st = 2;
|
||||
break;
|
||||
case 2:
|
||||
switch (sensors.color1.color()) {
|
||||
case ColorSensorColor.Red:
|
||||
music.playTone(2000, 100);
|
||||
Cdrv = 0;
|
||||
Cstr = 0;
|
||||
break;
|
||||
case ColorSensorColor.Green:
|
||||
music.playTone(2000, 100);
|
||||
Cdrv = 150;
|
||||
Cstr = 0;
|
||||
break;
|
||||
case ColorSensorColor.Blue:
|
||||
music.playTone(2000, 100);
|
||||
Cstr = 70;
|
||||
break;
|
||||
case ColorSensorColor.Yellow:
|
||||
music.playTone(2000, 100);
|
||||
Cstr = -70;
|
||||
break;
|
||||
case ColorSensorColor.White:
|
||||
music.playTone(2000, 100);
|
||||
Cdrv = -75;
|
||||
break;
|
||||
}
|
||||
if (sensors.ultrasonic4.distance() < 25) {
|
||||
Cstr = 0;
|
||||
oldDr = Cdrv;
|
||||
Cdrv = -10;
|
||||
motors.mediumC.setSpeed(30, 30, MoveUnit.Degrees);
|
||||
motors.mediumC.setSpeed(-30, 60, MoveUnit.Degrees);
|
||||
motors.mediumC.setSpeed(30, 30, MoveUnit.Degrees);
|
||||
if (Math.randomRange(-1, 1) >= 1)
|
||||
Cstr = 70;
|
||||
else
|
||||
Cstr = -70;
|
||||
loops.pause(4000);
|
||||
music.playTone(2000, 100)
|
||||
Cstr = 0;
|
||||
Cdrv = oldDr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
loops.pause(80);
|
||||
})
|
||||
```
|
@ -3,10 +3,10 @@
|
||||
Use a touch sensor to make the brick happy.
|
||||
|
||||
```blocks
|
||||
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||
sensors.touchSensor1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||
brick.showImage(images.expressionsBigSmile)
|
||||
})
|
||||
sensors.touch1.onEvent(TouchSensorEvent.Released, function () {
|
||||
sensors.touchSensor1.onEvent(TouchSensorEvent.Released, function () {
|
||||
brick.showImage(images.expressionsSick)
|
||||
})
|
||||
```
|
@ -1,27 +0,0 @@
|
||||
# Lessons
|
||||
|
||||
Learning activities for LEGO Mindstorms with MakeCode.
|
||||
|
||||
## Motors and motion
|
||||
|
||||
```codecard
|
||||
[{
|
||||
"name": "Make it Move",
|
||||
"imageUrl":"/static/lessons/make-it-move.jpg",
|
||||
"url": "/lessons/make-it-move",
|
||||
"cardType": "project",
|
||||
"description": "Make a robot that moves itself without wheels."
|
||||
}, {
|
||||
"name": "Make it Move TUTORIAL",
|
||||
"imageUrl":"/static/lessons/make-it-move.jpg",
|
||||
"url": "/lessons/make-it-move-tutorial",
|
||||
"cardType": "tutorial",
|
||||
"description": "Make a robot that moves itself without wheels."
|
||||
}, {
|
||||
"name": "Line Detection",
|
||||
"imageUrl":"/static/lessons/line-detection.jpg",
|
||||
"url": "/lessons/line-detection",
|
||||
"cardType": "project",
|
||||
"description": "Make your robot drive itself by following lines."
|
||||
}]
|
||||
```
|
@ -1,266 +0,0 @@
|
||||
# Line Detection
|
||||
|
||||
## Objective
|
||||
|
||||
Design ways to improve driving safety by helping to prevent drivers from falling asleep and causing an accident.
|
||||
|
||||

|
||||
|
||||
## Connect
|
||||
|
||||
Make sure that you can answer the following questions:
|
||||
|
||||
* Can autonomous cars react to different traffic light signals?
|
||||
* What can happen if a driver falls asleep while driving?
|
||||
* How can we detect when a driver is falling asleep?
|
||||
|
||||
Think about what you have learned, then document it. Describe the problem in your own words. Creatively record your ideas and findings.
|
||||
|
||||
## Construct
|
||||
|
||||
Start by constructing this model. Read the building instructions [here](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/building-instructions/ev3-rem-color-sensor-down-driving-base-d30ed30610c3d6647d56e17bc64cf6e2.pdf) first.
|
||||
|
||||

|
||||
|
||||
## Program
|
||||
|
||||
Autonomous cars need to recognize and respond to traffic lights automatically.
|
||||
First, create a program that will make your robot stop at red lights.
|
||||
Make sure your robot is only responding to the color red.
|
||||
Once you have succeeded, program your robot to drive forward again when the light changes from red to green.
|
||||
|
||||
There are two coding tasks for this lesson:
|
||||
|
||||
1. Create a program that will make your robot stop at red lights.
|
||||
2. Create a program that drives the robot forward until the Color Sensor sees red. The robot then stops.
|
||||
|
||||
## Coding task 1 - Stop at red lights
|
||||
|
||||
**Goal:** Create a program that will make your robot stop at red lights.
|
||||
|
||||
### Step 1
|
||||
|
||||
Create a program that drives the robot forward until the Color Sensor sees red. The robot then stops.
|
||||
|
||||
Place a ``||motors:steer large B+C||`` block from ``||motors:Motors||`` under ``||loops:on start||``. Change the speed to 20%.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.steer(0, 20)
|
||||
```
|
||||
|
||||
### Step 2
|
||||
|
||||
Place a ``||loops:while||`` loop block under ``||motors:steer large B+C||``.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3
|
||||
|
||||
Place a ``||sensors:pause for color||`` from ``||sensors:Sensors||`` inside the ``||loops:while||`` loop block. Change the color to red.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4
|
||||
|
||||
Place a ``||motors:stop all motors||`` block under the ``||sensors:pause for color||`` block.
|
||||
|
||||
Study the program...what do you think the program will do?
|
||||
|
||||
**Hint:** The motors will run until the Color Sensor senses the color red, then all motors will stop. The motors will run until the sensor reading in the while block is true.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
motors.stopAllMotors()
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5
|
||||
|
||||
Click `|Download|` and follow the instructions to get your code onto your EV3 Brick. Press the **center** button on the EV3 Brick to run the program.
|
||||
|
||||
## Coding task 2 - Detect light changes
|
||||
|
||||
**Goal:** Program your robot to drive forward again when the light changes from red to green.
|
||||
|
||||
### Step 1
|
||||
|
||||
Place a ``||loops:while||`` loop block under ``||loops:on start||``.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2
|
||||
|
||||
Place a ``||motors:steer large B+C||`` block from ``||motors:Motors||`` inside the ``||loops:while||`` loop block. Change the speed to 20%.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
motors.largeBC.steer(0, 20)
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4
|
||||
|
||||
Place a ``||loops:while||`` loop block under the ``||motors:steer large B+C||`` block.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5
|
||||
|
||||
Place a ``||sensors:pause for color||`` block from ``||sensors:Sensors||`` inside the ``||loops:while||`` loop block. Change the color to red.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6
|
||||
|
||||
Place a ``||motors:stop all motors||`` block under the ``||sensors:pause for color||`` block.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
motors.stopAllMotors()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 7
|
||||
|
||||
Place a ``||loops:while||`` loop block under the second ``||loops:while||`` loop block.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
motors.stopAllMotors()
|
||||
}
|
||||
while (true) {
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 8
|
||||
|
||||
Place a ``||sensors:pause for color||`` block inside the new ``||loops:while||`` loop block. Change the color to red.
|
||||
|
||||
What do you think the program will do?
|
||||
|
||||
**Hint:** The motors will run until the Color Sensor detects the color red, then it will stop all motors. The motors will also run and not stop when the color sensor detects the color green.
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
motors.stopAllMotors()
|
||||
}
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 9
|
||||
|
||||
Click `|Download|` and follow the instructions to get your code onto your EV3 Brick. Press the **center** button on the EV3 Brick to run the program.
|
||||
|
||||
## Contemplate
|
||||
|
||||
To simulate what could happen if a driver falls asleep while driving, your robot could sound an alarm signal when it crosses the line. This feature is often available in new cars.
|
||||
|
||||
Program your robot to perform this function.
|
||||
|
||||
Think about what you have learned, then document it. Describe your pseudocode for this task. Creatively record your ideas, and findings.
|
||||
|
||||
### Programming hint
|
||||
|
||||
```blocks
|
||||
motors.largeBC.steer(0, 20)
|
||||
while (true) {
|
||||
sensors.color3.pauseForColor(ColorSensorColor.Yellow)
|
||||
music.playSoundEffect(sounds.systemGeneralAlert)
|
||||
}
|
||||
while (true) {
|
||||
while (true) { sensors.color3.pauseForLight(LightIntensityMode.Reflected, LightCondition.Bright)
|
||||
motors.largeB.setSpeed(10)
|
||||
motors.largeC.setSpeed(-10)
|
||||
}
|
||||
while (true) {
|
||||
sensors.color3.pauseForLight(LightIntensityMode.Reflected, LightCondition.Bright)
|
||||
motors.largeA.setSpeed(-10)
|
||||
motors.largeA.setSpeed(10)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Continue
|
||||
|
||||
Program your robot to drive on “autopilot” along a given route. You will need to create a program that recognizes and responds to a dark line (or white line). You will create a line-following program and your robot will need to travel along the line without losing contact with it.
|
||||
|
||||
You will need to constantly debug your program in order to make your robot travel as smoothly as possible along the line.
|
||||
|
||||
### Programming hint
|
||||
|
||||
```blocks
|
||||
while (true) {
|
||||
while (true) { sensors.color3.pauseForLight(LightIntensityMode.Reflected, LightCondition.Bright)
|
||||
motors.largeB.setSpeed(10)
|
||||
motors.largeC.setSpeed(-10)
|
||||
}
|
||||
while (true) {
|
||||
sensors.color3.pauseForLight(LightIntensityMode.Reflected, LightCondition.Bright)
|
||||
motors.largeB.setSpeed(-10)
|
||||
motors.largeC.setSpeed(10)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Share
|
||||
|
||||
Consider the following questions:
|
||||
|
||||
1. What challenged you?
|
||||
2. Where there any surprises?
|
||||
3. How could you improve your program?
|
||||
4. Could your program have been more streamlined?
|
||||
5. Have you used too many blocks?
|
||||
6. Is there a more efficient way of building your program?
|
||||
7. How could your program be used in real-world scenarios?
|
||||
|
||||
Think about what you have learned, then document it. Creatively record and present your ideas, creations, and findings.
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
# Make It Move Without Wheels
|
||||
|
||||
## Objective @unplugged
|
||||
|
||||
Design, build and program a robot that can move itself:
|
||||
|
||||
Your robot will:
|
||||
|
||||
* Go a distance of at least 30cm
|
||||
* Use at least one motor
|
||||
* Use NO wheels for locomotion
|
||||
|
||||

|
||||
|
||||
|
||||
## Construct @unplugged
|
||||
|
||||
Build a Walker Bot!
|
||||
|
||||
The Walker Bot is one example of many possible solutions for making a robot move without wheels.
|
||||
|
||||
The Walker Bot combines an EV3 Frame and two legs that are mirror-images to create left and right legs.
|
||||
|
||||
The legs in the Walker Bot are designed to show how to change the rotary motion of a motor to reciprocating motion.
|
||||
|
||||
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
||||
|
||||

|
||||
|
||||
|
||||
## Program 1 @fullscreen
|
||||
|
||||
In nature, creatures use many methods to get around. None of them, however, use wheels to move. Can we copy the method of animal locomotion with our robot? Using motors and legs, make the robot move without using any wheels.
|
||||
|
||||
Place a ``||motors:tank large B+C||`` block from ``||motors:Motors||`` under ``||loops:on start||``.
|
||||
|
||||
Change the speed to `-60%` (for motor B) and `+60%` (for motor C).
|
||||
Change the rotations to `9`.
|
||||
|
||||
The ``||motors:tank large B+C||`` block will run for `9` rotations when the **center** button is pressed on the EV3 brick. The motors are set for the reverse direction because they are mounted upside down in this model.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.tank(-60, 60, 9, MoveUnit.Rotations)
|
||||
```
|
||||
|
||||
## Program 2 @fullscreen
|
||||
|
||||
Place a ``||motors:stop all motors||`` block under ``||motors:tank large B+C||``.
|
||||
|
||||
The ``||motors:tank large B+C||`` block will run for `9` rotations when the **center** button is pressed on the EV3 brick then stop.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.tank(-60, 60, 9, MoveUnit.Rotations)
|
||||
motors.stopAllMotors()
|
||||
```
|
||||
|
||||
## Program 3 @fullscreen
|
||||
|
||||
Place a ``||brick:show string||`` block under ``||motors:stop all motors||``.
|
||||
Change the `"Hello World"` text to `"30 cm"`.
|
||||
|
||||
The ``||motors:tank large B+C||`` will run for `9` rotations when the **center** button is pressed on the EV3 brick then stop and display "30 cm" on the EV3 Brick’s screen.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.tank(-60, 60, 9, MoveUnit.Rotations)
|
||||
motors.stopAllMotors()
|
||||
brick.showString("30 cm", 1)
|
||||
```
|
||||
|
||||
## Download @fullscreen
|
||||
|
||||
Click `|Download|` and follow the instructions to get your code onto your EV3 Brick. Press the **center** button on the EV3 Brick to run the program.
|
@ -1,73 +0,0 @@
|
||||
# Make It Move Without Wheels
|
||||
|
||||
## Objective
|
||||
|
||||
Design, build and program a robot that can move itself:
|
||||
|
||||
Your robot will:
|
||||
|
||||
* Go a distance of at least 30cm
|
||||
* Use at least one motor
|
||||
* Use NO wheels for locomotion
|
||||
|
||||

|
||||
|
||||
## Construct
|
||||
|
||||
Build a Walker Bot!
|
||||
|
||||
The Walker Bot is one example of many possible solutions for making a robot move without wheels.
|
||||
|
||||
The Walker Bot combines an EV3 Frame and two legs that are mirror-images to create left and right legs.
|
||||
|
||||
The legs in the Walker Bot are designed to show how to change the rotary motion of a motor to reciprocating motion.
|
||||
|
||||
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
||||
|
||||

|
||||
|
||||
|
||||
## Program
|
||||
|
||||
In nature, creatures use many methods to get around. None of them, however, use wheels to move. Can we copy the method of animal locomotion with our robot? Using motors and legs, make the robot move without using any wheels.
|
||||
|
||||
### Step 1
|
||||
|
||||
Place a ``||motors:tank large B+C||`` block from ``||motors:Motors||`` under ``||loops:on start||``.
|
||||
|
||||
Change the speed to `-60%` (for motor B) and `+60%` (for motor C).
|
||||
Change the rotations to `9`.
|
||||
|
||||
The ``||motors:tank large B+C||`` block will run for `9` rotations when the **center** button is pressed on the EV3 brick. The motors are set for the reverse direction because they are mounted upside down in this model.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.tank(-60, 60, 9, MoveUnit.Rotations)
|
||||
```
|
||||
|
||||
### Step 2
|
||||
|
||||
Place a ``||motors:stop all motors||`` block under ``||motors:tank large B+C||``.
|
||||
|
||||
The ``||motors:tank large B+C||`` block will run for `9` rotations when the **center** button is pressed on the EV3 brick then stop.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.tank(-60, 60, 9, MoveUnit.Rotations)
|
||||
motors.largeBC.stop()
|
||||
```
|
||||
|
||||
### Step 3
|
||||
|
||||
Place a ``||brick:show string||`` block under ``||motors:stop all motors||``.
|
||||
Change the `"Hello World"` text to `"30 cm"`.
|
||||
|
||||
The ``||motors:tank large B+C||`` will run for `9` rotations when the **center** button is pressed on the EV3 brick then stop and display "30 cm" on the EV3 Brick’s screen.
|
||||
|
||||
```blocks
|
||||
motors.largeBC.tank(-60, 60, 9, MoveUnit.Rotations)
|
||||
motors.largeBC.stop()
|
||||
brick.showString("30 cm", 1)
|
||||
```
|
||||
|
||||
### Step 4
|
||||
|
||||
Click `|Download|` and follow the instructions to get your code onto your EV3 Brick. Press the **center** button on the EV3 Brick to run the program.
|
@ -2,8 +2,10 @@
|
||||
|
||||
This program will activate an alarm when an object moves in front of the Ultrasonic Sensor.
|
||||
|
||||
TODO support for event when value changes
|
||||
|
||||
```blocks
|
||||
sensors.ultrasonic4.onEvent(UltrasonicSensorEvent.ObjectNear, function () {
|
||||
music.playSoundEffectUntilDone(sounds.informationActivate)
|
||||
input.ultrasonic4.onObjectNear(function () {
|
||||
music.playSoundUntilDone(music.sounds(Sounds.PowerUp))
|
||||
})
|
||||
```
|
@ -4,12 +4,14 @@ Use this program with the Programmable Brick and Large Motor.
|
||||
|
||||
```blocks
|
||||
loops.forever(function () {
|
||||
motors.largeA.setSpeed(30)
|
||||
output.largeMotorA.setPower(30)
|
||||
output.largeMotorA.on(true)
|
||||
loops.pause(100)
|
||||
motors.largeA.stop()
|
||||
music.playSoundEffectUntilDone(sounds.animalsCatPurr)
|
||||
motors.largeA.setSpeed(-30)
|
||||
output.largeMotorA.on(false)
|
||||
music.playSoundUntilDone(music.sounds(Sounds.PowerUp))
|
||||
output.largeMotorA.setPower(-30)
|
||||
output.largeMotorA.on(true)
|
||||
loops.pause(100)
|
||||
motors.largeA.stop()
|
||||
output.largeMotorA.on(false)
|
||||
})
|
||||
```
|
||||
|
@ -3,7 +3,7 @@
|
||||
This program will activate an alarm when an object is lifted from the Touch Sensor.
|
||||
|
||||
```blocks
|
||||
sensors.touch1.onEvent(TouchSensorEvent.Released, function () {
|
||||
music.playSoundEffectUntilDone(sounds.informationActivate);
|
||||
input.touchSensor1.onEvent(TouchSensorEvent.Released, function () {
|
||||
music.playSoundUntilDone(music.sounds(Sounds.PowerUp))
|
||||
})
|
||||
```
|
@ -4,9 +4,9 @@ This example program combined with the small model will make a beat and rhythm o
|
||||
|
||||
```blocks
|
||||
loops.forever(function () {
|
||||
motors.largeA.setSpeed(50)
|
||||
output.motorA.on(50)
|
||||
loops.pause(200)
|
||||
motors.largeA.setSpeed(100)
|
||||
output.motorA.on(100)
|
||||
loops.pause(200)
|
||||
})
|
||||
```
|
@ -3,13 +3,13 @@
|
||||
This program will play different sounds when the wheel is rotated. The sound is determined by which color is placed in front of the color Sensor.
|
||||
|
||||
```blocks
|
||||
sensors.color3.onColorDetected(ColorSensorColor.Blue, function () {
|
||||
input.color3.onColorDetected(ColorSensorColor.Blue, function () {
|
||||
music.playTone(Note.G4, music.beat(BeatFraction.Half))
|
||||
})
|
||||
sensors.color3.onColorDetected(ColorSensorColor.Red, function () {
|
||||
input.color3.onColorDetected(ColorSensorColor.Red, function () {
|
||||
music.playTone(Note.C5, music.beat(BeatFraction.Half))
|
||||
})
|
||||
sensors.color3.onColorDetected(ColorSensorColor.Green, function () {
|
||||
input.color3.onColorDetected(ColorSensorColor.Green, function () {
|
||||
music.playTone(Note.D5, music.beat(BeatFraction.Half))
|
||||
})
|
||||
```
|
109
docs/static/avatar.svg
vendored
@ -1,109 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1"
|
||||
id="svg2" inkscape:version="0.91 r13725" sodipodi:docname="avatar.svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 32 32"
|
||||
style="enable-background:new 0 0 32 32;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#303030;}
|
||||
</style>
|
||||
<sodipodi:namedview bordercolor="#666666" borderopacity="1" gridtolerance="10" guidetolerance="10" id="namedview15" inkscape:current-layer="svg2" inkscape:cx="16" inkscape:cy="16" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-height="661" inkscape:window-maximized="0" inkscape:window-width="997" inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="5.2149125" objecttolerance="10" pagecolor="#ffffff" showgrid="false">
|
||||
</sodipodi:namedview>
|
||||
<g id="avatar_mf" transform="translate(-5304.979 8145.745)">
|
||||
<path id="Path_180" class="st0" d="M5317.1-8125.6c0.2,0,0.3-0.1,0.5-0.1l2.9-0.6c1.3-0.3,2.5-0.5,3.8-0.8c0.5-0.1,1-0.2,1.5-0.3
|
||||
c0.1,0,0.1,0,0.1-0.1c0-0.5,0-1-0.1-1.5c-0.1-0.6-0.2-1.1-0.3-1.7c-0.1-0.4-0.1-0.8-0.2-1.2c-0.1-0.7-0.2-1.4-0.3-2
|
||||
c-0.1-0.6-0.2-1.1-0.3-1.7c0-0.2-0.2-0.4-0.4-0.4c0,0,0,0-0.1,0c-0.2,0-0.5,0.1-0.7,0.1c-0.5,0.1-1,0.1-1.5,0.2
|
||||
c-0.5,0.1-1,0.1-1.6,0.2c-0.5,0.1-1,0.1-1.4,0.2c-0.2,0-0.3,0-0.5,0.1c-0.2,0-0.4,0.2-0.5,0.4c0,0.2-0.1,0.4-0.1,0.5
|
||||
c0,0.4-0.1,0.8-0.1,1.2c-0.1,0.5-0.1,1-0.2,1.5c0,0.4-0.1,0.9-0.1,1.3l-0.1,1.3l-0.1,1.3c-0.1,0.5-0.1,1-0.2,1.5
|
||||
C5317.1-8126,5317.1-8125.8,5317.1-8125.6z"/>
|
||||
<path id="Path_181" class="st0" d="M5316.1-8140c0,0.6,0.1,1.2,0.1,1.8c0,0.4,0.2,0.8,0.6,1c0.3,0.2,0.7,0.3,1.1,0.3
|
||||
c0.7,0.1,1.4,0.1,2.1,0c0.6,0,1.2-0.1,1.8-0.2c0.4,0,0.9-0.2,1.2-0.5c0.3-0.3,0.5-0.7,0.5-1.1c0-1.2,0-2.3-0.1-3.5
|
||||
c0-0.3-0.1-0.6-0.3-0.8c-0.3-0.4-0.8-0.6-1.4-0.6c0,0,0,0-0.1,0c-0.2,0.1-0.4,0.1-0.6,0.1c-0.9,0-1.8,0.1-2.7,0.1
|
||||
c-0.1,0-0.3,0-0.4,0c-0.4-0.1-0.8,0-1.2,0.2c-0.4,0.2-0.6,0.6-0.7,1c0,0.1,0,0.2,0,0.3C5316-8141.2,5316.1-8140.6,5316.1-8140
|
||||
L5316.1-8140z"/>
|
||||
<path id="Path_182" class="st0" d="M5312-8129.2c0,0.6,0,1.2,0,1.8c0,0.1,0,0.1,0.1,0.1c0.3,0,0.6,0.1,0.9,0.1c0.3,0,0.7,0,1,0
|
||||
c0.1,0,0.2,0,0.3,0c0.1,0,0.1,0,0.1-0.1c0.1-0.4,0.2-0.8,0.2-1.2c0.1-0.5,0.2-1,0.3-1.4c0-0.1,0.1-0.1,0.1-0.1
|
||||
c0.4-0.2,0.8-0.5,1.2-0.8c0.4-0.4,0.7-0.9,0.8-1.5c0.1-0.6,0-1.2-0.4-1.7c-0.2-0.3-0.6-0.4-0.9-0.3c-0.3,0.1-0.6,0.3-0.9,0.5
|
||||
c-0.7,0.6-1.5,1.2-2.2,1.8c-0.3,0.2-0.5,0.5-0.6,0.8c0,0.2-0.1,0.4-0.1,0.6C5311.9-8130.2,5311.9-8129.7,5312-8129.2
|
||||
C5311.9-8129.2,5312-8129.2,5312-8129.2z"/>
|
||||
<path id="Path_183" class="st0" d="M5315.5-8124.7c0,0.2-0.1,0.5-0.1,0.7c-0.1,0.5-0.4,0.9-0.8,1.1c0,0,0,0,0,0
|
||||
c-0.1,0-0.2,0.2-0.2,0.3c-0.4,1.4-0.9,2.7-1.3,4.1c0,0,0,0.1,0,0.1c0.8,1.1,1.6,2.2,2.4,3.3c0,0,0,0,0.1,0.1
|
||||
c0.1-0.2,0.1-0.3,0.2-0.5c0.1-0.3,0.2-0.5,0.3-0.8c0,0,0-0.1,0-0.1c-0.2-0.3-0.5-0.7-0.7-1c0,0,0-0.1,0-0.2
|
||||
c0.3-0.9,0.6-1.7,0.9-2.6c0,0,0-0.1,0.1-0.1c0.5-0.2,0.9-0.6,1.1-1.1c0.1-0.3,0.1-0.7,0.1-1.1c0-0.4-0.1-0.8-0.3-1.2
|
||||
c-0.2-0.4-0.5-0.8-1-1C5315.9-8124.7,5315.7-8124.7,5315.5-8124.7z"/>
|
||||
<path id="Path_184" class="st0" d="M5314.7-8134.2c0.1-0.1,0.2-0.1,0.3-0.2c0.3-0.2,0.7-0.3,1-0.3c0.4,0,0.7,0.2,0.8,0.6
|
||||
c0.6,1.1,0.5,2.4-0.4,3.3c-0.4,0.4-0.8,0.7-1.3,1c0,0-0.1,0.1-0.1,0.1c-0.2,0.8-0.3,1.6-0.5,2.5c0,0,0,0.1,0,0.1
|
||||
c0,0.2,0,0.2-0.2,0.2c-0.1,0-0.1,0-0.2,0c0,0.1,0,0.2,0,0.3c0,0,0,0,0.1,0.1l1.9,0.7c0.2,0.1,0.4,0.2,0.7,0.2c0-0.1,0-0.2,0-0.2
|
||||
c0-0.3,0-0.6,0-0.8l0.2-1.5l0.2-1.5c0.1-0.5,0.1-1,0.2-1.5c0.1-0.5,0.1-1.1,0.2-1.6c0.1-0.5,0.1-1,0.2-1.5c0-0.2,0-0.4,0-0.6
|
||||
c0-0.2-0.1-0.4-0.3-0.4c0,0,0,0,0,0c-0.1,0-0.1,0-0.2,0c-0.6-0.1-1.2-0.2-1.9-0.3c-0.1,0-0.2,0-0.3,0c-0.1,0-0.2,0.1-0.3,0.3
|
||||
C5314.8-8135,5314.7-8134.6,5314.7-8134.2z"/>
|
||||
<path id="Path_185" class="st0" d="M5324.5-8117.2c-0.2-0.7-0.5-1.3-0.7-2l-0.7,0.3c0,0-0.1,0-0.1,0c-0.1,0.1-0.2,0-0.2-0.1
|
||||
c-0.1-0.3-0.2-0.5-0.3-0.8c-0.2-0.7-0.5-1.4-0.7-2.1c0,0,0-0.1,0-0.1c0,0,0,0.1-0.1,0.1c-0.1,0.2-0.3,0.3-0.5,0.5c0,0-0.1,0-0.1,0
|
||||
c-0.3,0.1-0.6,0.1-0.8,0.2c0,0-0.1,0-0.1,0c0,0.2-0.1,0.3-0.1,0.5c0.6,1.5,1.1,3.1,1.7,4.6c0,0,0,0,0,0.1
|
||||
C5322.7-8116.3,5323.6-8116.7,5324.5-8117.2z"/>
|
||||
<path id="Path_186" class="st0" d="M5325.4-8123.1c-0.7,0.2-1.3,0.3-2,0.5c-0.5,0.1-0.9,0.2-1.4,0.3c-0.1,0-0.2,0.1-0.1,0.2
|
||||
c0,0,0,0,0,0.1c0.2,0.5,0.3,0.9,0.5,1.4c0.2,0.5,0.4,1.1,0.6,1.6c0,0,0,0,0,0c0.1-0.1,0.2-0.1,0.3-0.2c0.2-0.1,0.3-0.2,0.5-0.2
|
||||
c0.2-0.1,0.4-0.1,0.6-0.2c0.7-0.2,1.5-0.4,2.2-0.6c0,0,0,0,0.1,0C5326.3-8121.1,5325.9-8122.1,5325.4-8123.1z"/>
|
||||
<path id="Path_187" class="st0" d="M5320.7-8124.4c-0.4,0.1-0.8,0.2-1.2,0.3c-0.6,0.1-1.3,0.3-1.9,0.4c0,0-0.1,0-0.1,0
|
||||
c-0.1,0-0.2-0.1-0.3-0.1c0,0,0,0.1,0,0.1c0.3,0.7,0.4,1.5,0.3,2.2c-0.1,0.4-0.3,0.8-0.5,1.1c0,0,0,0-0.1,0.1
|
||||
c0.2-0.1,0.4-0.1,0.6-0.1l2.5-0.6c0.5-0.1,0.9-0.6,1-1.1c0.1-0.5,0-1-0.1-1.5C5320.8-8124,5320.8-8124.2,5320.7-8124.4z"/>
|
||||
<path id="Path_188" class="st0" d="M5325.5-8127c-2.7,0.5-5.3,1.1-7.9,1.6c0,0.5,0,0.9,0.1,1.4c0.1,0,0.2,0,0.3-0.1
|
||||
c1.2-0.3,2.3-0.5,3.5-0.8c1.2-0.3,2.4-0.5,3.6-0.8c0.1,0,0.3-0.1,0.4-0.1c0,0,0.1,0,0.1-0.1
|
||||
C5325.6-8126.2,5325.5-8126.6,5325.5-8127z"/>
|
||||
<path id="Path_189" class="st0" d="M5328.6-8118.4c-0.2-0.4-0.3-0.7-0.5-1.1c-0.1-0.2-0.2-0.5-0.3-0.7c0-0.1,0-0.1-0.1,0
|
||||
c-1.2,0.3-2.4,0.6-3.6,1c0,0,0,0-0.1,0c0.2,0.7,0.5,1.3,0.7,2C5326-8117.6,5327.3-8118,5328.6-8118.4z"/>
|
||||
<path id="Path_190" class="st0" d="M5319.9-8120.9l-0.6,0.1c-1,0.2-2,0.5-3,0.7c-0.1,0-0.1,0.1-0.1,0.1c-0.3,0.7-0.5,1.5-0.8,2.2
|
||||
c0,0,0,0,0,0.1c0.2,0,0.4-0.1,0.5-0.1c1-0.3,2-0.5,3.1-0.8c0.1,0,0.2-0.1,0.3-0.2C5319.5-8119.5,5319.7-8120.2,5319.9-8120.9z"/>
|
||||
<path id="Path_191" class="st0" d="M5325.1-8125.4c-1.1,0.2-2.2,0.5-3.3,0.7c0.3,0.7,0.4,1.4,0.3,2.2c0.2,0,0.4-0.1,0.5-0.1
|
||||
c0.9-0.2,1.8-0.4,2.7-0.6c0.1,0,0.1,0,0.1-0.1c0.1-0.4,0-0.9-0.1-1.3C5325.3-8124.9,5325.2-8125.1,5325.1-8125.4
|
||||
C5325.1-8125.3,5325.1-8125.4,5325.1-8125.4z"/>
|
||||
<path id="Path_192" class="st0" d="M5325.6-8132c0.2,0,0.4,0,0.5,0c0.2,0,0.4,0,0.6,0c0.3,0,0.6-0.2,0.8-0.4c0.3-0.4,0.7-0.8,1-1.2
|
||||
c-0.1-0.1-0.1-0.1-0.1-0.2c0,0,0,0-0.1,0c-0.7-0.1-1.3-0.5-1.4-1.2c-0.1-0.2-0.1-0.4-0.1-0.6c-0.2,0.1-0.3,0.3-0.5,0.4
|
||||
c-0.1,0.1-0.2,0.1-0.3,0.2c0,0-0.1,0.1-0.2,0c-0.2,0-0.5-0.1-0.7-0.1c0,0,0,0-0.1,0C5325.3-8134.1,5325.4-8133.1,5325.6-8132z"/>
|
||||
<path id="Path_193" class="st0" d="M5328.4-8134.2c0.2-0.3,0.5-0.5,0.8-0.7c0.4-0.4,0.6-0.8,0.7-1.4c0-0.1,0-0.2-0.1-0.3
|
||||
c-0.3-0.5-0.7-1.1-1-1.6c0-0.1-0.1-0.1-0.1,0c-0.4,0.2-0.8,0.5-1.1,0.8c-0.2,0.2-0.4,0.4-0.6,0.6c-0.1,0.1-0.1,0.3,0,0.4
|
||||
c0.5,0.7,1,1.5,1.4,2.2C5328.4-8134.2,5328.4-8134.2,5328.4-8134.2z"/>
|
||||
<path id="Path_194" class="st0" d="M5314.3-8126.1c-0.1-0.1-0.1-0.1-0.2-0.2c-0.1,0-0.1-0.1-0.1-0.2c0-0.1,0-0.3,0-0.4h-0.1
|
||||
c-0.6,0-1.2-0.1-1.7-0.2c0,0-0.1,0-0.1,0c-0.4,0.2-0.7,0.4-1,0.8c-0.4,0.6-0.4,1.4,0.1,1.9c0.2,0.2,0.4,0.4,0.6,0.6
|
||||
c0.1,0.1,0.2,0.2,0.3,0.2c-0.2-0.6,0-1.3,0.5-1.8C5313-8125.9,5313.6-8126.2,5314.3-8126.1z"/>
|
||||
<path id="Path_195" class="st0" d="M5315.7-8114.9c0.5-0.1,0.9-0.3,1.4-0.4c0.8-0.2,1.6-0.4,2.4-0.7c0.1,0,0.1,0,0.1-0.1
|
||||
c0.1-0.4,0.2-0.7,0.4-1.1c0,0,0,0,0-0.1c-0.1,0-0.2,0-0.3,0.1c-1.2,0.3-2.3,0.6-3.5,1c-0.1,0-0.1,0.1-0.1,0.1
|
||||
c-0.1,0.4-0.3,0.7-0.4,1.1C5315.7-8115,5315.7-8115,5315.7-8114.9z"/>
|
||||
<path id="Path_196" class="st0" d="M5315.4-8117.4c0.2,0.3,0.4,0.6,0.6,0.9c0,0,0.1,0,0.1,0c1-0.3,1.9-0.5,2.9-0.8
|
||||
c0.3-0.1,0.6-0.2,0.9-0.2c-0.1-0.1-0.1-0.2-0.2-0.2c-0.2-0.2-0.3-0.4-0.5-0.6c0,0-0.1-0.1-0.1,0c-0.9,0.3-1.9,0.5-2.8,0.8
|
||||
C5316-8117.5,5315.7-8117.5,5315.4-8117.4z"/>
|
||||
<path id="Path_197" class="st0" d="M5321.3-8143.6c0-0.3,0-0.7,0-1c0,0-0.1,0-0.1,0c-0.7,0-1.5,0-2.2,0.1c-0.4,0-0.7,0-1.1,0.1
|
||||
c-0.1,0-0.1,0-0.1,0.1c0,0.3,0,0.6,0,0.8c0,0,0,0.1,0.1,0.1c0.4,0,0.8,0,1.1,0c0.5,0,1.1,0,1.6-0.1
|
||||
C5320.9-8143.5,5321.1-8143.6,5321.3-8143.6z"/>
|
||||
<path id="Path_198" class="st0" d="M5329.2-8134.3c0.1,0,0.2,0,0.2-0.1c0.4-0.2,0.8-0.4,1.1-0.7c0.3-0.2,0.4-0.5,0.6-0.8
|
||||
c0.1-0.3,0.1-0.6-0.1-0.9c-0.4-0.5-0.7-1-1.1-1.6c0,0,0,0-0.1-0.1c-0.2,0.2-0.4,0.4-0.6,0.6c0,0,0,0,0,0c0,0,0,0.1,0,0.1
|
||||
c0.2,0.4,0.5,0.7,0.7,1c0.1,0.2,0.2,0.4,0.1,0.6c0,0.5-0.1,0.9-0.4,1.3c-0.1,0.1-0.2,0.2-0.3,0.3
|
||||
C5329.4-8134.5,5329.3-8134.4,5329.2-8134.3C5329.2-8134.3,5329.2-8134.3,5329.2-8134.3z"/>
|
||||
<path id="Path_199" class="st0" d="M5317.5-8136.7c0,0.2,0,0.3,0,0.5c0,0,0,0.1,0.1,0.1c0.2,0,0.3,0.1,0.5,0.1c0.7,0.1,1.4,0.1,2,0
|
||||
c0.4,0,0.8-0.1,1.2-0.1c0.2,0,0.5-0.1,0.7-0.1c0.1,0,0.1,0,0.1-0.1c0-0.2,0-0.3,0-0.5C5320.5-8136.6,5319-8136.5,5317.5-8136.7z"/>
|
||||
<path id="Path_200" class="st0" d="M5312.5-8123.2c0.1-0.4,0.1-0.8,0.2-1.2c0.1-0.6,0.6-1,1.2-1c0.3,0,0.5,0.1,0.7,0.3
|
||||
c0.2,0.2,0.2,0.4,0.2,0.7c-0.1,0.3-0.2,0.6-0.2,0.9c0,0.1-0.1,0.2-0.1,0.4c0,0,0,0,0,0c0.1-0.1,0.2-0.2,0.3-0.3
|
||||
c0.3-0.4,0.4-0.9,0.4-1.4c0-0.6-0.4-1-0.9-1.1c-0.1,0-0.1,0-0.2,0c-0.5,0-1,0.3-1.4,0.7c-0.3,0.3-0.4,0.6-0.5,1
|
||||
c-0.1,0.3,0,0.7,0.2,1C5312.5-8123.2,5312.5-8123.2,5312.5-8123.2z"/>
|
||||
<path id="Path_201" class="st0" d="M5314.3-8123.2c0.1-0.5,0.3-0.9,0.4-1.4c0.1-0.2,0-0.4-0.2-0.5c-0.4-0.2-0.9-0.1-1.2,0.2
|
||||
c0,0,0,0,0,0.1c0,0.2,0,0.4,0.1,0.6c0,0.1,0.1,0.2,0.2,0.3C5313.7-8123.6,5314-8123.4,5314.3-8123.2
|
||||
C5314.2-8123.2,5314.3-8123.2,5314.3-8123.2z"/>
|
||||
<path id="Path_202" class="st0" d="M5317.4-8124.1c0-0.4,0-0.9-0.1-1.3c-0.1,0-0.1,0-0.2,0c-0.1,0-0.2,0-0.3,0
|
||||
c-0.7-0.3-1.4-0.5-2.1-0.8c0,0,0,0,0,0c0.1,0.1,0.1,0.1,0.2,0.2c0.3,0.2,0.5,0.6,0.6,0.9c0,0,0,0,0,0c0.1,0,0.3,0,0.4,0.1
|
||||
c0.3,0.1,0.6,0.3,0.9,0.5c0,0,0.1,0.1,0.1,0.1C5317.1-8124.2,5317.2-8124.1,5317.4-8124.1z"/>
|
||||
<path id="Path_203" class="st0" d="M5321.6-8124.6c-0.2,0-0.4,0.1-0.6,0.1c0.1,0.2,0.1,0.4,0.2,0.6c0.1,0.4,0.2,0.8,0.1,1.2
|
||||
c0,0.5-0.1,0.9-0.4,1.3c0,0,0,0,0,0c0.3,0,0.6-0.2,0.7-0.5c0.2-0.3,0.3-0.6,0.3-0.9C5321.9-8123.4,5321.8-8124,5321.6-8124.6z"/>
|
||||
<path id="Path_204" class="st0" d="M5315.7-8135.8c0.2,0,0.3,0.1,0.5,0.1c0.5,0.1,1,0.2,1.5,0.2c0.2,0,0.5,0,0.7,0
|
||||
c0.7-0.1,1.4-0.2,2.1-0.2c0.6-0.1,1.2-0.2,1.8-0.2c0.5-0.1,1.1-0.1,1.6-0.2l-1.5-0.2c0,0,0,0,0,0c0,0.2-0.1,0.3-0.2,0.3
|
||||
c0,0,0,0,0,0c-0.3,0.1-0.5,0.1-0.8,0.2c-0.8,0.1-1.6,0.1-2.3,0.1c-0.4,0-0.9,0-1.3-0.1c-0.1,0-0.2-0.1-0.3-0.2c0,0-0.1,0-0.1,0
|
||||
c-0.3,0-0.6,0.1-0.9,0.1L5315.7-8135.8L5315.7-8135.8z"/>
|
||||
<path id="Path_205" class="st0" d="M5327.3-8117.7c-0.3,0.1-0.5,0.2-0.8,0.2c-0.6,0.2-1.1,0.3-1.7,0.5c0,0-0.1,0-0.1,0.1
|
||||
c-0.5,0.2-1,0.5-1.5,0.7c0,0,0,0,0,0c0.3-0.1,0.5-0.1,0.8-0.2c0.5-0.2,1.1-0.3,1.6-0.5c0.1,0,0.2-0.1,0.2-0.1
|
||||
C5326.2-8117.2,5326.8-8117.5,5327.3-8117.7C5327.3-8117.7,5327.3-8117.7,5327.3-8117.7C5327.3-8117.7,5327.3-8117.7,5327.3-8117.7
|
||||
z"/>
|
||||
<path id="Path_206" class="st0" d="M5327-8135.8c0,0.1,0,0.2,0,0.4c0.1,0.5,0.3,0.9,0.7,1.1c0.1,0.1,0.3,0.1,0.4,0.2l0,0
|
||||
C5327.8-8134.7,5327.4-8135.2,5327-8135.8L5327-8135.8z"/>
|
||||
<path id="Path_207" class="st0" d="M5329-8134.4c-0.1,0.1-0.2,0.2-0.3,0.4c0,0,0,0,0,0.1c0,0.1,0,0.1,0.1,0.1c0.1,0,0.2,0,0.3-0.1
|
||||
c0.1,0,0.2-0.1,0.3-0.1c-0.1,0-0.1-0.1-0.2-0.1C5329-8134.2,5329-8134.3,5329-8134.4z"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 11 KiB |
4
docs/static/filelogo.svg
vendored
@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<path fill="#aa278f" d="M32 15.994v-.011c0-.108-.005-.209-.016-.303h-.001c-.032-.285-.112-.504-.239-.656-.171-.204-.459-.435-.864-.691a4.275 4.275 0 0 1-.986-.827c-.252-.296-.442-.734-.57-1.316-.049-.227-.087-.719-.112-1.473V8.696c0-.38-.031-.723-.076-1.049a12.313 12.313 0 0 0-.004-.188c-.009-.782-.18-1.475-.513-2.078a3.462 3.462 0 0 0-1.416-1.401c-.611-.33-1.305-.495-2.081-.495H6.271s-.674.067-.962.201a4.021 4.021 0 0 0-.521.295 3.502 3.502 0 0 0-.798.59c-.693.688-1.061 1.601-1.113 2.734a9.172 9.172 0 0 0-.088 1.283v2.558a6.802 6.802 0 0 1-.183 1.373 2.311 2.311 0 0 1-.532 1.033 2.67 2.67 0 0 0-.202.196c-.265.238-.638.511-1.13.823-.404.262-.64.633-.715 1.108l-.002.023a2.195 2.195 0 0 0-.023.287L0 16.006v.011c0 .108.005.209.016.303h.001c.032.285.112.504.239.656.171.204.459.435.864.691.406.256.735.532.986.827.252.296.442.734.57 1.316.049.227.087.719.112 1.473v2.019c0 .38.031.723.076 1.049l.004.188c.009.782.18 1.475.513 2.078a3.462 3.462 0 0 0 1.416 1.401c.611.33 1.305.495 2.081.495H25.73c.35 0 .673-.067.961-.201.184-.085.356-.187.521-.296.291-.159.559-.353.798-.59.693-.688 1.061-1.601 1.113-2.734.056-.398.088-.823.088-1.283v-2.558c.019-.495.079-.953.183-1.373.104-.419.282-.762.532-1.033a2.67 2.67 0 0 0 .202-.196c.265-.238.638-.511 1.13-.823.404-.262.64-.633.715-1.108h.002l.002-.023c.013-.092.022-.187.023-.287v-.014z"/>
|
||||
<path fill="#fff" d="M27.366 16.522l.819-.518-.821-.516a4.547 4.547 0 0 1-.927-.744 3.033 3.033 0 0 1-.554-.896 5.166 5.166 0 0 1-.328-1.339 16.319 16.319 0 0 1-.103-1.961c0-.781-.016-1.365-.05-1.786-.039-.489-.123-.852-.258-1.112a1.36 1.36 0 0 0-.718-.661c-.223-.089-.527-.154-.924-.199a.532.532 0 0 1-.356-.213c-.11-.133-.165-.344-.165-.627 0-.41.086-.811 1.121-.811.636 0 1.196.127 1.666.376.464.247.818.589 1.085 1.046.267.458.406.995.413 1.597.064 3.554.129 4.265.184 4.492.153.63.382 1.109.701 1.464.287.319.635.602 1.035.843.29.175.501.341.627.493.035.043.116.181.116.554 0 .383-.12.628-.39.794-.606.373-1.041.699-1.331.997a2.734 2.734 0 0 0-.678 1.24c-.112.437-.177 1.05-.198 1.875-.02.773-.042 1.741-.066 2.904-.021.941-.306 1.668-.873 2.222-.568.554-1.317.823-2.291.823-.409 0-.71-.077-.895-.23-.155-.128-.226-.32-.226-.604 0-.179.03-.336.093-.479a.682.682 0 0 1 .188-.268.463.463 0 0 1 .24-.094c.414-.055.725-.127.951-.219.317-.131.567-.378.723-.716.124-.269.2-.625.233-1.089.029-.402.044-.968.044-1.725.016-1.061.077-1.896.182-2.481.095-.53.274-.987.533-1.359.261-.375.665-.736 1.198-1.073zm-16.618 6.519h10.458a.75.75 0 0 0 .751-.751l-.001-3.709c-.134-.449-.518-.492-.878-.15-.033 0-.393.443-1.22.443a2.033 2.033 0 0 1-1.944-1.715h-.011a6.59 6.59 0 0 1 0-.526h.011a2.03 2.03 0 0 1 1.944-1.715c.827 0 1.187.443 1.22.443.35.332.738.252.879-.147l.001-3.432a.769.769 0 0 0-.562-.741c-.061.016-3.259 0-3.259 0-.786.065-1.063-.466-.624-.928 0-.033.443-.393.443-1.22a2.033 2.033 0 0 0-1.715-1.944v-.011a6.59 6.59 0 0 0-.526 0v.011A2.03 2.03 0 0 0 14 8.893c0 .827.443 1.187.443 1.22.439.462.254.97-.624.928 0 0-3.198.016-3.259 0a.77.77 0 0 0-.562.741V22.29a.75.75 0 0 0 .75.751zm-6.197-3.692c.055.227.12.938.184 4.492.007.602.146 1.138.413 1.597.267.458.622.8 1.085 1.046.47.25 1.03.376 1.666.376 1.035 0 1.121-.4 1.121-.811 0-.283-.056-.493-.165-.627a.537.537 0 0 0-.356-.213c-.397-.045-.701-.11-.925-.199a1.367 1.367 0 0 1-.718-.661c-.135-.259-.219-.623-.258-1.112a24.159 24.159 0 0 1-.05-1.786c0-.751-.035-1.41-.103-1.961a5.174 5.174 0 0 0-.329-1.339 3.028 3.028 0 0 0-.554-.896 4.52 4.52 0 0 0-.927-.744l-.821-.516.819-.518c.533-.337.936-.698 1.199-1.075.259-.372.438-.829.533-1.359.105-.585.166-1.419.182-2.481 0-.757.014-1.323.044-1.725.033-.464.109-.82.233-1.089.156-.337.406-.584.723-.715.226-.092.537-.163.951-.219a.463.463 0 0 0 .24-.094.662.662 0 0 0 .189-.267 1.18 1.18 0 0 0 .093-.479c0-.284-.072-.476-.226-.604-.186-.153-.487-.23-.895-.23-.974 0-1.723.269-2.291.823-.567.554-.852 1.281-.873 2.222a588.806 588.806 0 0 1-.065 2.904c-.021.825-.086 1.438-.198 1.875a2.731 2.731 0 0 1-.679 1.24c-.289.298-.725.624-1.331.997-.27.166-.39.41-.39.794 0 .373.081.511.116.554.127.153.338.319.627.493.4.24.748.524 1.035.843.319.355.548.834.701 1.464z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.1 KiB |
BIN
docs/static/hero.png
vendored
Before Width: | Height: | Size: 585 KiB After Width: | Height: | Size: 40 KiB |
BIN
docs/static/lessons/line-detection.jpg
vendored
Before Width: | Height: | Size: 25 KiB |
BIN
docs/static/lessons/line-detection/car-driving.jpg
vendored
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 41 KiB |
BIN
docs/static/lessons/make-it-move.jpg
vendored
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 29 KiB |
BIN
docs/static/lessons/make-it-move/walker-bot.jpg
vendored
Before Width: | Height: | Size: 26 KiB |
@ -4,11 +4,10 @@
|
||||
import { deployCoreAsync, initAsync } from "./deploy";
|
||||
import { FieldPorts } from "./field_ports";
|
||||
import { FieldImages } from "./field_images";
|
||||
import { FieldSpeed } from "./field_speed";
|
||||
import {FieldSpeed} from "./field_speed";
|
||||
import { FieldBrickButtons } from "./field_brickbuttons";
|
||||
import { FieldTurnRatio } from "./field_turnratio";
|
||||
|
||||
pxt.editor.initExtensionsAsync = function(opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
|
||||
pxt.editor.initExtensionsAsync = function (opts: pxt.editor.ExtensionOptions): Promise<pxt.editor.ExtensionResult> {
|
||||
pxt.debug('loading pxt-ev3 target extensions...')
|
||||
updateBlocklyShape();
|
||||
const res: pxt.editor.ExtensionResult = {
|
||||
@ -24,9 +23,6 @@ pxt.editor.initExtensionsAsync = function(opts: pxt.editor.ExtensionOptions): Pr
|
||||
}, {
|
||||
selector: "brickbuttons",
|
||||
editor: FieldBrickButtons
|
||||
}, {
|
||||
selector: "turnratio",
|
||||
editor: FieldTurnRatio
|
||||
}],
|
||||
deployCoreAsync
|
||||
};
|
||||
|
@ -24,9 +24,6 @@ export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCu
|
||||
this.width_ = parseInt(options.width) || 300;
|
||||
}
|
||||
|
||||
trimOptions_() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dropdown menu under the text.
|
||||
* @private
|
||||
@ -45,8 +42,7 @@ export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCu
|
||||
// Accessibility properties
|
||||
contentDiv.setAttribute('role', 'menu');
|
||||
contentDiv.setAttribute('aria-haspopup', 'true');
|
||||
let options = this.getOptions();
|
||||
options = options.sort();
|
||||
const options = this.getOptions();
|
||||
for (let i = 0, option: any; option = options[i]; i++) {
|
||||
let content = (options[i] as any)[0]; // Human-readable text or image.
|
||||
const value = (options[i] as any)[1]; // Language-neutral value.
|
||||
|
@ -1,108 +0,0 @@
|
||||
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||
|
||||
export interface FieldTurnRatioOptions extends Blockly.FieldCustomOptions {
|
||||
}
|
||||
|
||||
export class FieldTurnRatio extends Blockly.FieldSlider implements Blockly.FieldCustom {
|
||||
public isFieldCustom_ = true;
|
||||
|
||||
private params: any;
|
||||
|
||||
private path_: SVGPathElement;
|
||||
private reporter_: SVGTextElement;
|
||||
|
||||
/**
|
||||
* Class for a color wheel field.
|
||||
* @param {number|string} value The initial content of the field.
|
||||
* @param {Function=} opt_validator An optional function that is called
|
||||
* to validate any constraints on what the user entered. Takes the new
|
||||
* text as an argument and returns either the accepted text, a replacement
|
||||
* text, or null to abort the change.
|
||||
* @extends {Blockly.FieldNumber}
|
||||
* @constructor
|
||||
*/
|
||||
constructor(value_: any, params: FieldTurnRatioOptions, opt_validator?: Function) {
|
||||
super(String(value_), '-100', '100', null, '10', 'TurnRatio', opt_validator);
|
||||
this.params = params;
|
||||
(this as any).sliderColor_ = '#a8aaa8';
|
||||
}
|
||||
|
||||
static HALF = 80;
|
||||
static HANDLE_RADIUS = 30;
|
||||
static RADIUS = FieldTurnRatio.HALF - FieldTurnRatio.HANDLE_RADIUS - 1;
|
||||
|
||||
createLabelDom_(labelText: string) {
|
||||
let labelContainer = document.createElement('div');
|
||||
let svg = Blockly.utils.createSvgElement('svg', {
|
||||
'xmlns': 'http://www.w3.org/2000/svg',
|
||||
'xmlns:html': 'http://www.w3.org/1999/xhtml',
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
'version': '1.1',
|
||||
'height': (FieldTurnRatio.HALF + FieldTurnRatio.HANDLE_RADIUS + 10) + 'px',
|
||||
'width': (FieldTurnRatio.HALF * 2) + 'px'
|
||||
}, labelContainer);
|
||||
let defs = Blockly.utils.createSvgElement('defs', {}, svg);
|
||||
let marker = Blockly.utils.createSvgElement('marker', {
|
||||
'id': 'head',
|
||||
'orient': "auto",
|
||||
'markerWidth': '2',
|
||||
'markerHeight': '4',
|
||||
'refX': '0.1', 'refY': '1.5'
|
||||
}, defs);
|
||||
let markerPath = Blockly.utils.createSvgElement('path', {
|
||||
'd': 'M0,0 V3 L1.5,1.5 Z',
|
||||
'fill': '#f12a21'
|
||||
}, marker);
|
||||
this.reporter_ = pxsim.svg.child(svg, "text", {
|
||||
'x': FieldTurnRatio.HALF, 'y': 96,
|
||||
'text-anchor': 'middle', 'alignment-baseline': 'middle',
|
||||
'style': 'font-size: 50px',
|
||||
'class': 'sim-text inverted number'
|
||||
}) as SVGTextElement;
|
||||
this.path_ = Blockly.utils.createSvgElement('path', {
|
||||
'x1': FieldTurnRatio.HALF,
|
||||
'y1': FieldTurnRatio.HALF,
|
||||
'marker-end': 'url(#head)',
|
||||
'style': 'fill: none; stroke: #f12a21; stroke-width: 10'
|
||||
}, svg);
|
||||
this.updateGraph_();
|
||||
let readout = document.createElement('span');
|
||||
readout.setAttribute('class', 'blocklyFieldSliderReadout');
|
||||
return [labelContainer, readout];
|
||||
};
|
||||
|
||||
updateGraph_() {
|
||||
if (!this.path_) {
|
||||
return;
|
||||
}
|
||||
let v = goog.math.clamp(parseFloat(this.getText()), -100, 100);
|
||||
if (isNaN(v)) {
|
||||
v = 0;
|
||||
}
|
||||
|
||||
const x = goog.math.clamp(parseFloat(this.getText()), -100, 100) / 100;
|
||||
const theta = x * Math.PI / 2;
|
||||
const cx = FieldTurnRatio.HALF;
|
||||
const cy = FieldTurnRatio.HALF - 14;
|
||||
const gamma = Math.PI - 2 * theta;
|
||||
const r = FieldTurnRatio.RADIUS;
|
||||
const alpha = 0.2 + Math.abs(x) * 0.5;
|
||||
const x1 = 0;
|
||||
const y1 = r * alpha;
|
||||
const y2 = r * Math.sin(Math.PI / 2 - theta);
|
||||
const x2 = r * Math.cos(Math.PI / 2 - theta);
|
||||
const y3 = y2 - r * alpha * Math.cos(2 * theta);
|
||||
const x3 = x2 - r * alpha * Math.sin(2 * theta);
|
||||
|
||||
|
||||
const d = `M ${cx} ${cy} C ${cx} ${cy - y1} ${cx + x3} ${cy - y3} ${cx + x2} ${cy - y2}`;
|
||||
this.path_.setAttribute('d', d);
|
||||
|
||||
this.reporter_.textContent = `${v}`;
|
||||
}
|
||||
|
||||
setReadout_(readout: Element, value: string) {
|
||||
this.updateGraph_();
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
{
|
||||
"automation": "Automation, process control and robotic controllers",
|
||||
"automation.Behavior": "A behavior",
|
||||
"automation.Behavior.update": "Called on each behavior iteration even for suppresed behaviors",
|
||||
"automation.Behavior.update|param|elapsed": "milli seconds since last call",
|
||||
"automation.BehaviorManager": "A manager for behaviors",
|
||||
"automation.BehaviorManager.add": "Adds a new behavior to the behavior manager",
|
||||
"automation.BehaviorManager.add|param|behavior": "the behavior to add",
|
||||
"automation.BehaviorManager.start": "Starts the behavior control loop",
|
||||
"automation.BehaviorManager.stop": "Stops the execution loop",
|
||||
"automation.PIDController": "A PID controller.\n* Reference: Feedback System, Karl Johan Astrom & Rickard M. Murry",
|
||||
"automation.PIDController.compute": "Computes the output based on the system state",
|
||||
"automation.PIDController.setControlSaturation": "Sets the control saturation values",
|
||||
"automation.PIDController.setControlSaturation|param|high": "highest control value, eg: 100",
|
||||
"automation.PIDController.setControlSaturation|param|low": "lowest control value, eg: -100",
|
||||
"automation.PIDController.setDerivativeFilter": "Sets the derivative filter gain",
|
||||
"automation.PIDController.setDerivativeFilter|param|N": "the filter gain, eg:10",
|
||||
"automation.PIDController.setGains": "Sets the PID gains",
|
||||
"automation.PIDController.setGains|param|b": "setpoint weight, eg: 0.9",
|
||||
"automation.PIDController.setGains|param|kd": "derivative gain",
|
||||
"automation.PIDController.setGains|param|ki": "integral gain",
|
||||
"automation.PIDController.setGains|param|kp": "proportional gain",
|
||||
"automation.PIDController.setPoint": "Updates the desired setpoint",
|
||||
"automation.addBehavior": "Adds the behavior and starts it",
|
||||
"automation.addBehavior|param|behavior": "a behavior"
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"automation.PIDController.compute|block": "%pid|compute for timestep %timestep|(ms) at state %y",
|
||||
"automation.PIDController.setControlSaturation|block": "set %pid|control saturation from %low|to %high",
|
||||
"automation.PIDController.setDerivativeFilter|block": "set %pid|derivative filter %N",
|
||||
"automation.PIDController.setGains|block": "set %pid|gains kp %kp|ki %ki|kd %kd",
|
||||
"automation.PIDController.setPoint|block": "set %pid|point to %ysp",
|
||||
"automation.addBehavior|block": "add behavior %behavior",
|
||||
"automation|block": "automation",
|
||||
"{id:category}Automation": "Automation",
|
||||
"{id:group}Behaviors": "Behaviors",
|
||||
"{id:group}PID": "PID"
|
||||
}
|
@ -134,7 +134,7 @@
|
||||
"control.panic": "Display an error code and stop the program.",
|
||||
"control.panic|param|code": "an error number to display. eg: 5",
|
||||
"control.reset": "Reset the device.",
|
||||
"control.runInParallel": "Run other code in the parallel.",
|
||||
"control.runInBackground": "Run other code in the background.",
|
||||
"control.waitForEvent": "Blocks the calling thread until the specified event is raised.",
|
||||
"control.waitMicros": "Block the current fiber for the given microseconds",
|
||||
"control.waitMicros|param|micros": "number of micro-seconds to wait. eg: 4",
|
||||
|
@ -25,11 +25,10 @@
|
||||
"control.onEvent|block": "on event|from %src|with value %value",
|
||||
"control.panic|block": "panic %code",
|
||||
"control.reset|block": "reset",
|
||||
"control.runInParallel|block": "run in parallel",
|
||||
"control.runInBackground|block": "run in background",
|
||||
"control.waitForEvent|block": "wait for event|from %src|with value %value",
|
||||
"control.waitMicros|block": "wait (µs)%micros",
|
||||
"control|block": "control",
|
||||
"fieldeditors|block": "fieldeditors",
|
||||
"loops.forever|block": "forever",
|
||||
"loops.pause|block": "pause %pause=timePicker|ms",
|
||||
"loops|block": "loops",
|
||||
|
@ -17,8 +17,7 @@
|
||||
"control.cpp",
|
||||
"control.ts",
|
||||
"serial.cpp",
|
||||
"serial.ts",
|
||||
"fieldeditors.ts"
|
||||
"serial.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
"test.ts"
|
||||
|
8
libs/base/shims.d.ts
vendored
@ -118,11 +118,11 @@ declare namespace control {
|
||||
function waitMicros(micros: int32): void;
|
||||
|
||||
/**
|
||||
* Run other code in the parallel.
|
||||
* Run other code in the background.
|
||||
*/
|
||||
//% help=control/run-in-parallel handlerStatement=1
|
||||
//% blockId="control_run_in_parallel" block="run in parallel" blockGap=8 shim=control::runInParallel
|
||||
function runInParallel(a: () => void): void;
|
||||
//% help=control/run-in-background blockAllowMultiple=1 afterOnStart=true
|
||||
//% blockId="control_run_in_background" block="run in background" blockGap=8 shim=control::runInBackground
|
||||
function runInBackground(a: () => void): void;
|
||||
|
||||
/**
|
||||
* Blocks the calling thread until the specified event is raised.
|
||||
|
14
libs/behaviors/_locales/behaviors-jsdoc-strings.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"behaviors": "Behavior drive blocks",
|
||||
"behaviors.Behavior": "A behavior",
|
||||
"behaviors.BehaviorManager": "A manager for behaviors",
|
||||
"behaviors.BehaviorManager.add": "Adds a new behavior to the behavior manager",
|
||||
"behaviors.BehaviorManager.add|param|behavior": "the behavior to add",
|
||||
"behaviors.BehaviorManager.start": "Starts the behavior control loop",
|
||||
"behaviors.BehaviorManager.stop": "Stops the execution loop",
|
||||
"behaviors.addBehavior": "Adds the behavior and starts it",
|
||||
"behaviors.addBehavior|param|behavior": "a behavior",
|
||||
"behaviors.avoidCrash": "A behavior that stops all motors if the sensor distance get too short",
|
||||
"behaviors.driveForward": "A behavior that turns on the motors to the specified speed",
|
||||
"behaviors.driveForward|param|motors": "@param speed the desired speed, eg: 50"
|
||||
}
|
7
libs/behaviors/_locales/behaviors-strings.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"behaviors.addBehavior|block": "add behavior %behavior",
|
||||
"behaviors.avoidCrash|block": "avoid crash using %ultrasonic",
|
||||
"behaviors.driveForward|block": "drive %motors|forward at %speed=motorSpeedPicker|%",
|
||||
"behaviors|block": "behaviors",
|
||||
"{id:category}Behaviors": "Behaviors"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/automation",
|
||||
"additionalFilePath": "../../node_modules/pxt-common-packages/libs/behaviors",
|
||||
"dependencies": {
|
||||
"ev3": "file:../ev3"
|
||||
"core": "file:../ev3"
|
||||
}
|
||||
}
|
56
libs/behaviors/targetoverrides.ts
Normal file
@ -0,0 +1,56 @@
|
||||
namespace behaviors {
|
||||
class AvoidCrashBehavior extends behaviors.Behavior {
|
||||
private ultrasonic: sensors.UltraSonicSensor;
|
||||
constructor(ultrasonic: sensors.UltraSonicSensor) {
|
||||
super();
|
||||
this.ultrasonic = ultrasonic;
|
||||
}
|
||||
|
||||
shouldRun(): boolean {
|
||||
return this.ultrasonic.distance() < 5;
|
||||
}
|
||||
|
||||
run(): void {
|
||||
motors.stopAllMotors();
|
||||
this.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A behavior that stops all motors if the sensor distance get too short
|
||||
*/
|
||||
//% blockId=behaviorsAvoidCrash block="avoid crash using %ultrasonic"
|
||||
export function avoidCrash(ultrasonic: sensors.UltraSonicSensor) : behaviors.Behavior {
|
||||
return new AvoidCrashBehavior(ultrasonic);
|
||||
}
|
||||
|
||||
class DriveForwardBehavior extends behaviors.Behavior {
|
||||
private motors: motors.MotorBase;
|
||||
private speed: number;
|
||||
constructor(motors: motors.MotorBase, speed: number) {
|
||||
super();
|
||||
this.motors = motors;
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
shouldRun(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
run(): void {
|
||||
this.motors.setSpeed(this.speed);
|
||||
pauseUntil(() => !this.active);
|
||||
this.motors.setSpeed(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A behavior that turns on the motors to the specified speed
|
||||
* @param motors
|
||||
* @param speed the desired speed, eg: 50
|
||||
*/
|
||||
//% blockId=behaviorsDriveForward block="drive %motors|forward at %speed=motorSpeedPicker|%"
|
||||
export function driveForward(motors: motors.MotorBase, speed: number): behaviors.Behavior {
|
||||
return new DriveForwardBehavior(motors, speed);
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
{
|
||||
"chassis.Chassis": "A differential drive robot",
|
||||
"chassis.Chassis.drive": "Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)\nusing a unicycle model.",
|
||||
"chassis.Chassis.driveFor": "Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)\nusing a unicycle model.",
|
||||
"chassis.Chassis.driveFor|param|rotationSpeed": "rotation of the robot around the center point, eg: 30",
|
||||
"chassis.Chassis.driveFor|param|speed": "speed of the center point between motors, eg: 10",
|
||||
"chassis.Chassis.driveFor|param|value": "the amount of movement, eg: 2",
|
||||
"chassis.Chassis.drive|param|rotationSpeed": "rotation of the robot around the center point, eg: 30",
|
||||
"chassis.Chassis.drive|param|speed": "speed of the center point between motors, eg: 10",
|
||||
"chassis.Chassis.drive|param|value": "the amount of movement, eg: 2",
|
||||
"chassis.Chassis.setMotors": "Sets the motors used by the chassis, default is B+C",
|
||||
"chassis.Chassis.setProperty": "Sets a property of the robot",
|
||||
"chassis.Chassis.setProperty|param|property": "the property to set",
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"ChassisProperty.BaseLength|block": "base length (cm)",
|
||||
"ChassisProperty.WheelRadius|block": "wheel radius (cm)",
|
||||
"chassis.Chassis.driveFor|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit",
|
||||
"chassis.Chassis.drive|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s",
|
||||
"chassis.Chassis.setMotors|block": "set %chassis|motors to %motors",
|
||||
"chassis.Chassis.setProperty|block": "set %chassis|%property|to %value",
|
||||
|
@ -29,13 +29,26 @@ namespace chassis {
|
||||
* using a unicycle model.
|
||||
* @param speed speed of the center point between motors, eg: 10
|
||||
* @param rotationSpeed rotation of the robot around the center point, eg: 30
|
||||
* @param value the amount of movement, eg: 2
|
||||
* @param unit
|
||||
*/
|
||||
//% blockId=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s"
|
||||
//% inlineInputMode=inline
|
||||
//% weight=99 blockGap=8
|
||||
drive(speed: number, rotationSpeed: number) {
|
||||
this.driveFor(speed, rotationSpeed, 0, MoveUnit.Degrees);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a differential drive robot move with a given speed (cm/s) and rotation rate (deg/s)
|
||||
* using a unicycle model.
|
||||
* @param speed speed of the center point between motors, eg: 10
|
||||
* @param rotationSpeed rotation of the robot around the center point, eg: 30
|
||||
* @param value the amount of movement, eg: 2
|
||||
* @param unit
|
||||
*/
|
||||
//% blockId=motorDriveFor block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit"
|
||||
//% inlineInputMode=inline
|
||||
//% weight=95 blockGap=8
|
||||
drive(speed: number, rotationSpeed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
||||
driveFor(speed: number, rotationSpeed: number, value: number, unit: MoveUnit) {
|
||||
// speed is expressed in %
|
||||
const R = this.wheelRadius; // cm
|
||||
const L = this.baseLength; // cm
|
||||
@ -52,7 +65,7 @@ namespace chassis {
|
||||
const sr = vr / maxw * 100; // %
|
||||
const sl = vl / maxw * 100; // %
|
||||
|
||||
this.motors.tank(sr, sl, value, unit)
|
||||
this.motors.tankFor(sr, sl, value, unit)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"sensors.ColorSensor": "The color sensor is a digital sensor that can detect the color or intensity\nof light that enters the small window on the face of the sensor.",
|
||||
"sensors.ColorSensor.calibrateLight": "Collects measurement of the light condition and adjusts the threshold to 10% / 90%.",
|
||||
"sensors.ColorSensor.color": "Get the current color from the color sensor.",
|
||||
"sensors.ColorSensor.colorMode": "Gets the current color mode",
|
||||
"sensors.ColorSensor.light": "Measures the ambient or reflected light value from 0 (darkest) to 100 (brightest).",
|
||||
@ -12,8 +11,5 @@
|
||||
"sensors.ColorSensor.onLightChanged|param|handler": "the code to run when detected",
|
||||
"sensors.ColorSensor.pauseForColor": "Waits for the given color to be detected",
|
||||
"sensors.ColorSensor.pauseForColor|param|color": "the color to detect",
|
||||
"sensors.ColorSensor.pauseForLight": "Waits for the given color to be detected",
|
||||
"sensors.ColorSensor.setThreshold": "Sets a threshold value",
|
||||
"sensors.ColorSensor.setThreshold|param|condition": "the dark or bright light condition",
|
||||
"sensors.ColorSensor.setThreshold|param|value": "the value threshold"
|
||||
"sensors.ColorSensor.pauseForLight": "Waits for the given color to be detected"
|
||||
}
|
@ -13,20 +13,17 @@
|
||||
"LightCondition.Dark|block": "dark",
|
||||
"LightIntensityMode.Ambient|block": "ambient light",
|
||||
"LightIntensityMode.Reflected|block": "reflected light",
|
||||
"sensors.ColorSensor.calibrateLight|block": "calibrate|%sensor|for %mode|light",
|
||||
"sensors.ColorSensor.color|block": "%sensor| color",
|
||||
"sensors.ColorSensor.light|block": "%sensor|%mode",
|
||||
"sensors.ColorSensor.onColorDetected|block": "on %sensor|detected color %color",
|
||||
"sensors.ColorSensor.onLightChanged|block": "on %sensor|%mode|%condition",
|
||||
"sensors.ColorSensor.pauseForColor|block": "pause %sensor|for color %color",
|
||||
"sensors.ColorSensor.pauseForLight|block": "pause %sensor|for %mode|%condition",
|
||||
"sensors.ColorSensor.setThreshold|block": "set %sensor|%condition|to %value",
|
||||
"sensors.color1|block": "color 1",
|
||||
"sensors.color2|block": "color 2",
|
||||
"sensors.color3|block": "color 3",
|
||||
"sensors.color4|block": "color 4",
|
||||
"sensors|block": "sensors",
|
||||
"{id:category}Sensors": "Sensors",
|
||||
"{id:group}Color Sensor": "Color Sensor",
|
||||
"{id:group}Threshold": "Threshold"
|
||||
"{id:group}Color Sensor": "Color Sensor"
|
||||
}
|
@ -39,9 +39,9 @@ const enum ColorSensorColor {
|
||||
|
||||
enum LightCondition {
|
||||
//% block="dark"
|
||||
Dark = sensors.ThresholdState.Low,
|
||||
Dark = sensors.internal.ThresholdState.Low,
|
||||
//$ block="bright"
|
||||
Bright = sensors.ThresholdState.High
|
||||
Bright = sensors.internal.ThresholdState.High
|
||||
}
|
||||
|
||||
namespace sensors {
|
||||
@ -52,14 +52,12 @@ namespace sensors {
|
||||
*/
|
||||
//% fixedInstances
|
||||
export class ColorSensor extends internal.UartSensor {
|
||||
thresholdDetector: sensors.ThresholdDetector;
|
||||
calibrating: boolean;
|
||||
thresholdDetector: sensors.internal.ThresholdDetector;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port)
|
||||
this._setMode(ColorSensorMode.None);
|
||||
this.thresholdDetector = new sensors.ThresholdDetector(this.id());
|
||||
this.calibrating = false;
|
||||
this.thresholdDetector = new sensors.internal.ThresholdDetector(this.id());
|
||||
}
|
||||
|
||||
_colorEventValue(value: number) {
|
||||
@ -97,7 +95,6 @@ namespace sensors {
|
||||
}
|
||||
|
||||
_update(prev: number, curr: number) {
|
||||
if (this.calibrating) return; // simply ignore data updates while calibrating
|
||||
if (this.mode == ColorSensorMode.Color)
|
||||
control.raiseEvent(this._id, this._colorEventValue(curr));
|
||||
else
|
||||
@ -155,7 +152,7 @@ namespace sensors {
|
||||
//% parts="colorsensor"
|
||||
//% blockNamespace=sensors
|
||||
//% sensor.fieldEditor="ports"
|
||||
//% weight=98
|
||||
//% weight=99
|
||||
//% group="Color Sensor"
|
||||
color(): ColorSensorColor {
|
||||
this.setMode(ColorSensorMode.Color)
|
||||
@ -224,74 +221,12 @@ namespace sensors {
|
||||
reflectedLight() {
|
||||
return this.light(LightIntensityMode.Reflected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a threshold value
|
||||
* @param condition the dark or bright light condition
|
||||
* @param value the value threshold
|
||||
*/
|
||||
//% blockId=colorSetThreshold block="set %sensor|%condition|to %value"
|
||||
//% group="Threshold" blockGap=8 weight=90
|
||||
//% value.min=0 value.max=100
|
||||
//% sensor.fieldEditor="ports"
|
||||
setThreshold(condition: LightCondition, value: number) {
|
||||
if (condition == LightCondition.Dark)
|
||||
this.thresholdDetector.setLowThreshold(value)
|
||||
else
|
||||
this.thresholdDetector.setHighThreshold(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects measurement of the light condition and adjusts the threshold to 10% / 90%.
|
||||
*/
|
||||
//% blockId=colorCalibrateLight block="calibrate|%sensor|for %mode|light"
|
||||
//% group="Threshold" weight=91 blockGap=8
|
||||
//% sensor.fieldEditor="ports"
|
||||
calibrateLight(mode: LightIntensityMode, deviation: number = 8) {
|
||||
this.calibrating = true; // prevent events
|
||||
|
||||
this.light(mode); // trigger a read
|
||||
pauseUntil(() => this.isActive()); // ensure sensor is live
|
||||
|
||||
|
||||
let vold = 0;
|
||||
let vcount = 0;
|
||||
let min = 200;
|
||||
let max = -200;
|
||||
let k = 0;
|
||||
while(k++ < 1000 && vcount < 50) {
|
||||
let v = this.light(mode);
|
||||
min = Math.min(min, v);
|
||||
max = Math.max(max, v);
|
||||
// detect if nothing has changed and stop calibration
|
||||
if (Math.abs(v - vold) <= 2)
|
||||
vcount ++;
|
||||
else {
|
||||
vold = v;
|
||||
vcount = 1;
|
||||
}
|
||||
|
||||
// wait a bit
|
||||
loops.pause(50);
|
||||
}
|
||||
|
||||
// apply tolerance
|
||||
const minDist = 10;
|
||||
min = Math.max(minDist / 2, Math.min(min + deviation / 2, max - deviation / 2 - minDist / 2));
|
||||
max = Math.min(100 - minDist / 2, Math.max(min + minDist, max - deviation / 2));
|
||||
|
||||
// apply thresholds
|
||||
this.thresholdDetector.setLowThreshold(min);
|
||||
this.thresholdDetector.setHighThreshold(max);
|
||||
|
||||
this.calibrating = false;
|
||||
}
|
||||
}
|
||||
|
||||
//% whenUsed block="color 3" weight=95 fixedInstance jres=icons.port3
|
||||
//% whenUsed block="color 3" weight=90 fixedInstance jres=icons.port3
|
||||
export const color3: ColorSensor = new ColorSensor(3)
|
||||
|
||||
//% whenUsed block="color 1" weight=90 fixedInstance jres=icons.port1
|
||||
//% whenUsed block="color 1" weight=95 fixedInstance jres=icons.port1
|
||||
export const color1: ColorSensor = new ColorSensor(1)
|
||||
|
||||
//% whenUsed block="color 2" weight=90 fixedInstance jres=icons.port2
|
||||
|
@ -3,9 +3,9 @@
|
||||
```blocks
|
||||
loops.forever(function () {
|
||||
if (sensors.color1.ambientLight() > 20) {
|
||||
brick.setLight(BrickLight.Green)
|
||||
brick.setStatusLight(LightsPattern.Green)
|
||||
} else {
|
||||
brick.setLight(BrickLight.Orange)
|
||||
brick.setStatusLight(LightsPattern.Orange)
|
||||
}
|
||||
})
|
||||
```
|
@ -3,9 +3,9 @@
|
||||
```blocks
|
||||
loops.forever(function () {
|
||||
if (sensors.color1.color() == ColorSensorColor.Green) {
|
||||
brick.setLight(BrickLight.Green)
|
||||
brick.setStatusLight(LightsPattern.Green)
|
||||
} else {
|
||||
brick.setLight(BrickLight.Orange)
|
||||
brick.setStatusLight(LightsPattern.Orange)
|
||||
}
|
||||
})
|
||||
```
|
@ -3,9 +3,9 @@
|
||||
```blocks
|
||||
loops.forever(function () {
|
||||
if (sensors.color1.reflectedLight() > 20) {
|
||||
brick.setLight(BrickLight.Green)
|
||||
brick.setStatusLight(LightsPattern.Green)
|
||||
} else {
|
||||
brick.setLight(BrickLight.Orange)
|
||||
brick.setStatusLight(LightsPattern.Orange)
|
||||
}
|
||||
})
|
||||
```
|
@ -1,5 +1,4 @@
|
||||
{
|
||||
"BrickLight": "Patterns for lights under the buttons.",
|
||||
"ButtonEvent": "User interaction on buttons",
|
||||
"Draw": "Drawing modes",
|
||||
"Image.buffer": "Returns the underlaying Buffer object.",
|
||||
@ -7,15 +6,14 @@
|
||||
"Image.draw": "Draw an image on the screen.",
|
||||
"Image.height": "Returns the height of an image.",
|
||||
"Image.width": "Returns the width of an image.",
|
||||
"LightsPattern": "Patterns for lights under the buttons.",
|
||||
"MMap.getNumber": "Read a number in specified format from the buffer.",
|
||||
"MMap.ioctl": "Perform ioctl(2) on the underlaying file",
|
||||
"MMap.length": "Returns the length of a Buffer object.",
|
||||
"MMap.lseek": "Set pointer on the underlaying file.",
|
||||
"MMap.read": "Perform read(2) on the underlaying file",
|
||||
"MMap.setNumber": "Write a number in specified format in the buffer.",
|
||||
"MMap.slice": "Read a range of bytes into a buffer.",
|
||||
"MMap.write": "Perform write(2) on the underlaying file",
|
||||
"SeekWhence": "Mode for lseek()",
|
||||
"brick.Button": "Generic button class, for device buttons and sensors.",
|
||||
"brick.Button.isPressed": "Check if button is currently pressed or not.",
|
||||
"brick.Button.onEvent": "Do something when a button or sensor is clicked, up or down.",
|
||||
@ -30,9 +28,11 @@
|
||||
"brick.buttonRight": "Right button on the EV3 Brick.",
|
||||
"brick.buttonUp": "Up button on the EV3 Brick.",
|
||||
"brick.clearScreen": "Clears the screen",
|
||||
"brick.lightPattern": "Pattern block.",
|
||||
"brick.lightPattern|param|pattern": "the lights pattern to use. eg: LightsPattern.Green",
|
||||
"brick.printPorts": "Prints the port states on the screen",
|
||||
"brick.setLight": "Set lights.",
|
||||
"brick.setLight|param|pattern": "the lights pattern to use. eg: BrickLight.Orange",
|
||||
"brick.setLight|param|pattern": "the lights pattern to use.",
|
||||
"brick.showImage": "Shows an image on screen",
|
||||
"brick.showImage|param|image": "image to draw",
|
||||
"brick.showNumber": "Shows a number on the screen",
|
||||
@ -52,12 +52,6 @@
|
||||
"console.logValue|param|value": "to write",
|
||||
"console.sendToScreen": "Sends the log messages to the brick screen and uses the brick up and down buttons to scroll.",
|
||||
"control": "Program controls and events.",
|
||||
"control.Timer": "A timer",
|
||||
"control.Timer.millis": "Gets the elapsed time in millis since the last reset",
|
||||
"control.Timer.pauseUntil": "Pauses until the timer reaches the given amount of milliseconds",
|
||||
"control.Timer.pauseUntil|param|ms": "how long to pause for, eg: 5, 100, 200, 500, 1000, 2000",
|
||||
"control.Timer.reset": "Resets the timer",
|
||||
"control.Timer.seconds": "Gets the elapsed time in seconds since the last reset",
|
||||
"control.allocateNotifyEvent": "Allocates the next user notification event",
|
||||
"control.deviceFirmwareVersion": "Determine the version of system software currently running.",
|
||||
"control.dmesg": "Write data to DMESG debugging buffer.",
|
||||
@ -67,8 +61,6 @@
|
||||
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
|
||||
"motors.Motor.angle": "Gets motor angle.",
|
||||
"motors.Motor.clearCounts": "Clears the motor count",
|
||||
"motors.Motor.setRegulated": "Indicates if the motor speed should be regulated. Default is true.",
|
||||
"motors.Motor.setRegulated|param|value": "true for regulated motor",
|
||||
"motors.Motor.speed": "Gets motor actual speed.",
|
||||
"motors.Motor.tacho": "Gets motor tachometer count.",
|
||||
"motors.Motor.toString": "Returns the status of the motor",
|
||||
@ -79,7 +71,7 @@
|
||||
"motors.MotorBase.setBrake": "Sets the automatic brake on or off when the motor is off",
|
||||
"motors.MotorBase.setBrake|param|brake": "a value indicating if the motor should break when off",
|
||||
"motors.MotorBase.setReversed": "Reverses the motor polarity",
|
||||
"motors.MotorBase.setSpeed": "Sets the motor speed for limited time or distance.",
|
||||
"motors.MotorBase.setSpeed": "Sets the motor speed for limited time or distance",
|
||||
"motors.MotorBase.setSpeed|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
|
||||
"motors.MotorBase.setSpeed|param|unit": "(optional) unit of the value",
|
||||
"motors.MotorBase.setSpeed|param|value": "(optional) measured distance or rotation",
|
||||
|
@ -1,17 +1,17 @@
|
||||
{
|
||||
"BrickLight.GreenFlash|block": "green flash",
|
||||
"BrickLight.GreenPulse|block": "green pulse",
|
||||
"BrickLight.Green|block": "green",
|
||||
"BrickLight.Off|block": "off",
|
||||
"BrickLight.OrangeFlash|block": "orange flash",
|
||||
"BrickLight.OrangePulse|block": "orange pulse",
|
||||
"BrickLight.Orange|block": "orange",
|
||||
"BrickLight.RedFlash|block": "red flash",
|
||||
"BrickLight.RedPulse|block": "red pulse",
|
||||
"BrickLight.Red|block": "red",
|
||||
"ButtonEvent.Click|block": "click",
|
||||
"ButtonEvent.Down|block": "down",
|
||||
"ButtonEvent.Up|block": "up",
|
||||
"LightsPattern.GreenFlash|block": "Flashing Green",
|
||||
"LightsPattern.GreenPulse|block": "Pulsing Green",
|
||||
"LightsPattern.Green|block": "Green",
|
||||
"LightsPattern.Off|block": "Off",
|
||||
"LightsPattern.OrangeFlash|block": "Flashing Orange",
|
||||
"LightsPattern.OrangePulse|block": "Pulsing Orange",
|
||||
"LightsPattern.Orange|block": "Orange",
|
||||
"LightsPattern.RedFlash|block": "Flashing Red",
|
||||
"LightsPattern.RedPulse|block": "Pulsing Red",
|
||||
"LightsPattern.Red|block": "Red",
|
||||
"MoveUnit.Degrees|block": "degrees",
|
||||
"MoveUnit.MilliSeconds|block": "milliseconds",
|
||||
"MoveUnit.Rotations|block": "rotations",
|
||||
@ -30,14 +30,15 @@
|
||||
"brick.Button.pauseUntil|block": "pause until %button|%event",
|
||||
"brick.Button.wasPressed|block": "%button|was pressed",
|
||||
"brick.batteryLevel|block": "battery level",
|
||||
"brick.buttonDown|block": "button down",
|
||||
"brick.buttonEnter|block": "button enter",
|
||||
"brick.buttonLeft|block": "button left",
|
||||
"brick.buttonRight|block": "button right",
|
||||
"brick.buttonUp|block": "button up",
|
||||
"brick.buttonDown|block": "down",
|
||||
"brick.buttonEnter|block": "enter",
|
||||
"brick.buttonLeft|block": "left",
|
||||
"brick.buttonRight|block": "right",
|
||||
"brick.buttonUp|block": "up",
|
||||
"brick.clearScreen|block": "clear screen",
|
||||
"brick.lightPattern|block": "%pattern",
|
||||
"brick.printPorts|block": "print ports",
|
||||
"brick.setLight|block": "set light to %pattern",
|
||||
"brick.setLight|block": "set light to %pattern=led_pattern",
|
||||
"brick.showImage|block": "show image %image=screen_image_picker",
|
||||
"brick.showNumber|block": "show number %name|at line %line",
|
||||
"brick.showString|block": "show string %text|at line %line",
|
||||
@ -47,32 +48,17 @@
|
||||
"console.log|block": "console|log %text",
|
||||
"console.sendToScreen|block": "send console to screen",
|
||||
"console|block": "console",
|
||||
"control.Timer.millis|block": "%timer|millis",
|
||||
"control.Timer.pauseUntil|block": "%timer|pause until (ms) %ms",
|
||||
"control.Timer.reset|block": "%timer|reset",
|
||||
"control.Timer.seconds|block": "%timer|seconds",
|
||||
"control.raiseEvent|block": "raise event|from %src|with value %value",
|
||||
"control.timer1|block": "timer 1",
|
||||
"control.timer2|block": "timer 2",
|
||||
"control.timer3|block": "timer 3",
|
||||
"control.timer4|block": "timer 4",
|
||||
"control.timer5|block": "timer 5",
|
||||
"control.timer6|block": "timer 6",
|
||||
"control.timer7|block": "timer 7",
|
||||
"control.timer8|block": "timer 8",
|
||||
"control|block": "control",
|
||||
"motors.Motor.angle|block": "%motor|angle",
|
||||
"motors.Motor.clearCounts|block": "%motor|clear counts",
|
||||
"motors.Motor.setRegulated|block": "set %motor|regulated %value=toggleOnOff",
|
||||
"motors.Motor.speed|block": "%motor|speed",
|
||||
"motors.Motor.tacho|block": "%motor|tacho",
|
||||
"motors.MotorBase.pauseUntilReady|block": "%motor|pause until ready",
|
||||
"motors.MotorBase.reset|block": "%motors|reset",
|
||||
"motors.MotorBase.setBrake|block": "set %motor|brake %brake=toggleOnOff",
|
||||
"motors.MotorBase.setReversed|block": "set %motor|reversed %reversed=toggleOnOff",
|
||||
"motors.MotorBase.setBrake|block": "set %motor|brake %brake",
|
||||
"motors.MotorBase.setReversed|block": "set %motor|reversed %reversed",
|
||||
"motors.MotorBase.setSpeed|block": "set %motor|speed to %speed=motorSpeedPicker|%",
|
||||
"motors.MotorBase.stop|block": "%motors|stop",
|
||||
"motors.SynchedMotorPair.steer|block": "steer %chassis|turn ratio %turnRatio=motorTurnRatioPicker|speed %speed=motorSpeedPicker|%",
|
||||
"motors.SynchedMotorPair.steer|block": "steer %chassis|turn ratio %turnRatio|speed %speed=motorSpeedPicker|%",
|
||||
"motors.SynchedMotorPair.tank|block": "tank %motors|%speedLeft=motorSpeedPicker|%|%speedRight=motorSpeedPicker|%",
|
||||
"motors.largeAB|block": "large A+B",
|
||||
"motors.largeAD|block": "large A+D",
|
||||
@ -101,10 +87,10 @@
|
||||
"{id:category}Motors": "Motors",
|
||||
"{id:category}Output": "Output",
|
||||
"{id:category}Screen": "Screen",
|
||||
"{id:category}Sensors": "Sensors",
|
||||
"{id:category}Serial": "Serial",
|
||||
"{id:group}Buttons": "Buttons",
|
||||
"{id:group}Counters": "Counters",
|
||||
"{id:group}Light": "Light",
|
||||
"{id:group}More": "More",
|
||||
"{id:group}Move": "Move",
|
||||
"{id:group}Screen": "Screen",
|
||||
|
@ -2,26 +2,36 @@
|
||||
/**
|
||||
* Patterns for lights under the buttons.
|
||||
*/
|
||||
const enum BrickLight {
|
||||
//% block=off enumval=0
|
||||
const enum LightsPattern {
|
||||
//% block=Off enumval=0
|
||||
//% blockIdentity=brick.lightPattern
|
||||
Off = 0,
|
||||
//% block=green enumval=1
|
||||
//% block=Green enumval=1
|
||||
//% blockIdentity=brick.lightPattern
|
||||
Green = 1,
|
||||
//% block=red enumval=2
|
||||
//% block=Red enumval=2
|
||||
//% blockIdentity=brick.lightPattern
|
||||
Red = 2,
|
||||
//% block=orange enumval=3
|
||||
//% block=Orange enumval=3
|
||||
//% blockIdentity=brick.lightPattern
|
||||
Orange = 3,
|
||||
//% block="green flash" enumval=4
|
||||
//% block="Flashing Green" enumval=4
|
||||
//% blockIdentity=brick.lightPattern
|
||||
GreenFlash = 4,
|
||||
//% block="red flash" enumval=5
|
||||
//% block="Flashing Red" enumval=5
|
||||
//% blockIdentity=brick.lightPattern
|
||||
RedFlash = 5,
|
||||
//% block="orange flash" enumval=6
|
||||
//% block="Flashing Orange" enumval=6
|
||||
//% blockIdentity=brick.lightPattern
|
||||
OrangeFlash = 6,
|
||||
//% block="green pulse" enumval=7
|
||||
//% block="Pulsing Green" enumval=7
|
||||
//% blockIdentity=brick.lightPattern
|
||||
GreenPulse = 7,
|
||||
//% block="red pulse" enumval=8
|
||||
//% block="Pulsing Red" enumval=8
|
||||
//% blockIdentity=brick.lightPattern
|
||||
RedPulse = 8,
|
||||
//% block="orange pulse" enumval=9
|
||||
//% block="Pulsing Orange" enumval=9
|
||||
//% blockIdentity=brick.lightPattern
|
||||
OrangePulse = 9,
|
||||
}
|
||||
|
||||
@ -160,7 +170,6 @@ namespace brick {
|
||||
// this needs to be done in query(), which is run without the main JS execution mutex
|
||||
// otherwise, while(true){} will lock the device
|
||||
if (ret & DAL.BUTTON_ID_ESCAPE) {
|
||||
motors.stopAllMotors(); // ensuring that all motors are off
|
||||
control.reset()
|
||||
}
|
||||
return ret
|
||||
@ -194,31 +203,31 @@ namespace brick {
|
||||
/**
|
||||
* Enter button on the EV3 Brick.
|
||||
*/
|
||||
//% whenUsed block="button enter" weight=95 fixedInstance
|
||||
//% whenUsed block="enter" weight=95 fixedInstance
|
||||
export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER)
|
||||
|
||||
/**
|
||||
* Left button on the EV3 Brick.
|
||||
*/
|
||||
//% whenUsed block="button left" weight=95 fixedInstance
|
||||
//% whenUsed block="left" weight=95 fixedInstance
|
||||
export const buttonLeft: Button = new DevButton(DAL.BUTTON_ID_LEFT)
|
||||
|
||||
/**
|
||||
* Right button on the EV3 Brick.
|
||||
*/
|
||||
//% whenUsed block="button right" weight=94 fixedInstance
|
||||
//% whenUsed block="right" weight=94 fixedInstance
|
||||
export const buttonRight: Button = new DevButton(DAL.BUTTON_ID_RIGHT)
|
||||
|
||||
/**
|
||||
* Up button on the EV3 Brick.
|
||||
*/
|
||||
//% whenUsed block="button up" weight=95 fixedInstance
|
||||
//% whenUsed block="up" weight=95 fixedInstance
|
||||
export const buttonUp: Button = new DevButton(DAL.BUTTON_ID_UP)
|
||||
|
||||
/**
|
||||
* Down button on the EV3 Brick.
|
||||
*/
|
||||
//% whenUsed block="button down" weight=95 fixedInstance
|
||||
//% whenUsed block="down" weight=95 fixedInstance
|
||||
export const buttonDown: Button = new DevButton(DAL.BUTTON_ID_DOWN)
|
||||
}
|
||||
|
||||
@ -242,21 +251,32 @@ namespace control {
|
||||
}
|
||||
|
||||
namespace brick {
|
||||
// the brick starts with the red color
|
||||
let currPattern: BrickLight = BrickLight.Red;
|
||||
let currPattern: LightsPattern
|
||||
|
||||
/**
|
||||
* Set lights.
|
||||
* @param pattern the lights pattern to use. eg: BrickLight.Orange
|
||||
* @param pattern the lights pattern to use.
|
||||
*/
|
||||
//% blockId=setLights block="set light to %pattern"
|
||||
//% blockId=setLights block="set light to %pattern=led_pattern"
|
||||
//% weight=100 group="Buttons"
|
||||
export function setLight(pattern: BrickLight): void {
|
||||
export function setLight(pattern: number): void {
|
||||
if (currPattern === pattern)
|
||||
return
|
||||
currPattern = pattern;
|
||||
const cmd = output.createBuffer(2)
|
||||
currPattern = pattern
|
||||
let cmd = output.createBuffer(2)
|
||||
cmd[0] = pattern + 48
|
||||
brick.internal.getBtnsMM().write(cmd)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pattern block.
|
||||
* @param pattern the lights pattern to use. eg: LightsPattern.Green
|
||||
*/
|
||||
//% blockId=led_pattern block="%pattern"
|
||||
//% shim=TD_ID colorSecondary="#6e9a36" group="Light"
|
||||
//% blockHidden=true useEnumVal=1 pattern.fieldOptions.decompileLiterals=1
|
||||
export function lightPattern(pattern: LightsPattern): number {
|
||||
return pattern;
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ namespace console {
|
||||
|
||||
namespace console.screen {
|
||||
const maxLines = 100;
|
||||
const screenLines = 10;
|
||||
const screenLines = 8;
|
||||
let lines: string[];
|
||||
let scrollPosition = 0;
|
||||
|
||||
@ -66,8 +66,8 @@ namespace console.screen {
|
||||
if (!lines) {
|
||||
lines = [];
|
||||
console.addListener(log);
|
||||
brick.buttonUp.onEvent(ButtonEvent.Click, () => scroll(-3))
|
||||
brick.buttonDown.onEvent(ButtonEvent.Click, () => scroll(3))
|
||||
brick.buttonUp.onEvent(ButtonEvent.Click, () => scroll(-1))
|
||||
brick.buttonDown.onEvent(ButtonEvent.Click, () => scroll(1))
|
||||
}
|
||||
}
|
||||
|
||||
|
11
libs/core/enums.d.ts
vendored
@ -1,17 +1,6 @@
|
||||
// Auto-generated. Do not edit.
|
||||
|
||||
|
||||
/**
|
||||
* Mode for lseek()
|
||||
*/
|
||||
|
||||
declare const enum SeekWhence {
|
||||
Set = 0,
|
||||
Current = 1,
|
||||
End = 2,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drawing modes
|
||||
*/
|
||||
|
@ -114,7 +114,23 @@
|
||||
"progressWaterLevel3": "iVBORw0KGgoAAAANSUhEUgAAALIAAACAAQAAAACHQw5jAAABP0lEQVR42u2VMWrEMBBFRxGsGrNqXYT4CltuFV9lj5EqVlhImyPkKoKFbJcrrHKCKJ2XKFb+BGxsGBdbBRJ/mGHm+VtjJGNT/srQO6cG8cnFKXvKLVdHRFcjfXD3xDyybY9IFVJgbpgHtilEa5E8XJ1m/gJbVwJFXuwRrqSYa9hSCZt/A1/B1VLjqdMG1mu0bgeD4W5Te2r1A6YVJne0qfNP57fWU9AY5dYKd29tDgodldoTqagjGaoc3VAiiibQmlg1ApeIQIjuufDUq+C0Q1z1xaJFi/60iluZ28aJ3Jy9yPU5iFxlmesZvsry+kUz8/z/5qTuZKyizM2F3IYZfnDyuR7kc61fL+P4qYmq0mCZ+tuhfHZjPvhV8iKnMVejuZNXrjnK3O77aeo03hEzNGqyUcbNnJdfPjqLFv2+vgH+JtBJ4nz/SAAAAABJRU5ErkJggg==",
|
||||
"systemAccept1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQElEQVR42mM4wMDMsP//X4b6//+AWI6h/p8dQ/2fOob6H/8YKj/+Y6h4/I+hxvkfQx07UJ4fiOf/A6sF6QHqBQDsYh9jNdETHwAAAABJRU5ErkJggg==",
|
||||
"systemAccept2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQUlEQVR42mM4wMDMsP//X4YEBjYGB4ZHDA6MhxgcmJsYHNiZGNz4mBjcZZgYnPcwMTj+YGJw+ADECUxgtSA9QL0A+IIPxwiZFtwAAAAASUVORK5CYII=",
|
||||
"systemAlert": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAVAQAAAAB0khOLAAAARUlEQVR42iXD0QmAIAAE0IvWCtqmMbLG8MtVhAZwjBvALyE85XzwoE/QO8f5WPsd0K+An6c3Jq8sThIUUVg9qfmDDRn7AD/WMAQEJ+pCAAAAAElFTkSuQmCC",
|
||||
"systemBox": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAGklEQVR42mM4wMDMsP//X4b6//9IwiA9QL0AlQYkzY8nCoAAAAAASUVORK5CYII=",
|
||||
"systemBusy0": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPAQAAAAAuP8mBAAAAMElEQVR42mPY/38Bg/x/BgbnHw4Msd8dGKLeA+k4IL0XSGdB6TioOFAepA6kHqgPAJCPFdTsOCPGAAAAAElFTkSuQmCC",
|
||||
"systemBusy1": "iVBORw0KGgoAAAANSUhEUgAAAA8AAAATAQAAAABnuWoHAAAAOUlEQVR42mNoYGKw/8EAJO9/A6GrYQyv1jF8jWP4tY/hbx3D730M3+4xvH/HcO8bw90yhlvbGGDqAdjhGYsKgwC5AAAAAElFTkSuQmCC",
|
||||
"systemDecline1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4b6//8Y6urtGOrt6hjq5/xjqD8JxI+hGMQGiQHlwGqAakF6gHoBybUeX0RcSJEAAAAASUVORK5CYII=",
|
||||
"systemDecline2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4YEBjYGx4ZDDA4HmxgckpkYHMyAWAaKQWyQGFAOpAakFqQHqBcAGz4QyzSHE/gAAAAASUVORK5CYII="
|
||||
"systemDecline2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4YEBjYGx4ZDDA4HmxgckpkYHMyAWAaKQWyQGFAOpAakFqQHqBcAGz4QyzSHE/gAAAAASUVORK5CYII=",
|
||||
"systemDotEmpty": "iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQAAAAA31SuUAAAAYklEQVR42oWOMQ5AQBRE5yZ7FEfSKTmC25CQuILehkahkc12IvgjRqHUTPX/ew+MzsByNlhxGq7ochz90mFL9gmBFjCSGTxZoSUb1OTwTkquP/Md61cU8USWQzZ5VaCWp+oGeLZn9EklJaAAAAAASUVORK5CYII=",
|
||||
"systemDotFull": "iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQAAAAA31SuUAAAAX0lEQVR42mP4/0H+H8P//sf/GP7V//nH8PeDfB3D7wPs+xi+MzDeY3jHAER3GBjKGG4wMJgx7GBgsGLYwMAgBSESGBh4CBAIxWC9YFPA5oFNBtsBtg1sL9gFYLeAXAUAPIwyHWLMTS8AAAAASUVORK5CYII=",
|
||||
"systemEv3small": "iVBORw0KGgoAAAANSUhEUgAAACsAAAANAQAAAAAY06pGAAAAPUlEQVR42mNg4LFvYwACFEr+n32fPYiS5/8P5PLLyz8AUXwQqs8eSMn/b7H/D6IO1NmDBA/UgbTzP/gHpwBcwBWO2QYBDwAAAABJRU5ErkJggg==",
|
||||
"systemPlay": "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQAAAAA3iMLMAAAAMElEQVR42mP4Y8/wsZ/h+XOG858Z5v5k2POXwcaGoUYOhIAMIBcoCJQCKgAq+2MPAAFKFVmziLfGAAAAAElFTkSuQmCC",
|
||||
"systemSlider0": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAEklEQVR42mM4YMBwfwPV0AEDAHmKKNims3dJAAAAAElFTkSuQmCC",
|
||||
"systemSlider1": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAGklEQVR42mM4YMBwfwNFCAKuGjCc2sBwwAAAT7olG9TpXdAAAAAASUVORK5CYII=",
|
||||
"systemSlider2": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwM5CAJObWC4aoAgDxgAACpUJGftPg+WAAAAAElFTkSuQmCC",
|
||||
"systemSlider3": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwMJCAKuGjCc2oCFPGAAAPSIIz417p4OAAAAAElFTkSuQmCC",
|
||||
"systemSlider4": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwNhBAGnNjBcNcBHHjAAAMJ6IooqNLP/AAAAAElFTkSuQmCC",
|
||||
"systemSlider5": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwNOBAFXDRhObSCKPGAAAHfbIWHuFKlNAAAAAElFTkSuQmCC",
|
||||
"systemSlider6": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwM6goBTGxiuGpBGHjAAADklIK1PooVQAAAAAElFTkSuQmCC",
|
||||
"systemSlider7": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAG0lEQVR42mM4YMBwfwMUQcBVA4ZTG8gkDxgAANmVH4SOiUHMAAAAAElFTkSuQmCC",
|
||||
"systemSlider8": "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAbAQAAAABg3VNpAAAAFElEQVR42mM4YMBwagPDVSqRBwwASoohT92wVBIAAAAASUVORK5CYII="
|
||||
}
|
@ -220,10 +220,41 @@ namespace images {
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemAccept2 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemAlert = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemBox = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemBusy0 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemBusy1 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemDecline1 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemDecline2 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemDotEmpty = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemDotFull = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemEv3small = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemPlay = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider0 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider1 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider2 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider3 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider4 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider5 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider6 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider7 = screen.unpackPNG(hex``);
|
||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||
export const systemSlider8 = screen.unpackPNG(hex``);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace sensors.internal {
|
||||
|
||||
// This is implementation for the simulator.
|
||||
|
||||
control.runInParallel(() => {
|
||||
control.runInBackground(() => {
|
||||
let prev = query()
|
||||
changeHandler(prev, prev)
|
||||
while (true) {
|
||||
@ -93,7 +93,7 @@ namespace sensors.internal {
|
||||
init();
|
||||
return {
|
||||
temp: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryTemp),
|
||||
current: Math.round(analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent) / 10)
|
||||
current: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent)
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,6 +196,83 @@ namespace sensors.internal {
|
||||
}
|
||||
}
|
||||
|
||||
export enum ThresholdState {
|
||||
Normal = 1,
|
||||
High = 2,
|
||||
Low = 3,
|
||||
}
|
||||
|
||||
export class ThresholdDetector {
|
||||
public id: number;
|
||||
private min: number;
|
||||
private max: number;
|
||||
private lowThreshold: number;
|
||||
private highThreshold: number;
|
||||
private level: number;
|
||||
public state: ThresholdState;
|
||||
|
||||
constructor(id: number, min = 0, max = 100, lowThreshold = 20, highThreshold = 80) {
|
||||
this.id = id;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.lowThreshold = lowThreshold;
|
||||
this.highThreshold = highThreshold;
|
||||
this.level = Math.ceil((max - min) / 2);
|
||||
this.state = ThresholdState.Normal;
|
||||
}
|
||||
|
||||
public setLevel(level: number) {
|
||||
if (this == null) return
|
||||
this.level = this.clampValue(level);
|
||||
|
||||
if (this.level >= this.highThreshold) {
|
||||
this.setState(ThresholdState.High);
|
||||
}
|
||||
else if (this.level <= this.lowThreshold) {
|
||||
this.setState(ThresholdState.Low);
|
||||
}
|
||||
else {
|
||||
this.setState(ThresholdState.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
public setLowThreshold(value: number) {
|
||||
this.lowThreshold = this.clampValue(value);
|
||||
this.highThreshold = Math.max(this.lowThreshold + 1, this.highThreshold);
|
||||
}
|
||||
|
||||
public setHighThreshold(value: number) {
|
||||
this.highThreshold = this.clampValue(value);
|
||||
this.lowThreshold = Math.min(this.highThreshold - 1, this.lowThreshold);
|
||||
}
|
||||
|
||||
private clampValue(value: number) {
|
||||
if (value < this.min) {
|
||||
return this.min;
|
||||
}
|
||||
else if (value > this.max) {
|
||||
return this.max;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private setState(state: ThresholdState) {
|
||||
if (this.state == state) return;
|
||||
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case ThresholdState.High:
|
||||
control.raiseEvent(this.id, ThresholdState.High);
|
||||
break;
|
||||
case ThresholdState.Low:
|
||||
control.raiseEvent(this.id, ThresholdState.Low);
|
||||
break;
|
||||
case ThresholdState.Normal:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class UartSensor extends Sensor {
|
||||
protected mode: number // the mode user asked for
|
||||
protected realmode: number // the mode the hardware is in
|
||||
@ -233,9 +310,8 @@ namespace sensors.internal {
|
||||
return getUartNumber(fmt, off, this._port)
|
||||
}
|
||||
|
||||
reset() {
|
||||
protected reset() {
|
||||
if (this.isActive()) uartReset(this._port);
|
||||
this.realmode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,83 +498,3 @@ namespace sensors.internal {
|
||||
TST_UART_WRITE = 0xc048740a,
|
||||
}
|
||||
}
|
||||
|
||||
namespace sensors {
|
||||
export enum ThresholdState {
|
||||
Normal = 1,
|
||||
High = 2,
|
||||
Low = 3,
|
||||
}
|
||||
|
||||
export class ThresholdDetector {
|
||||
public id: number;
|
||||
private min: number;
|
||||
private max: number;
|
||||
private lowThreshold: number;
|
||||
private highThreshold: number;
|
||||
private level: number;
|
||||
public state: ThresholdState;
|
||||
|
||||
constructor(id: number, min = 0, max = 100, lowThreshold = 20, highThreshold = 80) {
|
||||
this.id = id;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.lowThreshold = lowThreshold;
|
||||
this.highThreshold = highThreshold;
|
||||
this.level = Math.ceil((max - min) / 2);
|
||||
this.state = ThresholdState.Normal;
|
||||
}
|
||||
|
||||
public setLevel(level: number) {
|
||||
if (this == null) return
|
||||
this.level = this.clampValue(level);
|
||||
|
||||
if (this.level >= this.highThreshold) {
|
||||
this.setState(ThresholdState.High);
|
||||
}
|
||||
else if (this.level <= this.lowThreshold) {
|
||||
this.setState(ThresholdState.Low);
|
||||
}
|
||||
else {
|
||||
const interval = (this.highThreshold - this.lowThreshold) / 6;
|
||||
if ((this.state == ThresholdState.High && this.level < this.highThreshold - interval) ||
|
||||
(this.state == ThresholdState.Low && this.level > this.lowThreshold + interval))
|
||||
this.setState(ThresholdState.Normal);
|
||||
}
|
||||
}
|
||||
|
||||
public setLowThreshold(value: number) {
|
||||
this.lowThreshold = this.clampValue(value);
|
||||
this.highThreshold = Math.max(this.lowThreshold + 1, this.highThreshold);
|
||||
}
|
||||
|
||||
public setHighThreshold(value: number) {
|
||||
this.highThreshold = this.clampValue(value);
|
||||
this.lowThreshold = Math.min(this.highThreshold - 1, this.lowThreshold);
|
||||
}
|
||||
|
||||
private clampValue(value: number) {
|
||||
if (value < this.min) {
|
||||
return this.min;
|
||||
}
|
||||
else if (value > this.max) {
|
||||
return this.max;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private setState(state: ThresholdState) {
|
||||
if (this.state == state) return;
|
||||
|
||||
this.state = state;
|
||||
switch (state) {
|
||||
case ThresholdState.High:
|
||||
control.raiseEvent(this.id, ThresholdState.High);
|
||||
break;
|
||||
case ThresholdState.Low:
|
||||
control.raiseEvent(this.id, ThresholdState.Low);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -271,11 +271,7 @@ void setupThread(Action a, TValue arg = 0, void (*runner)(Thread *) = NULL, TVal
|
||||
}
|
||||
}
|
||||
|
||||
void releaseFiber() {
|
||||
// called from main in pxt.cpp
|
||||
}
|
||||
|
||||
void runInParallel(Action a) {
|
||||
void runInBackground(Action a) {
|
||||
setupThread(a);
|
||||
}
|
||||
|
||||
|
@ -7,16 +7,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/**
|
||||
* Mode for lseek()
|
||||
*/
|
||||
enum class SeekWhence {
|
||||
Set = 0,
|
||||
Current = 1,
|
||||
End = 2,
|
||||
};
|
||||
|
||||
|
||||
namespace pxt {
|
||||
PXT_VTABLE_CTOR(MMap) {
|
||||
length = 0;
|
||||
@ -121,10 +111,4 @@ int read(MMap *mmap, Buffer data) {
|
||||
return ::read(mmap->fd, data->data, data->length);
|
||||
}
|
||||
|
||||
/** Set pointer on the underlaying file. */
|
||||
//%
|
||||
int lseek(MMap *mmap, int offset, SeekWhence whence) {
|
||||
return ::lseek(mmap->fd, offset, (int)whence);
|
||||
}
|
||||
|
||||
}
|
@ -11,15 +11,4 @@ namespace motors {
|
||||
export function __speedPicker(speed: number): number {
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* A turn ratio picker
|
||||
* @param turnratio the turn ratio, eg: 0
|
||||
*/
|
||||
//% blockId=motorTurnRatioPicker block="%turnratio" shim=TD_ID
|
||||
//% turnratio.fieldEditor="turnratio" colorSecondary="#FFFFFF"
|
||||
//% weight=0 blockHidden=1 turnRatio.fieldOptions.decompileLiterals=1
|
||||
export function __turnRatioPicker(turnratio: number): number {
|
||||
return turnratio;
|
||||
}
|
||||
}
|
@ -111,7 +111,7 @@ namespace motors {
|
||||
* Stops all motors
|
||||
*/
|
||||
//% blockId=motorStopAll block="stop all motors"
|
||||
//% weight=1
|
||||
//% weight=5
|
||||
//% group="Move"
|
||||
export function stopAllMotors() {
|
||||
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
|
||||
@ -161,7 +161,8 @@ namespace motors {
|
||||
* 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=outputMotorSetBrakeMode block="set %motor|brake %brake=toggleOnOff"
|
||||
//% blockId=outputMotorSetBrakeMode block="set %motor|brake %brake"
|
||||
//% brake.fieldEditor=toggleonoff
|
||||
//% weight=60 blockGap=8
|
||||
//% group="Move"
|
||||
setBrake(brake: boolean) {
|
||||
@ -172,8 +173,9 @@ namespace motors {
|
||||
/**
|
||||
* Reverses the motor polarity
|
||||
*/
|
||||
//% blockId=motorSetReversed block="set %motor|reversed %reversed=toggleOnOff"
|
||||
//% weight=59 blockGap=8
|
||||
//% blockId=motorSetReversed block="set %motor|reversed %reversed"
|
||||
//% reversed.fieldEditor=toggleonoff
|
||||
//% weight=59
|
||||
//% group="Move"
|
||||
setReversed(reversed: boolean) {
|
||||
this.init();
|
||||
@ -185,35 +187,23 @@ namespace motors {
|
||||
/**
|
||||
* Stops the motor(s).
|
||||
*/
|
||||
//% weight=6 blockGap=8
|
||||
//% group="Move"
|
||||
//% blockId=motorStop block="%motors|stop"
|
||||
//%
|
||||
stop() {
|
||||
this.init();
|
||||
stop(this._port, this._brake);
|
||||
this.settle();
|
||||
}
|
||||
|
||||
private settle() {
|
||||
// if we've recently completed a motor command with brake
|
||||
// allow 500ms for robot to settle
|
||||
if(this._brake)
|
||||
loops.pause(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the motor(s).
|
||||
*/
|
||||
//% weight=5
|
||||
//% group="Move"
|
||||
//% blockId=motorReset block="%motors|reset"
|
||||
//%
|
||||
reset() {
|
||||
this.init();
|
||||
reset(this._port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the motor speed for limited time or distance.
|
||||
* Sets the motor speed for limited time or distance
|
||||
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
||||
* @param value (optional) measured distance or rotation
|
||||
* @param unit (optional) unit of the value
|
||||
@ -224,17 +214,10 @@ namespace motors {
|
||||
setSpeed(speed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
||||
this.init();
|
||||
speed = Math.clamp(-100, 100, speed >> 0);
|
||||
// stop if speed is 0
|
||||
if (!speed) {
|
||||
this.stop();
|
||||
return;
|
||||
}
|
||||
// special: 0 is infinity
|
||||
if (value == 0) {
|
||||
this._setSpeed(speed);
|
||||
return;
|
||||
}
|
||||
// timed motor moves
|
||||
let useSteps: boolean;
|
||||
let stepsOrTime: number;
|
||||
switch (unit) {
|
||||
@ -257,10 +240,6 @@ namespace motors {
|
||||
}
|
||||
|
||||
this._move(useSteps, stepsOrTime, speed);
|
||||
// wait till motor is done with this work
|
||||
this.pauseUntilReady();
|
||||
// allow robot to settle
|
||||
this.settle();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -290,12 +269,10 @@ namespace motors {
|
||||
//% fixedInstances
|
||||
export class Motor extends MotorBase {
|
||||
private _large: boolean;
|
||||
private _regulated: boolean;
|
||||
|
||||
constructor(port: Output, large: boolean) {
|
||||
super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
||||
this._large = large;
|
||||
this._regulated = true;
|
||||
this.markUsed();
|
||||
}
|
||||
|
||||
@ -311,7 +288,7 @@ namespace motors {
|
||||
}
|
||||
|
||||
private __setSpeed(speed: number) {
|
||||
const b = mkCmd(this._port, this._regulated ? DAL.opOutputSpeed : DAL.opOutputPower, 1)
|
||||
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
|
||||
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
||||
writePWM(b)
|
||||
if (speed) {
|
||||
@ -325,23 +302,11 @@ namespace motors {
|
||||
step1: 0,
|
||||
step2: stepsOrTime,
|
||||
step3: 0,
|
||||
speed: this._regulated ? speed : undefined,
|
||||
power: this._regulated ? undefined : speed,
|
||||
speed: speed,
|
||||
useBrake: this._brake
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the motor speed should be regulated. Default is true.
|
||||
* @param value true for regulated motor
|
||||
*/
|
||||
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value=toggleOnOff"
|
||||
//% weight=58
|
||||
//% group="Move"
|
||||
setRegulated(value: boolean) {
|
||||
this._regulated = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets motor actual speed.
|
||||
* @param motor the port which connects to the motor
|
||||
@ -509,7 +474,7 @@ namespace motors {
|
||||
* @param value (optional) move duration or rotation
|
||||
* @param unit (optional) unit of the value
|
||||
*/
|
||||
//% blockId=motorPairSteer block="steer %chassis|turn ratio %turnRatio=motorTurnRatioPicker|speed %speed=motorSpeedPicker|%"
|
||||
//% blockId=motorPairSteer block="steer %chassis|turn ratio %turnRatio|speed %speed=motorSpeedPicker|%"
|
||||
//% weight=95
|
||||
//% turnRatio.min=-200 turnRatio=200
|
||||
//% inlineInputMode=inline
|
||||
|
@ -11,7 +11,6 @@
|
||||
"mmap.cpp",
|
||||
"control.cpp",
|
||||
"console.ts",
|
||||
"timer.ts",
|
||||
"serialnumber.cpp",
|
||||
"buttons.ts",
|
||||
"png.cpp",
|
||||
|
4
libs/core/shims.d.ts
vendored
@ -41,10 +41,6 @@ declare interface MMap {
|
||||
/** Perform read(2) on the underlaying file */
|
||||
//% shim=MMapMethods::read
|
||||
read(data: Buffer): int32;
|
||||
|
||||
/** Set pointer on the underlaying file. */
|
||||
//% shim=MMapMethods::lseek
|
||||
lseek(offset: int32, whence: SeekWhence): int32;
|
||||
}
|
||||
declare namespace control {
|
||||
|
||||
|
@ -2,7 +2,7 @@ screen.clear()
|
||||
brick.print("PXT!", 10, 30, Draw.Quad)
|
||||
|
||||
brick.drawRect(40, 40, 20, 10, Draw.Fill)
|
||||
brick.setLight(BrickLight.Orange)
|
||||
brick.setLight(LightsPattern.Orange)
|
||||
|
||||
brick.heart.doubled().draw(100, 50, Draw.Double | Draw.Transparent)
|
||||
|
||||
@ -12,7 +12,7 @@ brick.buttonEnter.onEvent(ButtonEvent.Click, () => {
|
||||
|
||||
brick.buttonLeft.onEvent(ButtonEvent.Click, () => {
|
||||
brick.drawRect(10, 70, 20, 10, Draw.Fill)
|
||||
brick.setLight(BrickLight.Red)
|
||||
brick.setLight(LightsPattern.Red)
|
||||
brick.setFont(brick.microbitFont())
|
||||
})
|
||||
|
||||
|
@ -1,64 +0,0 @@
|
||||
namespace control {
|
||||
/**
|
||||
* A timer
|
||||
*/
|
||||
//% fixedInstances
|
||||
export class Timer {
|
||||
start: number;
|
||||
|
||||
constructor() {
|
||||
this.start = control.millis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the elapsed time in millis since the last reset
|
||||
*/
|
||||
//% blockId=timerMillis block="%timer|millis"
|
||||
millis(): number {
|
||||
return control.millis() - this.start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the elapsed time in seconds since the last reset
|
||||
*/
|
||||
//% blockId=timerSeconds block="%timer|seconds"
|
||||
seconds(): number {
|
||||
return this.millis() / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the timer
|
||||
*/
|
||||
//% blockId=timerRest block="%timer|reset"
|
||||
reset() {
|
||||
this.start = control.millis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses until the timer reaches the given amount of milliseconds
|
||||
* @param ms how long to pause for, eg: 5, 100, 200, 500, 1000, 2000
|
||||
*/
|
||||
//% blockId=timerPauseUntil block="%timer|pause until (ms) %ms"
|
||||
pauseUntil(ms: number) {
|
||||
const remaining = this.millis() - ms;
|
||||
loops.pause(Math.max(0, remaining));
|
||||
}
|
||||
}
|
||||
|
||||
//% whenUsed fixedInstance block="timer 1"
|
||||
export const timer1 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 2"
|
||||
export const timer2 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 3"
|
||||
export const timer3 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 4"
|
||||
export const timer4 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 5"
|
||||
export const timer5 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 6"
|
||||
export const timer6 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 7"
|
||||
export const timer7 = new Timer();
|
||||
//% whenUsed fixedInstance block="timer 8"
|
||||
export const timer8 = new Timer();
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# Datalog
|
||||
|
||||
A tiny libraty to create CSV datalog files.
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"datalog.addRow": "Starts a row of data",
|
||||
"datalog.addValue": "Adds a cell to the row of data",
|
||||
"datalog.addValue|param|name": "name of the cell, eg: \"x\"",
|
||||
"datalog.addValue|param|value": "value of the cell, eg: 0",
|
||||
"datalog.flush": "Commits any buffered row to disk",
|
||||
"datalog.setEnabled": "Turns on or off datalogging",
|
||||
"datalog.setFile": "Starts a new data logger for the given file",
|
||||
"datalog.setFile|param|filename": "the filename, eg: \"datalog.csv\"",
|
||||
"datalog.setStorage": "* @param storage custom storage solution"
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"datalog.addRow|block": "datalog add row",
|
||||
"datalog.addValue|block": "datalog add %name|=%value",
|
||||
"datalog.setEnabled|block": "datalog %enabled",
|
||||
"datalog|block": "datalog",
|
||||
"{id:category}Datalog": "Datalog"
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
//% weight=100 color=#0fbc11 icon=""
|
||||
namespace datalog {
|
||||
let _headers: string[] = undefined;
|
||||
let _headersLength: number;
|
||||
let _values: number[];
|
||||
let _buffer: string = "";
|
||||
let _start: number;
|
||||
let _filename = "datalog.csv";
|
||||
let _storage: storage.Storage = storage.temporary;
|
||||
let _enabled = true;
|
||||
|
||||
function clear() {
|
||||
_headers = undefined;
|
||||
_values = undefined;
|
||||
_buffer = "";
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (!_headers) {
|
||||
_headers = [];
|
||||
_headersLength = 0;
|
||||
_start = control.millis();
|
||||
_storage.remove(_filename);
|
||||
}
|
||||
_values = [];
|
||||
}
|
||||
|
||||
function commit() {
|
||||
// write row if any data
|
||||
if (_values && _values.length > 0) {
|
||||
// write headers for the first row
|
||||
if (!_headersLength) {
|
||||
_storage.appendCSVHeaders(_filename, _headers);
|
||||
_headersLength = _storage.size(_filename);
|
||||
}
|
||||
// commit row data
|
||||
_buffer += storage.toCSV(_values, _storage.csvSeparator);
|
||||
// buffered writes
|
||||
if (_buffer.length > 1024)
|
||||
flush();
|
||||
}
|
||||
|
||||
// clear values
|
||||
_values = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a row of data
|
||||
*/
|
||||
//% weight=100
|
||||
//% blockId=datalogAddRow block="datalog add row"
|
||||
export function addRow(): void {
|
||||
if (!_enabled) return;
|
||||
|
||||
commit();
|
||||
init();
|
||||
const s = (control.millis() - _start) / 1000;
|
||||
addValue("time (s)", s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a cell to the row of data
|
||||
* @param name name of the cell, eg: "x"
|
||||
* @param value value of the cell, eg: 0
|
||||
*/
|
||||
//% weight=99
|
||||
//% blockId=datalogAddValue block="datalog add %name|=%value"
|
||||
export function addValue(name: string, value: number) {
|
||||
if (!_values) return;
|
||||
let i = _headers.indexOf(name);
|
||||
if (i < 0) {
|
||||
_headers.push(name);
|
||||
i = _headers.length - 1;
|
||||
}
|
||||
_values[i] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new data logger for the given file
|
||||
* @param filename the filename, eg: "datalog.csv"
|
||||
*/
|
||||
//%
|
||||
export function setFile(filename: string) {
|
||||
flush();
|
||||
_filename = filename;
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param storage custom storage solution
|
||||
*/
|
||||
//%
|
||||
export function setStorage(storage: storage.Storage) {
|
||||
flush();
|
||||
_storage = storage;
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits any buffered row to disk
|
||||
*/
|
||||
//%
|
||||
export function flush() {
|
||||
if (_buffer) {
|
||||
const b = _buffer;
|
||||
_buffer = "";
|
||||
_storage.append(_filename, b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on or off datalogging
|
||||
* @param enabled
|
||||
*/
|
||||
//% blockId=datalogEnabled block="datalog %enabled"
|
||||
//% enabled.fieldEditor=fieldonoff
|
||||
export function setEnabled(enabled: boolean) {
|
||||
flush();
|
||||
_enabled = enabled;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
{
|
||||
"name": "datalog",
|
||||
"description": "Tiny data logging framework",
|
||||
"files": [
|
||||
"README.md",
|
||||
"datalog.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
"test.ts"
|
||||
],
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"core": "file:../core",
|
||||
"storage": "file:../storage"
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
loops.forever(function () {
|
||||
datalog.addRow()
|
||||
datalog.addValue("x", Math.random())
|
||||
datalog.addValue("y", Math.random())
|
||||
})
|
@ -8,7 +8,7 @@ namespace brick {
|
||||
|
||||
//% color="#C8509B" weight=95 icon="\uf10f"
|
||||
//% labelLineWidth=0
|
||||
//% groups='["Touch Sensor", "Color Sensor", "Ultrasonic Sensor", "Gyro Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Threshold"]'
|
||||
//% groups='["Ultrasonic Sensor", "Touch Sensor", "Color Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Gyro Sensor"]'
|
||||
//% groupIcons='["\uf101","\uf103","\uf102","","","\uf104"]'
|
||||
namespace sensors {
|
||||
}
|
||||
@ -56,9 +56,4 @@ namespace loops {
|
||||
//% color="#1E5AA8"
|
||||
namespace light {
|
||||
|
||||
}
|
||||
|
||||
//% color="#b0b0b0" advanced=true weight=5
|
||||
namespace storage {
|
||||
|
||||
}
|
@ -13,8 +13,7 @@
|
||||
"color-sensor": "file:../color-sensor",
|
||||
"touch-sensor": "file:../touch-sensor",
|
||||
"ultrasonic-sensor": "file:../ultrasonic-sensor",
|
||||
"gyro-sensor": "file:../gyro-sensor",
|
||||
"mood": "file:../mood"
|
||||
"gyro-sensor": "file:../gyro-sensor"
|
||||
},
|
||||
"public": true
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
{
|
||||
"sensors.GyroSensor.angle": "Get the current angle from the gyroscope.",
|
||||
"sensors.GyroSensor.drift": "Gets the computed rate drift",
|
||||
"sensors.GyroSensor.rate": "Get the current rotation rate from the gyroscope.",
|
||||
"sensors.GyroSensor.reset": "Forces a calibration of the gyro. Must be called when the sensor is completely still.",
|
||||
"sensors.GyroSensor.setDriftCorrection": "Enables or disable drift correction"
|
||||
"sensors.GyroSensor.calibrate": "Forces a calibration of the gyro. Must be called when the sensor is completely still.",
|
||||
"sensors.GyroSensor.rotationRate": "Get the current rotation rate from the gyroscope."
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"sensors.GyroSensor.angle|block": "%sensor|angle",
|
||||
"sensors.GyroSensor.rate|block": "%sensor|rate",
|
||||
"sensors.GyroSensor.reset|block": "%sensor|reset",
|
||||
"sensors.GyroSensor.calibrate|block": "%sensor|calibrate",
|
||||
"sensors.GyroSensor.rotationRate|block": "%sensor|rotation rate",
|
||||
"sensors.gyro1|block": "gyro 1",
|
||||
"sensors.gyro2|block": "gyro 2",
|
||||
"sensors.gyro3|block": "gyro 3",
|
||||
|
@ -8,27 +8,16 @@ namespace sensors {
|
||||
//% fixedInstances
|
||||
export class GyroSensor extends internal.UartSensor {
|
||||
private calibrating: boolean;
|
||||
private _drift: number;
|
||||
private _drifting: boolean;
|
||||
constructor(port: number) {
|
||||
super(port)
|
||||
this.calibrating = false;
|
||||
this._drift = 0;
|
||||
this._drifting = true;
|
||||
this.setMode(GyroSensorMode.Rate);
|
||||
}
|
||||
|
||||
_deviceType() {
|
||||
return DAL.DEVICE_TYPE_GYRO
|
||||
}
|
||||
|
||||
_query(): number {
|
||||
return this.getNumber(NumberFormat.Int16LE, 0);
|
||||
}
|
||||
|
||||
setMode(m: GyroSensorMode) {
|
||||
if (m == GyroSensorMode.Rate && this.mode != m)
|
||||
this._drift = 0;
|
||||
this._setMode(m)
|
||||
}
|
||||
|
||||
@ -42,97 +31,67 @@ namespace sensors {
|
||||
//% parts="gyroscope"
|
||||
//% blockNamespace=sensors
|
||||
//% sensor.fieldEditor="ports"
|
||||
//% weight=64 blockGap=8
|
||||
//% weight=65 blockGap=8
|
||||
//% group="Gyro Sensor"
|
||||
angle(): number {
|
||||
if (this.calibrating)
|
||||
pauseUntil(() => !this.calibrating, 2000);
|
||||
|
||||
this.setMode(GyroSensorMode.Angle);
|
||||
return this._query();
|
||||
this.setMode(GyroSensorMode.Angle)
|
||||
return this.getNumber(NumberFormat.Int16LE, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current rotation rate from the gyroscope.
|
||||
* @param sensor the gyroscope to query the request
|
||||
*/
|
||||
//% help=input/gyro/rate
|
||||
//% block="%sensor|rate"
|
||||
//% help=input/gyro/rotation-rate
|
||||
//% block="%sensor|rotation rate"
|
||||
//% blockId=gyroGetRate
|
||||
//% parts="gyroscope"
|
||||
//% blockNamespace=sensors
|
||||
//% sensor.fieldEditor="ports"
|
||||
//% weight=65 blockGap=8
|
||||
//% group="Gyro Sensor"
|
||||
rate(): number {
|
||||
rotationRate(): number {
|
||||
if (this.calibrating)
|
||||
pauseUntil(() => !this.calibrating, 2000);
|
||||
|
||||
this.setMode(GyroSensorMode.Rate);
|
||||
let curr = this._query();
|
||||
if (Math.abs(curr) < 20) {
|
||||
const p = 0.0005;
|
||||
this._drift = (1 - p) * this._drift + p * curr;
|
||||
curr -= this._drift;
|
||||
}
|
||||
return curr;
|
||||
this.setMode(GyroSensorMode.Rate)
|
||||
return this.getNumber(NumberFormat.Int16LE, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a calibration of the gyro. Must be called when the sensor is completely still.
|
||||
*/
|
||||
//% help=input/gyro/calibrate
|
||||
//% block="%sensor|reset"
|
||||
//% blockId=gyroReset
|
||||
//% block="%sensor|calibrate"
|
||||
//% blockId=gyroCalibrate
|
||||
//% parts="gyroscope"
|
||||
//% blockNamespace=sensors
|
||||
//% sensor.fieldEditor="ports"
|
||||
//% weight=50 blockGap=8
|
||||
//% weight=65 blockGap=8
|
||||
//% group="Gyro Sensor"
|
||||
reset(): void {
|
||||
calibrate(): void {
|
||||
if (this.calibrating) return; // already in calibration mode
|
||||
|
||||
this.calibrating = true;
|
||||
// may be triggered by a button click,
|
||||
// give time for robot to settle
|
||||
loops.pause(700);
|
||||
// may be triggered by a button click, give time to settle
|
||||
loops.pause(500);
|
||||
// send a reset command
|
||||
super.reset();
|
||||
// switch back to the desired mode
|
||||
this.setMode(this.mode);
|
||||
// wait till sensor is live
|
||||
pauseUntil(() => this.isActive());
|
||||
// give it a bit of time to init
|
||||
loops.pause(1000)
|
||||
// compute drift
|
||||
this._drift = 0;
|
||||
if (this.mode == GyroSensorMode.Rate) {
|
||||
for (let i = 0; i < 200; ++i) {
|
||||
this._drift += this._query();
|
||||
loops.pause(4);
|
||||
}
|
||||
this._drift /= 200;
|
||||
}
|
||||
// and we're done
|
||||
this.reset();
|
||||
// we need to switch mode twice to perform a calibration
|
||||
if (this.mode == GyroSensorMode.Rate)
|
||||
this.setMode(GyroSensorMode.Angle);
|
||||
else
|
||||
this.setMode(GyroSensorMode.Rate);
|
||||
// switch back and wait
|
||||
if (this.mode == GyroSensorMode.Rate)
|
||||
this.setMode(GyroSensorMode.Angle);
|
||||
else
|
||||
this.setMode(GyroSensorMode.Rate);
|
||||
this.calibrating = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the computed rate drift
|
||||
*/
|
||||
//%
|
||||
drift(): number {
|
||||
return this._drift;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disable drift correction
|
||||
* @param enabled
|
||||
*/
|
||||
//%
|
||||
setDriftCorrection(enabled: boolean) {
|
||||
this._drifting = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="gyro 2" weight=95 jres=icons.port2
|
||||
|
@ -4,9 +4,6 @@
|
||||
"sensors.InfraredSensor.pauseUntil": "Waits for the event to occur",
|
||||
"sensors.InfraredSensor.proximity": "Get the promixity measured by the infrared sensor, from ``0`` (close) to ``100`` (far)",
|
||||
"sensors.InfraredSensor.remoteCommand": "Get the remote commandreceived the infrared sensor.",
|
||||
"sensors.InfraredSensor.setThreshold": "Sets a threshold value",
|
||||
"sensors.InfraredSensor.setThreshold|param|condition": "the dark or bright light condition",
|
||||
"sensors.InfraredSensor.setThreshold|param|value": "the value threshold",
|
||||
"sensors.RemoteInfraredBeaconButton.isPressed": "Check if a remote button is currently pressed or not.",
|
||||
"sensors.RemoteInfraredBeaconButton.onEvent": "Do something when a button or sensor is clicked, up or down",
|
||||
"sensors.RemoteInfraredBeaconButton.onEvent|param|body": "code to run when the event is raised",
|
||||
|
@ -5,7 +5,6 @@
|
||||
"sensors.InfraredSensor.pauseUntil|block": "pause until %sensor| %event",
|
||||
"sensors.InfraredSensor.proximity|block": "%sensor|proximity",
|
||||
"sensors.InfraredSensor.remoteCommand|block": "%sensor|remote command",
|
||||
"sensors.InfraredSensor.setThreshold|block": "set %sensor|%condition|to %value",
|
||||
"sensors.RemoteInfraredBeaconButton.isPressed|block": "%button|is pressed",
|
||||
"sensors.RemoteInfraredBeaconButton.onEvent|block": "on %button|%event",
|
||||
"sensors.RemoteInfraredBeaconButton.wasPressed|block": "%button|was pressed",
|
||||
@ -21,6 +20,5 @@
|
||||
"sensors|block": "sensors",
|
||||
"{id:category}Sensors": "Sensors",
|
||||
"{id:group}Infrared Sensor": "Infrared Sensor",
|
||||
"{id:group}Remote Infrared Beacon": "Remote Infrared Beacon",
|
||||
"{id:group}Threshold": "Threshold"
|
||||
"{id:group}Remote Infrared Beacon": "Remote Infrared Beacon"
|
||||
}
|
@ -138,12 +138,12 @@ namespace sensors {
|
||||
//% fixedInstances
|
||||
export class InfraredSensor extends internal.UartSensor {
|
||||
private channel: IrRemoteChannel;
|
||||
private proximityThreshold: sensors.ThresholdDetector;
|
||||
private proximityThreshold: sensors.internal.ThresholdDetector;
|
||||
|
||||
constructor(port: number) {
|
||||
super(port)
|
||||
this.channel = IrRemoteChannel.Ch0
|
||||
this.proximityThreshold = new sensors.ThresholdDetector(this._id, 0, 100, 10, 90);
|
||||
this.proximityThreshold = new sensors.internal.ThresholdDetector(this._id, 0, 100, 10, 90);
|
||||
irButton(0) // make sure buttons array is initalized
|
||||
|
||||
// and set the mode, as otherwise button events won't work
|
||||
@ -250,22 +250,6 @@ namespace sensors {
|
||||
this._setMode(IrSensorMode.Seek)
|
||||
return this.getNumber(NumberFormat.UInt16LE, this.channel * 2)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a threshold value
|
||||
* @param condition the dark or bright light condition
|
||||
* @param value the value threshold
|
||||
*/
|
||||
//% blockId=irSetThreshold block="set %sensor|%condition|to %value"
|
||||
//% group="Threshold" blockGap=8
|
||||
//% value.min=0 value.max=100
|
||||
setThreshold(condition: InfraredSensorEvent, value: number) {
|
||||
if (condition == InfraredSensorEvent.ObjectNear)
|
||||
this.proximityThreshold.setLowThreshold(value)
|
||||
else
|
||||
this.proximityThreshold.setHighThreshold(value);
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="infrared 1" jres=icons.port1
|
||||
|
1
libs/matrix/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Matrix
|
15
libs/matrix/_locales/matrix-jsdoc-strings.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"matrix.Matrix": "A 2D matrix",
|
||||
"matrix.Matrix.add": "Returns a new matrix as the sum of both matrices",
|
||||
"matrix.Matrix.cholesky": "Performs a Cholesky factorized for a symmetric and positive definite",
|
||||
"matrix.Matrix.clone": "Clones the matrix",
|
||||
"matrix.Matrix.get": "Gets a value from the matrix",
|
||||
"matrix.Matrix.get|param|row": "@param col ",
|
||||
"matrix.Matrix.identity": "Creates an identity matrix",
|
||||
"matrix.Matrix.logToConsole": "Renders the matrix to the console",
|
||||
"matrix.Matrix.multiply": "Multiplies the current matrix with the other matrix and returns a new matrix",
|
||||
"matrix.Matrix.scale": "Returns a new matrix with scaled values",
|
||||
"matrix.Matrix.set": "Sets a value in the array",
|
||||
"matrix.Matrix.set|param|row": "@param col ",
|
||||
"matrix.Matrix.transpose": "Returns a transposed matrix"
|
||||
}
|
4
libs/matrix/_locales/matrix-strings.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"matrix|block": "matrix",
|
||||
"{id:category}Matrix": "Matrix"
|
||||
}
|
186
libs/matrix/matrix.ts
Normal file
@ -0,0 +1,186 @@
|
||||
namespace matrix {
|
||||
function pre(check: boolean) {
|
||||
if (!check)
|
||||
control.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* A 2D matrix
|
||||
*/
|
||||
export class Matrix {
|
||||
private _rows: number;
|
||||
private _cols: number;
|
||||
private _values: number[];
|
||||
|
||||
constructor(rows: number, cols: number, values: number[] = undefined) {
|
||||
pre(rows > 0);
|
||||
pre(cols > 0);
|
||||
this._rows = rows;
|
||||
this._cols = cols;
|
||||
const n = this._rows * this._cols;
|
||||
this._values = values || [];
|
||||
// fill gaps
|
||||
while (this._values.length < n)
|
||||
this._values.push(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an identity matrix
|
||||
* @param size
|
||||
*/
|
||||
static identity(size: number): Matrix {
|
||||
const m = new Matrix(size, size);
|
||||
for (let i = 0; i < size; ++i)
|
||||
m._values[i * size] = 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in the array
|
||||
* @param row
|
||||
* @param col
|
||||
* @param val
|
||||
*/
|
||||
set(row: number, col: number, val: number) {
|
||||
pre(row == row >> 0 && row >= 0 && row < this._rows && col == col >> 0 && col >= 0 && col < this._cols);
|
||||
this._values[row * this._cols + col] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from the matrix
|
||||
* @param row
|
||||
* @param col
|
||||
*/
|
||||
get(row: number, col: number): number {
|
||||
pre(row == row >> 0 && row >= 0 && row < this._rows && col == col >> 0 && col >= 0 && col < this._cols);
|
||||
return this._values[row * this._cols + col];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of rows
|
||||
*/
|
||||
get rows(): number {
|
||||
return this._rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of colums
|
||||
*/
|
||||
get cols(): number {
|
||||
return this._cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw storage buffer
|
||||
*/
|
||||
get values(): number[] {
|
||||
return this._values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new matrix as the sum of both matrices
|
||||
* @param other
|
||||
*/
|
||||
add(other: Matrix): Matrix {
|
||||
pre(this._rows != other._rows || this._cols != other._cols)
|
||||
const n = this._rows * this._cols;
|
||||
const r: number[] = [];
|
||||
for (let i = 0; i < n; ++i) {
|
||||
r[i] = this._values[i] + other._values[i];
|
||||
}
|
||||
return new Matrix(this._rows, this._cols, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new matrix with scaled values
|
||||
* @param factor
|
||||
*/
|
||||
scale(factor: number): Matrix {
|
||||
const n = this._rows * this._cols;
|
||||
const r: number[] = [];
|
||||
for (let i = 0; i < n; ++i) {
|
||||
r[i] = this._values[i] * factor;
|
||||
}
|
||||
return new Matrix(this._rows, this._cols, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the current matrix with the other matrix and returns a new matrix
|
||||
* @param other
|
||||
*/
|
||||
multiply(other: Matrix): Matrix {
|
||||
pre(this._cols == other._rows);
|
||||
const r: number[] = [];
|
||||
for (let i = 0; i < this._rows; ++i) {
|
||||
for (let j = 0; j < other._cols; ++j) {
|
||||
let s = 0;
|
||||
for (let k = 0; k < this._cols; ++k) {
|
||||
s += this._values[i * this._cols + k] * other._values[k * other._cols + j];
|
||||
}
|
||||
r[i * other._cols + j];
|
||||
}
|
||||
}
|
||||
return new Matrix(this._rows, other._cols, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a transposed matrix
|
||||
*/
|
||||
transpose(): Matrix {
|
||||
const R = new Matrix(this._cols, this._rows);
|
||||
const r: number[] = R._values;
|
||||
for (let i = 0; i < this._rows; ++i) {
|
||||
for (let j = 0; j < this._cols; ++j) {
|
||||
r[i + j * this._rows] = this._values[i * this._cols + j];
|
||||
}
|
||||
}
|
||||
return R;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones the matrix
|
||||
*/
|
||||
clone(): Matrix {
|
||||
const r = new Matrix(this._rows, this._cols, this._values.slice(0));
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a Cholesky factorized for a symmetric and positive definite
|
||||
*
|
||||
*/
|
||||
cholesky(): Matrix {
|
||||
pre(this._rows == this._cols);
|
||||
const l = this.clone();
|
||||
const n = this._rows;
|
||||
const L = l._values;
|
||||
|
||||
for (let j = 0; j < n; j++) {
|
||||
const jj = L[j * n + j] = Math.sqrt(L[j * n + j]);
|
||||
for (let i = j + 1; i < n; ++i)
|
||||
L[i * n + j] /= jj;
|
||||
for (let k = j + 1; k < n; k++)
|
||||
for (let i = k; i < n; i++)
|
||||
L[i * n + j] -= L[i * n + j] * L[k * n + j];
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the matrix to the console
|
||||
*/
|
||||
logToConsole(): void {
|
||||
let k = 0;
|
||||
for(let i = 0; i < this._rows; ++i) {
|
||||
let s = ""
|
||||
for(let j = 0; j < this._cols; ++j) {
|
||||
if (j > 0)
|
||||
s += " "
|
||||
s += Math.round((this._values[k++] * 100) / 100);
|
||||
}
|
||||
console.log(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
libs/matrix/pxt.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "matrix",
|
||||
"description": "Matrix algebra",
|
||||
"files": [
|
||||
"README.md",
|
||||
"matrix.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
"test.ts"
|
||||
],
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"core": "file:../core"
|
||||
}
|
||||
}
|
1
libs/matrix/test.ts
Normal file
@ -0,0 +1 @@
|
||||
// add tests here
|
@ -1,3 +0,0 @@
|
||||
# mood
|
||||
|
||||
A package to put the EV3 in various moods.
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"brick.Mood": "A mood",
|
||||
"brick.Mood.show": "Shows the mood on the EV3",
|
||||
"brick.showMood": "Shows a mood",
|
||||
"moods.angry": "An angry mood",
|
||||
"moods.awake": "A awake mood",
|
||||
"moods.dizzy": "A dizzy mood",
|
||||
"moods.knockedOut": "A knocked out mood",
|
||||
"moods.love": "In love mood",
|
||||
"moods.middleLeft": "Looking around left",
|
||||
"moods.middleRight": "Looking around right",
|
||||
"moods.neutral": "In a neutral mood",
|
||||
"moods.sad": "A sad mood",
|
||||
"moods.sleeping": "A sleeping mood",
|
||||
"moods.tired": "A tired mood",
|
||||
"moods.winking": "In laughing mood"
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"brick.showMood|block": "show mood %mood=mood_image_picker",
|
||||
"brick|block": "brick",
|
||||
"moods|block": "moods",
|
||||
"{id:category}Brick": "Brick",
|
||||
"{id:category}Moods": "Moods",
|
||||
"{id:group}Screen": "Screen"
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
namespace brick {
|
||||
/**
|
||||
* Shows a mood
|
||||
*/
|
||||
//% weight=90
|
||||
//% blockId=moodShow block="show mood %mood=mood_image_picker"
|
||||
//% weight=101 group="Screen" blockGap=8
|
||||
export function showMood(mood: Mood) {
|
||||
if(mood)
|
||||
mood.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* A mood
|
||||
*/
|
||||
//% fixedInstances
|
||||
export class Mood {
|
||||
private image: Image;
|
||||
private sound: Sound;
|
||||
private light: BrickLight;
|
||||
|
||||
constructor(image: Image, sound: Sound, light: BrickLight) {
|
||||
this.image = image;
|
||||
this.sound = sound;
|
||||
this.light = light;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the mood on the EV3
|
||||
*/
|
||||
show() {
|
||||
brick.setLight(this.light);
|
||||
brick.showImage(this.image);
|
||||
music.playSoundEffectUntilDone(this.sound);
|
||||
loops.pause(20);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An image
|
||||
* @param image the image
|
||||
*/
|
||||
//% blockId=mood_image_picker block="%image" shim=TD_ID
|
||||
//% image.fieldEditor="images"
|
||||
//% image.fieldOptions.columns=4
|
||||
//% image.fieldOptions.width=400
|
||||
//% group="Screen" weight=0 blockHidden=1
|
||||
export function __moodImagePicker(mood: Mood): Mood {
|
||||
return mood;
|
||||
}
|
||||
}
|
||||
|
||||
namespace moods {
|
||||
/**
|
||||
* A sleeping mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesSleeping
|
||||
export const sleeping = new brick.Mood(images.eyesSleeping, sounds.expressionsSnoring, BrickLight.OrangePulse);
|
||||
|
||||
/**
|
||||
* A awake mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesAwake
|
||||
export const awake = new brick.Mood(images.eyesAwake, sounds.informationActivate, BrickLight.Orange);
|
||||
|
||||
/**
|
||||
* A tired mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesTiredMiddle
|
||||
export const tired = new brick.Mood(images.eyesTiredMiddle, sounds.expressionsSneezing, BrickLight.OrangeFlash);
|
||||
|
||||
/**
|
||||
* An angry mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesAngry
|
||||
export const angry = new brick.Mood(images.eyesAngry, sounds.animalsDogGrowl, BrickLight.RedPulse);
|
||||
|
||||
/**
|
||||
* A sad mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesTear
|
||||
export const sad = new brick.Mood(images.eyesTear, sounds.animalsDogWhine, BrickLight.Red);
|
||||
|
||||
/**
|
||||
* A dizzy mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesDizzy
|
||||
export const dizzy = new brick.Mood(images.eyesDizzy, sounds.expressionsUhOh, BrickLight.OrangeFlash);
|
||||
|
||||
/**
|
||||
* A knocked out mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesKnockedOut
|
||||
export const knockedOut = new brick.Mood(images.eyesKnockedOut, sounds.informationError, BrickLight.RedFlash);
|
||||
|
||||
/**
|
||||
* Looking around left
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesMiddleLeft
|
||||
export const middleLeft = new brick.Mood(images.eyesMiddleLeft, sounds.informationAnalyze, BrickLight.Off);
|
||||
|
||||
/**
|
||||
* Looking around right
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesMiddleRight
|
||||
export const middleRight = new brick.Mood(images.eyesMiddleRight, sounds.informationAnalyze, BrickLight.Off);
|
||||
|
||||
/**
|
||||
* In love mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesLove
|
||||
export const love = new brick.Mood(images.eyesLove, sounds.expressionsMagicWand, BrickLight.GreenPulse);
|
||||
|
||||
/**
|
||||
* In laughing mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesWinking
|
||||
export const winking = new brick.Mood(images.eyesWinking, sounds.expressionsLaughing1, BrickLight.GreenFlash);
|
||||
|
||||
/**
|
||||
* In a neutral mood
|
||||
*/
|
||||
//% fixedInstance jres=images.eyesNeutral
|
||||
export const neutral = new brick.Mood(images.eyesNeutral, undefined, BrickLight.Green);
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "mood",
|
||||
"description": "The EV3 mood library",
|
||||
"files": [
|
||||
"README.md",
|
||||
"mood.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
],
|
||||
"public": true,
|
||||
"dependencies": {
|
||||
"core": "file:../core",
|
||||
"music": "file:../music"
|
||||
}
|
||||
}
|