Compare commits
131 Commits
Author | SHA1 | Date | |
---|---|---|---|
603e4c0fc1 | |||
e50c88008a | |||
f057964a50 | |||
2eda2061cf | |||
a4ebf4c746 | |||
f1880897d4 | |||
ad2e82060d | |||
d1bb19e30e | |||
280963d1eb | |||
9fadf49b0e | |||
3c2be25384 | |||
e1f623a94d | |||
cb5f9648f5 | |||
9158cfe4f6 | |||
0b763978f2 | |||
25fded6afb | |||
fc6fb0811f | |||
49bedcbcc5 | |||
32876f4584 | |||
da9bea30b5 | |||
d0aa68aeee | |||
51731fbbc9 | |||
751ea1494b | |||
dfe84471e8 | |||
0f3de6cf07 | |||
21195e4abf | |||
c992100a38 | |||
20a4673f98 | |||
966fd81870 | |||
cb9d2aeb39 | |||
3cee55f4c2 | |||
3815d2fd3b | |||
1453b7e0a3 | |||
6fb5c54280 | |||
9d5ca35e83 | |||
893dd0f9c4 | |||
c3419c0b74 | |||
a4164470d8 | |||
0dd5ab9bde | |||
e93e659e8a | |||
8357372fb5 | |||
54cb076002 | |||
dbd3eb464b | |||
10cd39a4ec | |||
fddc4e647a | |||
798a351f15 | |||
e61dffff03 | |||
b9f5096480 | |||
9912d68c8b | |||
951b9be6e4 | |||
aa8635c4e7 | |||
4e4f5495da | |||
f64bf57000 | |||
f1242724b5 | |||
cd0c9df86e | |||
337d42287a | |||
ce3383f1b7 | |||
e51721303a | |||
50f6c77fdb | |||
5ed0135124 | |||
892a2d585f | |||
9890f2340a | |||
109b809909 | |||
9cbf5efd7e | |||
a27a7fcd55 | |||
85263fb84d | |||
b5ad898c9e | |||
456df3c442 | |||
1552eb05b4 | |||
d60e2c4a7d | |||
f4b78c3ee7 | |||
dd5e1957d5 | |||
d61a63f70a | |||
4207bd06c0 | |||
58763e398b | |||
f77bf165eb | |||
4880d9ea5b | |||
ab4fb019f9 | |||
2c2df31ba3 | |||
0f2bda2496 | |||
44386be3c7 | |||
89ca66b8a9 | |||
64389a7689 | |||
f77778ef85 | |||
7d01823caf | |||
b3f9a4c92f | |||
7fe8580de8 | |||
c70d6fe01a | |||
ed7099cc97 | |||
a79704fecc | |||
6a1b560101 | |||
5e21f9ab6d | |||
74648bd1df | |||
e24d4d56b1 | |||
0345277bef | |||
9ae6482f28 | |||
77fb64043d | |||
f875681661 | |||
fbb1fa688d | |||
485f02ed27 | |||
81f406c6cc | |||
ac0a7b326f | |||
c814728354 | |||
abeb378b17 | |||
6928f9e50e | |||
931987468a | |||
94c4e508fe | |||
ea46f1cbc7 | |||
9f9ce29476 | |||
50f6b04ed4 | |||
64d6c2b090 | |||
76ff39605a | |||
2d3ea5631a | |||
e938f354fd | |||
886464b470 | |||
b9ff9d21f1 | |||
aa06fd344a | |||
dc6ce0efc7 | |||
4039a85bc9 | |||
7bd6280292 | |||
2ebe96e563 | |||
a9be582f90 | |||
ac428a3936 | |||
de91dc6ab7 | |||
1e460eef9e | |||
0db6987ee5 | |||
148657908c | |||
f3f87331c8 | |||
5aef77ccc6 | |||
16b9a5027d | |||
cbe68b3199 |
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
This repo contains the editor target hosted at https://d541eec2-1e96-4b7b-a223-da9d01d0337a.pxt.io/
|
This repo contains the editor target hosted at https://d541eec2-1e96-4b7b-a223-da9d01d0337a.pxt.io/
|
||||||
|
|
||||||
Issue tracker: https://src.education.lego.com/groups/ev3-makecode
|
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
|
||||||
|
|
||||||
## Local Dev setup
|
## Local Dev setup
|
||||||
|
|
||||||
|
@ -2,14 +2,10 @@
|
|||||||
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
require("./editor/deploy")
|
const deploy = require("./editor/deploy")
|
||||||
|
|
||||||
declare namespace pxt.editor {
|
|
||||||
function deployCoreAsync(resp: pxtc.CompileResult, disconnect?: boolean): Promise<void>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function deployCoreAsync(resp: pxtc.CompileResult) {
|
export function deployCoreAsync(resp: pxtc.CompileResult) {
|
||||||
return pxt.editor.deployCoreAsync(resp, process.env["PXT_SERIAL"] ? false : true)
|
return deploy.deployCoreAsync(resp, process.env["PXT_SERIAL"] ? false : true)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
fs.writeFileSync("built/full-" + pxtc.BINARY_UF2, resp.outfiles[pxtc.BINARY_UF2], {
|
fs.writeFileSync("built/full-" + pxtc.BINARY_UF2, resp.outfiles[pxtc.BINARY_UF2], {
|
||||||
encoding: "base64"
|
encoding: "base64"
|
||||||
|
171
docs/coding.md
Normal file
171
docs/coding.md
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
# Coding Activites
|
||||||
|
|
||||||
|
12 computer science activities, with cross-curricular opportunities in design and technology, science, and math.
|
||||||
|
|
||||||
|
* [Download Curriculum Materials](https://education.lego.com/en-us/downloads/mindstorms-ev3)
|
||||||
|
|
||||||
|
## Three Point Turn
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Three Point Turn 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/three-point-turn-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Three Point Turn 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/three-point-turn-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Three Point Turn 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/three-point-turn-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reversing the robot
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Reversing the robot 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/reversing-the-robot-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Reversing the robot 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/reversing-the-robot-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Reversing the robot 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/reversing-the-robot-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Light the way
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Light the way 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/light-the-way-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Light the way 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/light-the-way-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Light the way 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/light-the-way-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Traffic Lights
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Traffic Lights 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/traffic-lights-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Traffic Lights 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/traffic-lights-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Traffic Lights 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/traffic-lights-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Reverse Bepper
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Reverse Beeper 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/reverse-beeper-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Reverse Beeper 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/reverse-beeper-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Reverse Beeper 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/reverse-beeper-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ignition
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Ignition 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/ingition-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Ignition 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/ignition-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Ignition 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/ignition-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cruise Control
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Cruise Control 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/cruise-control-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Cruise Control 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/cruise-control-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Cruise Control 3",
|
||||||
|
"description": "Activity 3",
|
||||||
|
"url":"/coding/cruise-control-3",
|
||||||
|
"cardType": "example"
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Roaming
|
||||||
|
|
||||||
|
```codecard
|
||||||
|
[{
|
||||||
|
"name": "Roaming 1",
|
||||||
|
"description": "Activity 1",
|
||||||
|
"url":"/coding/roaming-1",
|
||||||
|
"cardType": "example"
|
||||||
|
}, {
|
||||||
|
"name": "Roaming 2",
|
||||||
|
"description": "Activity 2",
|
||||||
|
"url":"/coding/roaming-2",
|
||||||
|
"cardType": "example"
|
||||||
|
}]
|
||||||
|
```
|
10
docs/coding/cruise-control-1.md
Normal file
10
docs/coding/cruise-control-1.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Cruise Control Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let speed = 0;
|
||||||
|
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
if (speed < 100)
|
||||||
|
speed = speed + 10;
|
||||||
|
motors.largeBC.setSpeed(speed);
|
||||||
|
})
|
||||||
|
```
|
15
docs/coding/cruise-control-2.md
Normal file
15
docs/coding/cruise-control-2.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Cruise Control Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let speed = 0;
|
||||||
|
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
if (speed < 100)
|
||||||
|
speed = speed + 10;
|
||||||
|
motors.largeBC.setSpeed(speed);
|
||||||
|
})
|
||||||
|
sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
if (speed > -100)
|
||||||
|
speed = speed - 10;
|
||||||
|
motors.largeBC.setSpeed(speed);
|
||||||
|
})
|
||||||
|
```
|
28
docs/coding/cruise-control-3.md
Normal file
28
docs/coding/cruise-control-3.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Cruise Control Activity 3
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let speed = 0
|
||||||
|
function decelerate() {
|
||||||
|
if (speed > -100) {
|
||||||
|
speed = speed - 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function accelerate() {
|
||||||
|
if (speed < 100) {
|
||||||
|
speed = speed + 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function update() {
|
||||||
|
brick.clearScreen()
|
||||||
|
brick.showString("speed: " + speed, 1)
|
||||||
|
motors.largeBC.setSpeed(speed)
|
||||||
|
}
|
||||||
|
sensors.touch2.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
accelerate()
|
||||||
|
update()
|
||||||
|
})
|
||||||
|
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
decelerate()
|
||||||
|
update()
|
||||||
|
})
|
||||||
|
```
|
11
docs/coding/ignition-1.md
Normal file
11
docs/coding/ignition-1.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Ignition Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
brick.showImage(images.eyesDizzy)
|
||||||
|
})
|
||||||
|
sensors.ultrasonic4.onEvent(UltrasonicSensorEvent.ObjectDetected, function () {
|
||||||
|
brick.showImage(images.eyesTiredMiddle)
|
||||||
|
})
|
||||||
|
brick.showImage(images.eyesSleeping)
|
||||||
|
```
|
12
docs/coding/ignition-2.md
Normal file
12
docs/coding/ignition-2.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Ignition Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
while (true) {
|
||||||
|
if (sensors.touch1.wasPressed() &&
|
||||||
|
sensors.ultrasonic4.distance() < 10) {
|
||||||
|
music.playSoundEffectUntilDone(sounds.mechanicalMotorStart)
|
||||||
|
music.playSoundEffectUntilDone(sounds.mechanicalMotorIdle);
|
||||||
|
}
|
||||||
|
loops.pause(1);
|
||||||
|
}
|
||||||
|
```
|
13
docs/coding/ignition-3.md
Normal file
13
docs/coding/ignition-3.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Ignition Activity 3
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
while (true) {
|
||||||
|
if (sensors.ultrasonic4.distance() < 10 &&
|
||||||
|
sensors.touch1.wasPressed() &&
|
||||||
|
brick.buttonEnter.wasPressed()) {
|
||||||
|
music.playSoundEffectUntilDone(sounds.mechanicalMotorStart)
|
||||||
|
music.playSoundEffectUntilDone(sounds.mechanicalMotorIdle);
|
||||||
|
}
|
||||||
|
loops.pause(1);
|
||||||
|
}
|
||||||
|
```
|
9
docs/coding/light-the-way-1.md
Normal file
9
docs/coding/light-the-way-1.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Light the way Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Dark, function () {
|
||||||
|
brick.showImage(images.objectsLightOn)
|
||||||
|
loops.pause(5000)
|
||||||
|
brick.clearScreen()
|
||||||
|
})
|
||||||
|
```
|
10
docs/coding/light-the-way-2.md
Normal file
10
docs/coding/light-the-way-2.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Light the way Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Bright, function () {
|
||||||
|
brick.clearScreen()
|
||||||
|
})
|
||||||
|
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Dark, function () {
|
||||||
|
brick.showImage(images.objectsLightOn)
|
||||||
|
})
|
||||||
|
```
|
13
docs/coding/light-the-way-3.md
Normal file
13
docs/coding/light-the-way-3.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Light the way Activity 3
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Bright, function () {
|
||||||
|
brick.clearScreen()
|
||||||
|
})
|
||||||
|
sensors.color3.onLightChanged(LightIntensityMode.Ambient, LightCondition.Dark, function () {
|
||||||
|
brick.showImage(images.objectsLightOn)
|
||||||
|
})
|
||||||
|
sensors.touch1.onEvent(TouchSensorEvent.Pressed, function () {
|
||||||
|
brick.showImage(images.objectsLightOn);
|
||||||
|
})
|
||||||
|
```
|
11
docs/coding/reverse-beeper-1.md
Normal file
11
docs/coding/reverse-beeper-1.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Reverse Beeper Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
loops.forever(function () {
|
||||||
|
music.playTone(440, sensors.ultrasonic4.distance());
|
||||||
|
loops.pause(50)
|
||||||
|
})
|
||||||
|
motors.largeBC.setSpeed(-20);
|
||||||
|
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
|
||||||
|
motors.largeBC.stop();
|
||||||
|
```
|
13
docs/coding/reverse-beeper-2.md
Normal file
13
docs/coding/reverse-beeper-2.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Reverse Beeper Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
loops.forever(function () {
|
||||||
|
if (motors.largeB.speed() != 0 && sensors.ultrasonic4.distance() < 20) {
|
||||||
|
music.playTone(440, sensors.ultrasonic4.distance());
|
||||||
|
loops.pause(50)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
motors.largeBC.setSpeed(-20);
|
||||||
|
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
|
||||||
|
motors.largeBC.stop();
|
||||||
|
```
|
20
docs/coding/reverse-beeper-3.md
Normal file
20
docs/coding/reverse-beeper-3.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Reverse Beeper Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let beep = false
|
||||||
|
beep = true
|
||||||
|
control.runInBackground(function () {
|
||||||
|
motors.largeBC.setSpeed(-20)
|
||||||
|
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear)
|
||||||
|
motors.largeBC.stop()
|
||||||
|
beep = false
|
||||||
|
})
|
||||||
|
control.runInBackground(function () {
|
||||||
|
while (beep) {
|
||||||
|
if (sensors.ultrasonic4.distance() < 20) {
|
||||||
|
music.playTone(440, sensors.ultrasonic4.distance())
|
||||||
|
loops.pause(50)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
14
docs/coding/reversing-the-robot-1.md
Normal file
14
docs/coding/reversing-the-robot-1.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Reversing the robot Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
motors.largeBC.setSpeed(50)
|
||||||
|
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
loops.pause(1000)
|
||||||
|
brick.setLight(LightsPattern.OrangeFlash)
|
||||||
|
motors.largeBC.setSpeed(-50)
|
||||||
|
loops.pause(2000)
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
})
|
||||||
|
```
|
15
docs/coding/reversing-the-robot-2.md
Normal file
15
docs/coding/reversing-the-robot-2.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Reversing the robot Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
|
||||||
|
motors.largeBC.setSpeed(50)
|
||||||
|
sensors.touchSensor2.pauseUntil(TouchSensorEvent.Pressed)
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
loops.pause(1000)
|
||||||
|
brick.setLight(LightsPattern.OrangeFlash)
|
||||||
|
motors.largeBC.setSpeed(-50)
|
||||||
|
loops.pause(2000)
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
})
|
||||||
|
```
|
19
docs/coding/reversing-the-robot-3.md
Normal file
19
docs/coding/reversing-the-robot-3.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Reversing the robot Activity 3
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
brick.showImage(images.eyesSleeping)
|
||||||
|
sensors.touchSensor1.pauseUntil(TouchSensorEvent.Pressed)
|
||||||
|
brick.showImage(images.eyesNeutral)
|
||||||
|
motors.largeBC.setSpeed(50)
|
||||||
|
sensors.touchSensor2.pauseUntil(TouchSensorEvent.Pressed)
|
||||||
|
brick.showImage(images.eyesTiredMiddle)
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
loops.pause(1000)
|
||||||
|
brick.setLight(LightsPattern.OrangeFlash)
|
||||||
|
brick.showImage(images.eyesDizzy)
|
||||||
|
motors.largeBC.setSpeed(-50)
|
||||||
|
loops.pause(2000)
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
})
|
||||||
|
```
|
36
docs/coding/roaming-1.md
Normal file
36
docs/coding/roaming-1.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Roaming Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let drive: number[] = []
|
||||||
|
brick.buttonLeft.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(1)
|
||||||
|
})
|
||||||
|
brick.buttonRight.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(3)
|
||||||
|
})
|
||||||
|
brick.buttonUp.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(4)
|
||||||
|
})
|
||||||
|
brick.buttonDown.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(5)
|
||||||
|
})
|
||||||
|
pauseUntil(() => drive.length >= 5)
|
||||||
|
loops.pause(1000)
|
||||||
|
music.playSoundEffectUntilDone(sounds.communicationGo)
|
||||||
|
for (let d of drive) {
|
||||||
|
if (d == 1) {
|
||||||
|
motors.largeC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeC.pauseUntilReady()
|
||||||
|
} else if (d == 3) {
|
||||||
|
motors.largeB.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeB.pauseUntilReady()
|
||||||
|
} else if (d == 4) {
|
||||||
|
motors.largeBC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeBC.pauseUntilReady()
|
||||||
|
} else {
|
||||||
|
motors.largeBC.setSpeedFor(-50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeBC.pauseUntilReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
music.playSoundEffectUntilDone(sounds.communicationGameOver)
|
||||||
|
```
|
40
docs/coding/roaming-2.md
Normal file
40
docs/coding/roaming-2.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Roaming Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let drive: number[] = []
|
||||||
|
brick.buttonLeft.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(1)
|
||||||
|
music.playSoundEffectUntilDone(sounds.systemClick)
|
||||||
|
})
|
||||||
|
brick.buttonRight.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(3)
|
||||||
|
music.playSoundEffectUntilDone(sounds.systemClick)
|
||||||
|
})
|
||||||
|
brick.buttonUp.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(4)
|
||||||
|
music.playSoundEffectUntilDone(sounds.systemClick)
|
||||||
|
})
|
||||||
|
brick.buttonDown.onEvent(ButtonEvent.Click, function () {
|
||||||
|
drive.push(5)
|
||||||
|
music.playSoundEffectUntilDone(sounds.systemClick)
|
||||||
|
})
|
||||||
|
brick.buttonEnter.pauseUntil(ButtonEvent.Click);
|
||||||
|
loops.pause(1000)
|
||||||
|
music.playSoundEffectUntilDone(sounds.communicationGo)
|
||||||
|
for (let d of drive) {
|
||||||
|
if (d == 1) {
|
||||||
|
motors.largeC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeC.pauseUntilReady()
|
||||||
|
} else if (d == 3) {
|
||||||
|
motors.largeB.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeB.pauseUntilReady()
|
||||||
|
} else if (d == 4) {
|
||||||
|
motors.largeBC.setSpeedFor(50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeBC.pauseUntilReady()
|
||||||
|
} else {
|
||||||
|
motors.largeBC.setSpeedFor(-50, 360, MoveUnit.Degrees)
|
||||||
|
motors.largeBC.pauseUntilReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
music.playSoundEffectUntilDone(sounds.communicationGameOver)
|
||||||
|
```
|
12
docs/coding/three-point-turn-1.md
Normal file
12
docs/coding/three-point-turn-1.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Three Point Turn Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
motors.largeBC.tank(75, 30)
|
||||||
|
loops.pause(1500)
|
||||||
|
motors.largeBC.tank(-30, -75)
|
||||||
|
loops.pause(1000)
|
||||||
|
motors.largeBC.tank(50, 50)
|
||||||
|
loops.pause(3000)
|
||||||
|
})
|
||||||
|
```
|
14
docs/coding/three-point-turn-2.md
Normal file
14
docs/coding/three-point-turn-2.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Three Point Turn Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
motors.largeBC.tank(75, 30)
|
||||||
|
loops.pause(1500)
|
||||||
|
motors.largeBC.tank(-30, -75)
|
||||||
|
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
|
||||||
|
motors.largeBC.tank(0, 0)
|
||||||
|
loops.pause(1000)
|
||||||
|
motors.largeBC.tank(50, 50)
|
||||||
|
loops.pause(3000)
|
||||||
|
})
|
||||||
|
```
|
15
docs/coding/three-point-turn-3.md
Normal file
15
docs/coding/three-point-turn-3.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Three Point Turn Activity 3
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
motors.largeBC.tank(75, 30)
|
||||||
|
loops.pause(1500)
|
||||||
|
motors.largeBC.tank(-30, -75)
|
||||||
|
sensors.ultrasonic4.pauseUntil(UltrasonicSensorEvent.ObjectNear);
|
||||||
|
motors.largeBC.tank(0, 0)
|
||||||
|
music.playSoundEffect(sounds.animalsDogBark1)
|
||||||
|
loops.pause(1000)
|
||||||
|
motors.largeBC.tank(50, 50)
|
||||||
|
loops.pause(3000)
|
||||||
|
})
|
||||||
|
```
|
9
docs/coding/traffic-lights-1.md
Normal file
9
docs/coding/traffic-lights-1.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Traffic Lights Activity 1
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
brick.buttonEnter.onEvent(ButtonEvent.Click, function () {
|
||||||
|
motors.largeBC.tank(20, 20)
|
||||||
|
sensors.color3.pauseForColor(ColorSensorColor.Red)
|
||||||
|
motors.largeBC.tank(0, 0)
|
||||||
|
})
|
||||||
|
```
|
10
docs/coding/traffic-lights-2.md
Normal file
10
docs/coding/traffic-lights-2.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Traffic Lights Activity 2
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
sensors.color3.onColorDetected(ColorSensorColor.Red, function () {
|
||||||
|
motors.largeBC.tank(0, 0)
|
||||||
|
})
|
||||||
|
sensors.color3.onColorDetected(ColorSensorColor.Green, function () {
|
||||||
|
motors.largeBC.tank(20, 20)
|
||||||
|
})
|
||||||
|
```
|
11
docs/coding/traffic-lights-3.md
Normal file
11
docs/coding/traffic-lights-3.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Traffic Lights Activity 3
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
loops.forever(function () {
|
||||||
|
if (sensors.color3.light(LightIntensityMode.Reflected) < 15) {
|
||||||
|
motors.largeBC.tank(30, 12)
|
||||||
|
} else {
|
||||||
|
motors.largeBC.tank(12, 30)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
178
docs/examples/core-set/gyroboy-blocks.md
Normal file
178
docs/examples/core-set/gyroboy-blocks.md
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
# 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()
|
||||||
|
})
|
||||||
|
```
|
215
docs/examples/core-set/gyroboy-labview.md
Normal file
215
docs/examples/core-set/gyroboy-labview.md
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
# 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);
|
||||||
|
})
|
||||||
|
```
|
390
docs/examples/core-set/puppy-labview.md
Normal file
390
docs/examples/core-set/puppy-labview.md
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
# 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.runInBackground(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;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
51
docs/examples/core-set/robotarm-labview.md
Normal file
51
docs/examples/core-set/robotarm-labview.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# 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()
|
||||||
|
})
|
||||||
|
```
|
51
docs/examples/crane-labview.md
Normal file
51
docs/examples/crane-labview.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# 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()
|
||||||
|
})
|
||||||
|
```
|
215
docs/examples/gyro-boy-labview.md
Normal file
215
docs/examples/gyro-boy-labview.md
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
# 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);
|
||||||
|
})
|
||||||
|
```
|
50
docs/examples/line-follower-pid.md
Normal file
50
docs/examples/line-follower-pid.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# Gradien follower PID + calibration
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
let lasterror = 0
|
||||||
|
let D = 0
|
||||||
|
let I = 0
|
||||||
|
let P = 0
|
||||||
|
let error = 0
|
||||||
|
let setpoint = 0
|
||||||
|
let max = 0
|
||||||
|
let min = 0
|
||||||
|
let v = 0
|
||||||
|
v = sensors.color3.light(LightIntensityMode.Reflected)
|
||||||
|
min = v
|
||||||
|
max = v
|
||||||
|
setpoint = v
|
||||||
|
while (!(brick.buttonEnter.wasPressed())) {
|
||||||
|
brick.clearScreen()
|
||||||
|
brick.showString("Move robot on terrain", 1)
|
||||||
|
brick.showString("Press ENTER when done", 2)
|
||||||
|
v = sensors.color3.light(LightIntensityMode.Reflected)
|
||||||
|
min = Math.min(min, v)
|
||||||
|
max = Math.max(max, v)
|
||||||
|
setpoint = (max + min) / 2
|
||||||
|
brick.showValue("v", v, 3)
|
||||||
|
brick.showValue("min", min, 4)
|
||||||
|
brick.showValue("max", v, 5)
|
||||||
|
brick.showValue("setpoint", setpoint, 6)
|
||||||
|
loops.pause(100)
|
||||||
|
}
|
||||||
|
loops.forever(function () {
|
||||||
|
brick.clearScreen()
|
||||||
|
v = sensors.color3.light(LightIntensityMode.Reflected)
|
||||||
|
brick.showValue("light", v, 1)
|
||||||
|
error = v - setpoint
|
||||||
|
brick.showValue("error", error, 2)
|
||||||
|
P = error * 5
|
||||||
|
brick.showValue("P", P, 3)
|
||||||
|
I = I + error * 0.01
|
||||||
|
brick.showValue("I", I, 4)
|
||||||
|
D = (error - lasterror) * 0.2
|
||||||
|
brick.showValue("D", D, 5)
|
||||||
|
motors.largeBC.steer(P + (I + D), 100)
|
||||||
|
lasterror = error
|
||||||
|
if (brick.buttonEnter.wasPressed()) {
|
||||||
|
motors.largeBC.setSpeed(0)
|
||||||
|
brick.buttonDown.pauseUntil(ButtonEvent.Click)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
109
docs/static/avatar.svg
vendored
Normal file
109
docs/static/avatar.svg
vendored
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?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>
|
After Width: | Height: | Size: 11 KiB |
23
docs/static/fonts/icons/iconfont.css
vendored
23
docs/static/fonts/icons/iconfont.css
vendored
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont";
|
font-family: "iconfont";
|
||||||
src: url("iconfont.eot?73552ec404b3a3d3769a3f04fa58c2c4?#iefix") format("embedded-opentype"),
|
src: url("iconfont.eot?8b7e57577c2d1f1ae9e810b9e010bc84?#iefix") format("embedded-opentype"),
|
||||||
url("iconfont.woff2?73552ec404b3a3d3769a3f04fa58c2c4") format("woff2"),
|
url("iconfont.woff2?8b7e57577c2d1f1ae9e810b9e010bc84") format("woff2"),
|
||||||
url("iconfont.woff?73552ec404b3a3d3769a3f04fa58c2c4") format("woff");
|
url("iconfont.woff?8b7e57577c2d1f1ae9e810b9e010bc84") format("woff");
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
@ -67,24 +67,27 @@ url("iconfont.woff?73552ec404b3a3d3769a3f04fa58c2c4") format("woff");
|
|||||||
.icon-variables:before {
|
.icon-variables:before {
|
||||||
content: "\f111";
|
content: "\f111";
|
||||||
}
|
}
|
||||||
.icon-advancedcollapsed:before {
|
.icon-console:before {
|
||||||
content: "\f112";
|
content: "\f112";
|
||||||
}
|
}
|
||||||
.icon-advancedexpanded:before {
|
.icon-advancedcollapsed:before {
|
||||||
content: "\f113";
|
content: "\f113";
|
||||||
}
|
}
|
||||||
.icon-cancel:before {
|
.icon-advancedexpanded:before {
|
||||||
content: "\f114";
|
content: "\f114";
|
||||||
}
|
}
|
||||||
.icon-check:before {
|
.icon-cancel:before {
|
||||||
content: "\f115";
|
content: "\f115";
|
||||||
}
|
}
|
||||||
.icon-download:before {
|
.icon-check:before {
|
||||||
content: "\f116";
|
content: "\f116";
|
||||||
}
|
}
|
||||||
.icon-save:before {
|
.icon-download:before {
|
||||||
content: "\f117";
|
content: "\f117";
|
||||||
}
|
}
|
||||||
.icon-blocks:before {
|
.icon-save:before {
|
||||||
content: "\f118";
|
content: "\f118";
|
||||||
}
|
}
|
||||||
|
.icon-blocks:before {
|
||||||
|
content: "\f119";
|
||||||
|
}
|
||||||
|
BIN
docs/static/fonts/icons/iconfont.eot
vendored
BIN
docs/static/fonts/icons/iconfont.eot
vendored
Binary file not shown.
17
docs/static/fonts/icons/iconfont.svg
vendored
17
docs/static/fonts/icons/iconfont.svg
vendored
@ -58,26 +58,29 @@
|
|||||||
<glyph glyph-name="variables"
|
<glyph glyph-name="variables"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M36.8 12V7.8H3.4V12H36.8z M36.8 22.1V17.9H3.4V22.1H36.8z M36.7 32.2V28H3.3V32.2H36.7z" />
|
horiz-adv-x="40" d=" M36.8 12V7.8H3.4V12H36.8z M36.8 22.1V17.9H3.4V22.1H36.8z M36.7 32.2V28H3.3V32.2H36.7z" />
|
||||||
<glyph glyph-name="advancedcollapsed"
|
<glyph glyph-name="console"
|
||||||
unicode=""
|
unicode=""
|
||||||
|
horiz-adv-x="40" d=" M15.6 21.3L2.3 15L2.3 19.8L11.1 23.6L2.3 27.4L2.3 32.2L15.6 25.9L15.6 21.3z M36 9.1L16.6 9.1L16.6 12.2L36 12.2L36 9.1z" />
|
||||||
|
<glyph glyph-name="advancedcollapsed"
|
||||||
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M39.7 28.2L36.2 31.5L20 15.3L3.8 31.5L0.3 28.2L18.3 10.3L18.3 10.3L20 8.5L20.5 9L20.5 9z" />
|
horiz-adv-x="40" d=" M39.7 28.2L36.2 31.5L20 15.3L3.8 31.5L0.3 28.2L18.3 10.3L18.3 10.3L20 8.5L20.5 9L20.5 9z" />
|
||||||
<glyph glyph-name="advancedexpanded"
|
<glyph glyph-name="advancedexpanded"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M39.3 12L21.7 29.6L21.7 29.6L20 31.3L19.5 30.8L19.5 30.8L0.7 12L4 8.7L20 24.7L36 8.7z" />
|
horiz-adv-x="40" d=" M39.3 12L21.7 29.6L21.7 29.6L20 31.3L19.5 30.8L19.5 30.8L0.7 12L4 8.7L20 24.7L36 8.7z" />
|
||||||
<glyph glyph-name="cancel"
|
<glyph glyph-name="cancel"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M33 29.6L29.4 33.2L20.2 24L11 33.2L7.3 29.6L16.5 20.3L7.3 11.1L11 7.3L20.2 16.5L29.4 7.3L33 11.1L23.8 20.3z" />
|
horiz-adv-x="40" d=" M33 29.6L29.4 33.2L20.2 24L11 33.2L7.3 29.6L16.5 20.3L7.3 11.1L11 7.3L20.2 16.5L29.4 7.3L33 11.1L23.8 20.3z" />
|
||||||
<glyph glyph-name="check"
|
<glyph glyph-name="check"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M33.7 32.9L15.3 14.4L7.5 22.3L3.8 18.4L11.7 10.8L11.7 10.8L15.3 7.1L37.4 29.2z" />
|
horiz-adv-x="40" d=" M33.7 32.9L15.3 14.4L7.5 22.3L3.8 18.4L11.7 10.8L11.7 10.8L15.3 7.1L37.4 29.2z" />
|
||||||
<glyph glyph-name="download"
|
<glyph glyph-name="download"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M5.2 15.7H36.5V1.7H5.2V15.7z M28.5 24.2L26.1 26.6L22.6 23.1L22.6 36.5L19.1 36.5L19.1 23.5L16 26.6L13.6 24.2L20.9 16.7L21 16.9L21.2 16.7z" />
|
horiz-adv-x="40" d=" M5.2 15.7H36.5V1.7H5.2V15.7z M28.5 24.2L26.1 26.6L22.6 23.1L22.6 36.5L19.1 36.5L19.1 23.5L16 26.6L13.6 24.2L20.9 16.7L21 16.9L21.2 16.7z" />
|
||||||
<glyph glyph-name="save"
|
<glyph glyph-name="save"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M25 34.5C25 33.6 25 32.8 25 31.9C25 31 24.7 30.9 24 30.9C23.5 30.9 22.8 30.9 22.4 30.9C22.1 30.9 21.4 31 21.4 31.7V31.9V36.9C21.4 37.3 21.6 37.8 22.3 38C22.3 38 22.3 38 22.4 38C23 38 23.7 38 24.2 38C24.7 38 25.2 37.6 25.2 37.1C25.2 37.1 25.2 37.1 25.2 36.9C25 36.3 25 35.2 25 34.5z M37.6 31.2C35.8 32.9 34.3 34.5 32.5 36.3C31 37.8 31 37.8 28.5 37.8C27.5 37.8 27.3 37.6 27.3 36.6V28.4C27.3 27.4 27.1 27.2 26.1 27.2H14.3C13.2 27.2 13 27.4 13 28.4V36.4C13 37.6 12.9 37.8 11.7 37.8H3.8C2.6 37.8 2.4 37.6 2.4 36.4V19.9C2.4 14.3 2.4 8.9 2.4 3.2C2.4 2 2.6 1.8 3.7 1.8H36.9C37.9 1.8 38.1 2.2 38.1 3.2V29.6C38.3 30.5 37.9 30.9 37.6 31.2zM33.7 6.7H7.1V23H33.7V6.7z" />
|
horiz-adv-x="40" d=" M25 34.5C25 33.6 25 32.8 25 31.9C25 31 24.7 30.9 24 30.9C23.5 30.9 22.8 30.9 22.4 30.9C22.1 30.9 21.4 31 21.4 31.7V31.9V36.9C21.4 37.3 21.6 37.8 22.3 38C22.3 38 22.3 38 22.4 38C23 38 23.7 38 24.2 38C24.7 38 25.2 37.6 25.2 37.1C25.2 37.1 25.2 37.1 25.2 36.9C25 36.3 25 35.2 25 34.5z M37.6 31.2C35.8 32.9 34.3 34.5 32.5 36.3C31 37.8 31 37.8 28.5 37.8C27.5 37.8 27.3 37.6 27.3 36.6V28.4C27.3 27.4 27.1 27.2 26.1 27.2H14.3C13.2 27.2 13 27.4 13 28.4V36.4C13 37.6 12.9 37.8 11.7 37.8H3.8C2.6 37.8 2.4 37.6 2.4 36.4V19.9C2.4 14.3 2.4 8.9 2.4 3.2C2.4 2 2.6 1.8 3.7 1.8H36.9C37.9 1.8 38.1 2.2 38.1 3.2V29.6C38.3 30.5 37.9 30.9 37.6 31.2zM33.7 6.7H7.1V23H33.7V6.7z" />
|
||||||
<glyph glyph-name="blocks"
|
<glyph glyph-name="blocks"
|
||||||
unicode=""
|
unicode=""
|
||||||
horiz-adv-x="40" d=" M10.9 23H39V16.9H10.9V23z M39.2 27.1L39.2 33L0.9 33L0.9 31.1L0.9 27.1L0.9 12.9L0.9 7L39.2 7L39.2 12.9L6.9 12.9L6.9 27.1z" />
|
horiz-adv-x="40" d=" M10.9 23H39V16.9H10.9V23z M39.2 27.1L39.2 33L0.9 33L0.9 31.1L0.9 27.1L0.9 12.9L0.9 7L39.2 7L39.2 12.9L6.9 12.9L6.9 27.1z" />
|
||||||
</font>
|
</font>
|
||||||
</defs>
|
</defs>
|
||||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
docs/static/fonts/icons/iconfont.ttf
vendored
BIN
docs/static/fonts/icons/iconfont.ttf
vendored
Binary file not shown.
BIN
docs/static/fonts/icons/iconfont.woff
vendored
BIN
docs/static/fonts/icons/iconfont.woff
vendored
Binary file not shown.
BIN
docs/static/fonts/icons/iconfont.woff2
vendored
BIN
docs/static/fonts/icons/iconfont.woff2
vendored
Binary file not shown.
1
docs/static/loader_back.svg
vendored
Normal file
1
docs/static/loader_back.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="301.499" height="179.742" viewBox="0 0 282.655 168.508"><g transform="translate(-41.005 -446.364)"><rect ry="30" rx="30" y="458.77" x="53.41" height="143.698" width="105.312" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect width="105.668" height="144.183" x="53.232" y="458.527" rx="30.101" ry="30.101" fill="#fff"/></g><g transform="translate(111.528 -446.364)"><rect width="105.312" height="143.698" x="53.41" y="458.77" rx="30" ry="30" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect ry="30.101" rx="30.101" y="458.527" x="53.232" height="144.183" width="105.668" fill="#fff"/></g></svg>
|
After Width: | Height: | Size: 721 B |
1
docs/static/loader_front.svg
vendored
Normal file
1
docs/static/loader_front.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="301.499" height="179.742" viewBox="0 0 282.655 168.508"><g stroke="#000" stroke-linecap="round" stroke-linejoin="round"><g transform="translate(124.66 -243.829)"><circle r="25.968" cy="356.872" cx="-38.891" fill="none"/><circle cx="-38.891" cy="356.872" r="21.013" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g><g transform="translate(277.193 -243.829)"><circle cx="-38.891" cy="356.872" r="25.968" fill="none"/><circle r="21.013" cy="356.872" cx="-38.891" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g></g></svg>
|
After Width: | Height: | Size: 728 B |
1
docs/static/loader_full.svg
vendored
Normal file
1
docs/static/loader_full.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="301.499" height="179.742" viewBox="0 0 282.655 168.508"><g transform="translate(-41.005 -446.364)"><rect ry="30" rx="30" y="458.77" x="53.41" height="143.698" width="105.312" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect width="105.668" height="144.183" x="53.232" y="458.527" rx="30.101" ry="30.101" fill="#fff"/></g><g transform="translate(124.66 -243.829)" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><circle r="25.968" cy="356.872" cx="-38.891" fill="none"/><circle cx="-38.891" cy="356.872" r="21.013" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g><g transform="translate(111.528 -446.364)"><rect width="105.312" height="143.698" x="53.41" y="458.77" rx="30" ry="30" stroke="#000" stroke-width="17.724" stroke-linecap="round" stroke-linejoin="round"/><rect ry="30.101" rx="30.101" y="458.527" x="53.232" height="144.183" width="105.668" fill="#fff"/></g><g transform="translate(277.193 -243.829)" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><circle cx="-38.891" cy="356.872" r="25.968" fill="none"/><circle r="21.013" cy="356.872" cx="-38.891" stroke-width=".809"/><path d="M-30.581 341.741a13.835 13.835 0 0 1 5.76 4.504l-11.099 8.26z" fill="#fff" stroke-width=".533"/></g></svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -29,7 +29,8 @@ export function initAsync() {
|
|||||||
|
|
||||||
let canHID = false
|
let canHID = false
|
||||||
if (pxt.U.isNodeJS) {
|
if (pxt.U.isNodeJS) {
|
||||||
canHID = true
|
// doesn't seem to work ATM
|
||||||
|
canHID = false
|
||||||
} else {
|
} else {
|
||||||
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
|
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
|
||||||
if (pxt.Cloud.isLocalHost() && pxt.Cloud.localToken && !forceHexDownload)
|
if (pxt.Cloud.isLocalHost() && pxt.Cloud.localToken && !forceHexDownload)
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
import { deployCoreAsync, initAsync } from "./deploy";
|
import { deployCoreAsync, initAsync } from "./deploy";
|
||||||
import { FieldPorts } from "./field_ports";
|
import { FieldPorts } from "./field_ports";
|
||||||
import { FieldImages } from "./field_images";
|
import { FieldImages } from "./field_images";
|
||||||
|
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...')
|
pxt.debug('loading pxt-ev3 target extensions...')
|
||||||
@ -15,6 +18,15 @@ pxt.editor.initExtensionsAsync = function(opts: pxt.editor.ExtensionOptions): Pr
|
|||||||
}, {
|
}, {
|
||||||
selector: "images",
|
selector: "images",
|
||||||
editor: FieldImages
|
editor: FieldImages
|
||||||
|
}, {
|
||||||
|
selector: "speed",
|
||||||
|
editor: FieldSpeed
|
||||||
|
}, {
|
||||||
|
selector: "brickbuttons",
|
||||||
|
editor: FieldBrickButtons
|
||||||
|
}, {
|
||||||
|
selector: "turnratio",
|
||||||
|
editor: FieldTurnRatio
|
||||||
}],
|
}],
|
||||||
deployCoreAsync
|
deployCoreAsync
|
||||||
};
|
};
|
||||||
@ -111,6 +123,20 @@ function updateBlocklyShape() {
|
|||||||
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS * 2 +
|
'l ' + 0 + ',' + (Blockly.BlockSvg as any).CORNER_RADIUS * 2 +
|
||||||
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',' + 0;
|
'l ' + (Blockly.BlockSvg as any).CORNER_RADIUS + ',' + 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corner radius of the flyout background.
|
||||||
|
* @type {number}
|
||||||
|
* @const
|
||||||
|
*/
|
||||||
|
(Blockly as any).Flyout.prototype.CORNER_RADIUS = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Margin around the edges of the blocks in the flyout.
|
||||||
|
* @type {number}
|
||||||
|
* @const
|
||||||
|
*/
|
||||||
|
(Blockly as any).Flyout.prototype.MARGIN = 8;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When require()d from node, bind the global pxt namespace
|
// When require()d from node, bind the global pxt namespace
|
||||||
|
159
editor/field_brickbuttons.ts
Normal file
159
editor/field_brickbuttons.ts
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
|
||||||
|
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||||
|
|
||||||
|
export interface FieldPortsOptions extends Blockly.FieldCustomDropdownOptions {
|
||||||
|
columns?: string;
|
||||||
|
width?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.FieldCustom {
|
||||||
|
public isFieldCustom_ = true;
|
||||||
|
|
||||||
|
// Width in pixels
|
||||||
|
private width_: number;
|
||||||
|
|
||||||
|
// Columns in grid
|
||||||
|
private columns_: number;
|
||||||
|
|
||||||
|
private savedPrimary_: string;
|
||||||
|
|
||||||
|
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
|
||||||
|
super(options.data);
|
||||||
|
|
||||||
|
this.columns_ = parseInt(options.columns) || 4;
|
||||||
|
this.width_ = parseInt(options.width) || 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a dropdown menu under the text.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
public showEditor_() {
|
||||||
|
// If there is an existing drop-down we own, this is a request to hide the drop-down.
|
||||||
|
if (Blockly.DropDownDiv.hideIfOwner(this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
|
||||||
|
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||||
|
Blockly.DropDownDiv.clearContent();
|
||||||
|
// Populate the drop-down with the icons for this field.
|
||||||
|
let dropdownDiv = Blockly.DropDownDiv.getContentDiv();
|
||||||
|
let contentDiv = document.createElement('div');
|
||||||
|
// Accessibility properties
|
||||||
|
contentDiv.setAttribute('role', 'menu');
|
||||||
|
contentDiv.setAttribute('aria-haspopup', 'true');
|
||||||
|
|
||||||
|
const buttonsSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg") as SVGGElement;
|
||||||
|
pxsim.svg.hydrate(buttonsSVG, {
|
||||||
|
viewBox: "0 0 256.68237 256.68237",
|
||||||
|
width: this.width_,
|
||||||
|
height: this.width_
|
||||||
|
});
|
||||||
|
contentDiv.appendChild(buttonsSVG);
|
||||||
|
|
||||||
|
const gWrapper = pxsim.svg.child(buttonsSVG, 'g', { 'transform': 'translate(-4.695057,58.29823)' });
|
||||||
|
const gInnerWrapper = pxsim.svg.child(gWrapper, 'g', { 'transform': 'translate(3.9780427e-6,-32.677281)' });
|
||||||
|
|
||||||
|
const back = pxsim.svg.child(gInnerWrapper, 'path', {
|
||||||
|
style: 'fill:#6a6a6a;stroke-width:3.91719985',
|
||||||
|
d: 'M 106.30882,198.38022 C 84.431262,177.26258 50.453467,142.52878 50.453467,142.52878 v -7.12931 H 37.087971 a 32.381533,32.381533 0 1 1 0,-64.763062 H 50.457376 V 63.503186 L 105.71731,7.0563355 h 55.25604 c 25.02699,25.5048885 55.25994,55.2599395 55.25994,55.2599395 v 8.320133 h 12.77398 a 32.381533,32.381533 0 0 1 0,64.763062 h -12.77398 v 7.13323 c -29.43384,30.27603 -54.66454,55.85144 -54.66454,55.85144 z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const buttonLeft = pxsim.svg.child(gInnerWrapper, 'path', {
|
||||||
|
style: 'fill:#a8a9a8;stroke-width:3.91719985',
|
||||||
|
d: 'm 36.492567,78.357208 h 40.69971 V 126.48393 H 36.492567 A 24.063359,24.063359 0 0 1 12.429199,102.42057 v 0 A 24.063359,24.063359 0 0 1 36.492567,78.357208 Z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const buttonRight = pxsim.svg.child(gInnerWrapper, 'path', {
|
||||||
|
style: 'fill:#a8a9a8;stroke-width:3.91719985',
|
||||||
|
d: 'M 229.00727,126.48784 H 188.30756 V 78.361126 h 40.69971 a 24.063359,24.063359 0 0 1 24.06335,24.063354 v 0 a 24.063359,24.063359 0 0 1 -24.06335,24.06336 z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const buttonEnter = pxsim.svg.child(gInnerWrapper, 'path', {
|
||||||
|
style: 'fill:#3c3c3c;stroke-width:3.91719985',
|
||||||
|
d: 'm 109.27806,78.357208 h 46.9398 a 1.782326,1.782326 0 0 1 1.78233,1.782326 V 124.7016 a 1.782326,1.782326 0 0 1 -1.78233,1.78233 h -46.9398 a 1.782326,1.782326 0 0 1 -1.78233,-1.78233 V 80.139534 a 1.782326,1.782326 0 0 1 1.78233,-1.782326 z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const buttonTop = pxsim.svg.child(gInnerWrapper, 'path', {
|
||||||
|
style: 'fill:#a8a9a8;stroke-width:3.91719985',
|
||||||
|
d: 'm 108.09114,15.967966 49.90905,-0.59542 37.43276,38.619675 -15.44943,15.449437 V 97.367379 H 165.7249 V 81.306861 A 11.978797,11.978797 0 0 0 153.84012,69.422075 c -11.59883,-0.184102 -43.37516,0 -43.37516,0 A 9.6676495,9.6676495 0 0 0 100.36251,79.520618 V 97.347793 H 86.103905 V 69.422075 L 70.654464,53.97264 Z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const buttonBottom = pxsim.svg.child(gInnerWrapper, 'path', {
|
||||||
|
style: 'fill:#a8a9a8;stroke-width:3.91719985',
|
||||||
|
d: 'M 157.78865,189.01028 108.18908,189.38233 70.654464,150.794 86.323259,135.4895 v -28.08625 h 14.101921 v 16.11144 a 12.006218,12.006218 0 0 0 11.85346,11.9788 c 11.59882,0.1841 43.13227,0 43.13227,0 a 10.18472,10.18472 0 0 0 10.38059,-10.38058 v -17.70966 h 14.39179 v 28.08632 l 15.3045,15.3045 z'
|
||||||
|
})
|
||||||
|
|
||||||
|
const buttons = [buttonEnter, buttonLeft, buttonRight, buttonTop, buttonBottom];
|
||||||
|
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.
|
||||||
|
const button = buttons[i];
|
||||||
|
button.setAttribute('id', ':' + i); // For aria-activedescendant
|
||||||
|
button.setAttribute('role', 'menuitem');
|
||||||
|
button.setAttribute('cursor', 'pointer');
|
||||||
|
const title = pxsim.svg.child(button, 'title');
|
||||||
|
title.textContent = content;
|
||||||
|
|
||||||
|
Blockly.bindEvent_(button, 'click', this, this.buttonClick_);
|
||||||
|
Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_);
|
||||||
|
// These are applied manually instead of using the :hover pseudoclass
|
||||||
|
// because Android has a bad long press "helper" menu and green highlight
|
||||||
|
// that we must prevent with ontouchstart preventDefault
|
||||||
|
Blockly.bindEvent_(button, 'mousedown', button, function (e) {
|
||||||
|
this.setAttribute('stroke', '#ffffff');
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
Blockly.bindEvent_(button, 'mouseover', button, function () {
|
||||||
|
this.setAttribute('stroke', '#ffffff');
|
||||||
|
});
|
||||||
|
Blockly.bindEvent_(button, 'mouseout', button, function () {
|
||||||
|
this.setAttribute('stroke', 'transparent');
|
||||||
|
});
|
||||||
|
|
||||||
|
button.setAttribute('data-value', value);
|
||||||
|
}
|
||||||
|
|
||||||
|
contentDiv.style.width = this.width_ + 'px';
|
||||||
|
dropdownDiv.appendChild(contentDiv);
|
||||||
|
|
||||||
|
Blockly.DropDownDiv.setColour('#ffffff', '#dddddd');
|
||||||
|
|
||||||
|
// Calculate positioning based on the field position.
|
||||||
|
var scale = this.sourceBlock_.workspace.scale;
|
||||||
|
var bBox = { width: this.size_.width, height: this.size_.height };
|
||||||
|
bBox.width *= scale;
|
||||||
|
bBox.height *= scale;
|
||||||
|
var position = this.fieldGroup_.getBoundingClientRect();
|
||||||
|
var primaryX = position.left + bBox.width / 2;
|
||||||
|
var primaryY = position.top + bBox.height;
|
||||||
|
var secondaryX = primaryX;
|
||||||
|
var secondaryY = position.top;
|
||||||
|
// Set bounds to workspace; show the drop-down.
|
||||||
|
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
|
||||||
|
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
||||||
|
this.onHide_.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for when a button is clicked inside the drop-down.
|
||||||
|
* Should be bound to the FieldIconMenu.
|
||||||
|
* @param {Event} e DOM event for the click/touch
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private buttonClick_ = function (e: any) {
|
||||||
|
let value = e.target.getAttribute('data-value');
|
||||||
|
this.setValue(value);
|
||||||
|
Blockly.DropDownDiv.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for when the drop-down is hidden.
|
||||||
|
*/
|
||||||
|
private onHide_ = function () {
|
||||||
|
Blockly.DropDownDiv.content_.removeAttribute('role');
|
||||||
|
Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup');
|
||||||
|
Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant');
|
||||||
|
};
|
||||||
|
}
|
@ -24,6 +24,9 @@ export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCu
|
|||||||
this.width_ = parseInt(options.width) || 300;
|
this.width_ = parseInt(options.width) || 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trimOptions_() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a dropdown menu under the text.
|
* Create a dropdown menu under the text.
|
||||||
* @private
|
* @private
|
||||||
@ -42,7 +45,8 @@ export class FieldPorts extends Blockly.FieldDropdown implements Blockly.FieldCu
|
|||||||
// Accessibility properties
|
// Accessibility properties
|
||||||
contentDiv.setAttribute('role', 'menu');
|
contentDiv.setAttribute('role', 'menu');
|
||||||
contentDiv.setAttribute('aria-haspopup', 'true');
|
contentDiv.setAttribute('aria-haspopup', 'true');
|
||||||
const options = this.getOptions();
|
let options = this.getOptions();
|
||||||
|
options = options.sort();
|
||||||
for (let i = 0, option: any; option = options[i]; i++) {
|
for (let i = 0, option: any; option = options[i]; i++) {
|
||||||
let content = (options[i] as any)[0]; // Human-readable text or image.
|
let content = (options[i] as any)[0]; // Human-readable text or image.
|
||||||
const value = (options[i] as any)[1]; // Language-neutral value.
|
const value = (options[i] as any)[1]; // Language-neutral value.
|
||||||
|
96
editor/field_speed.ts
Normal file
96
editor/field_speed.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/// <reference path="../node_modules/pxt-core/localtypings/blockly.d.ts"/>
|
||||||
|
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||||
|
|
||||||
|
export interface FieldSpeedOptions extends Blockly.FieldCustomOptions {
|
||||||
|
min?: string;
|
||||||
|
max?: string;
|
||||||
|
label?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FieldSpeed extends Blockly.FieldSlider implements Blockly.FieldCustom {
|
||||||
|
public isFieldCustom_ = true;
|
||||||
|
|
||||||
|
private params: any;
|
||||||
|
|
||||||
|
private speedSVG: SVGElement;
|
||||||
|
private circleBar: SVGCircleElement;
|
||||||
|
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: FieldSpeedOptions, opt_validator?: Function) {
|
||||||
|
super(String(value_), '-100', '100', null, '10', 'Speed', opt_validator);
|
||||||
|
this.params = params;
|
||||||
|
if (this.params['min']) this.min_ = parseFloat(this.params.min);
|
||||||
|
if (this.params['max']) this.max_ = parseFloat(this.params.max);
|
||||||
|
if (this.params['label']) this.labelText_ = this.params.label;
|
||||||
|
|
||||||
|
(this as any).sliderColor_ = '#a8aaa8';
|
||||||
|
}
|
||||||
|
|
||||||
|
createLabelDom_(labelText: string) {
|
||||||
|
var labelContainer = document.createElement('div');
|
||||||
|
this.speedSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg") as SVGGElement;
|
||||||
|
pxsim.svg.hydrate(this.speedSVG, {
|
||||||
|
viewBox: "0 0 200 100"
|
||||||
|
});
|
||||||
|
|
||||||
|
labelContainer.appendChild(this.speedSVG);
|
||||||
|
|
||||||
|
const outerCircle = pxsim.svg.child(this.speedSVG, "circle", {
|
||||||
|
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
|
||||||
|
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent; transition: stroke-dashoffset 0.1s linear;`,
|
||||||
|
'stroke': '#a8aaa8', 'stroke-width': '1rem'
|
||||||
|
}) as SVGCircleElement;
|
||||||
|
this.circleBar = pxsim.svg.child(this.speedSVG, "circle", {
|
||||||
|
'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
|
||||||
|
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent; transition: stroke-dashoffset 0.1s linear;`,
|
||||||
|
'stroke': '#f12a21', 'stroke-width': '1rem'
|
||||||
|
}) as SVGCircleElement;
|
||||||
|
|
||||||
|
this.reporter = pxsim.svg.child(this.speedSVG, "text", {
|
||||||
|
'x': 100, 'y': 80,
|
||||||
|
'text-anchor': 'middle', 'alignment-baseline': 'middle',
|
||||||
|
'style': 'font-size: 50px',
|
||||||
|
'class': 'sim-text inverted number'
|
||||||
|
}) as SVGTextElement;
|
||||||
|
|
||||||
|
// labelContainer.setAttribute('class', 'blocklyFieldSliderLabel');
|
||||||
|
var readout = document.createElement('span');
|
||||||
|
readout.setAttribute('class', 'blocklyFieldSliderReadout');
|
||||||
|
// var label = document.createElement('span');
|
||||||
|
// label.setAttribute('class', 'blocklyFieldSliderLabelText');
|
||||||
|
// label.innerHTML = labelText;
|
||||||
|
// labelContainer.appendChild(label);
|
||||||
|
// labelContainer.appendChild(readout);
|
||||||
|
return [labelContainer, readout];
|
||||||
|
};
|
||||||
|
|
||||||
|
setReadout_(readout: Element, value: string) {
|
||||||
|
this.updateSpeed(parseFloat(value));
|
||||||
|
// Update reporter
|
||||||
|
this.reporter.textContent = `${value}%`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateSpeed(speed: number) {
|
||||||
|
let sign = this.sign(speed);
|
||||||
|
speed = (Math.abs(speed) / 100 * 50) + 50;
|
||||||
|
if (sign == -1) speed = 50 - speed;
|
||||||
|
let c = Math.PI * (90 * 2);
|
||||||
|
let pct = ((100 - speed) / 100) * c;
|
||||||
|
this.circleBar.setAttribute('stroke-dashoffset', `${pct}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A re-implementation of Math.sign (since IE11 doesn't support it)
|
||||||
|
private sign(num: number) {
|
||||||
|
return num ? num < 0 ? -1 : 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
108
editor/field_turnratio.ts
Normal file
108
editor/field_turnratio.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/// <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,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"behaviors.addBehavior|block": "add behavior %behavior",
|
"behaviors.addBehavior|block": "add behavior %behavior",
|
||||||
"behaviors.avoidCrash|block": "avoid crash using %ultrasonic",
|
"behaviors.avoidCrash|block": "avoid crash using %ultrasonic",
|
||||||
"behaviors.driveForward|block": "drive %motors|forward at %speed|%",
|
"behaviors.driveForward|block": "drive %motors|forward at %speed=motorSpeedPicker|%",
|
||||||
"behaviors|block": "behaviors",
|
"behaviors|block": "behaviors",
|
||||||
"{id:category}Behaviors": "Behaviors"
|
"{id:category}Behaviors": "Behaviors"
|
||||||
}
|
}
|
@ -49,7 +49,7 @@ namespace behaviors {
|
|||||||
* @param motors
|
* @param motors
|
||||||
* @param speed the desired speed, eg: 50
|
* @param speed the desired speed, eg: 50
|
||||||
*/
|
*/
|
||||||
//% blockId=behaviorsDriveForward block="drive %motors|forward at %speed|%"
|
//% blockId=behaviorsDriveForward block="drive %motors|forward at %speed=motorSpeedPicker|%"
|
||||||
export function driveForward(motors: motors.MotorBase, speed: number): behaviors.Behavior {
|
export function driveForward(motors: motors.MotorBase, speed: number): behaviors.Behavior {
|
||||||
return new DriveForwardBehavior(motors, speed);
|
return new DriveForwardBehavior(motors, speed);
|
||||||
}
|
}
|
||||||
|
3
libs/chassis/README.md
Normal file
3
libs/chassis/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Chassis
|
||||||
|
|
||||||
|
A library to control a chassis.
|
11
libs/chassis/_locales/chassis-jsdoc-strings.json
Normal file
11
libs/chassis/_locales/chassis-jsdoc-strings.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"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.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",
|
||||||
|
"chassis.Chassis.setProperty|param|value": "the value to set"
|
||||||
|
}
|
9
libs/chassis/_locales/chassis-strings.json
Normal file
9
libs/chassis/_locales/chassis-strings.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ChassisProperty.BaseLength|block": "base length (cm)",
|
||||||
|
"ChassisProperty.WheelRadius|block": "wheel radius (cm)",
|
||||||
|
"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",
|
||||||
|
"chassis|block": "chassis",
|
||||||
|
"{id:category}Chassis": "Chassis"
|
||||||
|
}
|
88
libs/chassis/chassis.ts
Normal file
88
libs/chassis/chassis.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
enum ChassisProperty {
|
||||||
|
//% block="wheel radius (cm)"
|
||||||
|
WheelRadius,
|
||||||
|
//% block="base length (cm)"
|
||||||
|
BaseLength
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace chassis {
|
||||||
|
/**
|
||||||
|
* A differential drive robot
|
||||||
|
*/
|
||||||
|
//% fixedInstances
|
||||||
|
export class Chassis {
|
||||||
|
// the motor pair
|
||||||
|
public motors: motors.SynchedMotorPair;
|
||||||
|
// the radius of the wheel (cm)
|
||||||
|
public wheelRadius: number;
|
||||||
|
// the distance between the wheels (cm)
|
||||||
|
public baseLength: number;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.motors = motors.largeBC;
|
||||||
|
this.wheelRadius = 3;
|
||||||
|
this.baseLength = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s"
|
||||||
|
//% inlineInputMode=inline
|
||||||
|
//% weight=95 blockGap=8
|
||||||
|
drive(speed: number, rotationSpeed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
||||||
|
// speed is expressed in %
|
||||||
|
const R = this.wheelRadius; // cm
|
||||||
|
const L = this.baseLength; // cm
|
||||||
|
const PI = 3.14;
|
||||||
|
const maxw = 170 / 60 * 2 * PI; // rad / s
|
||||||
|
const maxv = maxw * R; // cm / s
|
||||||
|
// speed is cm / s
|
||||||
|
const v = speed; // cm / s
|
||||||
|
const w = rotationSpeed / 360 * 2 * PI; // rad / s
|
||||||
|
|
||||||
|
const vr = (2 * v + w * L) / (2 * R); // rad / s
|
||||||
|
const vl = (2 * v - w * L) / (2 * R); // rad / s
|
||||||
|
|
||||||
|
const sr = vr / maxw * 100; // %
|
||||||
|
const sl = vl / maxw * 100; // %
|
||||||
|
|
||||||
|
this.motors.tank(sr, sl, value, unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a property of the robot
|
||||||
|
* @param property the property to set
|
||||||
|
* @param value the value to set
|
||||||
|
*/
|
||||||
|
//% blockId=chassisSetProperty block="set %chassis|%property|to %value"
|
||||||
|
//% blockGap=8
|
||||||
|
//% weight=10
|
||||||
|
setProperty(property: ChassisProperty, value: number) {
|
||||||
|
switch (property) {
|
||||||
|
case ChassisProperty.WheelRadius:
|
||||||
|
this.wheelRadius = Math.max(0.1, value); break;
|
||||||
|
case ChassisProperty.BaseLength:
|
||||||
|
this.baseLength = Math.max(0.1, value); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the motors used by the chassis, default is B+C
|
||||||
|
* @param motors
|
||||||
|
*/
|
||||||
|
//% blockId=chassisSetMotors block="set %chassis|motors to %motors"
|
||||||
|
//% weight=10
|
||||||
|
setMotors(motors: motors.SynchedMotorPair) {
|
||||||
|
this.motors = motors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//% fixedInstance whenUsed
|
||||||
|
export const chassis = new Chassis();
|
||||||
|
}
|
15
libs/chassis/pxt.json
Normal file
15
libs/chassis/pxt.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "chassis",
|
||||||
|
"description": "Chassis robot support",
|
||||||
|
"files": [
|
||||||
|
"README.md",
|
||||||
|
"chassis.ts"
|
||||||
|
],
|
||||||
|
"testFiles": [
|
||||||
|
"test.ts"
|
||||||
|
],
|
||||||
|
"public": true,
|
||||||
|
"dependencies": {
|
||||||
|
"core": "file:../core"
|
||||||
|
}
|
||||||
|
}
|
1
libs/chassis/test.ts
Normal file
1
libs/chassis/test.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -11,5 +11,8 @@
|
|||||||
"sensors.ColorSensor.onLightChanged|param|handler": "the code to run when detected",
|
"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": "Waits for the given color to be detected",
|
||||||
"sensors.ColorSensor.pauseForColor|param|color": "the color to detect",
|
"sensors.ColorSensor.pauseForColor|param|color": "the color to detect",
|
||||||
"sensors.ColorSensor.pauseForLight": "Waits for the given color to be detected"
|
"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"
|
||||||
}
|
}
|
@ -18,12 +18,14 @@
|
|||||||
"sensors.ColorSensor.onColorDetected|block": "on %sensor|detected color %color",
|
"sensors.ColorSensor.onColorDetected|block": "on %sensor|detected color %color",
|
||||||
"sensors.ColorSensor.onLightChanged|block": "on %sensor|%mode|%condition",
|
"sensors.ColorSensor.onLightChanged|block": "on %sensor|%mode|%condition",
|
||||||
"sensors.ColorSensor.pauseForColor|block": "pause %sensor|for color %color",
|
"sensors.ColorSensor.pauseForColor|block": "pause %sensor|for color %color",
|
||||||
"sensors.ColorSensor.pauseForLight|block": "pause %sensor|for %mode|light %condition",
|
"sensors.ColorSensor.pauseForLight|block": "pause %sensor|for %mode|%condition",
|
||||||
|
"sensors.ColorSensor.setThreshold|block": "set %sensor|%condition|to %value",
|
||||||
"sensors.color1|block": "color 1",
|
"sensors.color1|block": "color 1",
|
||||||
"sensors.color2|block": "color 2",
|
"sensors.color2|block": "color 2",
|
||||||
"sensors.color3|block": "color 3",
|
"sensors.color3|block": "color 3",
|
||||||
"sensors.color4|block": "color 4",
|
"sensors.color4|block": "color 4",
|
||||||
"sensors|block": "sensors",
|
"sensors|block": "sensors",
|
||||||
"{id:category}Sensors": "Sensors",
|
"{id:category}Sensors": "Sensors",
|
||||||
"{id:group}Color Sensor": "Color Sensor"
|
"{id:group}Color Sensor": "Color Sensor",
|
||||||
|
"{id:group}Threshold": "Threshold"
|
||||||
}
|
}
|
@ -152,7 +152,7 @@ namespace sensors {
|
|||||||
//% parts="colorsensor"
|
//% parts="colorsensor"
|
||||||
//% blockNamespace=sensors
|
//% blockNamespace=sensors
|
||||||
//% sensor.fieldEditor="ports"
|
//% sensor.fieldEditor="ports"
|
||||||
//% weight=99
|
//% weight=98
|
||||||
//% group="Color Sensor"
|
//% group="Color Sensor"
|
||||||
color(): ColorSensorColor {
|
color(): ColorSensorColor {
|
||||||
this.setMode(ColorSensorMode.Color)
|
this.setMode(ColorSensorMode.Color)
|
||||||
@ -182,7 +182,7 @@ namespace sensors {
|
|||||||
* @param color the color to detect
|
* @param color the color to detect
|
||||||
*/
|
*/
|
||||||
//% help=sensors/color-sensor/pause-for-light
|
//% help=sensors/color-sensor/pause-for-light
|
||||||
//% block="pause %sensor|for %mode|light %condition"
|
//% block="pause %sensor|for %mode|%condition"
|
||||||
//% blockId=colorPauseForLight
|
//% blockId=colorPauseForLight
|
||||||
//% parts="colorsensor"
|
//% parts="colorsensor"
|
||||||
//% blockNamespace=sensors
|
//% blockNamespace=sensors
|
||||||
@ -221,17 +221,32 @@ namespace sensors {
|
|||||||
reflectedLight() {
|
reflectedLight() {
|
||||||
return this.light(LightIntensityMode.Reflected);
|
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
|
||||||
|
setThreshold(condition: LightCondition, value: number) {
|
||||||
|
if (condition == LightCondition.Dark)
|
||||||
|
this.thresholdDetector.setLowThreshold(value)
|
||||||
|
else
|
||||||
|
this.thresholdDetector.setHighThreshold(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//% whenUsed block="color 3" weight=90 fixedInstance jres=icons.port3
|
||||||
|
export const color3: ColorSensor = new ColorSensor(3)
|
||||||
|
|
||||||
//% whenUsed block="color 1" weight=95 fixedInstance jres=icons.port1
|
//% whenUsed block="color 1" weight=95 fixedInstance jres=icons.port1
|
||||||
export const color1: ColorSensor = new ColorSensor(1)
|
export const color1: ColorSensor = new ColorSensor(1)
|
||||||
|
|
||||||
//% whenUsed block="color 2" weight=90 fixedInstance jres=icons.port2
|
//% whenUsed block="color 2" weight=90 fixedInstance jres=icons.port2
|
||||||
export const color2: ColorSensor = new ColorSensor(2)
|
export const color2: ColorSensor = new ColorSensor(2)
|
||||||
|
|
||||||
//% whenUsed block="color 3" weight=90 fixedInstance jres=icons.port3
|
|
||||||
export const color3: ColorSensor = new ColorSensor(3)
|
|
||||||
|
|
||||||
//% whenUsed block="color 4" weight=90 fixedInstance jres=icons.port4
|
//% whenUsed block="color 4" weight=90 fixedInstance jres=icons.port4
|
||||||
export const color4: ColorSensor = new ColorSensor(4)
|
export const color4: ColorSensor = new ColorSensor(4)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"BrickLight": "Patterns for lights under the buttons.",
|
||||||
"ButtonEvent": "User interaction on buttons",
|
"ButtonEvent": "User interaction on buttons",
|
||||||
"Draw": "Drawing modes",
|
"Draw": "Drawing modes",
|
||||||
"Image.buffer": "Returns the underlaying Buffer object.",
|
"Image.buffer": "Returns the underlaying Buffer object.",
|
||||||
@ -6,14 +7,15 @@
|
|||||||
"Image.draw": "Draw an image on the screen.",
|
"Image.draw": "Draw an image on the screen.",
|
||||||
"Image.height": "Returns the height of an image.",
|
"Image.height": "Returns the height of an image.",
|
||||||
"Image.width": "Returns the width 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.getNumber": "Read a number in specified format from the buffer.",
|
||||||
"MMap.ioctl": "Perform ioctl(2) on the underlaying file",
|
"MMap.ioctl": "Perform ioctl(2) on the underlaying file",
|
||||||
"MMap.length": "Returns the length of a Buffer object.",
|
"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.read": "Perform read(2) on the underlaying file",
|
||||||
"MMap.setNumber": "Write a number in specified format in the buffer.",
|
"MMap.setNumber": "Write a number in specified format in the buffer.",
|
||||||
"MMap.slice": "Read a range of bytes into a buffer.",
|
"MMap.slice": "Read a range of bytes into a buffer.",
|
||||||
"MMap.write": "Perform write(2) on the underlaying file",
|
"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": "Generic button class, for device buttons and sensors.",
|
||||||
"brick.Button.isPressed": "Check if button is currently pressed or not.",
|
"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.",
|
"brick.Button.onEvent": "Do something when a button or sensor is clicked, up or down.",
|
||||||
@ -21,22 +23,27 @@
|
|||||||
"brick.Button.pauseUntil": "Waits until the event is raised",
|
"brick.Button.pauseUntil": "Waits until the event is raised",
|
||||||
"brick.Button.pauseUntil|param|ev": "the event to wait for",
|
"brick.Button.pauseUntil|param|ev": "the event to wait for",
|
||||||
"brick.Button.wasPressed": "See if the button was pressed again since the last time you checked.",
|
"brick.Button.wasPressed": "See if the button was pressed again since the last time you checked.",
|
||||||
|
"brick.batteryLevel": "Returns the current battery level",
|
||||||
"brick.buttonDown": "Down button on the EV3 Brick.",
|
"brick.buttonDown": "Down button on the EV3 Brick.",
|
||||||
"brick.buttonEnter": "Enter button on the EV3 Brick.",
|
"brick.buttonEnter": "Enter button on the EV3 Brick.",
|
||||||
"brick.buttonLeft": "Left button on the EV3 Brick.",
|
"brick.buttonLeft": "Left button on the EV3 Brick.",
|
||||||
"brick.buttonRight": "Right button on the EV3 Brick.",
|
"brick.buttonRight": "Right button on the EV3 Brick.",
|
||||||
"brick.buttonUp": "Up button on the EV3 Brick.",
|
"brick.buttonUp": "Up button on the EV3 Brick.",
|
||||||
"brick.clearScreen": "Clears the screen",
|
"brick.clearScreen": "Clears the screen",
|
||||||
"brick.lightPattern": "Pattern block.",
|
|
||||||
"brick.lightPattern|param|pattern": "the lights pattern to use. eg: LightsPattern.Green",
|
|
||||||
"brick.printLine": "Show text on the screen at a specific line.",
|
|
||||||
"brick.printLine|param|line": "the line number to print the text at, eg: 0",
|
|
||||||
"brick.printLine|param|text": "the text to print on the screen, eg: \"Hello world\"",
|
|
||||||
"brick.printPorts": "Prints the port states on the screen",
|
"brick.printPorts": "Prints the port states on the screen",
|
||||||
"brick.setLight": "Set lights.",
|
"brick.setLight": "Set lights.",
|
||||||
"brick.setLight|param|pattern": "the lights pattern to use.",
|
"brick.setLight|param|pattern": "the lights pattern to use. eg: BrickLight.Orange",
|
||||||
"brick.showImage": "Shows an image on screen",
|
"brick.showImage": "Shows an image on screen",
|
||||||
"brick.showImage|param|image": "image to draw",
|
"brick.showImage|param|image": "image to draw",
|
||||||
|
"brick.showNumber": "Shows a number on the screen",
|
||||||
|
"brick.showNumber|param|line": "the line number to print the text at, eg: 1",
|
||||||
|
"brick.showNumber|param|value": "the numeric value",
|
||||||
|
"brick.showString": "Show text on the screen at a specific line.",
|
||||||
|
"brick.showString|param|line": "the line number to print the text at, eg: 1",
|
||||||
|
"brick.showString|param|text": "the text to print on the screen, eg: \"Hello world\"",
|
||||||
|
"brick.showValue": "Shows a name, value pair on the screen",
|
||||||
|
"brick.showValue|param|line": "the line number to print the text at, eg: 1",
|
||||||
|
"brick.showValue|param|value": "the numeric value",
|
||||||
"console": "Reading and writing data to the console output.\n\nReading and writing data to the console output.",
|
"console": "Reading and writing data to the console output.\n\nReading and writing data to the console output.",
|
||||||
"console.addListener": "Adds a listener for the log messages",
|
"console.addListener": "Adds a listener for the log messages",
|
||||||
"console.log": "Write a line of text to the console output.",
|
"console.log": "Write a line of text to the console output.",
|
||||||
@ -45,6 +52,12 @@
|
|||||||
"console.logValue|param|value": "to write",
|
"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.",
|
"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": "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.allocateNotifyEvent": "Allocates the next user notification event",
|
||||||
"control.deviceFirmwareVersion": "Determine the version of system software currently running.",
|
"control.deviceFirmwareVersion": "Determine the version of system software currently running.",
|
||||||
"control.dmesg": "Write data to DMESG debugging buffer.",
|
"control.dmesg": "Write data to DMESG debugging buffer.",
|
||||||
@ -54,38 +67,33 @@
|
|||||||
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
|
"control.raiseEvent|param|value": "Component specific code indicating the cause of the event.",
|
||||||
"motors.Motor.angle": "Gets motor angle.",
|
"motors.Motor.angle": "Gets motor angle.",
|
||||||
"motors.Motor.clearCounts": "Clears the motor count",
|
"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.speed": "Gets motor actual speed.",
|
||||||
"motors.Motor.tacho": "Gets motor tachometer count.",
|
"motors.Motor.tacho": "Gets motor tachometer count.",
|
||||||
"motors.Motor.toString": "Returns the status of the motor",
|
"motors.Motor.toString": "Returns the status of the motor",
|
||||||
"motors.MotorBase.isReady": "Returns a value indicating if the motor is still running a previous command.",
|
"motors.MotorBase.isReady": "Returns a value indicating if the motor is still running a previous command.",
|
||||||
"motors.MotorBase.move": "Moves the motor by a number of rotations, degress or seconds",
|
|
||||||
"motors.MotorBase.move|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
|
|
||||||
"motors.MotorBase.move|param|unit": "the meaning of the value",
|
|
||||||
"motors.MotorBase.move|param|value": "the move quantity, eg: 2",
|
|
||||||
"motors.MotorBase.pauseUntilReady": "Pauses the execution until the previous command finished.",
|
"motors.MotorBase.pauseUntilReady": "Pauses the execution until the previous command finished.",
|
||||||
"motors.MotorBase.pauseUntilReady|param|timeOut": "optional maximum pausing time in milliseconds",
|
"motors.MotorBase.pauseUntilReady|param|timeOut": "optional maximum pausing time in milliseconds",
|
||||||
"motors.MotorBase.reset": "Resets the motor(s).",
|
"motors.MotorBase.reset": "Resets the motor(s).",
|
||||||
"motors.MotorBase.setBrake": "Sets the automatic brake on or off when the motor is off",
|
"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.setBrake|param|brake": "a value indicating if the motor should break when off",
|
||||||
"motors.MotorBase.setReversed": "Reverses the motor polarity",
|
"motors.MotorBase.setReversed": "Reverses the motor polarity",
|
||||||
"motors.MotorBase.setSpeed": "Sets the speed of the motor.",
|
"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|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",
|
||||||
"motors.MotorBase.stop": "Stops the motor(s).",
|
"motors.MotorBase.stop": "Stops the motor(s).",
|
||||||
"motors.SynchedMotorPair.drive": "Makes a differential drive robot move with a given speed (%) and rotation rate (deg/s)\nusing a unicycle model.",
|
|
||||||
"motors.SynchedMotorPair.drive|param|rotationSpeed": "rotation of the robot around the center point, eg: 30",
|
|
||||||
"motors.SynchedMotorPair.drive|param|speed": "speed of the center point between motors, eg: 10",
|
|
||||||
"motors.SynchedMotorPair.drive|param|value": "the amount of movement, eg: 2",
|
|
||||||
"motors.SynchedMotorPair.setDimensions": "Sets the wheels radius and base length of a directional drive robot",
|
|
||||||
"motors.SynchedMotorPair.setDimensions|param|wheelRadius": "@param baseLength ",
|
|
||||||
"motors.SynchedMotorPair.steer": "Turns the motor and the follower motor by a number of rotations",
|
"motors.SynchedMotorPair.steer": "Turns the motor and the follower motor by a number of rotations",
|
||||||
"motors.SynchedMotorPair.steer|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
|
"motors.SynchedMotorPair.steer|param|speed": "the speed from ``100`` full forward to ``-100`` full backward, eg: 50",
|
||||||
"motors.SynchedMotorPair.steer|param|turnRatio": "the ratio of power sent to the follower motor, from ``-200`` to ``200``, eg: 0",
|
"motors.SynchedMotorPair.steer|param|turnRatio": "the ratio of power sent to the follower motor, from ``-200`` to ``200``, eg: 0",
|
||||||
"motors.SynchedMotorPair.steer|param|unit": "the meaning of the value",
|
"motors.SynchedMotorPair.steer|param|unit": "(optional) unit of the value",
|
||||||
"motors.SynchedMotorPair.steer|param|value": "the move quantity, eg: 2",
|
"motors.SynchedMotorPair.steer|param|value": "(optional) move duration or rotation",
|
||||||
"motors.SynchedMotorPair.tank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.",
|
"motors.SynchedMotorPair.tank": "The Move Tank block can make a robot drive forward, backward, turn, or stop. \nUse the Move Tank block for robot vehicles that have two Large Motors, \nwith one motor driving the left side of the vehicle and the other the right side. \nYou can make the two motors go at different speeds or in different directions \nto make your robot turn.",
|
||||||
|
"motors.SynchedMotorPair.tank|param|speedLeft": "the speed on the left motor, eg: 50",
|
||||||
"motors.SynchedMotorPair.tank|param|speedRight": "the speed on the right motor, eg: 50",
|
"motors.SynchedMotorPair.tank|param|speedRight": "the speed on the right motor, eg: 50",
|
||||||
"motors.SynchedMotorPair.tank|param|unit": "@param speedLeft the speed on the left motor, eg: 50",
|
"motors.SynchedMotorPair.tank|param|unit": "(optional) unit of the value",
|
||||||
"motors.SynchedMotorPair.tank|param|value": "the amount of movement, eg: 2",
|
"motors.SynchedMotorPair.tank|param|value": "(optional) move duration or rotation",
|
||||||
"motors.SynchedMotorPair.toString": "Returns the name(s) of the motor",
|
"motors.SynchedMotorPair.toString": "Returns the name(s) of the motor",
|
||||||
"motors.mkCmd": "Allocates a message buffer",
|
"motors.mkCmd": "Allocates a message buffer",
|
||||||
"motors.mkCmd|param|addSize": "required additional bytes",
|
"motors.mkCmd|param|addSize": "required additional bytes",
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
{
|
{
|
||||||
|
"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.Click|block": "click",
|
||||||
"ButtonEvent.Down|block": "down",
|
"ButtonEvent.Down|block": "down",
|
||||||
"ButtonEvent.Up|block": "up",
|
"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.Degrees|block": "degrees",
|
||||||
"MoveUnit.MilliSeconds|block": "milliseconds",
|
"MoveUnit.MilliSeconds|block": "milliseconds",
|
||||||
"MoveUnit.Rotations|block": "rotations",
|
"MoveUnit.Rotations|block": "rotations",
|
||||||
|
"MoveUnit.Seconds|block": "seconds",
|
||||||
"Output.AB|block": "A+B",
|
"Output.AB|block": "A+B",
|
||||||
"Output.AD|block": "A+D",
|
"Output.AD|block": "A+D",
|
||||||
"Output.ALL|block": "All",
|
"Output.ALL|block": "All",
|
||||||
@ -28,36 +29,51 @@
|
|||||||
"brick.Button.onEvent|block": "on %button|%event",
|
"brick.Button.onEvent|block": "on %button|%event",
|
||||||
"brick.Button.pauseUntil|block": "pause until %button|%event",
|
"brick.Button.pauseUntil|block": "pause until %button|%event",
|
||||||
"brick.Button.wasPressed|block": "%button|was pressed",
|
"brick.Button.wasPressed|block": "%button|was pressed",
|
||||||
"brick.buttonDown|block": "down",
|
"brick.batteryLevel|block": "battery level",
|
||||||
"brick.buttonEnter|block": "enter",
|
"brick.buttonDown|block": "button down",
|
||||||
"brick.buttonLeft|block": "left",
|
"brick.buttonEnter|block": "button enter",
|
||||||
"brick.buttonRight|block": "right",
|
"brick.buttonLeft|block": "button left",
|
||||||
"brick.buttonUp|block": "up",
|
"brick.buttonRight|block": "button right",
|
||||||
|
"brick.buttonUp|block": "button up",
|
||||||
"brick.clearScreen|block": "clear screen",
|
"brick.clearScreen|block": "clear screen",
|
||||||
"brick.lightPattern|block": "%pattern",
|
|
||||||
"brick.printLine|block": "print %text| at line %line",
|
|
||||||
"brick.printPorts|block": "print ports",
|
"brick.printPorts|block": "print ports",
|
||||||
"brick.setLight|block": "set light to %pattern=led_pattern",
|
"brick.setLight|block": "set light to %pattern",
|
||||||
"brick.showImage|block": "show image %image=screen_image_picker",
|
"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",
|
||||||
|
"brick.showValue|block": "show value %name|= %text|at line %line",
|
||||||
"brick|block": "brick",
|
"brick|block": "brick",
|
||||||
"console.logValue|block": "console|log value %name|= %value",
|
"console.logValue|block": "console|log value %name|= %value",
|
||||||
"console.log|block": "console|log %text",
|
"console.log|block": "console|log %text",
|
||||||
"console.sendToScreen|block": "send console to screen",
|
"console.sendToScreen|block": "send console to screen",
|
||||||
"console|block": "console",
|
"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.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",
|
"control|block": "control",
|
||||||
"motors.Motor.angle|block": "%motor|angle",
|
"motors.Motor.angle|block": "%motor|angle",
|
||||||
"motors.Motor.clearCounts|block": "%motor|clear counts",
|
"motors.Motor.clearCounts|block": "%motor|clear counts",
|
||||||
|
"motors.Motor.setRegulated|block": "set %motor|regulated %value",
|
||||||
"motors.Motor.speed|block": "%motor|speed",
|
"motors.Motor.speed|block": "%motor|speed",
|
||||||
"motors.Motor.tacho|block": "%motor|tacho",
|
"motors.Motor.tacho|block": "%motor|tacho",
|
||||||
"motors.MotorBase.move|block": "move %motor|for %value|%unit|at %speed|%",
|
|
||||||
"motors.MotorBase.pauseUntilReady|block": "%motor|pause until ready",
|
"motors.MotorBase.pauseUntilReady|block": "%motor|pause until ready",
|
||||||
|
"motors.MotorBase.reset|block": "%motors|reset",
|
||||||
"motors.MotorBase.setBrake|block": "set %motor|brake %brake",
|
"motors.MotorBase.setBrake|block": "set %motor|brake %brake",
|
||||||
"motors.MotorBase.setReversed|block": "set %motor|reversed %reversed",
|
"motors.MotorBase.setReversed|block": "set %motor|reversed %reversed",
|
||||||
"motors.MotorBase.setSpeed|block": "set speed of %motor|to %speed|%",
|
"motors.MotorBase.setSpeed|block": "set %motor|speed to %speed=motorSpeedPicker|%",
|
||||||
"motors.SynchedMotorPair.drive|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit",
|
"motors.MotorBase.stop|block": "%motors|stop",
|
||||||
"motors.SynchedMotorPair.steer|block": "steer %chassis turn by|%turnRatio|at speed %speed|%|for %value|%unit",
|
"motors.SynchedMotorPair.steer|block": "steer %chassis|turn ratio %turnRatio=motorTurnRatioPicker|speed %speed=motorSpeedPicker|%",
|
||||||
"motors.SynchedMotorPair.tank|block": "tank %chassis|left %speedLeft|%|right %speedRight|%|for %value|%unit",
|
"motors.SynchedMotorPair.tank|block": "tank %motors|%speedLeft=motorSpeedPicker|%|%speedRight=motorSpeedPicker|%",
|
||||||
"motors.largeAB|block": "large A+B",
|
"motors.largeAB|block": "large A+B",
|
||||||
"motors.largeAD|block": "large A+D",
|
"motors.largeAD|block": "large A+D",
|
||||||
"motors.largeA|block": "large A",
|
"motors.largeA|block": "large A",
|
||||||
@ -87,9 +103,9 @@
|
|||||||
"{id:category}Screen": "Screen",
|
"{id:category}Screen": "Screen",
|
||||||
"{id:category}Serial": "Serial",
|
"{id:category}Serial": "Serial",
|
||||||
"{id:group}Buttons": "Buttons",
|
"{id:group}Buttons": "Buttons",
|
||||||
"{id:group}Chassis": "Chassis",
|
"{id:group}Counters": "Counters",
|
||||||
"{id:group}Light": "Light",
|
"{id:group}More": "More",
|
||||||
"{id:group}Motion": "Motion",
|
"{id:group}Move": "Move",
|
||||||
"{id:group}Screen": "Screen",
|
"{id:group}Screen": "Screen",
|
||||||
"{id:group}Sensors": "Sensors"
|
"{id:group}Sensors": "Sensors"
|
||||||
}
|
}
|
12
libs/core/battery.ts
Normal file
12
libs/core/battery.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
namespace brick {
|
||||||
|
/**
|
||||||
|
* Returns the current battery level
|
||||||
|
*/
|
||||||
|
//% blockId=brickBatteryLevel block="battery level"
|
||||||
|
//% group="More"
|
||||||
|
export function batteryLevel(): number {
|
||||||
|
const info = sensors.internal.getBatteryInfo();
|
||||||
|
return info.current;
|
||||||
|
}
|
||||||
|
}
|
@ -2,36 +2,26 @@
|
|||||||
/**
|
/**
|
||||||
* Patterns for lights under the buttons.
|
* Patterns for lights under the buttons.
|
||||||
*/
|
*/
|
||||||
const enum LightsPattern {
|
const enum BrickLight {
|
||||||
//% block=Off enumval=0
|
//% block=off enumval=0
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
Off = 0,
|
Off = 0,
|
||||||
//% block=Green enumval=1
|
//% block=green enumval=1
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
Green = 1,
|
Green = 1,
|
||||||
//% block=Red enumval=2
|
//% block=red enumval=2
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
Red = 2,
|
Red = 2,
|
||||||
//% block=Orange enumval=3
|
//% block=orange enumval=3
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
Orange = 3,
|
Orange = 3,
|
||||||
//% block="Flashing Green" enumval=4
|
//% block="green flash" enumval=4
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
GreenFlash = 4,
|
GreenFlash = 4,
|
||||||
//% block="Flashing Red" enumval=5
|
//% block="red flash" enumval=5
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
RedFlash = 5,
|
RedFlash = 5,
|
||||||
//% block="Flashing Orange" enumval=6
|
//% block="orange flash" enumval=6
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
OrangeFlash = 6,
|
OrangeFlash = 6,
|
||||||
//% block="Pulsing Green" enumval=7
|
//% block="green pulse" enumval=7
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
GreenPulse = 7,
|
GreenPulse = 7,
|
||||||
//% block="Pulsing Red" enumval=8
|
//% block="red pulse" enumval=8
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
RedPulse = 8,
|
RedPulse = 8,
|
||||||
//% block="Pulsing Orange" enumval=9
|
//% block="orange pulse" enumval=9
|
||||||
//% blockIdentity=brick.lightPattern
|
|
||||||
OrangePulse = 9,
|
OrangePulse = 9,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +82,7 @@ namespace brick {
|
|||||||
//% blockNamespace=brick
|
//% blockNamespace=brick
|
||||||
//% weight=81 blockGap=8
|
//% weight=81 blockGap=8
|
||||||
//% group="Buttons"
|
//% group="Buttons"
|
||||||
|
//% button.fieldEditor="brickbuttons"
|
||||||
isPressed() {
|
isPressed() {
|
||||||
return this._isPressed
|
return this._isPressed
|
||||||
}
|
}
|
||||||
@ -107,6 +98,7 @@ namespace brick {
|
|||||||
//% blockNamespace=brick
|
//% blockNamespace=brick
|
||||||
//% weight=80
|
//% weight=80
|
||||||
//% group="Buttons"
|
//% group="Buttons"
|
||||||
|
//% button.fieldEditor="brickbuttons"
|
||||||
wasPressed() {
|
wasPressed() {
|
||||||
const r = this._wasPressed
|
const r = this._wasPressed
|
||||||
this._wasPressed = false
|
this._wasPressed = false
|
||||||
@ -125,6 +117,7 @@ namespace brick {
|
|||||||
//% blockNamespace=brick
|
//% blockNamespace=brick
|
||||||
//% weight=99 blockGap=8
|
//% weight=99 blockGap=8
|
||||||
//% group="Buttons"
|
//% group="Buttons"
|
||||||
|
//% button.fieldEditor="brickbuttons"
|
||||||
onEvent(ev: ButtonEvent, body: () => void) {
|
onEvent(ev: ButtonEvent, body: () => void) {
|
||||||
control.onEvent(this._id, ev, body)
|
control.onEvent(this._id, ev, body)
|
||||||
}
|
}
|
||||||
@ -139,6 +132,7 @@ namespace brick {
|
|||||||
//% blockNamespace=brick
|
//% blockNamespace=brick
|
||||||
//% weight=98 blockGap=8
|
//% weight=98 blockGap=8
|
||||||
//% group="Buttons"
|
//% group="Buttons"
|
||||||
|
//% button.fieldEditor="brickbuttons"
|
||||||
pauseUntil(ev: ButtonEvent) {
|
pauseUntil(ev: ButtonEvent) {
|
||||||
control.waitForEvent(this._id, ev);
|
control.waitForEvent(this._id, ev);
|
||||||
}
|
}
|
||||||
@ -163,6 +157,12 @@ namespace brick {
|
|||||||
if (sl[i])
|
if (sl[i])
|
||||||
ret |= 1 << i
|
ret |= 1 << i
|
||||||
}
|
}
|
||||||
|
// 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
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,8 +172,6 @@ namespace brick {
|
|||||||
if (!btnsMM) control.fail("no buttons?")
|
if (!btnsMM) control.fail("no buttons?")
|
||||||
buttons = []
|
buttons = []
|
||||||
sensors.internal.unsafePollForChanges(50, readButtons, (prev, curr) => {
|
sensors.internal.unsafePollForChanges(50, readButtons, (prev, curr) => {
|
||||||
if (curr & DAL.BUTTON_ID_ESCAPE)
|
|
||||||
control.reset()
|
|
||||||
for (let b of buttons)
|
for (let b of buttons)
|
||||||
b._update(!!(curr & b.mask))
|
b._update(!!(curr & b.mask))
|
||||||
})
|
})
|
||||||
@ -188,7 +186,7 @@ namespace brick {
|
|||||||
initBtns()
|
initBtns()
|
||||||
buttons.push(this)
|
buttons.push(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initBtns() // always ON as it handles ESCAPE button
|
initBtns() // always ON as it handles ESCAPE button
|
||||||
|
|
||||||
@ -196,31 +194,31 @@ namespace brick {
|
|||||||
/**
|
/**
|
||||||
* Enter button on the EV3 Brick.
|
* Enter button on the EV3 Brick.
|
||||||
*/
|
*/
|
||||||
//% whenUsed block="enter" weight=95 fixedInstance
|
//% whenUsed block="button enter" weight=95 fixedInstance
|
||||||
export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER)
|
export const buttonEnter: Button = new DevButton(DAL.BUTTON_ID_ENTER)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Left button on the EV3 Brick.
|
* Left button on the EV3 Brick.
|
||||||
*/
|
*/
|
||||||
//% whenUsed block="left" weight=95 fixedInstance
|
//% whenUsed block="button left" weight=95 fixedInstance
|
||||||
export const buttonLeft: Button = new DevButton(DAL.BUTTON_ID_LEFT)
|
export const buttonLeft: Button = new DevButton(DAL.BUTTON_ID_LEFT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Right button on the EV3 Brick.
|
* Right button on the EV3 Brick.
|
||||||
*/
|
*/
|
||||||
//% whenUsed block="right" weight=94 fixedInstance
|
//% whenUsed block="button right" weight=94 fixedInstance
|
||||||
export const buttonRight: Button = new DevButton(DAL.BUTTON_ID_RIGHT)
|
export const buttonRight: Button = new DevButton(DAL.BUTTON_ID_RIGHT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Up button on the EV3 Brick.
|
* Up button on the EV3 Brick.
|
||||||
*/
|
*/
|
||||||
//% whenUsed block="up" weight=95 fixedInstance
|
//% whenUsed block="button up" weight=95 fixedInstance
|
||||||
export const buttonUp: Button = new DevButton(DAL.BUTTON_ID_UP)
|
export const buttonUp: Button = new DevButton(DAL.BUTTON_ID_UP)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Down button on the EV3 Brick.
|
* Down button on the EV3 Brick.
|
||||||
*/
|
*/
|
||||||
//% whenUsed block="down" weight=95 fixedInstance
|
//% whenUsed block="button down" weight=95 fixedInstance
|
||||||
export const buttonDown: Button = new DevButton(DAL.BUTTON_ID_DOWN)
|
export const buttonDown: Button = new DevButton(DAL.BUTTON_ID_DOWN)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +227,7 @@ namespace control {
|
|||||||
/**
|
/**
|
||||||
* Determine the version of system software currently running.
|
* Determine the version of system software currently running.
|
||||||
*/
|
*/
|
||||||
|
//%
|
||||||
export function deviceFirmwareVersion(): string {
|
export function deviceFirmwareVersion(): string {
|
||||||
let buf = output.createBuffer(6)
|
let buf = output.createBuffer(6)
|
||||||
brick.internal.getBtnsMM().read(buf)
|
brick.internal.getBtnsMM().read(buf)
|
||||||
@ -243,32 +242,21 @@ namespace control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace brick {
|
namespace brick {
|
||||||
let currPattern: LightsPattern
|
// the brick starts with the red color
|
||||||
|
let currPattern: BrickLight = BrickLight.Red;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set lights.
|
* Set lights.
|
||||||
* @param pattern the lights pattern to use.
|
* @param pattern the lights pattern to use. eg: BrickLight.Orange
|
||||||
*/
|
*/
|
||||||
//% blockId=setLights block="set light to %pattern=led_pattern"
|
//% blockId=setLights block="set light to %pattern"
|
||||||
//% weight=100 group="Buttons"
|
//% weight=100 group="Buttons"
|
||||||
export function setLight(pattern: number): void {
|
export function setLight(pattern: BrickLight): void {
|
||||||
if (currPattern === pattern)
|
if (currPattern === pattern)
|
||||||
return
|
return
|
||||||
currPattern = pattern
|
currPattern = pattern;
|
||||||
let cmd = output.createBuffer(2)
|
const cmd = output.createBuffer(2)
|
||||||
cmd[0] = pattern + 48
|
cmd[0] = pattern + 48
|
||||||
brick.internal.getBtnsMM().write(cmd)
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Reading and writing data to the console output.
|
* Reading and writing data to the console output.
|
||||||
*/
|
*/
|
||||||
//% weight=12 color=#002050 icon="\uf120"
|
//% weight=12 color=#00451A icon="\uf112"
|
||||||
//% advanced=true
|
//% advanced=true
|
||||||
namespace console {
|
namespace console {
|
||||||
type Listener = (text: string) => void;
|
type Listener = (text: string) => void;
|
||||||
@ -58,7 +58,7 @@ namespace console {
|
|||||||
|
|
||||||
namespace console.screen {
|
namespace console.screen {
|
||||||
const maxLines = 100;
|
const maxLines = 100;
|
||||||
const screenLines = 8;
|
const screenLines = 10;
|
||||||
let lines: string[];
|
let lines: string[];
|
||||||
let scrollPosition = 0;
|
let scrollPosition = 0;
|
||||||
|
|
||||||
@ -66,8 +66,8 @@ namespace console.screen {
|
|||||||
if (!lines) {
|
if (!lines) {
|
||||||
lines = [];
|
lines = [];
|
||||||
console.addListener(log);
|
console.addListener(log);
|
||||||
brick.buttonUp.onEvent(ButtonEvent.Click, () => scroll(-1))
|
brick.buttonUp.onEvent(ButtonEvent.Click, () => scroll(-3))
|
||||||
brick.buttonDown.onEvent(ButtonEvent.Click, () => scroll(1))
|
brick.buttonDown.onEvent(ButtonEvent.Click, () => scroll(3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
libs/core/enums.d.ts
vendored
11
libs/core/enums.d.ts
vendored
@ -1,6 +1,17 @@
|
|||||||
// Auto-generated. Do not edit.
|
// Auto-generated. Do not edit.
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode for lseek()
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare const enum SeekWhence {
|
||||||
|
Set = 0,
|
||||||
|
Current = 1,
|
||||||
|
End = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drawing modes
|
* Drawing modes
|
||||||
*/
|
*/
|
||||||
|
@ -114,23 +114,7 @@
|
|||||||
"progressWaterLevel3": "iVBORw0KGgoAAAANSUhEUgAAALIAAACAAQAAAACHQw5jAAABP0lEQVR42u2VMWrEMBBFRxGsGrNqXYT4CltuFV9lj5EqVlhImyPkKoKFbJcrrHKCKJ2XKFb+BGxsGBdbBRJ/mGHm+VtjJGNT/srQO6cG8cnFKXvKLVdHRFcjfXD3xDyybY9IFVJgbpgHtilEa5E8XJ1m/gJbVwJFXuwRrqSYa9hSCZt/A1/B1VLjqdMG1mu0bgeD4W5Te2r1A6YVJne0qfNP57fWU9AY5dYKd29tDgodldoTqagjGaoc3VAiiibQmlg1ApeIQIjuufDUq+C0Q1z1xaJFi/60iluZ28aJ3Jy9yPU5iFxlmesZvsry+kUz8/z/5qTuZKyizM2F3IYZfnDyuR7kc61fL+P4qYmq0mCZ+tuhfHZjPvhV8iKnMVejuZNXrjnK3O77aeo03hEzNGqyUcbNnJdfPjqLFv2+vgH+JtBJ4nz/SAAAAABJRU5ErkJggg==",
|
"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==",
|
"systemAccept1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQElEQVR42mM4wMDMsP//X4b6//+AWI6h/p8dQ/2fOob6H/8YKj/+Y6h4/I+hxvkfQx07UJ4fiOf/A6sF6QHqBQDsYh9jNdETHwAAAABJRU5ErkJggg==",
|
||||||
"systemAccept2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQUlEQVR42mM4wMDMsP//X4YEBjYGB4ZHDA6MhxgcmJsYHNiZGNz4mBjcZZgYnPcwMTj+YGJw+ADECUxgtSA9QL0A+IIPxwiZFtwAAAAASUVORK5CYII=",
|
"systemAccept2": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAQUlEQVR42mM4wMDMsP//X4YEBjYGB4ZHDA6MhxgcmJsYHNiZGNz4mBjcZZgYnPcwMTj+YGJw+ADECUxgtSA9QL0A+IIPxwiZFtwAAAAASUVORK5CYII=",
|
||||||
"systemAlert": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAVAQAAAAB0khOLAAAARUlEQVR42iXD0QmAIAAE0IvWCtqmMbLG8MtVhAZwjBvALyE85XzwoE/QO8f5WPsd0K+An6c3Jq8sThIUUVg9qfmDDRn7AD/WMAQEJ+pCAAAAAElFTkSuQmCC",
|
|
||||||
"systemBox": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAGklEQVR42mM4wMDMsP//X4b6//9IwiA9QL0AlQYkzY8nCoAAAAAASUVORK5CYII=",
|
"systemBox": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAAGklEQVR42mM4wMDMsP//X4b6//9IwiA9QL0AlQYkzY8nCoAAAAAASUVORK5CYII=",
|
||||||
"systemBusy0": "iVBORw0KGgoAAAANSUhEUgAAABMAAAAPAQAAAAAuP8mBAAAAMElEQVR42mPY/38Bg/x/BgbnHw4Msd8dGKLeA+k4IL0XSGdB6TioOFAepA6kHqgPAJCPFdTsOCPGAAAAAElFTkSuQmCC",
|
|
||||||
"systemBusy1": "iVBORw0KGgoAAAANSUhEUgAAAA8AAAATAQAAAABnuWoHAAAAOUlEQVR42mNoYGKw/8EAJO9/A6GrYQyv1jF8jWP4tY/hbx3D730M3+4xvH/HcO8bw90yhlvbGGDqAdjhGYsKgwC5AAAAAElFTkSuQmCC",
|
|
||||||
"systemDecline1": "iVBORw0KGgoAAAANSUhEUgAAABgAAAAQAQAAAAAkX4I4AAAANUlEQVR42mM4wMDMsP//X4b6//8Y6urtGOrt6hjq5/xjqD8JxI+hGMQGiQHlwGqAakF6gHoBybUeX0RcSJEAAAAASUVORK5CYII=",
|
"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,41 +220,10 @@ namespace images {
|
|||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemAccept2 = screen.unpackPNG(hex``);
|
export const systemAccept2 = screen.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemAlert = screen.unpackPNG(hex``);
|
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
|
||||||
export const systemBox = screen.unpackPNG(hex``);
|
export const systemBox = screen.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% 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``);
|
export const systemDecline1 = screen.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
||||||
export const systemDecline2 = screen.unpackPNG(hex``);
|
export const systemDecline2 = screen.unpackPNG(hex``);
|
||||||
//% fixedInstance jres blockIdentity=brick.__imagePicker
|
//% 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``);
|
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,14 @@ namespace sensors.internal {
|
|||||||
//serial.writeLine("UART " + port + " / " + mode + " - " + info)
|
//serial.writeLine("UART " + port + " / " + mode + " - " + info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getBatteryInfo(): { temp: number; current: number } {
|
||||||
|
init();
|
||||||
|
return {
|
||||||
|
temp: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryTemp),
|
||||||
|
current: Math.round(analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent) / 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function detectDevices() {
|
function detectDevices() {
|
||||||
let conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS)
|
let conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS)
|
||||||
let numChanged = 0
|
let numChanged = 0
|
||||||
@ -301,6 +309,11 @@ namespace sensors.internal {
|
|||||||
return 0
|
return 0
|
||||||
return getUartNumber(fmt, off, this._port)
|
return getUartNumber(fmt, off, this._port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
if (this.isActive()) uartReset(this._port);
|
||||||
|
this.realmode = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function uartReset(port: number) {
|
function uartReset(port: number) {
|
||||||
|
@ -483,7 +483,15 @@ void runLMS() {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stopMotors() {
|
||||||
|
uint8_t cmd[2] = { 0xA3, 0x0F };
|
||||||
|
int fd = open("/dev/lms_pwm", O_RDWR);
|
||||||
|
write(fd, cmd, 2);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void target_reset() {
|
extern "C" void target_reset() {
|
||||||
|
stopMotors();
|
||||||
if (lmsPid)
|
if (lmsPid)
|
||||||
runLMS();
|
runLMS();
|
||||||
else
|
else
|
||||||
|
@ -7,6 +7,16 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mode for lseek()
|
||||||
|
*/
|
||||||
|
enum class SeekWhence {
|
||||||
|
Set = 0,
|
||||||
|
Current = 1,
|
||||||
|
End = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace pxt {
|
namespace pxt {
|
||||||
PXT_VTABLE_CTOR(MMap) {
|
PXT_VTABLE_CTOR(MMap) {
|
||||||
length = 0;
|
length = 0;
|
||||||
@ -111,4 +121,10 @@ int read(MMap *mmap, Buffer data) {
|
|||||||
return ::read(mmap->fd, data->data, data->length);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1 +1,25 @@
|
|||||||
|
|
||||||
|
namespace motors {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A speed picker
|
||||||
|
* @param speed the speed, eg: 50
|
||||||
|
*/
|
||||||
|
//% blockId=motorSpeedPicker block="%speed" shim=TD_ID
|
||||||
|
//% speed.fieldEditor="speed" colorSecondary="#FFFFFF"
|
||||||
|
//% weight=0 blockHidden=1 speed.fieldOptions.decompileLiterals=1
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,8 @@ enum MoveUnit {
|
|||||||
Rotations,
|
Rotations,
|
||||||
//% block="degrees"
|
//% block="degrees"
|
||||||
Degrees,
|
Degrees,
|
||||||
|
//% block="seconds"
|
||||||
|
Seconds,
|
||||||
//% block="milliseconds"
|
//% block="milliseconds"
|
||||||
MilliSeconds
|
MilliSeconds
|
||||||
}
|
}
|
||||||
@ -94,7 +96,7 @@ namespace motors {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
function outputToName(out: Output): string {
|
export function outputToName(out: Output): string {
|
||||||
let r = "";
|
let r = "";
|
||||||
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
||||||
if (out & (1 << i)) {
|
if (out & (1 << i)) {
|
||||||
@ -109,8 +111,8 @@ namespace motors {
|
|||||||
* Stops all motors
|
* Stops all motors
|
||||||
*/
|
*/
|
||||||
//% blockId=motorStopAll block="stop all motors"
|
//% blockId=motorStopAll block="stop all motors"
|
||||||
//% weight=5
|
//% weight=1
|
||||||
//% group="Motion"
|
//% group="Move"
|
||||||
export function stopAllMotors() {
|
export function stopAllMotors() {
|
||||||
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
|
const b = mkCmd(Output.ALL, DAL.opOutputStop, 0)
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
@ -119,7 +121,7 @@ namespace motors {
|
|||||||
/**
|
/**
|
||||||
* Resets all motors
|
* Resets all motors
|
||||||
*/
|
*/
|
||||||
//% group="Motion"
|
//% group="Move"
|
||||||
export function resetAllMotors() {
|
export function resetAllMotors() {
|
||||||
reset(Output.ALL)
|
reset(Output.ALL)
|
||||||
}
|
}
|
||||||
@ -162,7 +164,7 @@ namespace motors {
|
|||||||
//% blockId=outputMotorSetBrakeMode block="set %motor|brake %brake"
|
//% blockId=outputMotorSetBrakeMode block="set %motor|brake %brake"
|
||||||
//% brake.fieldEditor=toggleonoff
|
//% brake.fieldEditor=toggleonoff
|
||||||
//% weight=60 blockGap=8
|
//% weight=60 blockGap=8
|
||||||
//% group="Motion"
|
//% group="Move"
|
||||||
setBrake(brake: boolean) {
|
setBrake(brake: boolean) {
|
||||||
this.init();
|
this.init();
|
||||||
this._brake = brake;
|
this._brake = brake;
|
||||||
@ -173,8 +175,8 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//% blockId=motorSetReversed block="set %motor|reversed %reversed"
|
//% blockId=motorSetReversed block="set %motor|reversed %reversed"
|
||||||
//% reversed.fieldEditor=toggleonoff
|
//% reversed.fieldEditor=toggleonoff
|
||||||
//% weight=59
|
//% weight=59 blockGap=8
|
||||||
//% group="Motion"
|
//% group="Move"
|
||||||
setReversed(reversed: boolean) {
|
setReversed(reversed: boolean) {
|
||||||
this.init();
|
this.init();
|
||||||
const b = mkCmd(this._port, DAL.opOutputPolarity, 1)
|
const b = mkCmd(this._port, DAL.opOutputPolarity, 1)
|
||||||
@ -185,7 +187,9 @@ namespace motors {
|
|||||||
/**
|
/**
|
||||||
* Stops the motor(s).
|
* Stops the motor(s).
|
||||||
*/
|
*/
|
||||||
//%
|
//% weight=6 blockGap=8
|
||||||
|
//% group="Move"
|
||||||
|
//% blockId=motorStop block="%motors|stop"
|
||||||
stop() {
|
stop() {
|
||||||
this.init();
|
this.init();
|
||||||
stop(this._port, this._brake);
|
stop(this._port, this._brake);
|
||||||
@ -194,47 +198,37 @@ namespace motors {
|
|||||||
/**
|
/**
|
||||||
* Resets the motor(s).
|
* Resets the motor(s).
|
||||||
*/
|
*/
|
||||||
//%
|
//% weight=5
|
||||||
|
//% group="Move"
|
||||||
|
//% blockId=motorReset block="%motors|reset"
|
||||||
reset() {
|
reset() {
|
||||||
this.init();
|
this.init();
|
||||||
reset(this._port);
|
reset(this._port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the speed of the motor.
|
* Sets the motor speed for limited time or distance.
|
||||||
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
||||||
|
* @param value (optional) measured distance or rotation
|
||||||
|
* @param unit (optional) unit of the value
|
||||||
*/
|
*/
|
||||||
//% blockId=motorSetSpeed block="set speed of %motor|to %speed|%"
|
//% blockId=motorSetSpeed block="set %motor|speed to %speed=motorSpeedPicker|%"
|
||||||
//% on.fieldEditor=toggleonoff
|
//% weight=100 blockGap=8
|
||||||
//% weight=99 blockGap=8
|
//% group="Move"
|
||||||
//% speed.min=-100 speed.max=100
|
setSpeed(speed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
||||||
//% group="Motion"
|
|
||||||
setSpeed(speed: number) {
|
|
||||||
this.init();
|
|
||||||
speed = Math.clamp(-100, 100, speed >> 0);
|
|
||||||
if (!speed) // always stop
|
|
||||||
this.stop();
|
|
||||||
else
|
|
||||||
this._setSpeed(speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves the motor by a number of rotations, degress or seconds
|
|
||||||
* @param value the move quantity, eg: 2
|
|
||||||
* @param unit the meaning of the value
|
|
||||||
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
|
||||||
*/
|
|
||||||
//% blockId=motorMove block="move %motor|for %value|%unit|at %speed|%"
|
|
||||||
//% weight=98 blockGap=8
|
|
||||||
//% speed.min=-100 speed.max=100
|
|
||||||
//% group="Motion"
|
|
||||||
move(value: number, unit: MoveUnit, speed: number) {
|
|
||||||
this.init();
|
this.init();
|
||||||
speed = Math.clamp(-100, 100, speed >> 0);
|
speed = Math.clamp(-100, 100, speed >> 0);
|
||||||
|
// stop if speed is 0
|
||||||
if (!speed) {
|
if (!speed) {
|
||||||
this.stop();
|
this.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// special: 0 is infinity
|
||||||
|
if (value == 0) {
|
||||||
|
this._setSpeed(speed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// timed motor moves
|
||||||
let useSteps: boolean;
|
let useSteps: boolean;
|
||||||
let stepsOrTime: number;
|
let stepsOrTime: number;
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
@ -246,6 +240,10 @@ namespace motors {
|
|||||||
stepsOrTime = value >> 0;
|
stepsOrTime = value >> 0;
|
||||||
useSteps = true;
|
useSteps = true;
|
||||||
break;
|
break;
|
||||||
|
case MoveUnit.Seconds:
|
||||||
|
stepsOrTime = (value * 1000) >> 0;
|
||||||
|
useSteps = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stepsOrTime = value;
|
stepsOrTime = value;
|
||||||
useSteps = false;
|
useSteps = false;
|
||||||
@ -253,6 +251,8 @@ namespace motors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._move(useSteps, stepsOrTime, speed);
|
this._move(useSteps, stepsOrTime, speed);
|
||||||
|
// wait till motor is done with this work
|
||||||
|
this.pauseUntilReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -264,13 +264,7 @@ namespace motors {
|
|||||||
const buf = mkCmd(this._port, DAL.opOutputTest, 2);
|
const buf = mkCmd(this._port, DAL.opOutputTest, 2);
|
||||||
readPWM(buf)
|
readPWM(buf)
|
||||||
const flags = buf.getNumber(NumberFormat.UInt8LE, 2);
|
const flags = buf.getNumber(NumberFormat.UInt8LE, 2);
|
||||||
// TODO: FIX with ~ support
|
return (~flags & this._port) == this._port;
|
||||||
for(let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
|
||||||
const flag = 1 << i;
|
|
||||||
if ((this._port & flag) && (flags & flag))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -278,8 +272,8 @@ namespace motors {
|
|||||||
* @param timeOut optional maximum pausing time in milliseconds
|
* @param timeOut optional maximum pausing time in milliseconds
|
||||||
*/
|
*/
|
||||||
//% blockId=motorPauseUntilRead block="%motor|pause until ready"
|
//% blockId=motorPauseUntilRead block="%motor|pause until ready"
|
||||||
//% weight=97
|
//% weight=90
|
||||||
//% group="Motion"
|
//% group="Move"
|
||||||
pauseUntilReady(timeOut?: number) {
|
pauseUntilReady(timeOut?: number) {
|
||||||
pauseUntil(() => this.isReady(), timeOut);
|
pauseUntil(() => this.isReady(), timeOut);
|
||||||
}
|
}
|
||||||
@ -288,10 +282,12 @@ namespace motors {
|
|||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class Motor extends MotorBase {
|
export class Motor extends MotorBase {
|
||||||
private _large: boolean;
|
private _large: boolean;
|
||||||
|
private _regulated: boolean;
|
||||||
|
|
||||||
constructor(port: Output, large: boolean) {
|
constructor(port: Output, large: boolean) {
|
||||||
super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
super(port, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
||||||
this._large = large;
|
this._large = large;
|
||||||
|
this._regulated = true;
|
||||||
this.markUsed();
|
this.markUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +303,7 @@ namespace motors {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private __setSpeed(speed: number) {
|
private __setSpeed(speed: number) {
|
||||||
const b = mkCmd(this._port, DAL.opOutputSpeed, 1)
|
const b = mkCmd(this._port, this._regulated ? DAL.opOutputSpeed : DAL.opOutputPower, 1)
|
||||||
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
b.setNumber(NumberFormat.Int8LE, 2, speed)
|
||||||
writePWM(b)
|
writePWM(b)
|
||||||
if (speed) {
|
if (speed) {
|
||||||
@ -321,11 +317,24 @@ namespace motors {
|
|||||||
step1: 0,
|
step1: 0,
|
||||||
step2: stepsOrTime,
|
step2: stepsOrTime,
|
||||||
step3: 0,
|
step3: 0,
|
||||||
speed: speed,
|
speed: this._regulated ? speed : undefined,
|
||||||
|
power: this._regulated ? undefined : speed,
|
||||||
useBrake: this._brake
|
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"
|
||||||
|
//% value.fieldEditor=toggleonoff
|
||||||
|
//% weight=58
|
||||||
|
//% group="Move"
|
||||||
|
setRegulated(value: boolean) {
|
||||||
|
this._regulated = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets motor actual speed.
|
* Gets motor actual speed.
|
||||||
* @param motor the port which connects to the motor
|
* @param motor the port which connects to the motor
|
||||||
@ -333,7 +342,7 @@ namespace motors {
|
|||||||
//% blockId=motorSpeed block="%motor|speed"
|
//% blockId=motorSpeed block="%motor|speed"
|
||||||
//% weight=72
|
//% weight=72
|
||||||
//% blockGap=8
|
//% blockGap=8
|
||||||
//% group="Sensors"
|
//% group="Counters"
|
||||||
speed(): number {
|
speed(): number {
|
||||||
this.init();
|
this.init();
|
||||||
return getMotorData(this._port).actualSpeed;
|
return getMotorData(this._port).actualSpeed;
|
||||||
@ -345,7 +354,8 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//% blockId=motorAngle block="%motor|angle"
|
//% blockId=motorAngle block="%motor|angle"
|
||||||
//% weight=70
|
//% weight=70
|
||||||
//% group="Sensors"
|
//% blockGap=8
|
||||||
|
//% group="Counters"
|
||||||
angle(): number {
|
angle(): number {
|
||||||
this.init();
|
this.init();
|
||||||
return getMotorData(this._port).count;
|
return getMotorData(this._port).count;
|
||||||
@ -359,7 +369,7 @@ namespace motors {
|
|||||||
//% blockId=motorTachoCount block="%motor|tacho"
|
//% blockId=motorTachoCount block="%motor|tacho"
|
||||||
//% weight=69
|
//% weight=69
|
||||||
//% blockGap=8
|
//% blockGap=8
|
||||||
//% group="Sensors"
|
//% group="Counters"
|
||||||
tacho(): number {
|
tacho(): number {
|
||||||
this.init();
|
this.init();
|
||||||
return getMotorData(this._port).tachoCount;
|
return getMotorData(this._port).tachoCount;
|
||||||
@ -371,7 +381,7 @@ namespace motors {
|
|||||||
//% blockId=motorClearCount block="%motor|clear counts"
|
//% blockId=motorClearCount block="%motor|clear counts"
|
||||||
//% weight=68
|
//% weight=68
|
||||||
//% blockGap=8
|
//% blockGap=8
|
||||||
//% group="Sensors"
|
//% group="Counters"
|
||||||
clearCounts() {
|
clearCounts() {
|
||||||
this.init();
|
this.init();
|
||||||
const b = mkCmd(this._port, DAL.opOutputClearCount, 0)
|
const b = mkCmd(this._port, DAL.opOutputClearCount, 0)
|
||||||
@ -418,13 +428,9 @@ namespace motors {
|
|||||||
|
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class SynchedMotorPair extends MotorBase {
|
export class SynchedMotorPair extends MotorBase {
|
||||||
private wheelRadius: number;
|
|
||||||
private baseLength: number;
|
|
||||||
|
|
||||||
constructor(ports: Output) {
|
constructor(ports: Output) {
|
||||||
super(ports, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
super(ports, () => this.__init(), (speed) => this.__setSpeed(speed), (steps, stepsOrTime, speed) => this.__move(steps, stepsOrTime, speed));
|
||||||
this.wheelRadius = 3;
|
|
||||||
this.baseLength = 12;
|
|
||||||
this.markUsed();
|
this.markUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +451,7 @@ namespace motors {
|
|||||||
private __setSpeed(speed: number) {
|
private __setSpeed(speed: number) {
|
||||||
syncMotors(this._port, {
|
syncMotors(this._port, {
|
||||||
speed: speed,
|
speed: speed,
|
||||||
turnRatio: 100, // same speed
|
turnRatio: 0, // same speed
|
||||||
useBrake: !!this._brake
|
useBrake: !!this._brake
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -454,7 +460,7 @@ namespace motors {
|
|||||||
syncMotors(this._port, {
|
syncMotors(this._port, {
|
||||||
useSteps: steps,
|
useSteps: steps,
|
||||||
speed: speed,
|
speed: speed,
|
||||||
turnRatio: 100, // same speed
|
turnRatio: 0, // same speed
|
||||||
stepsOrTime: stepsOrTime,
|
stepsOrTime: stepsOrTime,
|
||||||
useBrake: this._brake
|
useBrake: this._brake
|
||||||
});
|
});
|
||||||
@ -466,18 +472,16 @@ namespace motors {
|
|||||||
* with one motor driving the left side of the vehicle and the other the right side.
|
* with one motor driving the left side of the vehicle and the other the right side.
|
||||||
* You can make the two motors go at different speeds or in different directions
|
* You can make the two motors go at different speeds or in different directions
|
||||||
* to make your robot turn.
|
* to make your robot turn.
|
||||||
* @param value the amount of movement, eg: 2
|
|
||||||
* @param unit
|
|
||||||
* @param speedLeft the speed on the left motor, eg: 50
|
* @param speedLeft the speed on the left motor, eg: 50
|
||||||
* @param speedRight the speed on the right motor, eg: 50
|
* @param speedRight the speed on the right motor, eg: 50
|
||||||
|
* @param value (optional) move duration or rotation
|
||||||
|
* @param unit (optional) unit of the value
|
||||||
*/
|
*/
|
||||||
//% blockId=motorPairTank block="tank %chassis|left %speedLeft|%|right %speedRight|%|for %value|%unit"
|
//% blockId=motorPairTank block="tank %motors|%speedLeft=motorSpeedPicker|%|%speedRight=motorSpeedPicker|%"
|
||||||
//% weight=9 blockGap=8
|
//% weight=96 blockGap=8
|
||||||
//% speedLeft.min=-100 speedLeft=100
|
|
||||||
//% speedRight.min=-100 speedRight=100
|
|
||||||
//% inlineInputMode=inline
|
//% inlineInputMode=inline
|
||||||
//% group="Chassis"
|
//% group="Move"
|
||||||
tank(speedLeft: number, speedRight: number, value: number, unit: MoveUnit) {
|
tank(speedLeft: number, speedRight: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
||||||
this.init();
|
this.init();
|
||||||
|
|
||||||
speedLeft = Math.clamp(-100, 100, speedLeft >> 0);
|
speedLeft = Math.clamp(-100, 100, speedLeft >> 0);
|
||||||
@ -487,56 +491,23 @@ namespace motors {
|
|||||||
const turnRatio = speedLeft == speed
|
const turnRatio = speedLeft == speed
|
||||||
? (100 - speedRight / speedLeft * 100)
|
? (100 - speedRight / speedLeft * 100)
|
||||||
: (speedLeft / speedRight * 100 - 100);
|
: (speedLeft / speedRight * 100 - 100);
|
||||||
|
|
||||||
this.steer(turnRatio, speed, value, unit);
|
this.steer(turnRatio, speed, value, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a differential drive robot move with a given speed (%) 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=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s|for %value|%unit"
|
|
||||||
//% inlineInputMode=inline
|
|
||||||
//% group="Chassis"
|
|
||||||
//% weight=8 blockGap=8
|
|
||||||
drive(speed: number, rotationSpeed: number, value: number, unit: MoveUnit) {
|
|
||||||
this.init();
|
|
||||||
|
|
||||||
// speed is expressed in %
|
|
||||||
const R = this.wheelRadius; // cm
|
|
||||||
const L = this.baseLength; // cm
|
|
||||||
const PI = 3.14;
|
|
||||||
const maxw = 170 / 60 * 2 * PI; // rad / s
|
|
||||||
const maxv = maxw * R; // cm / s
|
|
||||||
// speed is cm / s
|
|
||||||
const v = speed; // cm / s
|
|
||||||
const w = rotationSpeed / 360 * 2 * PI; // rad / s
|
|
||||||
|
|
||||||
const vr = (2 * v + w * L) / (2 * R); // rad / s
|
|
||||||
const vl = (2 * v - w * L) / (2 * R); // rad / s
|
|
||||||
|
|
||||||
const sr = vr / maxw * 100; // %
|
|
||||||
const sl = vl / maxw * 100; // %
|
|
||||||
|
|
||||||
this.tank(sr, sl, value, unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns the motor and the follower motor by a number of rotations
|
* Turns the motor and the follower motor by a number of rotations
|
||||||
* @param turnRatio the ratio of power sent to the follower motor, from ``-200`` to ``200``, eg: 0
|
* @param turnRatio the ratio of power sent to the follower motor, from ``-200`` to ``200``, eg: 0
|
||||||
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
* @param speed the speed from ``100`` full forward to ``-100`` full backward, eg: 50
|
||||||
* @param value the move quantity, eg: 2
|
* @param value (optional) move duration or rotation
|
||||||
* @param unit the meaning of the value
|
* @param unit (optional) unit of the value
|
||||||
*/
|
*/
|
||||||
//% blockId=motorPairTurn block="steer %chassis turn by|%turnRatio|at speed %speed|%|for %value|%unit"
|
//% blockId=motorPairSteer block="steer %chassis|turn ratio %turnRatio=motorTurnRatioPicker|speed %speed=motorSpeedPicker|%"
|
||||||
//% weight=6 blockGap=8
|
//% weight=95
|
||||||
//% turnRatio.min=-200 turnRatio=200
|
//% turnRatio.min=-200 turnRatio=200
|
||||||
//% inlineInputMode=inline
|
//% inlineInputMode=inline
|
||||||
//% group="Chassis"
|
//% group="Move"
|
||||||
steer(turnRatio: number, speed: number, value: number, unit: MoveUnit) {
|
steer(turnRatio: number, speed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
||||||
this.init();
|
this.init();
|
||||||
speed = Math.clamp(-100, 100, speed >> 0);
|
speed = Math.clamp(-100, 100, speed >> 0);
|
||||||
if (!speed) {
|
if (!speed) {
|
||||||
@ -556,6 +527,10 @@ namespace motors {
|
|||||||
stepsOrTime = value >> 0;
|
stepsOrTime = value >> 0;
|
||||||
useSteps = true;
|
useSteps = true;
|
||||||
break;
|
break;
|
||||||
|
case MoveUnit.Seconds:
|
||||||
|
stepsOrTime = (value * 1000) >> 0;
|
||||||
|
useSteps = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
stepsOrTime = value >> 0;
|
stepsOrTime = value >> 0;
|
||||||
useSteps = false;
|
useSteps = false;
|
||||||
@ -569,17 +544,6 @@ namespace motors {
|
|||||||
stepsOrTime: stepsOrTime,
|
stepsOrTime: stepsOrTime,
|
||||||
useBrake: this._brake
|
useBrake: this._brake
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the wheels radius and base length of a directional drive robot
|
|
||||||
* @param wheelRadius
|
|
||||||
* @param baseLength
|
|
||||||
*/
|
|
||||||
//% group="Chassis"
|
|
||||||
setDimensions(wheelRadius: number, baseLength: number): void {
|
|
||||||
this.wheelRadius = wheelRadius;
|
|
||||||
this.baseLength = baseLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,11 +11,13 @@
|
|||||||
"mmap.cpp",
|
"mmap.cpp",
|
||||||
"control.cpp",
|
"control.cpp",
|
||||||
"console.ts",
|
"console.ts",
|
||||||
|
"timer.ts",
|
||||||
"serialnumber.cpp",
|
"serialnumber.cpp",
|
||||||
"buttons.ts",
|
"buttons.ts",
|
||||||
"png.cpp",
|
"png.cpp",
|
||||||
"screen.cpp",
|
"screen.cpp",
|
||||||
"screen.ts",
|
"screen.ts",
|
||||||
|
"battery.ts",
|
||||||
"output.cpp",
|
"output.cpp",
|
||||||
"output.ts",
|
"output.ts",
|
||||||
"core.ts",
|
"core.ts",
|
||||||
|
@ -58,29 +58,7 @@ namespace brick {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function microbitFont() {
|
function setPixel(on: boolean, x: number, y: number) {
|
||||||
return {
|
|
||||||
charWidth: 6,
|
|
||||||
charHeight: 5,
|
|
||||||
firstChar: 32,
|
|
||||||
// source https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFont.cpp
|
|
||||||
data: hex`
|
|
||||||
0000000000 0202020002 0a0a000000 0a1f0a1f0a 0e130e190e 1309041219 0609060916 0202000000 0402020204
|
|
||||||
0204040402 000a040a00 00040e0400 0000000402 00000e0000 0000000200 1008040201 0609090906 040604040e
|
|
||||||
070806010f 0f08040906 0c0a091f08 1f010f100f 08040e110e 1f08040201 0e110e110e 0e110e0402 0002000200
|
|
||||||
0004000402 0804020408 000e000e00 0204080402 0e110c0004 0e11151906 06090f0909 0709070907 0e0101010e
|
|
||||||
0709090907 0f0107010f 0f01070101 0e0119110e 09090f0909 0702020207 1f08080906 0905030509 010101010f
|
|
||||||
111b151111 1113151911 0609090906 0709070101 060909060c 0709070911 0e01060807 1f04040404 0909090906
|
|
||||||
1111110a04 1111151b11 0909060909 110a040404 0f0402010f 0e0202020e 0102040810 0e0808080e 040a000000
|
|
||||||
000000001f 0204000000 000e09091e 0101070907 000e01010e 08080e090e 060907010e 0c02070202 0e090e0806
|
|
||||||
0101070909 0200020202 0800080806 0105030509 020202020c 001b151111 0007090909 0006090906 0007090701
|
|
||||||
000e090e08 000e010101 000c020403 02020e021c 000909091e 0011110a04 001111151b 0009060609 00110a0403
|
|
||||||
000f04020f 0c0406040c 0202020202 0302060203 0000061800
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setPixel(on: boolean, x: number, y: number) {
|
|
||||||
x |= 0
|
x |= 0
|
||||||
y |= 0
|
y |= 0
|
||||||
if (0 <= x && x < DAL.LCD_WIDTH && 0 <= y && y < DAL.LCD_HEIGHT)
|
if (0 <= x && x < DAL.LCD_WIDTH && 0 <= y && y < DAL.LCD_HEIGHT)
|
||||||
@ -90,18 +68,43 @@ namespace brick {
|
|||||||
/**
|
/**
|
||||||
* Show text on the screen at a specific line.
|
* Show text on the screen at a specific line.
|
||||||
* @param text the text to print on the screen, eg: "Hello world"
|
* @param text the text to print on the screen, eg: "Hello world"
|
||||||
* @param line the line number to print the text at, eg: 0
|
* @param line the line number to print the text at, eg: 1
|
||||||
*/
|
*/
|
||||||
//% blockId=screen_print block="print %text| at line %line"
|
//% blockId=screen_print block="show string %text|at line %line"
|
||||||
//% weight=98 group="Screen" inlineInputMode="inline" blockGap=8
|
//% weight=98 group="Screen" inlineInputMode="inline" blockGap=8
|
||||||
//% line.min=0 line.max=9
|
//% line.min=1 line.max=10
|
||||||
export function printLine(text: string, line: number) {
|
export function showString(text: string, line: number) {
|
||||||
const NUM_LINES = 9;
|
const NUM_LINES = 9;
|
||||||
const offset = 5;
|
const offset = 5;
|
||||||
const y = offset + (Math.clamp(0, NUM_LINES, line) / (NUM_LINES + 2)) * DAL.LCD_HEIGHT;
|
const y = offset + (Math.clamp(0, NUM_LINES, line - 1) / (NUM_LINES + 2)) * DAL.LCD_HEIGHT;
|
||||||
brick.print(text, offset, y);
|
brick.print(text, offset, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a number on the screen
|
||||||
|
* @param value the numeric value
|
||||||
|
* @param line the line number to print the text at, eg: 1
|
||||||
|
*/
|
||||||
|
//% blockId=screenShowNumber block="show number %name|at line %line"
|
||||||
|
//% weight=96 group="Screen" inlineInputMode="inline" blockGap=8
|
||||||
|
//% line.min=1 line.max=10
|
||||||
|
export function showNumber(value: number, line: number) {
|
||||||
|
showString("" + value, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a name, value pair on the screen
|
||||||
|
* @param value the numeric value
|
||||||
|
* @param line the line number to print the text at, eg: 1
|
||||||
|
*/
|
||||||
|
//% blockId=screenShowValue block="show value %name|= %text|at line %line"
|
||||||
|
//% weight=96 group="Screen" inlineInputMode="inline" blockGap=8
|
||||||
|
//% line.min=1 line.max=10
|
||||||
|
export function showValue(name: string, value: number, line: number) {
|
||||||
|
value = Math.round(value * 1000) / 1000;
|
||||||
|
showString((name ? name + ": " : "") + value, line);
|
||||||
|
}
|
||||||
|
|
||||||
export function print(text: string, x: number, y: number, mode = Draw.Normal) {
|
export function print(text: string, x: number, y: number, mode = Draw.Normal) {
|
||||||
x |= 0
|
x |= 0
|
||||||
y |= 0
|
y |= 0
|
||||||
@ -138,12 +141,9 @@ namespace brick {
|
|||||||
*/
|
*/
|
||||||
//% blockId=screen_show_image block="show image %image=screen_image_picker"
|
//% blockId=screen_show_image block="show image %image=screen_image_picker"
|
||||||
//% weight=100 group="Screen" blockGap=8
|
//% weight=100 group="Screen" blockGap=8
|
||||||
export function showImage(image: Image, delay: number = 400) {
|
export function showImage(image: Image) {
|
||||||
if (!image) return;
|
if (!image) return;
|
||||||
image.draw(0, 0, Draw.Normal);
|
image.draw(0, 0, Draw.Normal);
|
||||||
delay = Math.max(0, delay);
|
|
||||||
if (delay > 0)
|
|
||||||
loops.pause(delay);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,7 +168,7 @@ namespace brick {
|
|||||||
screen.clear();
|
screen.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function drawRect(x: number, y: number, w: number, h: number, mode = Draw.Normal) {
|
function drawRect(x: number, y: number, w: number, h: number, mode = Draw.Normal) {
|
||||||
x |= 0;
|
x |= 0;
|
||||||
y |= 0;
|
y |= 0;
|
||||||
w |= 0;
|
w |= 0;
|
||||||
@ -213,30 +213,32 @@ namespace brick {
|
|||||||
//% blockId=brickPrintPorts block="print ports"
|
//% blockId=brickPrintPorts block="print ports"
|
||||||
//% weight=1 group="Screen"
|
//% weight=1 group="Screen"
|
||||||
export function printPorts() {
|
export function printPorts() {
|
||||||
|
const col = 44;
|
||||||
clearScreen();
|
clearScreen();
|
||||||
|
|
||||||
|
function scale(x: number) {
|
||||||
|
if (Math.abs(x) > 1000) return Math.round(x / 100) / 10 + "k";
|
||||||
|
return ("" + (x >> 0));
|
||||||
|
}
|
||||||
|
|
||||||
// motors
|
// motors
|
||||||
const datas = motors.getAllMotorData();
|
const datas = motors.getAllMotorData();
|
||||||
for(let i = 0; i < datas.length; ++i) {
|
for(let i = 0; i < datas.length; ++i) {
|
||||||
const data = datas[i];
|
const data = datas[i];
|
||||||
if (!data.actualSpeed && !data.count) continue;
|
if (!data.actualSpeed && !data.count) continue;
|
||||||
const x = i * 52;
|
const x = i * col;
|
||||||
print(`${data.actualSpeed}%`, x, brick.LINE_HEIGHT)
|
print(`${scale(data.actualSpeed)}%`, x, brick.LINE_HEIGHT)
|
||||||
print(`${data.count}>`, x, 2 * brick.LINE_HEIGHT)
|
print(`${scale(data.count)}>`, x, 2 * brick.LINE_HEIGHT)
|
||||||
|
print(`${scale(data.tachoCount)}|`, x, 3 * brick.LINE_HEIGHT)
|
||||||
console.logValue(`speed.` + "ABCD"[i], data.actualSpeed);
|
|
||||||
console.logValue(`angle.` + "ABCD"[i], data.count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// sensors
|
// sensors
|
||||||
const sis = sensors.internal.getActiveSensors();
|
const sis = sensors.internal.getActiveSensors();
|
||||||
for(let i =0; i < sis.length; ++i) {
|
for(let i =0; i < sis.length; ++i) {
|
||||||
const si = sis[i];
|
const si = sis[i];
|
||||||
const x = (si.port() - 1) * 52;
|
const x = (si.port() - 1) * col;
|
||||||
const v = si._query();
|
const v = si._query();
|
||||||
print(`${v}`, x, 9 * brick.LINE_HEIGHT)
|
print(`${scale(v)}`, x, 9 * brick.LINE_HEIGHT)
|
||||||
|
|
||||||
console.logValue(`sensor.` + si.port(), v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
4
libs/core/shims.d.ts
vendored
4
libs/core/shims.d.ts
vendored
@ -41,6 +41,10 @@ declare interface MMap {
|
|||||||
/** Perform read(2) on the underlaying file */
|
/** Perform read(2) on the underlaying file */
|
||||||
//% shim=MMapMethods::read
|
//% shim=MMapMethods::read
|
||||||
read(data: Buffer): int32;
|
read(data: Buffer): int32;
|
||||||
|
|
||||||
|
/** Set pointer on the underlaying file. */
|
||||||
|
//% shim=MMapMethods::lseek
|
||||||
|
lseek(offset: int32, whence: SeekWhence): int32;
|
||||||
}
|
}
|
||||||
declare namespace control {
|
declare namespace control {
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ screen.clear()
|
|||||||
brick.print("PXT!", 10, 30, Draw.Quad)
|
brick.print("PXT!", 10, 30, Draw.Quad)
|
||||||
|
|
||||||
brick.drawRect(40, 40, 20, 10, Draw.Fill)
|
brick.drawRect(40, 40, 20, 10, Draw.Fill)
|
||||||
brick.setLight(LightsPattern.Orange)
|
brick.setLight(BrickLight.Orange)
|
||||||
|
|
||||||
brick.heart.doubled().draw(100, 50, Draw.Double | Draw.Transparent)
|
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.buttonLeft.onEvent(ButtonEvent.Click, () => {
|
||||||
brick.drawRect(10, 70, 20, 10, Draw.Fill)
|
brick.drawRect(10, 70, 20, 10, Draw.Fill)
|
||||||
brick.setLight(LightsPattern.Red)
|
brick.setLight(BrickLight.Red)
|
||||||
brick.setFont(brick.microbitFont())
|
brick.setFont(brick.microbitFont())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
64
libs/core/timer.ts
Normal file
64
libs/core/timer.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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();
|
||||||
|
}
|
3
libs/datalog/README.md
Normal file
3
libs/datalog/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Datalog
|
||||||
|
|
||||||
|
A tiny libraty to create CSV datalog files.
|
11
libs/datalog/_locales/datalog-jsdoc-strings.json
Normal file
11
libs/datalog/_locales/datalog-jsdoc-strings.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
7
libs/datalog/_locales/datalog-strings.json
Normal file
7
libs/datalog/_locales/datalog-strings.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
122
libs/datalog/datalog.ts
Normal file
122
libs/datalog/datalog.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//% 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;
|
||||||
|
}
|
||||||
|
}
|
16
libs/datalog/pxt.json
Normal file
16
libs/datalog/pxt.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "datalog",
|
||||||
|
"description": "Tiny data logging framework",
|
||||||
|
"files": [
|
||||||
|
"README.md",
|
||||||
|
"datalog.ts"
|
||||||
|
],
|
||||||
|
"testFiles": [
|
||||||
|
"test.ts"
|
||||||
|
],
|
||||||
|
"public": true,
|
||||||
|
"dependencies": {
|
||||||
|
"core": "file:../core",
|
||||||
|
"storage": "file:../storage"
|
||||||
|
}
|
||||||
|
}
|
6
libs/datalog/test.ts
Normal file
6
libs/datalog/test.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
loops.forever(function () {
|
||||||
|
datalog.addRow()
|
||||||
|
datalog.addValue("x", Math.random())
|
||||||
|
datalog.addValue("y", Math.random())
|
||||||
|
})
|
@ -8,17 +8,22 @@ namespace brick {
|
|||||||
|
|
||||||
//% color="#C8509B" weight=95 icon="\uf10f"
|
//% color="#C8509B" weight=95 icon="\uf10f"
|
||||||
//% labelLineWidth=0
|
//% labelLineWidth=0
|
||||||
//% groups='["Ultrasonic Sensor", "Touch Sensor", "Color Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Gyro Sensor"]'
|
//% groups='["Touch Sensor", "Color Sensor", "Ultrasonic Sensor", "Gyro Sensor", "Infrared Sensor", "Remote Infrared Beacon", "Threshold"]'
|
||||||
//% groupIcons='["\uf101","\uf103","\uf102","","","\uf104"]'
|
//% groupIcons='["\uf101","\uf103","\uf102","","","\uf104"]'
|
||||||
namespace sensors {
|
namespace sensors {
|
||||||
}
|
}
|
||||||
|
|
||||||
//% color="#A5CA18" weight=90 icon="\uf10d"
|
//% color="#A5CA18" weight=90 icon="\uf10d"
|
||||||
//% groups='["Motion", "Sensors", "Chassis"]'
|
//% groups='["Move", "Counters"]'
|
||||||
//% labelLineWidth=0
|
//% labelLineWidth=0
|
||||||
namespace motors {
|
namespace motors {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//% labelLineWidth=0
|
||||||
|
namespace chassis {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//% labelLineWidth=0
|
//% labelLineWidth=0
|
||||||
namespace behaviors {
|
namespace behaviors {
|
||||||
}
|
}
|
||||||
@ -51,4 +56,9 @@ namespace loops {
|
|||||||
//% color="#1E5AA8"
|
//% color="#1E5AA8"
|
||||||
namespace light {
|
namespace light {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//% color="#b0b0b0" advanced=true weight=5
|
||||||
|
namespace storage {
|
||||||
|
|
||||||
}
|
}
|
@ -13,7 +13,8 @@
|
|||||||
"color-sensor": "file:../color-sensor",
|
"color-sensor": "file:../color-sensor",
|
||||||
"touch-sensor": "file:../touch-sensor",
|
"touch-sensor": "file:../touch-sensor",
|
||||||
"ultrasonic-sensor": "file:../ultrasonic-sensor",
|
"ultrasonic-sensor": "file:../ultrasonic-sensor",
|
||||||
"gyro-sensor": "file:../gyro-sensor"
|
"gyro-sensor": "file:../gyro-sensor",
|
||||||
|
"mood": "file:../mood"
|
||||||
},
|
},
|
||||||
"public": true
|
"public": true
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"sensors.GyroSensor.angle": "Get the current angle from the gyroscope.",
|
"sensors.GyroSensor.angle": "Get the current angle from the gyroscope.",
|
||||||
"sensors.GyroSensor.rate": "Get the current rotation rate 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"
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"sensors.GyroSensor.angle|block": "%sensor|angle",
|
"sensors.GyroSensor.angle|block": "%sensor|angle",
|
||||||
"sensors.GyroSensor.rate|block": "%sensor|rotation rate",
|
"sensors.GyroSensor.rate|block": "%sensor|rate",
|
||||||
|
"sensors.GyroSensor.reset|block": "%sensor|reset",
|
||||||
"sensors.gyro1|block": "gyro 1",
|
"sensors.gyro1|block": "gyro 1",
|
||||||
"sensors.gyro2|block": "gyro 2",
|
"sensors.gyro2|block": "gyro 2",
|
||||||
"sensors.gyro3|block": "gyro 3",
|
"sensors.gyro3|block": "gyro 3",
|
||||||
|
@ -7,15 +7,28 @@ const enum GyroSensorMode {
|
|||||||
namespace sensors {
|
namespace sensors {
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class GyroSensor extends internal.UartSensor {
|
export class GyroSensor extends internal.UartSensor {
|
||||||
|
private calibrating: boolean;
|
||||||
|
private _drift: number;
|
||||||
|
private _drifting: boolean;
|
||||||
constructor(port: number) {
|
constructor(port: number) {
|
||||||
super(port)
|
super(port)
|
||||||
|
this.calibrating = false;
|
||||||
|
this._drift = 0;
|
||||||
|
this._drifting = true;
|
||||||
|
this.setMode(GyroSensorMode.Rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
_deviceType() {
|
_deviceType() {
|
||||||
return DAL.DEVICE_TYPE_GYRO
|
return DAL.DEVICE_TYPE_GYRO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_query(): number {
|
||||||
|
return this.getNumber(NumberFormat.Int16LE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
setMode(m: GyroSensorMode) {
|
setMode(m: GyroSensorMode) {
|
||||||
|
if (m == GyroSensorMode.Rate && this.mode != m)
|
||||||
|
this._drift = 0;
|
||||||
this._setMode(m)
|
this._setMode(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,11 +42,14 @@ namespace sensors {
|
|||||||
//% parts="gyroscope"
|
//% parts="gyroscope"
|
||||||
//% blockNamespace=sensors
|
//% blockNamespace=sensors
|
||||||
//% sensor.fieldEditor="ports"
|
//% sensor.fieldEditor="ports"
|
||||||
//% weight=65 blockGap=8
|
//% weight=64 blockGap=8
|
||||||
//% group="Gyro Sensor"
|
//% group="Gyro Sensor"
|
||||||
angle(): number {
|
angle(): number {
|
||||||
this.setMode(GyroSensorMode.Angle)
|
if (this.calibrating)
|
||||||
return this.getNumber(NumberFormat.Int16LE, 0)
|
pauseUntil(() => !this.calibrating, 2000);
|
||||||
|
|
||||||
|
this.setMode(GyroSensorMode.Angle);
|
||||||
|
return this._query();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +57,7 @@ namespace sensors {
|
|||||||
* @param sensor the gyroscope to query the request
|
* @param sensor the gyroscope to query the request
|
||||||
*/
|
*/
|
||||||
//% help=input/gyro/rate
|
//% help=input/gyro/rate
|
||||||
//% block="%sensor|rotation rate"
|
//% block="%sensor|rate"
|
||||||
//% blockId=gyroGetRate
|
//% blockId=gyroGetRate
|
||||||
//% parts="gyroscope"
|
//% parts="gyroscope"
|
||||||
//% blockNamespace=sensors
|
//% blockNamespace=sensors
|
||||||
@ -49,17 +65,82 @@ namespace sensors {
|
|||||||
//% weight=65 blockGap=8
|
//% weight=65 blockGap=8
|
||||||
//% group="Gyro Sensor"
|
//% group="Gyro Sensor"
|
||||||
rate(): number {
|
rate(): number {
|
||||||
this.setMode(GyroSensorMode.Rate)
|
if (this.calibrating)
|
||||||
return this.getNumber(NumberFormat.Int16LE, 0)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces a calibration of the gyro. Must be called when the sensor is completely still.
|
||||||
|
*/
|
||||||
|
//% help=input/gyro/calibrate
|
||||||
|
//% block="%sensor|reset"
|
||||||
|
//% blockId=gyroReset
|
||||||
|
//% parts="gyroscope"
|
||||||
|
//% blockNamespace=sensors
|
||||||
|
//% sensor.fieldEditor="ports"
|
||||||
|
//% weight=50 blockGap=8
|
||||||
|
//% group="Gyro Sensor"
|
||||||
|
reset(): 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);
|
||||||
|
// 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.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 1" jres=icons.port1
|
|
||||||
export const gyro1: GyroSensor = new GyroSensor(1)
|
|
||||||
|
|
||||||
//% fixedInstance whenUsed block="gyro 2" weight=95 jres=icons.port2
|
//% fixedInstance whenUsed block="gyro 2" weight=95 jres=icons.port2
|
||||||
export const gyro2: GyroSensor = new GyroSensor(2)
|
export const gyro2: GyroSensor = new GyroSensor(2)
|
||||||
|
|
||||||
|
//% fixedInstance whenUsed block="gyro 1" jres=icons.port1
|
||||||
|
export const gyro1: GyroSensor = new GyroSensor(1)
|
||||||
|
|
||||||
//% fixedInstance whenUsed block="gyro 3" jres=icons.port3
|
//% fixedInstance whenUsed block="gyro 3" jres=icons.port3
|
||||||
export const gyro3: GyroSensor = new GyroSensor(3)
|
export const gyro3: GyroSensor = new GyroSensor(3)
|
||||||
|
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
"sensors.InfraredSensor.pauseUntil": "Waits for the event to occur",
|
"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.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.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.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": "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",
|
"sensors.RemoteInfraredBeaconButton.onEvent|param|body": "code to run when the event is raised",
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"sensors.InfraredSensor.pauseUntil|block": "pause until %sensor| %event",
|
"sensors.InfraredSensor.pauseUntil|block": "pause until %sensor| %event",
|
||||||
"sensors.InfraredSensor.proximity|block": "%sensor|proximity",
|
"sensors.InfraredSensor.proximity|block": "%sensor|proximity",
|
||||||
"sensors.InfraredSensor.remoteCommand|block": "%sensor|remote command",
|
"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.isPressed|block": "%button|is pressed",
|
||||||
"sensors.RemoteInfraredBeaconButton.onEvent|block": "on %button|%event",
|
"sensors.RemoteInfraredBeaconButton.onEvent|block": "on %button|%event",
|
||||||
"sensors.RemoteInfraredBeaconButton.wasPressed|block": "%button|was pressed",
|
"sensors.RemoteInfraredBeaconButton.wasPressed|block": "%button|was pressed",
|
||||||
@ -20,5 +21,6 @@
|
|||||||
"sensors|block": "sensors",
|
"sensors|block": "sensors",
|
||||||
"{id:category}Sensors": "Sensors",
|
"{id:category}Sensors": "Sensors",
|
||||||
"{id:group}Infrared Sensor": "Infrared Sensor",
|
"{id:group}Infrared Sensor": "Infrared Sensor",
|
||||||
"{id:group}Remote Infrared Beacon": "Remote Infrared Beacon"
|
"{id:group}Remote Infrared Beacon": "Remote Infrared Beacon",
|
||||||
|
"{id:group}Threshold": "Threshold"
|
||||||
}
|
}
|
@ -250,6 +250,22 @@ namespace sensors {
|
|||||||
this._setMode(IrSensorMode.Seek)
|
this._setMode(IrSensorMode.Seek)
|
||||||
return this.getNumber(NumberFormat.UInt16LE, this.channel * 2)
|
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
|
//% fixedInstance whenUsed block="infrared 1" jres=icons.port1
|
||||||
|
3
libs/mood/README.md
Normal file
3
libs/mood/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# mood
|
||||||
|
|
||||||
|
A package to put the EV3 in various moods.
|
17
libs/mood/_locales/mood-jsdoc-strings.json
Normal file
17
libs/mood/_locales/mood-jsdoc-strings.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
8
libs/mood/_locales/mood-strings.json
Normal file
8
libs/mood/_locales/mood-strings.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
125
libs/mood/mood.ts
Normal file
125
libs/mood/mood.ts
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
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);
|
||||||
|
}
|
15
libs/mood/pxt.json
Normal file
15
libs/mood/pxt.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "mood",
|
||||||
|
"description": "The EV3 mood library",
|
||||||
|
"files": [
|
||||||
|
"README.md",
|
||||||
|
"mood.ts"
|
||||||
|
],
|
||||||
|
"testFiles": [
|
||||||
|
],
|
||||||
|
"public": true,
|
||||||
|
"dependencies": {
|
||||||
|
"core": "file:../core",
|
||||||
|
"music": "file:../music"
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,7 @@
|
|||||||
"music.setTempo": "Set the tempo a number of beats per minute (bpm).",
|
"music.setTempo": "Set the tempo a number of beats per minute (bpm).",
|
||||||
"music.setTempo|param|bpm": "The new tempo in beats per minute, eg: 120",
|
"music.setTempo|param|bpm": "The new tempo in beats per minute, eg: 120",
|
||||||
"music.setVolume": "Set the output volume of the sound synthesizer.",
|
"music.setVolume": "Set the output volume of the sound synthesizer.",
|
||||||
"music.setVolume|param|volume": "the volume 0...256, eg: 128",
|
"music.setVolume|param|volume": "the volume 0...100, eg: 50",
|
||||||
"music.stopAllSounds": "Play a tone through the speaker for some amount of time.",
|
"music.stopAllSounds": "Play a tone through the speaker for some amount of time.",
|
||||||
"music.tempo": "Return the tempo in beats per minute (bpm).\nTempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play."
|
"music.tempo": "Return the tempo in beats per minute (bpm).\nTempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play."
|
||||||
}
|
}
|
@ -33,34 +33,34 @@
|
|||||||
"music.stopAllSounds|block": "stop all sounds",
|
"music.stopAllSounds|block": "stop all sounds",
|
||||||
"music.tempo|block": "tempo (bpm)",
|
"music.tempo|block": "tempo (bpm)",
|
||||||
"music|block": "music",
|
"music|block": "music",
|
||||||
"sounds.animalsCatPurr|block": "Animals cat purr",
|
"sounds.animalsCatPurr|block": "animals cat purr",
|
||||||
"sounds.animalsDogBark1|block": "Animals dog bark 1",
|
"sounds.animalsDogBark1|block": "animals dog bark 1",
|
||||||
"sounds.animalsDogBark2|block": "Animals dog bark 2",
|
"sounds.animalsDogBark2|block": "animals dog bark 2",
|
||||||
"sounds.animalsDogGrowl|block": "Animals dog growl",
|
"sounds.animalsDogGrowl|block": "animals dog growl",
|
||||||
"sounds.animalsDogSniff|block": "Animals dog sniff",
|
"sounds.animalsDogSniff|block": "animals dog sniff",
|
||||||
"sounds.animalsDogWhine|block": "Animals dog whine",
|
"sounds.animalsDogWhine|block": "animals dog whine",
|
||||||
"sounds.animalsElephantCall|block": "Animals elephant call",
|
"sounds.animalsElephantCall|block": "animals elephant call",
|
||||||
"sounds.animalsInsectBuzz1|block": "Animals insect buzz1",
|
"sounds.animalsInsectBuzz1|block": "animals insect buzz1",
|
||||||
"sounds.animalsInsectBuzz2|block": "Animals insect buzz2",
|
"sounds.animalsInsectBuzz2|block": "animals insect buzz2",
|
||||||
"sounds.animalsInsectChirp|block": "Animals insect chirp",
|
"sounds.animalsInsectChirp|block": "animals insect chirp",
|
||||||
"sounds.animalsSnakeHiss|block": "Animals snake hiss",
|
"sounds.animalsSnakeHiss|block": "animals snake hiss",
|
||||||
"sounds.animalsSnakeRattle|block": "Animals snake rattle",
|
"sounds.animalsSnakeRattle|block": "animals snake rattle",
|
||||||
"sounds.animalsTRexRoar|block": "Animals trex roar",
|
"sounds.animalsTRexRoar|block": "animals trex roar",
|
||||||
"sounds.colorsBlack|block": "Colors black",
|
"sounds.colorsBlack|block": "colors black",
|
||||||
"sounds.colorsBlue|block": "Colors blue",
|
"sounds.colorsBlue|block": "colors blue",
|
||||||
"sounds.colorsBrown|block": "Colors brown",
|
"sounds.colorsBrown|block": "colors brown",
|
||||||
"sounds.colorsGreen|block": "Colors green",
|
"sounds.colorsGreen|block": "colors green",
|
||||||
"sounds.colorsRed|block": "Colors red",
|
"sounds.colorsRed|block": "colors red",
|
||||||
"sounds.colorsWhite|block": "Colors white",
|
"sounds.colorsWhite|block": "colors white",
|
||||||
"sounds.colorsYellow|block": "Colors yellow",
|
"sounds.colorsYellow|block": "colors yellow",
|
||||||
"sounds.communicationBravo|block": "Communication bravo",
|
"sounds.communicationBravo|block": "communication bravo",
|
||||||
"sounds.communicationEv3|block": "Communication ev3",
|
"sounds.communicationEv3|block": "communication ev3",
|
||||||
"sounds.communicationFantastic|block": "Communication fantastic",
|
"sounds.communicationFantastic|block": "communication fantastic",
|
||||||
"sounds.communicationGameOver|block": "Communication game over",
|
"sounds.communicationGameOver|block": "communication game over",
|
||||||
"sounds.communicationGoodJob|block": "communicationGoodJob",
|
"sounds.communicationGoodJob|block": "communicationGoodJob",
|
||||||
"sounds.communicationGoodbye|block": "communication goodbye",
|
"sounds.communicationGoodbye|block": "communication goodbye",
|
||||||
"sounds.communicationGood|block": "communication good",
|
"sounds.communicationGood|block": "communication good",
|
||||||
"sounds.communicationGo|block": "Communication go",
|
"sounds.communicationGo|block": "communication go",
|
||||||
"sounds.communicationHello|block": "communication hello",
|
"sounds.communicationHello|block": "communication hello",
|
||||||
"sounds.communicationHi|block": "communication hi",
|
"sounds.communicationHi|block": "communication hi",
|
||||||
"sounds.communicationLego|block": "communication lego",
|
"sounds.communicationLego|block": "communication lego",
|
||||||
@ -121,7 +121,7 @@
|
|||||||
"sounds.mechanicalMotorStart|block": "mechanical motor start",
|
"sounds.mechanicalMotorStart|block": "mechanical motor start",
|
||||||
"sounds.mechanicalMotorStop|block": "mechanical motor stop",
|
"sounds.mechanicalMotorStop|block": "mechanical motor stop",
|
||||||
"sounds.mechanicalRatchet|block": "mechanical ratchet",
|
"sounds.mechanicalRatchet|block": "mechanical ratchet",
|
||||||
"sounds.mechanicalSonar|block": "\"mechanical sonar\"",
|
"sounds.mechanicalSonar|block": "mechanical sonar",
|
||||||
"sounds.mechanicalTickTack|block": "mechanical tick tack",
|
"sounds.mechanicalTickTack|block": "mechanical tick tack",
|
||||||
"sounds.mechanicalWalk|block": "mechanical walk",
|
"sounds.mechanicalWalk|block": "mechanical walk",
|
||||||
"sounds.movementsArm1|block": "movements arm1",
|
"sounds.movementsArm1|block": "movements arm1",
|
||||||
@ -159,7 +159,7 @@
|
|||||||
"sounds.systemOverpower|block": "system overpower",
|
"sounds.systemOverpower|block": "system overpower",
|
||||||
"sounds.systemPowerDown|block": "system power down",
|
"sounds.systemPowerDown|block": "system power down",
|
||||||
"sounds.systemReady|block": "system ready",
|
"sounds.systemReady|block": "system ready",
|
||||||
"sounds.systemStartUp|block": "S",
|
"sounds.systemStartUp|block": "system start up",
|
||||||
"{id:category}Music": "Music",
|
"{id:category}Music": "Music",
|
||||||
"{id:category}Sound": "Sound",
|
"{id:category}Sound": "Sound",
|
||||||
"{id:category}Sounds": "Sounds"
|
"{id:category}Sounds": "Sounds"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
namespace music {
|
namespace music {
|
||||||
|
|
||||||
uint8_t currVolume = 2;
|
uint8_t currVolume = 50;
|
||||||
uint8_t *lmsSoundMMap;
|
uint8_t *lmsSoundMMap;
|
||||||
|
|
||||||
int writeDev(void *data, int size) {
|
int writeDev(void *data, int size) {
|
||||||
@ -25,16 +25,16 @@ int writeDev(void *data, int size) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the output volume of the sound synthesizer.
|
* Set the output volume of the sound synthesizer.
|
||||||
* @param volume the volume 0...256, eg: 128
|
* @param volume the volume 0...100, eg: 50
|
||||||
*/
|
*/
|
||||||
//% weight=96
|
//% weight=96
|
||||||
//% blockId=synth_set_volume block="set volume %volume"
|
//% blockId=synth_set_volume block="set volume %volume"
|
||||||
//% parts="speaker" blockGap=8
|
//% parts="speaker" blockGap=8
|
||||||
//% volume.min=0 volume.max=256
|
//% volume.min=0 volume.max=100
|
||||||
//% help=music/set-volume
|
//% help=music/set-volume
|
||||||
//% weight=1
|
//% weight=1
|
||||||
void setVolume(int volume) {
|
void setVolume(int volume) {
|
||||||
currVolume = max(0, min(100, volume * 100 / 256));
|
currVolume = max(0, min(100, volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOUND_CMD_BREAK 0
|
#define SOUND_CMD_BREAK 0
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user