Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
312729142f | |||
5bd4aed0e1 | |||
cfaa4ae3ef | |||
faa839d59f | |||
630687bfce | |||
2b300a4094 | |||
5fb8c0de6e | |||
1f65cd59a8 |
9
.travis.yml
Normal file
9
.travis.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "8.9.0"
|
||||||
|
script:
|
||||||
|
- "node node_modules/pxt-core/built/pxt.js travis"
|
||||||
|
sudo: false
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
@ -190,12 +190,10 @@ if (true) {
|
|||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
forever(function () {
|
forever(function () {
|
||||||
while (true) {
|
while (sensors.color3.color() == ColorSensorColor.Black) {
|
||||||
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Black)
|
|
||||||
motors.largeBC.steer(-30, 50)
|
motors.largeBC.steer(-30, 50)
|
||||||
}
|
}
|
||||||
while (true) {
|
while (sensors.color3.color() == ColorSensorColor.White) {
|
||||||
sensors.color3.pauseUntilColorDetected(ColorSensorColor.White)
|
|
||||||
motors.largeBC.steer(30, 50)
|
motors.largeBC.steer(30, 50)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -209,11 +207,9 @@ Else the Color Sensor detects the color white, start motors ``B`` and ``C`` (dri
|
|||||||
|
|
||||||
```blocks
|
```blocks
|
||||||
forever(function () {
|
forever(function () {
|
||||||
if (true) {
|
if (sensors.color3.color() == ColorSensorColor.Black) {
|
||||||
sensors.color3.pauseUntilColorDetected(ColorSensorColor.Black)
|
|
||||||
motors.largeBC.steer(-30, 50)
|
motors.largeBC.steer(-30, 50)
|
||||||
} else {
|
} else {
|
||||||
sensors.color3.pauseUntilColorDetected(ColorSensorColor.White)
|
|
||||||
motors.largeBC.steer(30, 50)
|
motors.largeBC.steer(30, 50)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,46 +1,9 @@
|
|||||||
# Projects
|
# Projects
|
||||||
|
|
||||||
```codecard
|
Here are some cool projects that you can build with your @boardname@!
|
||||||
[
|
|
||||||
{
|
|
||||||
"name": "Getting Started",
|
|
||||||
"url": "/getting-started",
|
|
||||||
"imageUrl": "/static/lessons/firmware.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Tutorials",
|
|
||||||
"url": "/tutorials",
|
|
||||||
"imageUrl": "/static/tutorials/wake-up.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Design Engineering",
|
|
||||||
"url": "/design-engineering",
|
|
||||||
"imageUrl": "/static/lessons/make-it-move-without-wheels.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Coding",
|
|
||||||
"url": "/coding",
|
|
||||||
"imageUrl": "/static/lessons/autonomous-parking.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Maker",
|
|
||||||
"url": "/maker",
|
|
||||||
"imageUrl": "/static/lessons/make-a-sound-machine.png"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Videos",
|
|
||||||
"url": "/videos",
|
|
||||||
"imageUrl": "https://legoeducation.videomarketingplatform.co/27288170/35719444/5d009e5f93fbf479c2e5ed2bf87a7990/thumbnail.png"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## See Also
|
## Basic
|
||||||
|
|
||||||
[Getting Started](/getting-started),
|
Basic projects to build with your EV3 Brick.
|
||||||
[Tutorials](/tutorials),
|
|
||||||
[Design Engineering](/design-engineering),
|
|
||||||
[Coding](/coding),
|
|
||||||
[Maker](/maker),
|
|
||||||
[Videos](/videos)
|
|
||||||
|
|
||||||
|
Coming soon.
|
@ -1,35 +0,0 @@
|
|||||||
# Projects
|
|
||||||
|
|
||||||
* [Getting Started](/getting-started)
|
|
||||||
* [Prepare](https://makecode.mindstorms.com/troubleshoot)
|
|
||||||
* [Try](/getting-started/try)
|
|
||||||
* [Use](/getting-started/use)
|
|
||||||
* [Tutorials](/tutorials)
|
|
||||||
* [Wake Up!](/tutorials/wake-up)
|
|
||||||
* [Make an Animation](/tutorials/make-an-animation)
|
|
||||||
* [What Animal Am I?](/tutorials/what-animal-am-i)
|
|
||||||
* [Music Brick](/tutorials/music-brick)
|
|
||||||
* [Run Motors](/tutorials/run-motors)
|
|
||||||
* [Touch to Run](/tutorials/touch-to-run)
|
|
||||||
* [Touch Sensor Values](/tutorials/touch-sensor-values)
|
|
||||||
* [What Color?](/tutorials/what-color)
|
|
||||||
* [Line Following](/tutorials/line-following)
|
|
||||||
* [Red Light, Green Light](/tutorials/redlight-greenlight)
|
|
||||||
* [Security Alert](/tutorials/security-alert)
|
|
||||||
* [Design Engineering](/design-engineering)
|
|
||||||
* [Make It Move Without Wheels](/design-engineering/make-it-move)
|
|
||||||
* [Make It Smarter and Faster](/design-engineering/make-it-smarter)
|
|
||||||
* [Make a System that Communicates](/design-engineering/make-it-communicate)
|
|
||||||
* [Coding](/coding)
|
|
||||||
* [Autonomous Parking](/coding/autonomous-parking)
|
|
||||||
* [Object Detection](/coding/object-detection)
|
|
||||||
* [Line Detection](/coding/line-detection)
|
|
||||||
* [Maker](/maker)
|
|
||||||
* [Make A Sound Machine](/maker/sound-machine)
|
|
||||||
* [Make A Security Gadget](/maker/security-gadget)
|
|
||||||
* [Videos](/videos)
|
|
||||||
* [undefined](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=5d009e5f93fbf479c2e5ed2bf87a7990&source=embed&photo%5fid=35719444)
|
|
||||||
* [undefined](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=2008a566f1fb034d58d5ebe19ba8621f&source=embed&photo%5fid=35719467)
|
|
||||||
* [undefined](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=629730c938e452f0fd7653fbc4708166&source=embed&photo%5fid=35719470)
|
|
||||||
* [undefined](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=3513a83b87fe536b2dc512237465fd1b&source=embed&photo%5fid=35719471)
|
|
||||||
* [undefined](https://legoeducation.videomarketingplatform.co/v.ihtml/player.html?token=5c594c2373367f7870196f519f3bfc7a&source=embed&photo%5fid=35719472)
|
|
@ -33,7 +33,7 @@ export function initAsync() {
|
|||||||
canHID = false
|
canHID = false
|
||||||
} else {
|
} else {
|
||||||
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
|
const forceHexDownload = /forceHexDownload/i.test(window.location.href);
|
||||||
if (pxt.BrowserUtils.isLocalHost() && pxt.Cloud.localToken && !forceHexDownload)
|
if (pxt.Cloud.isLocalHost() && pxt.Cloud.localToken && !forceHexDownload)
|
||||||
canHID = true
|
canHID = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
import { FieldPorts } from "./field_ports";
|
import { FieldPorts } from "./field_ports";
|
||||||
import { FieldMotors } from "./field_motors";
|
import { FieldMotors } from "./field_motors";
|
||||||
|
import { FieldSpeed } from "./field_speed";
|
||||||
import { FieldBrickButtons } from "./field_brickbuttons";
|
import { FieldBrickButtons } from "./field_brickbuttons";
|
||||||
|
import { FieldTurnRatio } from "./field_turnratio";
|
||||||
import { FieldColorEnum } from "./field_color";
|
import { FieldColorEnum } from "./field_color";
|
||||||
import { FieldMusic } from "./field_music";
|
import { FieldMusic } from "./field_music";
|
||||||
|
|
||||||
@ -17,9 +19,15 @@ pxt.editor.initFieldExtensionsAsync = function (opts: pxt.editor.FieldExtensionO
|
|||||||
}, {
|
}, {
|
||||||
selector: "motors",
|
selector: "motors",
|
||||||
editor: FieldMotors
|
editor: FieldMotors
|
||||||
|
}, {
|
||||||
|
selector: "speed",
|
||||||
|
editor: FieldSpeed
|
||||||
}, {
|
}, {
|
||||||
selector: "brickbuttons",
|
selector: "brickbuttons",
|
||||||
editor: FieldBrickButtons
|
editor: FieldBrickButtons
|
||||||
|
}, {
|
||||||
|
selector: "turnratio",
|
||||||
|
editor: FieldTurnRatio
|
||||||
}, {
|
}, {
|
||||||
selector: "colorenum",
|
selector: "colorenum",
|
||||||
editor: FieldColorEnum
|
editor: FieldColorEnum
|
||||||
|
@ -121,7 +121,7 @@ export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.
|
|||||||
Blockly.DropDownDiv.setColour('#ffffff', '#dddddd');
|
Blockly.DropDownDiv.setColour('#ffffff', '#dddddd');
|
||||||
|
|
||||||
// Calculate positioning based on the field position.
|
// Calculate positioning based on the field position.
|
||||||
var scale = (<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).scale;
|
var scale = this.sourceBlock_.workspace.scale;
|
||||||
var bBox = { width: this.size_.width, height: this.size_.height };
|
var bBox = { width: this.size_.width, height: this.size_.height };
|
||||||
bBox.width *= scale;
|
bBox.width *= scale;
|
||||||
bBox.height *= scale;
|
bBox.height *= scale;
|
||||||
@ -131,7 +131,7 @@ export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.
|
|||||||
var secondaryX = primaryX;
|
var secondaryX = primaryX;
|
||||||
var secondaryY = position.top;
|
var secondaryY = position.top;
|
||||||
// Set bounds to workspace; show the drop-down.
|
// Set bounds to workspace; show the drop-down.
|
||||||
(Blockly.DropDownDiv as any).setBoundsElement((<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).getParentSvg().parentNode);
|
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
|
||||||
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
||||||
this.onHide_.bind(this));
|
this.onHide_.bind(this));
|
||||||
}
|
}
|
||||||
@ -152,10 +152,9 @@ export class FieldBrickButtons extends Blockly.FieldDropdown implements Blockly.
|
|||||||
* Callback for when the drop-down is hidden.
|
* Callback for when the drop-down is hidden.
|
||||||
*/
|
*/
|
||||||
private onHide_ = function () {
|
private onHide_ = function () {
|
||||||
const content = Blockly.DropDownDiv.getContentDiv();
|
Blockly.DropDownDiv.content_.removeAttribute('role');
|
||||||
content.removeAttribute('role');
|
Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup');
|
||||||
content.removeAttribute('aria-haspopup');
|
Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant');
|
||||||
content.removeAttribute('aria-activedescendant');
|
Blockly.DropDownDiv.getContentDiv().style.width = '';
|
||||||
content.style.width = '';
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -53,7 +53,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink',
|
this.arrow_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||||
'xlink:href', (Blockly.FieldDropdown as any).DROPDOWN_SVG_DATAURI);
|
'xlink:href', (Blockly.FieldDropdown as any).DROPDOWN_SVG_DATAURI);
|
||||||
|
|
||||||
this.arrow2_ = <SVGImageElement>Blockly.utils.createSvgElement('image', {
|
this.arrow2_ = Blockly.utils.createSvgElement('image', {
|
||||||
'height': (this as any).arrowSize_ + 'px',
|
'height': (this as any).arrowSize_ + 'px',
|
||||||
'width': (this as any).arrowSize_ + 'px'
|
'width': (this as any).arrowSize_ + 'px'
|
||||||
});
|
});
|
||||||
@ -79,7 +79,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
},
|
},
|
||||||
this.fieldGroup_);
|
this.fieldGroup_);
|
||||||
fieldX += 10; // size of first group.
|
fieldX += 10; // size of first group.
|
||||||
this.textElement2_ = <SVGTextElement>Blockly.utils.createSvgElement('text',
|
this.textElement2_ = Blockly.utils.createSvgElement('text',
|
||||||
{
|
{
|
||||||
'class': (this as any).className_,
|
'class': (this as any).className_,
|
||||||
'x': fieldX,
|
'x': fieldX,
|
||||||
@ -89,7 +89,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
this.fieldGroup_);
|
this.fieldGroup_);
|
||||||
|
|
||||||
this.updateEditable();
|
this.updateEditable();
|
||||||
(this.sourceBlock_ as Blockly.BlockSvg).getSvgRoot().appendChild(this.fieldGroup_);
|
this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
|
||||||
// Force a render.
|
// Force a render.
|
||||||
this.render_();
|
this.render_();
|
||||||
this.size_.width = 0;
|
this.size_.width = 0;
|
||||||
@ -99,7 +99,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
|
|
||||||
// Add second dropdown
|
// Add second dropdown
|
||||||
if (this.shouldShowRect_()) {
|
if (this.shouldShowRect_()) {
|
||||||
this.box_ = <SVGRectElement>Blockly.utils.createSvgElement('rect', {
|
this.box_ = Blockly.utils.createSvgElement('rect', {
|
||||||
'rx': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
'rx': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
||||||
'ry': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
'ry': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
||||||
'x': 0,
|
'x': 0,
|
||||||
@ -112,7 +112,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
'fill-opacity': 1
|
'fill-opacity': 1
|
||||||
}, null);
|
}, null);
|
||||||
this.fieldGroup_.insertBefore(this.box_, this.textElement_);
|
this.fieldGroup_.insertBefore(this.box_, this.textElement_);
|
||||||
this.box2_ = <SVGRectElement>Blockly.utils.createSvgElement('rect', {
|
this.box2_ = Blockly.utils.createSvgElement('rect', {
|
||||||
'rx': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
'rx': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
||||||
'ry': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
'ry': (Blockly.BlockSvg as any).CORNER_RADIUS,
|
||||||
'x': 0,
|
'x': 0,
|
||||||
@ -149,9 +149,9 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
getFirstValueI11n(value: string) {
|
getFirstValueI11n(value: string) {
|
||||||
const firstValue = this.getFirstValue(value);
|
const firstValue = this.getFirstValue(value);
|
||||||
const motorOptions = {
|
const motorOptions = {
|
||||||
'medium motor': lf("medium motor"),
|
'medium motor': lf('medium motor'),
|
||||||
'large motor': lf("large motor"),
|
'large motor': lf('large motor'),
|
||||||
'large motors': lf("large motors")
|
'large motors': lf('large motors')
|
||||||
}
|
}
|
||||||
return motorOptions[firstValue];
|
return motorOptions[firstValue];
|
||||||
}
|
}
|
||||||
@ -233,8 +233,8 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
if (this.textElement2_) {
|
if (this.textElement2_) {
|
||||||
this.textElement2_.parentNode.appendChild(this.arrow2_);
|
this.textElement2_.parentNode.appendChild(this.arrow2_);
|
||||||
}
|
}
|
||||||
if (this.sourceBlock_ && (<Blockly.BlockSvg>this.sourceBlock_).rendered) {
|
if (this.sourceBlock_ && this.sourceBlock_.rendered) {
|
||||||
(<Blockly.BlockSvg>this.sourceBlock_).render();
|
this.sourceBlock_.render();
|
||||||
this.sourceBlock_.bumpNeighbours_();
|
this.sourceBlock_.bumpNeighbours_();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,12 +311,12 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
|
|
||||||
// First dropdown
|
// First dropdown
|
||||||
// Use one of the following options, medium motor, large motor or large motors (translated)
|
// Use one of the following options, medium motor, large motor or large motors (translated)
|
||||||
const textNode1 = document.createTextNode(this.getFirstValueI11n(<string>this.value_));
|
const textNode1 = document.createTextNode(this.getFirstValueI11n(this.value_));
|
||||||
this.textElement_.appendChild(textNode1);
|
this.textElement_.appendChild(textNode1);
|
||||||
|
|
||||||
// Second dropdown, no need to translate. Only port numbers
|
// Second dropdown, no need to translate. Only port numbers
|
||||||
if (this.textElement2_) {
|
if (this.textElement2_) {
|
||||||
const textNode2 = document.createTextNode(this.getSecondValue(<string>this.value_));
|
const textNode2 = document.createTextNode(this.getSecondValue(this.value_));
|
||||||
this.textElement2_.appendChild(textNode2);
|
this.textElement2_.appendChild(textNode2);
|
||||||
}
|
}
|
||||||
this.updateWidth();
|
this.updateWidth();
|
||||||
@ -401,7 +401,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
if (Blockly.DropDownDiv.hideIfOwner(this)) {
|
if (Blockly.DropDownDiv.hideIfOwner(this)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isFirst_ = e.clientX - this.getScaledBBox_().left < ((this as any).width1 * (<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).scale);
|
this.isFirst_ = e.clientX - this.getScaledBBox_().left < ((this as any).width1 * this.sourceBlock_.workspace.scale);
|
||||||
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
|
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
|
||||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||||
Blockly.DropDownDiv.clearContent();
|
Blockly.DropDownDiv.clearContent();
|
||||||
@ -433,8 +433,8 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
vals[text] = value;
|
vals[text] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentFirst = this.getFirstValue(<string>this.value_);
|
const currentFirst = this.getFirstValue(this.value_);
|
||||||
const currentSecond = this.getSecondValue(<string>this.value_);
|
const currentSecond = this.getSecondValue(this.value_);
|
||||||
|
|
||||||
if (!this.isFirst_) {
|
if (!this.isFirst_) {
|
||||||
options = opts[currentFirst];
|
options = opts[currentFirst];
|
||||||
@ -526,7 +526,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
Blockly.DropDownDiv.setColour(this.backgroundColour_, this.borderColour_);
|
Blockly.DropDownDiv.setColour(this.backgroundColour_, this.borderColour_);
|
||||||
|
|
||||||
// Calculate positioning based on the field position.
|
// Calculate positioning based on the field position.
|
||||||
let scale = (<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).scale;
|
let scale = this.sourceBlock_.workspace.scale;
|
||||||
let width = this.isFirst_ ? (this as any).width1 : (this as any).width2;
|
let width = this.isFirst_ ? (this as any).width1 : (this as any).width2;
|
||||||
let bBox = { width: this.size_.width, height: this.size_.height };
|
let bBox = { width: this.size_.width, height: this.size_.height };
|
||||||
width *= scale;
|
width *= scale;
|
||||||
@ -538,7 +538,7 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
let secondaryX = primaryX;
|
let secondaryX = primaryX;
|
||||||
let secondaryY = position.top;
|
let secondaryY = position.top;
|
||||||
// Set bounds to workspace; show the drop-down.
|
// Set bounds to workspace; show the drop-down.
|
||||||
(Blockly.DropDownDiv as any).setBoundsElement((<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).getParentSvg().parentNode);
|
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
|
||||||
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
||||||
this.onHide_.bind(this));
|
this.onHide_.bind(this));
|
||||||
|
|
||||||
@ -561,11 +561,10 @@ export class FieldMotors extends Blockly.FieldDropdown implements Blockly.FieldC
|
|||||||
* Callback for when the drop-down is hidden.
|
* Callback for when the drop-down is hidden.
|
||||||
*/
|
*/
|
||||||
protected onHide_() {
|
protected onHide_() {
|
||||||
const content = Blockly.DropDownDiv.getContentDiv();
|
Blockly.DropDownDiv.content_.removeAttribute('role');
|
||||||
content.removeAttribute('role');
|
Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup');
|
||||||
content.removeAttribute('aria-haspopup');
|
Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant');
|
||||||
content.removeAttribute('aria-activedescendant');
|
Blockly.DropDownDiv.getContentDiv().style.width = '';
|
||||||
content.style.width = '';
|
|
||||||
if (this.isFirst_ && this.box_) {
|
if (this.isFirst_ && this.box_) {
|
||||||
this.box_.setAttribute('fill', this.sourceBlock_.getColour());
|
this.box_.setAttribute('fill', this.sourceBlock_.getColour());
|
||||||
} else if (!this.isFirst_ && this.box2_) {
|
} else if (!this.isFirst_ && this.box2_) {
|
||||||
|
@ -85,7 +85,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
|||||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary());
|
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary());
|
||||||
|
|
||||||
// Calculate positioning based on the field position.
|
// Calculate positioning based on the field position.
|
||||||
let scale = (<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).scale;
|
let scale = this.sourceBlock_.workspace.scale;
|
||||||
let bBox = { width: this.size_.width, height: this.size_.height };
|
let bBox = { width: this.size_.width, height: this.size_.height };
|
||||||
bBox.width *= scale;
|
bBox.width *= scale;
|
||||||
bBox.height *= scale;
|
bBox.height *= scale;
|
||||||
@ -95,7 +95,7 @@ export class FieldMusic extends pxtblockly.FieldImages implements Blockly.FieldC
|
|||||||
let secondaryX = primaryX;
|
let secondaryX = primaryX;
|
||||||
let secondaryY = position.top;
|
let secondaryY = position.top;
|
||||||
// Set bounds to workspace; show the drop-down.
|
// Set bounds to workspace; show the drop-down.
|
||||||
(Blockly.DropDownDiv as any).setBoundsElement((<Blockly.WorkspaceSvg>this.sourceBlock_.workspace).getParentSvg().parentNode);
|
(Blockly.DropDownDiv as any).setBoundsElement(this.sourceBlock_.workspace.getParentSvg().parentNode);
|
||||||
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
(Blockly.DropDownDiv as any).show(this, primaryX, primaryY, secondaryX, secondaryY,
|
||||||
this.onHide_.bind(this));
|
this.onHide_.bind(this));
|
||||||
|
|
||||||
|
97
fieldeditors/field_speed.ts
Normal file
97
fieldeditors/field_speed.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/// <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",
|
||||||
|
width: "170"
|
||||||
|
});
|
||||||
|
|
||||||
|
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', 'dominant-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
fieldeditors/field_turnratio.ts
Normal file
108
fieldeditors/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', 'dominant-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,41 +0,0 @@
|
|||||||
import jobs.generation.Utilities;
|
|
||||||
import jobs.generation.InternalUtilities;
|
|
||||||
|
|
||||||
def project = GithubProject
|
|
||||||
def projectName = "pxt-ev3"
|
|
||||||
|
|
||||||
[true, false].each { isPR ->
|
|
||||||
def newJobName = projectName
|
|
||||||
|
|
||||||
if (isPR) {
|
|
||||||
newJobName += "_PR"
|
|
||||||
} else {
|
|
||||||
newJobName += "_Push"
|
|
||||||
}
|
|
||||||
|
|
||||||
def newJob = job(newJobName) {
|
|
||||||
steps {
|
|
||||||
shell("chmod +x ./jenkins.sh")
|
|
||||||
shell("./jenkins.sh ${isPR}")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isPR) {
|
|
||||||
wrappers {
|
|
||||||
credentialsBinding {
|
|
||||||
string("PXT_ACCESS_TOKEN", "pxt_access_token")
|
|
||||||
string("PXT_RELEASE_REPO", "pxt_release_repo_ev3")
|
|
||||||
string("CROWDIN_KEY", "pxt_crowdin_key")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Utilities.setMachineAffinity(newJob, "Ubuntu", "20161020")
|
|
||||||
InternalUtilities.standardJobSetup(newJob, project, isPR, "*/*")
|
|
||||||
|
|
||||||
if (isPR) {
|
|
||||||
Utilities.addGithubPRTrigger(newJob, "Default Testing")
|
|
||||||
} else {
|
|
||||||
Utilities.addGithubPushTrigger(newJob)
|
|
||||||
}
|
|
||||||
}
|
|
56
jenkins.sh
56
jenkins.sh
@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Set up NVM
|
|
||||||
export NVM_DIR="/home/dotnet-bot/.nvm"
|
|
||||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
|
||||||
|
|
||||||
nvm install 8
|
|
||||||
|
|
||||||
# Set up build environment variables
|
|
||||||
echo ---------- Setting build environment variables
|
|
||||||
echo Git branch: $GIT_BRANCH
|
|
||||||
echo isPR: $1
|
|
||||||
|
|
||||||
originRegex="^origin/.*"
|
|
||||||
branchRegex="^origin/\K.*(?=$)"
|
|
||||||
releaseBranchRegex="^(master|v\d+)$"
|
|
||||||
|
|
||||||
if [[ "$GIT_BRANCH" =~ $originRegex ]]; then
|
|
||||||
branchName=$(echo ${GIT_BRANCH} | grep -oP $branchRegex)
|
|
||||||
echo Setting TRAVIS_BRANCH to ${branchName}
|
|
||||||
export TRAVIS_BRANCH=${branchName}
|
|
||||||
else
|
|
||||||
echo Setting TRAVIS_BRANCH to $GIT_BRANCH
|
|
||||||
export TRAVIS_BRANCH=$GIT_BRANCH
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$1" == "false" ]; then
|
|
||||||
echo Setting TRAVIS_PULL_REQUEST to false
|
|
||||||
export TRAVIS_PULL_REQUEST=false
|
|
||||||
|
|
||||||
if [[ "$TRAVIS_BRANCH" =~ $releaseBranchRegex ]]; then
|
|
||||||
if [[ -z $PXT_RELEASE_REPO ]]; then
|
|
||||||
echo Cannot find release repo\; skipping tag checks
|
|
||||||
else
|
|
||||||
gitTag=$(git describe --tags --exact-match 2> /dev/null)
|
|
||||||
builtTag=$(git ls-remote --tags $PXT_RELEASE_REPO | grep -o "refs/tags/$gitTag$")
|
|
||||||
|
|
||||||
echo Current tag: $gitTag
|
|
||||||
echo Built tag: $builtTag
|
|
||||||
|
|
||||||
if [[ ! -z $gitTag && -z $builtTag ]]; then
|
|
||||||
echo Built tag not found\; building tag
|
|
||||||
echo Setting TRAVIS_BRANCH to $gitTag
|
|
||||||
export TRAVIS_BRANCH=$gitTag
|
|
||||||
echo Setting TRAVIS_TAG to $gitTag
|
|
||||||
export TRAVIS_TAG=$gitTag
|
|
||||||
else
|
|
||||||
echo Not a tag build
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Perform build
|
|
||||||
npm install
|
|
||||||
npm test
|
|
9
libs/base/enums.d.ts
vendored
9
libs/base/enums.d.ts
vendored
@ -22,8 +22,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
declare const enum PerfCounters {
|
declare const enum ValType {
|
||||||
GC = 0,
|
Undefined = 0,
|
||||||
|
Boolean = 1,
|
||||||
|
Number = 2,
|
||||||
|
String = 3,
|
||||||
|
Object = 4,
|
||||||
|
Function = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-generated. Do not edit. Really.
|
// Auto-generated. Do not edit. Really.
|
||||||
|
39
libs/base/shims.d.ts
vendored
39
libs/base/shims.d.ts
vendored
@ -42,12 +42,6 @@ declare interface Buffer {
|
|||||||
//% start.defl=0 length.defl=-1 shim=BufferMethods::shift
|
//% start.defl=0 length.defl=-1 shim=BufferMethods::shift
|
||||||
shift(offset: int32, start?: int32, length?: int32): void;
|
shift(offset: int32, start?: int32, length?: int32): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a buffer to string assuming UTF8 encoding
|
|
||||||
*/
|
|
||||||
//% shim=BufferMethods::toString
|
|
||||||
toString(): string;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a buffer to its hexadecimal representation.
|
* Convert a buffer to its hexadecimal representation.
|
||||||
*/
|
*/
|
||||||
@ -78,13 +72,6 @@ declare namespace control {
|
|||||||
*/
|
*/
|
||||||
//% shim=control::createBuffer
|
//% shim=control::createBuffer
|
||||||
function createBuffer(size: int32): Buffer;
|
function createBuffer(size: int32): Buffer;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new buffer with UTF8-encoded string
|
|
||||||
* @param str the string to put in the buffer
|
|
||||||
*/
|
|
||||||
//% shim=control::createBufferFromUTF8
|
|
||||||
function createBufferFromUTF8(str: string): Buffer;
|
|
||||||
}
|
}
|
||||||
declare namespace loops {
|
declare namespace loops {
|
||||||
|
|
||||||
@ -160,31 +147,7 @@ declare namespace control {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//% shim=control::__log
|
//% shim=control::__log
|
||||||
function __log(prority: int32, text: string): void;
|
function __log(text: string): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Dump internal information about a value.
|
|
||||||
*/
|
|
||||||
//% shim=control::dmesgValue
|
|
||||||
function dmesgValue(v: any): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Force GC and dump basic information about heap.
|
|
||||||
*/
|
|
||||||
//% shim=control::gc
|
|
||||||
function gc(): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Force GC and halt waiting for debugger to do a full heap dump.
|
|
||||||
*/
|
|
||||||
//% shim=control::heapDump
|
|
||||||
function heapDump(): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if profiling is enabled in the current build.
|
|
||||||
*/
|
|
||||||
//% shim=control::profilingEnabled
|
|
||||||
function profilingEnabled(): boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto-generated. Do not edit. Really.
|
// Auto-generated. Do not edit. Really.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const enum ColorSensorMode {
|
const enum ColorSensorMode {
|
||||||
None = -1,
|
None = 0,
|
||||||
//% block="reflected light intensity"
|
//% block="reflected light intensity"
|
||||||
ReflectedLightIntensity = 0,
|
ReflectedLightIntensity = 0,
|
||||||
//% block="ambient light intensity"
|
//% block="ambient light intensity"
|
||||||
|
@ -212,7 +212,6 @@ namespace sensors.internal {
|
|||||||
|
|
||||||
_activated() {
|
_activated() {
|
||||||
this.realmode = 0
|
this.realmode = 0
|
||||||
// uartReset(this.port) // TODO is it ever needed?
|
|
||||||
this._setMode(this.mode)
|
this._setMode(this.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +134,7 @@ namespace motors {
|
|||||||
protected _brake: boolean;
|
protected _brake: boolean;
|
||||||
private _pauseOnRun: boolean;
|
private _pauseOnRun: boolean;
|
||||||
private _initialized: boolean;
|
private _initialized: boolean;
|
||||||
|
private _brakeSettleTime: number;
|
||||||
private _init: () => void;
|
private _init: () => void;
|
||||||
private _run: (speed: number) => void;
|
private _run: (speed: number) => void;
|
||||||
private _move: (steps: boolean, stepsOrTime: number, speed: number) => void;
|
private _move: (steps: boolean, stepsOrTime: number, speed: number) => void;
|
||||||
@ -147,6 +148,7 @@ namespace motors {
|
|||||||
this._brake = false;
|
this._brake = false;
|
||||||
this._pauseOnRun = true;
|
this._pauseOnRun = true;
|
||||||
this._initialized = false;
|
this._initialized = false;
|
||||||
|
this._brakeSettleTime = 10;
|
||||||
this._init = init;
|
this._init = init;
|
||||||
this._run = run;
|
this._run = run;
|
||||||
this._move = move;
|
this._move = move;
|
||||||
@ -204,6 +206,20 @@ namespace motors {
|
|||||||
writePWM(b)
|
writePWM(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the settle time after braking in milliseconds (default is 10ms).
|
||||||
|
*/
|
||||||
|
//% blockId=motorSetBrakeSettleTime block="set %motor|brake settle time %millis|ms"
|
||||||
|
//% motor.fieldEditor="motors"
|
||||||
|
//% weight=1 blockGap=8
|
||||||
|
//% group="Properties"
|
||||||
|
//% millis.defl=200 millis.min=0 millis.max=500
|
||||||
|
setBrakeSettleTime(millis: number) {
|
||||||
|
this.init();
|
||||||
|
// ensure in [0,500]
|
||||||
|
this._brakeSettleTime = Math.max(0, Math.min(500, millis | 0))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the motor(s).
|
* Stops the motor(s).
|
||||||
*/
|
*/
|
||||||
@ -221,8 +237,8 @@ namespace motors {
|
|||||||
protected settle() {
|
protected settle() {
|
||||||
// if we've recently completed a motor command with brake
|
// if we've recently completed a motor command with brake
|
||||||
// allow 500ms for robot to settle
|
// allow 500ms for robot to settle
|
||||||
if (this._brake)
|
if (this._brake && this._brakeSettleTime > 0)
|
||||||
pause(500);
|
pause(this._brakeSettleTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected pauseOnRun(stepsOrTime: number) {
|
protected pauseOnRun(stepsOrTime: number) {
|
||||||
@ -396,7 +412,7 @@ namespace motors {
|
|||||||
*/
|
*/
|
||||||
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value=toggleOnOff"
|
//% blockId=outputMotorSetRegulated block="set %motor|regulated %value=toggleOnOff"
|
||||||
//% motor.fieldEditor="motors"
|
//% motor.fieldEditor="motors"
|
||||||
//% weight=58
|
//% weight=58 blockGap=8
|
||||||
//% group="Properties"
|
//% group="Properties"
|
||||||
//% help=motors/motor/set-regulated
|
//% help=motors/motor/set-regulated
|
||||||
setRegulated(value: boolean) {
|
setRegulated(value: boolean) {
|
||||||
@ -749,3 +765,9 @@ namespace motors {
|
|||||||
control.dmesg('end step')
|
control.dmesg('end step')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface Buffer {
|
||||||
|
[index: number]: number;
|
||||||
|
// rest defined in buffer.cpp
|
||||||
|
}
|
@ -44,7 +44,7 @@ namespace console._screen {
|
|||||||
printLog();
|
printLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
function log(priority: ConsolePriority, msg: string): void {
|
function log(msg: string): void {
|
||||||
lines.push(msg);
|
lines.push(msg);
|
||||||
if (lines.length + 5 > maxLines) {
|
if (lines.length + 5 > maxLines) {
|
||||||
lines.splice(0, maxLines - lines.length);
|
lines.splice(0, maxLines - lines.length);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const enum GyroSensorMode {
|
const enum GyroSensorMode {
|
||||||
None = -1,
|
None = 0,
|
||||||
Angle = 0,
|
Angle = 0,
|
||||||
Rate = 1,
|
Rate = 1,
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const enum InfraredSensorMode {
|
const enum InfraredSensorMode {
|
||||||
None = -1,
|
None = 0,
|
||||||
Proximity = 0,
|
Proximity = 0,
|
||||||
Seek = 1,
|
Seek = 1,
|
||||||
RemoteControl = 2,
|
RemoteControl = 2,
|
||||||
|
12
libs/screen/shims.d.ts
vendored
12
libs/screen/shims.d.ts
vendored
@ -45,18 +45,6 @@ declare interface Image {
|
|||||||
//% shim=ImageMethods::fill
|
//% shim=ImageMethods::fill
|
||||||
fill(c: int32): void;
|
fill(c: int32): void;
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy row(s) of pixel from image to buffer (8 bit per pixel).
|
|
||||||
*/
|
|
||||||
//% shim=ImageMethods::getRows
|
|
||||||
getRows(x: int32, dst: Buffer): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy row(s) of pixel from buffer to image.
|
|
||||||
*/
|
|
||||||
//% shim=ImageMethods::setRows
|
|
||||||
setRows(x: int32, src: Buffer): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a copy of the current image
|
* Return a copy of the current image
|
||||||
*/
|
*/
|
||||||
|
4670
package-lock.json
generated
4670
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pxt-ev3",
|
"name": "pxt-ev3",
|
||||||
"version": "1.1.0",
|
"version": "1.1.2",
|
||||||
"description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode",
|
"description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode",
|
||||||
"private": true,
|
"private": true,
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -39,8 +39,8 @@
|
|||||||
"webfonts-generator": "^0.4.0"
|
"webfonts-generator": "^0.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pxt-common-packages": "6.4.13",
|
"pxt-common-packages": "0.23.56",
|
||||||
"pxt-core": "5.5.18"
|
"pxt-core": "4.0.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
namespace pxsim {
|
namespace pxsim {
|
||||||
|
|
||||||
export class EV3Board extends CoreBoard {
|
export class EV3Board extends CoreBoard {
|
||||||
viewHost: visuals.BoardHost;
|
|
||||||
view: SVGSVGElement;
|
view: SVGSVGElement;
|
||||||
|
|
||||||
outputState: EV3OutputState;
|
outputState: EV3OutputState;
|
||||||
@ -84,16 +83,15 @@ namespace pxsim {
|
|||||||
highContrast: msg.highContrast,
|
highContrast: msg.highContrast,
|
||||||
light: msg.light
|
light: msg.light
|
||||||
};
|
};
|
||||||
this.viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView(<pxsim.visuals.BoardViewOptions>{
|
const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({
|
||||||
visual: boardDef.visual,
|
visual: boardDef.visual,
|
||||||
boardDef,
|
|
||||||
highContrast: msg.highContrast,
|
highContrast: msg.highContrast,
|
||||||
light: msg.light
|
light: msg.light
|
||||||
}), opts);
|
}), opts);
|
||||||
|
|
||||||
document.body.innerHTML = ""; // clear children
|
document.body.innerHTML = ""; // clear children
|
||||||
document.body.className = msg.light ? "light" : "";
|
document.body.className = msg.light ? "light" : "";
|
||||||
document.body.appendChild(this.view = this.viewHost.getView() as SVGSVGElement);
|
document.body.appendChild(this.view = viewHost.getView() as SVGSVGElement);
|
||||||
|
|
||||||
this.inputNodes = [];
|
this.inputNodes = [];
|
||||||
this.outputNodes = [];
|
this.outputNodes = [];
|
||||||
@ -104,8 +102,8 @@ namespace pxsim {
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
screenshotAsync(width?: number): Promise<ImageData> {
|
screenshot(): string {
|
||||||
return this.viewHost.screenshotAsync(width);
|
return svg.toDataUri(new XMLSerializer().serializeToString(this.view));
|
||||||
}
|
}
|
||||||
|
|
||||||
getBrickNode() {
|
getBrickNode() {
|
||||||
|
Reference in New Issue
Block a user