Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
6c253182e4 | |||
0198be6dda | |||
57ab6d153d | |||
fd0bd4ef39 | |||
8b2ae10980 | |||
4627328bcd | |||
80989cf4c9 | |||
00b193b126 | |||
e65db0b756 | |||
8f211a5c19 | |||
379a6a26be | |||
8398c8efdb | |||
f41310e879 |
@ -1,5 +1,11 @@
|
||||
# @extends
|
||||
|
||||
## Support #support
|
||||
|
||||
* [Troubleshoot](/troubleshoot)
|
||||
* [LEGO Support](http://service.lego.com/)
|
||||
* [EV3 Manager](https://ev3manager.education.lego.com/)
|
||||
|
||||
## Projects #projects
|
||||
|
||||
* [Getting Started](/getting-started)
|
||||
@ -16,8 +22,9 @@
|
||||
* [Touch Sensor Values](/tutorials/touch-sensor-values)
|
||||
* [What Color?](/tutorials/what-color)
|
||||
* [Line Following](/tutorials/line-following)
|
||||
* [Green Light, Red Light](/tutorials/greenlight-redlight)
|
||||
* [Red Light, Green Light](/tutorials/redlight-greenlight)
|
||||
* [Object Near?](/tutorials/object-near)
|
||||
* [Intruder Alert](/tutorials/intruder-alert)
|
||||
|
||||
* [Coding](/coding)
|
||||
* [Autonomous Parking](/coding/autonomous-parking)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Lessons
|
||||
|
||||
Learning activities for LEGO Mindstorms with MakeCode.
|
||||
Learning activities for @boardname@ with MakeCode.
|
||||
|
||||
## Motors and motion
|
||||
|
||||
|
@ -10,7 +10,7 @@ Your robot will:
|
||||
* Use at least one motor
|
||||
* Use NO wheels for locomotion
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## Construct @unplugged
|
||||
@ -25,7 +25,7 @@ The legs in the Walker Bot are designed to show how to change the rotary motion
|
||||
|
||||
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## Program 1 @fullscreen
|
||||
|
@ -10,7 +10,7 @@ Your robot will:
|
||||
* Use at least one motor
|
||||
* Use NO wheels for locomotion
|
||||
|
||||

|
||||

|
||||
|
||||
## Construct
|
||||
|
||||
@ -24,7 +24,7 @@ The legs in the Walker Bot are designed to show how to change the rotary motion
|
||||
|
||||
Start by reading [these](https://le-www-live-s.legocdn.com/sc/media/lessons/mindstorms-ev3/ev3-dep/building%20instructions/walker-bot-bi-180fc24f9298e1dd6201099627d43903.pdf) instructions first.
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## Program
|
||||
|
BIN
docs/static/setup/ev3-drive-windows.png
vendored
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
docs/static/tutorials/intruder-alert.png
vendored
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
docs/static/tutorials/intruder-alert/detect-method-dropdown.png
vendored
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
docs/static/tutorials/intruder-alert/intruder-alert.gif
vendored
Normal file
After Width: | Height: | Size: 199 KiB |
BIN
docs/static/tutorials/intruder-alert/play-sound-effect-dropdown.png
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
docs/static/tutorials/intruder-alert/set-status-light-dropdown.png
vendored
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
docs/static/tutorials/intruder-alert/show-image-dropdown.png
vendored
Normal file
After Width: | Height: | Size: 35 KiB |
@ -0,0 +1,56 @@
|
||||
# Troubleshooting download problems
|
||||
|
||||
If your're having trouble getting your code onto the @boardname@, try these steps to see if you can fix the problem.
|
||||
|
||||
## Can I see the LEGO drive on my computer?
|
||||
|
||||
When your @boardname@ is connected to your computer, you should see a new drive called **@drivename@** attached.
|
||||
|
||||
On Windows, it looks like this in Explorer:
|
||||
|
||||

|
||||
|
||||
If you don't see the **@drivename@** drive, make sure your brick is powered on and check that your USB connection is good.
|
||||
|
||||
## Is my brick charged and powered on?
|
||||
|
||||
Make sure your brick is charged and powered on. If your brick doesn't turn on, find the charger and plug it into wall power, then connect it to your brick. Does it turn on and start up?
|
||||
|
||||
## Is my USB connection good?
|
||||
|
||||
Make sure that one end of your USB cable is firmly inserted into the port on the computer and the other end is connected to the brick. If you still can't see the **@drivename@** drive, try a different port on the computer. If that doesn't work then maybe your cable is bad or you need to reset the brick.
|
||||
|
||||
## How do I reset my brick?
|
||||
|
||||
If you think your USB connection is good and you still can't see your **@drivename@** drive, try giving the brick a reset. You can follow these steps to reset:
|
||||
|
||||
1. Using a finger from one hand, press the **Back** button. Keep holding it.
|
||||
2. With your other hand, use two fingers to hold down both the **Left** button and the **Enter** button. You hold these at the same time while your still pressing the **Back** button.
|
||||
3. Now, release your finger from the **Back** button.
|
||||
4. When the brick says "Starting..." you can let go of the **Left** and **Enter** buttons.
|
||||
|
||||
You can also watch this [How to Reset](https://www.lego.com/en-us/videos/themes/mindstorms/how-to-reset-the-ev3-p-brick-fbcbdbed398e4e12a7ce30fa662c54be) video to see how to do a reset.
|
||||
|
||||
If you try a reset and the **@drivename@** drive still doesn't appear, or you attempted a download and it didn't copy to the brick, you might need a firmware update.
|
||||
|
||||
## What's a firmware update and how do I get one?
|
||||
|
||||
Firmware is the software that runs all the basic operations on your brick. Your programs run with the firmware to make the @boardname@ do all the things you want it to do. Your brick comes with the firmware already installed. You could have a brick with an older version of firmware that needs updating in order for it to work properly with MakeCode.
|
||||
|
||||
To update your firmware, follow these instructions: [Updating and Resetting Firmware](https://www.lego.com/en-us/service/help/products/themes-sets/mindstorms/updating-and-resetting-lego-mindstorms-ev3-firmware-408100000007884).
|
||||
|
||||
### ~hint
|
||||
|
||||
**Offline firmware update**
|
||||
|
||||
If your @boardname@ isn't connected to the internet through a computer, or with some other mobile device, you'll need to do a manual update of the firmware. You need to have the firmware file already downloaded and available on the computer connected to the brick.
|
||||
|
||||
To do this, read the instructions in the **Manual Firmware Update** section of the [Firmware Update](https://education.lego.com/en-us/support/mindstorms-ev3/firmware-update) support page.
|
||||
|
||||
### ~
|
||||
|
||||
## LEGO Support
|
||||
|
||||
If you've checked everything here and can't get the **@drivename@** drive to show up on your computer, you can't make the brick reset, or your program just won't download, then try the [Troubleshooting Walkthrough](https://www.lego.com/en-us/service/help/products/themes-sets/mindstorms/lego-mindstorms-ev3-troubleshooting-walkthrough-408100000009798).
|
||||
|
||||
You can also find more help at [LEGO Support](https://www.lego.com/en-us/mindstorms/support).
|
@ -7,13 +7,13 @@ Step by step guides to coding your @boardname@.
|
||||
```codecard
|
||||
[{
|
||||
"name": "Wake Up!",
|
||||
"description": "Show different moods on your @boardname@. Is it tired, sleepy, or awake?",
|
||||
"description": "Show different moods on the screen. Is it tired, sleepy, or awake?",
|
||||
"cardType": "tutorial",
|
||||
"url":"/tutorials/wake-up",
|
||||
"imageUrl":"/static/tutorials/wake-up.png"
|
||||
}, {
|
||||
"name": "Make An Animation",
|
||||
"description": "Create a custom animation for your @boardname@.",
|
||||
"description": "Create a custom animation on your brick screen.",
|
||||
"cardType": "tutorial",
|
||||
"url":"/tutorials/make-an-animation",
|
||||
"imageUrl":"/static/tutorials/make-an-animation.png"
|
||||
@ -25,7 +25,7 @@ Step by step guides to coding your @boardname@.
|
||||
"imageUrl":"/static/tutorials/what-animal-am-i.png"
|
||||
}, {
|
||||
"name": "Music Brick",
|
||||
"description": "Transform your @boardname@ into a musical instrument!",
|
||||
"description": "Transform the brick into a musical instrument!",
|
||||
"cardType": "tutorial",
|
||||
"url":"/tutorials/mindstorms-music",
|
||||
"imageUrl":"/static/tutorials/mindstorms-music.png"
|
||||
@ -97,3 +97,16 @@ Step by step guides to coding your @boardname@.
|
||||
"imageUrl":"/static/tutorials/object-near.png"
|
||||
}]
|
||||
```
|
||||
|
||||
## Infrared Sensor
|
||||
|
||||
```codecard
|
||||
[{
|
||||
"name": "Intruder Alert",
|
||||
"description": "Build an intruder alert using the infrared sensor.",
|
||||
"cardType": "tutorial",
|
||||
"url":"/tutorials/intruder-alert",
|
||||
"imageUrl":"/static/tutorials/intruder-alert.png"
|
||||
}]
|
||||
```
|
||||
|
||||
|
105
docs/tutorials/intruder-alert.md
Normal file
@ -0,0 +1,105 @@
|
||||
# Intruder Alert
|
||||
|
||||
## Introduction @fullscreen
|
||||
|
||||
The Infrared Sensor uses infrared light waves to detect proximity to the robot. Build an intruder alert using the infrared sensor.
|
||||
|
||||

|
||||
|
||||
## Step 1
|
||||
|
||||
Open the ``||sensors:Sensors||`` Toolbox drawer. Drag out an ``||sensors:on infrared||`` block onto the Workspace (you can place this anywhere). Use the second drop-down menu to select ``detected``.
|
||||
|
||||

|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
|
||||
})
|
||||
```
|
||||
|
||||
## Step 2
|
||||
|
||||
Open the ``||brick:Brick||`` Toolbox drawer. From the **Screen** section, drag out a ``||brick:show image||`` block onto the Workspace, and drop it into the ``||sensors:on infrared||`` block.
|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
brick.showImage(images.expressionsBigSmile)
|
||||
})
|
||||
```
|
||||
|
||||
## Step 3
|
||||
|
||||
In the ``||brick:show image||`` block, use the drop-down menu to select the **STOP** sign image.
|
||||
|
||||

|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
brick.showImage(images.informationStop1)
|
||||
})
|
||||
```
|
||||
|
||||
## Step 4
|
||||
|
||||
Open the ``||brick:Brick||`` Toolbox drawer. From the **Buttons** section, drag out a ``||brick:set status light||`` block onto the Workspace, and drop it after the ``||brick:show image||`` block.
|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
brick.showImage(images.informationStop1)
|
||||
brick.setStatusLight(StatusLight.Orange)
|
||||
})
|
||||
```
|
||||
|
||||
## Step 5
|
||||
|
||||
In the ``||brick:set status light||`` block, use the drop-down menu to select the ``red flash`` light
|
||||
|
||||

|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
brick.showImage(images.informationStop1)
|
||||
brick.setStatusLight(StatusLight.RedFlash)
|
||||
})
|
||||
```
|
||||
|
||||
## Step 6
|
||||
|
||||
Open the ``||loops:Loops||`` Toolbox drawer. Drag a ``||loops:repeat||`` loop onto the Workspace, and drop it after the ``||brick:set status light||`` block.
|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
brick.showImage(images.informationStop1)
|
||||
brick.setStatusLight(StatusLight.RedFlash)
|
||||
for (let i = 0; i < 4; i++) {
|
||||
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Step 7
|
||||
|
||||
Open the ``||music:Music||`` Toolbox drawer. Drag a ``||music:play sound effect until done||`` block onto the Workspace, and drop it into the ``||loops:repeat||`` loop.
|
||||
|
||||
```blocks
|
||||
sensors.infrared1.onEvent(InfraredSensorEvent.ObjectDetected, function () {
|
||||
brick.showImage(images.informationStop1)
|
||||
brick.setStatusLight(StatusLight.RedFlash)
|
||||
for (let i = 0; i < 4; i++) {
|
||||
music.playSoundEffectUntilDone(sounds.animalsCatPurr)
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Step 8
|
||||
|
||||
In the ``||music:play sound effect until done||`` block, use the drop-down menu to select ``information error alarm`` sound effect.
|
||||
|
||||

|
||||
|
||||
## Step 9
|
||||
|
||||
Now, plug your @boardname@ into the computer with the USB cable, and click the **Download** button at the bottom of your screen. Follow the directions to save your program to the brick.
|
||||
|
||||
Attach an Infrared Sensor to Port 1 of your brick. Test your program by putting an object increasingly closer to the Infrared Sensor – your Intruder Alert should trigger when you get too close!
|
@ -23,7 +23,7 @@ In the ``||brick:show string||`` block, type the text ``"Press my buttons to mak
|
||||
brick.showString("Press my buttons to make music!", 1)
|
||||
```
|
||||
|
||||
# Step 3
|
||||
## Step 3
|
||||
|
||||
Open the ``||brick:Brick||`` Toolbox drawer. From the **Buttons** section, drag out an ``||brick:on button||`` block onto the Workspace (you can put it anywhere).
|
||||
|
||||
|
@ -36,7 +36,7 @@ sensors.touch1.onEvent(ButtonEvent.Released, function () {
|
||||
|
||||
## Step 3
|
||||
|
||||
Open the ``||motors:Motors||`` Toolbox drawer. Drag out a ``||motors:run||`` block onto the Workspace, and drop it into the ``||brick:on touch pressed||`` block.
|
||||
Open the ``||motors:Motors||`` Toolbox drawer. Drag out a ``||motors:run||`` block onto the Workspace, and drop it into the ``||sensors:on touch pressed||`` block.
|
||||
|
||||
```blocks
|
||||
sensors.touch1.onEvent(ButtonEvent.Pressed, function () {
|
||||
|
@ -2,7 +2,7 @@
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtblocks.d.ts"/>
|
||||
/// <reference path="../node_modules/pxt-core/built/pxtsim.d.ts"/>
|
||||
|
||||
export interface FieldPortsOptions extends Blockly.FieldCustomDropdownOptions {
|
||||
export interface FieldPortsOptions extends pxtblockly.FieldImagesOptions {
|
||||
columns?: string;
|
||||
width?: string;
|
||||
}
|
||||
@ -11,7 +11,7 @@ export class FieldPorts extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
public isFieldCustom_ = true;
|
||||
|
||||
constructor(text: string, options: FieldPortsOptions, validator?: Function) {
|
||||
super(text, options, validator);
|
||||
super(text, { sort: true, data: options.data }, validator);
|
||||
|
||||
this.columns_ = parseInt(options.columns) || 4;
|
||||
this.width_ = parseInt(options.width) || 300;
|
||||
@ -24,11 +24,6 @@ export class FieldPorts extends pxtblockly.FieldImages implements Blockly.FieldC
|
||||
trimOptions_() {
|
||||
}
|
||||
|
||||
getOptions() {
|
||||
const options = super.getOptions();
|
||||
return options ? options.sort() : undefined;
|
||||
}
|
||||
|
||||
protected buttonClick_ = function (e: any) {
|
||||
let value = e.target.getAttribute('data-value');
|
||||
this.setValue(value);
|
||||
|
@ -298,6 +298,23 @@ namespace motors {
|
||||
pauseUntilReady(timeOut?: number) {
|
||||
pauseUntil(() => this.isReady(), timeOut);
|
||||
}
|
||||
|
||||
protected setOutputType(large: boolean) {
|
||||
/*
|
||||
Instruction opOutput_Set_Type (LAYER, NO, TYPE)
|
||||
Opcode 0xA1 Arguments (Data8) LAYER – Specify chain layer number [0 - 3]
|
||||
(Data8) NO – Port number [0 - 3]
|
||||
(Data8) TYPE – Output device type, (0x07: Large motor, Medium motor = 0x08) Dispatch status Unchanged
|
||||
Description This function enables specifying the output device type
|
||||
*/
|
||||
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
||||
if (this._port & (1 << i)) {
|
||||
const b = mkCmd(i, DAL.opOutputSetType, 1)
|
||||
b.setNumber(NumberFormat.Int8LE, 2, large ? 0x07 : 0x08)
|
||||
writePWM(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstances
|
||||
@ -316,11 +333,8 @@ namespace motors {
|
||||
motors.__motorUsed(this._port, this._large);
|
||||
}
|
||||
|
||||
private __init() {
|
||||
// specify motor size on this port
|
||||
const b = mkCmd(outOffset(this._port), DAL.opOutputSetType, 1)
|
||||
b.setNumber(NumberFormat.Int8LE, 2, this._large ? 0x07 : 0x08)
|
||||
writePWM(b)
|
||||
private __init() {
|
||||
this.setOutputType(this._large);
|
||||
}
|
||||
|
||||
private __setSpeed(speed: number) {
|
||||
@ -453,13 +467,7 @@ namespace motors {
|
||||
}
|
||||
|
||||
private __init() {
|
||||
for (let i = 0; i < DAL.NUM_OUTPUTS; ++i) {
|
||||
if (this._port & (1 << i)) {
|
||||
const b = mkCmd(outOffset(1 << i), DAL.opOutputSetType, 1)
|
||||
b.setNumber(NumberFormat.Int8LE, 2, 0x07) // large motor
|
||||
writePWM(b)
|
||||
}
|
||||
}
|
||||
this.setOutputType(true);
|
||||
}
|
||||
|
||||
private __setSpeed(speed: number) {
|
||||
|
@ -22,6 +22,13 @@ namespace _screen_internal {
|
||||
namespace brick {
|
||||
const textOffset = 4;
|
||||
const lineOffset = 2;
|
||||
enum ScreenMode {
|
||||
None,
|
||||
ShowLines,
|
||||
Image,
|
||||
Custom
|
||||
}
|
||||
let screenMode = ScreenMode.None;
|
||||
export let font = image.font8;
|
||||
|
||||
/**
|
||||
@ -50,6 +57,11 @@ namespace brick {
|
||||
//% help=brick/show-string
|
||||
//% line.min=1 line.max=10
|
||||
export function showString(text: string, line: number) {
|
||||
if (screenMode != ScreenMode.ShowLines) {
|
||||
screenMode = ScreenMode.ShowLines;
|
||||
screen.fill(0);
|
||||
}
|
||||
|
||||
// line indexing starts at 1.
|
||||
line = (line - 1) >> 0;
|
||||
const nlines = lineCount();
|
||||
@ -98,6 +110,7 @@ namespace brick {
|
||||
//% help=brick/show-image
|
||||
export function showImage(image: Image, duration: number = 400) {
|
||||
if (!image) return;
|
||||
screenMode = ScreenMode.Image;
|
||||
screen.fill(0);
|
||||
screen.drawImage(image, 0, 0);
|
||||
if (duration > 0)
|
||||
@ -111,6 +124,8 @@ namespace brick {
|
||||
//% help=brick/show-ports blockGap=8
|
||||
//% weight=10 group="Screen"
|
||||
export function showPorts() {
|
||||
screenMode = ScreenMode.Custom;
|
||||
|
||||
const col = 44;
|
||||
const lineHeight8 = image.font8.charHeight + 2;
|
||||
clearScreen();
|
||||
|
@ -18,7 +18,7 @@ The distance value returned is the number of centimeters to the object that the
|
||||
When the ultrasonic sensor on port 4 detects a near object, display its distance on the screen.
|
||||
|
||||
```blocks
|
||||
sensors.ultrasonic4.onEvent(UltrasonicSensorEvent.ObjecNear, function () {
|
||||
sensors.ultrasonic4.onEvent(UltrasonicSensorEvent.ObjectNear, function () {
|
||||
brick.showString("Object detected at:", 1)
|
||||
brick.showNumber(sensors.ultrasonic4.distance(), 2)
|
||||
brick.showString("centimeters", 3)
|
||||
|
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pxt-ev3",
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.16",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pxt-ev3",
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.16",
|
||||
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
|
||||
"private": true,
|
||||
"keywords": [
|
||||
@ -46,7 +46,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"pxt-common-packages": "0.20.38",
|
||||
"pxt-core": "3.8.6"
|
||||
"pxt-core": "3.8.8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
||||
|
@ -2,9 +2,9 @@
|
||||
"id": "ev3",
|
||||
"platformid": "linux",
|
||||
"nickname": "lego",
|
||||
"name": "LEGO Mindstorms EV3",
|
||||
"title": "LEGO Mindstorms EV3 - Blocks / Javascript editor",
|
||||
"description": "A Blocks / JavaScript code editor for the LEGO Mindstorms EV3.",
|
||||
"name": "LEGO MINDSTORMS EV3",
|
||||
"title": "LEGO MINDSTORMS EV3 - Blocks / Javascript editor",
|
||||
"description": "A Blocks / JavaScript code editor for the LEGO MINDSTORMS EV3.",
|
||||
"corepkg": "ev3",
|
||||
"bundleddirs": [
|
||||
"libs/base",
|
||||
@ -44,7 +44,7 @@
|
||||
"hasHex": true,
|
||||
"deployDrives": ".*",
|
||||
"deployFileMarker": "INFO_UF2.TXT",
|
||||
"driveName": "LEGO",
|
||||
"driveName": "EV3",
|
||||
"flashCodeAlign": 256,
|
||||
"floatingPoint": true,
|
||||
"taggedInts": true,
|
||||
@ -97,7 +97,8 @@
|
||||
"termsOfUseUrl": "https://go.microsoft.com/fwlink/?LinkID=206977",
|
||||
"githubUrl": "https://github.com/Microsoft/pxt-ev3",
|
||||
"betaUrl": "https://makecode.legoeducation.com/about",
|
||||
"boardName": "LEGO Mindstorms EV3 Brick",
|
||||
"driveDisplayName": "EV3",
|
||||
"boardName": "LEGO MINDSTORMS EV3 Brick",
|
||||
"selectLanguage": true,
|
||||
"availableLocales": [
|
||||
"en"
|
||||
|
@ -122,10 +122,11 @@ namespace pxsim {
|
||||
return 2;
|
||||
}
|
||||
case DAL.opOutputSetType: {
|
||||
const port = buf.data[1];
|
||||
const portIndex = buf.data[1]; // not a port but a port index 0..3
|
||||
const large = buf.data[2] == 0x07;
|
||||
const motors = ev3board().getMotor(port);
|
||||
motors.forEach(motor => motor.setLarge(large));
|
||||
const motor = ev3board().getMotors()[portIndex];
|
||||
if (motor)
|
||||
motor.setLarge(large);
|
||||
return 2;
|
||||
}
|
||||
default:
|
||||
|
@ -60,10 +60,10 @@
|
||||
<circle id="LM_red-2" cx="17.96" cy="17.95" r="17.06"></circle>
|
||||
</g>
|
||||
<g id="LM_details_in_red" transform="translate(2.000000, 2.000000)">
|
||||
<circle id="LM_detail_red_hole4" fill="#393939" cx="12.9" cy="27.01" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole3" fill="#393939" cx="4.75" cy="12.89" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole2" fill="#393939" cx="18.87" cy="4.74" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole1" fill="#393939" cx="27.02" cy="18.86" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole4" fill="#D6EDFF" cx="12.9" cy="27.01" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole3" fill="#D6EDFF" cx="4.75" cy="12.89" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole2" fill="#D6EDFF" cx="18.87" cy="4.74" r="3.79"></circle>
|
||||
<circle id="LM_detail_red_hole1" fill="#D6EDFF" cx="27.02" cy="18.86" r="3.79"></circle>
|
||||
<path d="M18.18,15.31 C17.9816076,15.2705154 17.8089761,15.149396 17.7043432,14.9762761 C17.5997103,14.8031562 17.5727287,14.5940066 17.63,14.4 C17.84,13.68 17.99,13.07 17.99,13.07 C17.99,13.07 17.82,12.72 16.72,12.43 C15.62,12.14 15.37,12.37 15.37,12.37 L14.98,13.7 C14.98,13.7 14.82,14.42 14.17,14.24 L12.98,13.9 C12.98,13.9 12.58,14.03 12.38,14.96 C12.2599627,15.4271881 12.2395203,15.9143986 12.32,16.39 L13.57,16.72 C13.9132251,16.8260991 14.1147049,17.1808788 14.03,17.53 C13.87,18.14 13.7,18.74 13.7,18.74 C13.7,18.74 13.82,19.04 14.9,19.36 C15.98,19.68 16.32,19.45 16.32,19.45 L16.64,18.23 C16.64,18.23 16.9,17.47 17.64,17.64 C18.04,17.7533333 18.44,17.8833333 18.84,18.03 C19.3790257,17.4116231 19.6330766,16.5950309 19.54,15.78 C18.89,15.55 18.18,15.31 18.18,15.31 Z" id="LM_detail_hole" fill="#1F1F1F"></path>
|
||||
<path d="M15.62,23.13 L14.07,22.9 L12.54,22.33 C12.29437,22.2663058 12.1467122,22.015735 12.21,21.77 L12.76,19.72 C12.8281001,19.4784149 13.0772913,19.3360199 13.32,19.4 L14.77,20 L16.4,20.22 C16.64563,20.2836942 16.7932878,20.534265 16.73,20.78 L16.18,22.83 C16.1519467,22.9468655 16.0773095,23.0471692 15.9734274,23.1076097 C15.8695454,23.1680501 15.7454609,23.1833663 15.63,23.15 L15.62,23.13 Z" id="LM_detail_red4" fill="#393939"></path>
|
||||
<path d="M23.13,16.2 L22.87,17.75 L22.3,19.27 C22.2716803,19.3872072 22.1975067,19.4881458 22.0941102,19.5501837 C21.9907137,19.6122216 21.8667451,19.6301684 21.75,19.6 L19.69,19.05 C19.4484149,18.9818999 19.3060199,18.7327087 19.37,18.49 L19.98,17.05 L20.2,15.42 C20.2283197,15.3027928 20.3024933,15.2018542 20.4058898,15.1398163 C20.5092863,15.0777784 20.6332549,15.0598316 20.75,15.09 L22.75,15.64 C22.9915851,15.7081001 23.1339801,15.9572913 23.07,16.2 L23.13,16.2 Z" id="LM_detail_red3" fill="#393939"></path>
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@ -1,4 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 68">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient" x1="-427.2" y1="440.79" x2="-427.2" y2="440.63" gradientTransform="matrix(44.14, 0, 0, -44.15, 18878.72, 19502.57)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#a8aaa8"/>
|
||||
@ -6,7 +6,7 @@
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<title>MediumMotor</title>
|
||||
<g style="isolation: isolate">
|
||||
<g style="isolation: isolate" transform="translate(0 20)">
|
||||
<g id="svg7610">
|
||||
<g id="Medium_Motor" data-name="Medium Motor">
|
||||
<g id="medmotor_box" data-name="medmotor box">
|
||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.7 KiB |
@ -1,3 +1,3 @@
|
||||
namespace pxsim.visuals {
|
||||
export const MEDIUM_MOTOR_SVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 48"><defs><linearGradient id="linear-gradient" x1="-427.2" y1="440.79" x2="-427.2" y2="440.63" gradientTransform="matrix(44.14 0 0 -44.15 18878.72 19502.57)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a8aaa8"/><stop offset="1" stop-color="#535453"/></linearGradient></defs><g style="isolation:isolate"><g id="svg7610"><g id="Medium_Motor" data-name="Medium Motor"><g id="medmotor_box" data-name="medmotor box"><path id="medmotor_box_wgradient" data-name="medmotor box wgradient" d="M2.57 0h39a2.36 2.36 0 0 1 2.57 2v40.33c0 1-1.1 1.82-2.57 1.82h-39C1.1 44.15 0 43.34 0 42.33V2a2.36 2.36 0 0 1 2.57-2z" transform="translate(2 1.84)" fill="url(#linear-gradient)"/></g><g id="medmotor_star" data-name="medmotor star"><image width="48" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAxCAYAAACcXioiAAAACXBIWXMAAAsSAAALEgHS3X78AAACfElEQVRoQ+2aPXLbMBBG32ZUijlCnDo/R1AukCoHyAFS5Sw5g5t0bnwCu0ofpTZ9A1usvSmwoClRJEEAI4gzejMcqliS+2FB4AMoUVVyISICrIErO3dpgBpoNONDJde9RKTCJf4R+Ga/u9TADbAFalXdkYEsAiz5L8B3nICxCmyBa+Auh4jVVMAUneR/ABugAuRIaIUT9w4TJyLJIpIEWJ+/wrX8Bng7fgViMRtcRR5F5G/KO/FmKiCANa5Vq6nADhXwwY7DrjaLHALgeJcZQ4D32MtulYwil4AYfOXOogKxRLe8p7SAZC4CSnMRUJrBmThwbBbSRxIh4HFDs3VPwIQl7oXj/M1U3BBr3PUAY3aiEZGjVnzPjQZY4mOscbNqjIgGeLDzGINWvBUQaImHSOlGIUZu2IqbgAr4CtwCT8AL7sbndLzgcrvF5Vq1jQ98An5bwNSNSh9PuFw/A+KH0RhLXIo9K96dB1L68SnZs+JLnchaK75UAWA9ZskCgGULUFiugAZ4BJquAB0IPjcUZz9ugNoL8IqSNplOxA74Z0ezUlU1p3eNG5787tocUuaQOZXfAfe4XB9UVVcAqroTkTsLaghzoZ5TuFGPb+jWzA3Z6dBk/Hrgp53nVEJx7vKXnUMq0XBgp/cWNFaJbe+yYXzCoS14SINL/g9hAnors96KbM5Gqy0Dg+MHUNxjo+6z1Hmg5SKgNBcBpSktIGrk6VJSQOsopwLHKCVAed2sqmPnAMgnICaB9sv9VOAYOQTEWPEdGZKHRAFWeu8Q74Fnpjemnnm1xEndBxI/dEOUFe9Z4hSy/FcCZlnxniVOIZsACPhKYaR2my5ZBZTgP7HrUIs43RAaAAAAAElFTkSuQmCC" style="mix-blend-mode:multiply" opacity=".3"/><path id="medmotor_cut-2" data-name="medmotor cut-2" d="M0 21.25A6.21 6.21 0 0 1 6.22 15H15V6.23A6.22 6.22 0 0 1 21.24 0h1.66a6.22 6.22 0 0 1 6.22 6.22V15h8.8a6.21 6.21 0 0 1 6.22 6.22v1.66a6.21 6.21 0 0 1-6.22 6.22h-8.8v8.8a6.21 6.21 0 0 1-6.22 6.22h-1.66A6.22 6.22 0 0 1 15 37.93v-8.8H6.22A6.22 6.22 0 0 1 0 22.92z" transform="translate(2 1.84)" fill="#a8aaa8"/><circle id="medmotor_hole_4" data-name="medmotor hole 4" cx="39.77" cy="24" r="4.85" fill="#393939"/><circle id="medmotor_hole_3" data-name="medmotor hole 3" cx="8.37" cy="24" r="4.85" fill="#393939"/><circle id="medmotor_hole_2" data-name="medmotor hole 2" cx="24.15" cy="8.22" r="4.85" fill="#393939"/><circle id="medmotor_hole_1" data-name="medmotor hole 1" cx="24.15" cy="39.62" r="4.85" fill="#393939"/></g><g id="medmotor_red" data-name="medmotor red"><circle cx="24.3" cy="24" r="6.75" fill="#d42715"/><circle cx="24.3" cy="24" r="6.63" fill="none" stroke="#a20800" stroke-width=".25"/></g><path id="medmotor_Hole" data-name="medmotor Hole" d="M20.59 19.46s-.05 1-.77 1h-1.46a2.38 2.38 0 0 0-.45 1.69c0 1.27.36 1.6.36 1.6h1.62a.64.64 0 0 1 .7.59.21.21 0 0 1 0 .11v1.67a4 4 0 0 0 1.77.29 6.88 6.88 0 0 0 1.64-.26v-1.67a.73.73 0 0 1 .73-.7 9.89 9.89 0 0 0 1.44-.14s.4-.37.44-1.63-.36-1.64-.36-1.64H24.6a.65.65 0 0 1-.75-.51.49.49 0 0 1 0-.17 11.22 11.22 0 0 1 0-1.64 4.78 4.78 0 0 0-3.25 0c-.02.69-.01 1.41-.01 1.41z" transform="translate(2 1.84)"/></g></g></g></svg>`;
|
||||
export const MEDIUM_MOTOR_SVG = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 48 68"><defs><linearGradient id="linear-gradient" x1="-427.2" y1="440.79" x2="-427.2" y2="440.63" gradientTransform="matrix(44.14 0 0 -44.15 18878.72 19502.57)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a8aaa8"/><stop offset="1" stop-color="#535453"/></linearGradient></defs><g style="isolation:isolate" transform="translate(0 20)"><g id="svg7610"><g id="Medium_Motor" data-name="Medium Motor"><g id="medmotor_box" data-name="medmotor box"><path id="medmotor_box_wgradient" data-name="medmotor box wgradient" d="M2.57 0h39a2.36 2.36 0 0 1 2.57 2v40.33c0 1-1.1 1.82-2.57 1.82h-39C1.1 44.15 0 43.34 0 42.33V2a2.36 2.36 0 0 1 2.57-2z" transform="translate(2 1.84)" fill="url(#linear-gradient)"/></g><g id="medmotor_star" data-name="medmotor star"><image width="48" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAxCAYAAACcXioiAAAACXBIWXMAAAsSAAALEgHS3X78AAACfElEQVRoQ+2aPXLbMBBG32ZUijlCnDo/R1AukCoHyAFS5Sw5g5t0bnwCu0ofpTZ9A1usvSmwoClRJEEAI4gzejMcqliS+2FB4AMoUVVyISICrIErO3dpgBpoNONDJde9RKTCJf4R+Ga/u9TADbAFalXdkYEsAiz5L8B3nICxCmyBa+Auh4jVVMAUneR/ABugAuRIaIUT9w4TJyLJIpIEWJ+/wrX8Bng7fgViMRtcRR5F5G/KO/FmKiCANa5Vq6nADhXwwY7DrjaLHALgeJcZQ4D32MtulYwil4AYfOXOogKxRLe8p7SAZC4CSnMRUJrBmThwbBbSRxIh4HFDs3VPwIQl7oXj/M1U3BBr3PUAY3aiEZGjVnzPjQZY4mOscbNqjIgGeLDzGINWvBUQaImHSOlGIUZu2IqbgAr4CtwCT8AL7sbndLzgcrvF5Vq1jQ98An5bwNSNSh9PuFw/A+KH0RhLXIo9K96dB1L68SnZs+JLnchaK75UAWA9ZskCgGULUFiugAZ4BJquAB0IPjcUZz9ugNoL8IqSNplOxA74Z0ezUlU1p3eNG5787tocUuaQOZXfAfe4XB9UVVcAqroTkTsLaghzoZ5TuFGPb+jWzA3Z6dBk/Hrgp53nVEJx7vKXnUMq0XBgp/cWNFaJbe+yYXzCoS14SINL/g9hAnors96KbM5Gqy0Dg+MHUNxjo+6z1Hmg5SKgNBcBpSktIGrk6VJSQOsopwLHKCVAed2sqmPnAMgnICaB9sv9VOAYOQTEWPEdGZKHRAFWeu8Q74Fnpjemnnm1xEndBxI/dEOUFe9Z4hSy/FcCZlnxniVOIZsACPhKYaR2my5ZBZTgP7HrUIs43RAaAAAAAElFTkSuQmCC" style="mix-blend-mode:multiply" opacity=".3"/><path id="medmotor_cut-2" data-name="medmotor cut-2" d="M0 21.25A6.21 6.21 0 0 1 6.22 15H15V6.23A6.22 6.22 0 0 1 21.24 0h1.66a6.22 6.22 0 0 1 6.22 6.22V15h8.8a6.21 6.21 0 0 1 6.22 6.22v1.66a6.21 6.21 0 0 1-6.22 6.22h-8.8v8.8a6.21 6.21 0 0 1-6.22 6.22h-1.66A6.22 6.22 0 0 1 15 37.93v-8.8H6.22A6.22 6.22 0 0 1 0 22.92z" transform="translate(2 1.84)" fill="#a8aaa8"/><circle id="medmotor_hole_4" data-name="medmotor hole 4" cx="39.77" cy="24" r="4.85" fill="#393939"/><circle id="medmotor_hole_3" data-name="medmotor hole 3" cx="8.37" cy="24" r="4.85" fill="#393939"/><circle id="medmotor_hole_2" data-name="medmotor hole 2" cx="24.15" cy="8.22" r="4.85" fill="#393939"/><circle id="medmotor_hole_1" data-name="medmotor hole 1" cx="24.15" cy="39.62" r="4.85" fill="#393939"/></g><g id="medmotor_red" data-name="medmotor red"><circle cx="24.3" cy="24" r="6.75" fill="#d42715"/><circle cx="24.3" cy="24" r="6.63" fill="none" stroke="#a20800" stroke-width=".25"/></g><path id="medmotor_Hole" data-name="medmotor Hole" d="M20.59 19.46s-.05 1-.77 1h-1.46a2.38 2.38 0 0 0-.45 1.69c0 1.27.36 1.6.36 1.6h1.62a.64.64 0 0 1 .7.59.21.21 0 0 1 0 .11v1.67a4 4 0 0 0 1.77.29 6.88 6.88 0 0 0 1.64-.26v-1.67a.73.73 0 0 1 .73-.7 9.89 9.89 0 0 0 1.44-.14s.4-.37.44-1.63-.36-1.64-.36-1.64H24.6a.65.65 0 0 1-.75-.51.49.49 0 0 1 0-.17 11.22 11.22 0 0 1 0-1.64 4.78 4.78 0 0 0-3.25 0c-.02.69-.01 1.41-.01 1.41z" transform="translate(2 1.84)"/></g></g></g></svg>`;
|
||||
}
|
@ -45,6 +45,9 @@ namespace pxsim.visuals {
|
||||
.sim-text.small {
|
||||
font-size:6px;
|
||||
}
|
||||
.sim-text.medium {
|
||||
font-size:16px;
|
||||
}
|
||||
.sim-text.large {
|
||||
font-size:30px;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ namespace pxsim.visuals {
|
||||
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
|
||||
this.group = svg.elt("g") as SVGGElement;
|
||||
|
||||
let gc = "gradient-color";
|
||||
let gc = "gradient-color-" + this.getPort();
|
||||
this.colorGradient = svg.linearGradient(globalDefs, gc, false);
|
||||
svg.setGradientValue(this.colorGradient, "50%");
|
||||
svg.setGradientColors(this.colorGradient, "black", "yellow");
|
||||
@ -99,5 +99,10 @@ namespace pxsim.visuals {
|
||||
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this.colorGradient) this.colorGradient.parentElement.removeChild(this.colorGradient);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ namespace pxsim.visuals {
|
||||
private static SLIDER_SIDE_PADDING = 6;
|
||||
|
||||
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
|
||||
let gid = "gradient-slider-" + this.getId();
|
||||
let gid = "gradient-slider-" + this.getPort();
|
||||
this.group = svg.elt("g") as SVGGElement;
|
||||
this.gradient = createGradient(gid, this.getGradientDefinition());
|
||||
this.gradient.setAttribute('x1', '0%');
|
||||
@ -74,6 +74,11 @@ namespace pxsim.visuals {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
if (this.gradient) this.gradient.parentElement.removeChild(this.gradient);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
getInnerHeight() {
|
||||
return 192;
|
||||
}
|
||||
|
@ -24,7 +24,9 @@ namespace pxsim.visuals {
|
||||
} else if (this.syncedLabelG) {
|
||||
this.syncedLabelG.parentNode.removeChild(this.syncedLabelG);
|
||||
}
|
||||
this.setMotorLabel(motorState.getSpeed(), true);
|
||||
}
|
||||
this.setMotorLabel(motorState.getSpeed());
|
||||
}
|
||||
|
||||
private showSyncedLabel(motorNode: MotorNode, syncedMotor: MotorNode) {
|
||||
@ -55,5 +57,11 @@ namespace pxsim.visuals {
|
||||
getWiringRatio() {
|
||||
return 0.37;
|
||||
}
|
||||
|
||||
protected positionMotorLabel() {
|
||||
const hasSyncedLabel = this.syncedMotor;
|
||||
this.motorLabelGroup.setAttribute('transform', `translate(${hasSyncedLabel ? '15 35' : '25 15'})`);
|
||||
this.motorLabel.style.fontSize = '13px';
|
||||
}
|
||||
}
|
||||
}
|
@ -26,5 +26,10 @@ namespace pxsim.visuals {
|
||||
const transform = `translate(2 1.84) rotate(${angle} ${width / 2} ${height / 2})`;
|
||||
holeEl.setAttribute("transform", transform);
|
||||
}
|
||||
|
||||
protected positionMotorLabel() {
|
||||
this.motorLabelGroup.setAttribute('transform', 'translate(25 13)');
|
||||
this.motorLabel.style.fontSize = '11px';
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,10 @@
|
||||
namespace pxsim.visuals {
|
||||
export abstract class MotorView extends ModuleView implements LayoutElement {
|
||||
|
||||
protected motorLabelGroup: SVGGElement;
|
||||
protected motorLabel: SVGTextElement;
|
||||
private currentLabel: string;
|
||||
|
||||
constructor(xml: string, prefix: string, id: NodeType, port: NodeType,
|
||||
protected rotating_hole_id: string) {
|
||||
super(xml, prefix, id, port);
|
||||
@ -15,7 +19,8 @@ namespace pxsim.visuals {
|
||||
const speed = motorState.getSpeed();
|
||||
|
||||
if (!speed) return;
|
||||
this.setMotorAngle(motorState.getAngle());
|
||||
this.setMotorAngle(motorState.getAngle() % 360);
|
||||
this.setMotorLabel(speed);
|
||||
}
|
||||
|
||||
private setMotorAngle(angle: number) {
|
||||
@ -29,5 +34,23 @@ namespace pxsim.visuals {
|
||||
getWiringRatio() {
|
||||
return 0.37;
|
||||
}
|
||||
|
||||
setMotorLabel(speed: number, force?: boolean) {
|
||||
if (!force && this.currentLabel === `${speed}`) return;
|
||||
this.currentLabel = `${speed}`;
|
||||
if (!this.motorLabel) {
|
||||
this.motorLabelGroup = pxsim.svg.child(this.content, "g") as SVGGElement;
|
||||
this.motorLabel = pxsim.svg.child(this.motorLabelGroup, "text", { 'text-anchor': 'middle', 'x': '0', 'y': '0', 'class': 'sim-text number inverted' }) as SVGTextElement;
|
||||
}
|
||||
// If Motor speed is not 0
|
||||
if (this.currentLabel) {
|
||||
this.motorLabel.textContent = `${this.currentLabel}%`;
|
||||
this.positionMotorLabel();
|
||||
} else {
|
||||
this.motorLabel.textContent = ``;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract positionMotorLabel(): void;
|
||||
}
|
||||
}
|
@ -8,6 +8,5 @@
|
||||
}
|
||||
|
||||
#mainmenu, #homemenu {
|
||||
background: @legoGreyLight;
|
||||
border-bottom: 5px solid #00a5c8;
|
||||
}
|
@ -108,8 +108,8 @@
|
||||
Menu
|
||||
--------------------*/
|
||||
|
||||
@mainMenuBackground: #ffffff;
|
||||
@mainMenuInvertedBackground: @yellow;
|
||||
@mainMenuBackground: @legoGreyLight;
|
||||
@mainMenuInvertedBackground: #FFFFFF;
|
||||
@mainMenuTutorialBackground: @orange;
|
||||
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
/*******************************
|
||||
User Variable Overrides
|
||||
*******************************/
|
||||
|
||||
@backgroundColor: fade(#A2A2A2, 80%);
|