Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
437c36b983 | |||
3d73f193a8 | |||
a71dee2923 | |||
9ef5b8d4ad | |||
8aa47f3d1e |
@ -1,11 +1,10 @@
|
|||||||
{
|
{
|
||||||
|
"chassis": "A differential drive robot",
|
||||||
"chassis.Chassis": "A differential drive robot",
|
"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": "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|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|speed": "speed of the center point between motors, eg: 10",
|
||||||
"chassis.Chassis.drive|param|value": "the amount of movement, eg: 2",
|
"chassis.Chassis.setBaseLength": "Sets the base length in centimeters",
|
||||||
"chassis.Chassis.setMotors": "Sets the motors used by the chassis, default is B+C",
|
"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.setWheelRadius": "Sets the wheel radius in centimeters"
|
||||||
"chassis.Chassis.setProperty|param|property": "the property to set",
|
|
||||||
"chassis.Chassis.setProperty|param|value": "the value to set"
|
|
||||||
}
|
}
|
@ -1,9 +1,8 @@
|
|||||||
{
|
{
|
||||||
"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.drive|block": "drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s",
|
||||||
|
"chassis.Chassis.setBaseLength|block": "set %chassis|base length to %cm|(cm)",
|
||||||
"chassis.Chassis.setMotors|block": "set %chassis|motors to %motors",
|
"chassis.Chassis.setMotors|block": "set %chassis|motors to %motors",
|
||||||
"chassis.Chassis.setProperty|block": "set %chassis|%property|to %value",
|
"chassis.Chassis.setWheelRadius|block": "set %chassis|wheel radius to %cm|(cm)",
|
||||||
"chassis|block": "chassis",
|
"chassis|block": "chassis",
|
||||||
"{id:category}Chassis": "Chassis"
|
"{id:category}Chassis": "Chassis"
|
||||||
}
|
}
|
@ -1,10 +1,7 @@
|
|||||||
enum ChassisProperty {
|
/**
|
||||||
//% block="wheel radius (cm)"
|
* A differential drive robot
|
||||||
WheelRadius,
|
*/
|
||||||
//% block="base length (cm)"
|
//% weight=50 color=#cf00cf
|
||||||
BaseLength
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace chassis {
|
namespace chassis {
|
||||||
/**
|
/**
|
||||||
* A differential drive robot
|
* A differential drive robot
|
||||||
@ -29,13 +26,17 @@ namespace chassis {
|
|||||||
* using a unicycle model.
|
* using a unicycle model.
|
||||||
* @param speed speed of the center point between motors, eg: 10
|
* @param speed speed of the center point between motors, eg: 10
|
||||||
* @param rotationSpeed rotation of the robot around the center point, eg: 30
|
* @param rotationSpeed rotation of the robot around the center point, eg: 30
|
||||||
* @param value the amount of movement, eg: 2
|
* @param distance
|
||||||
* @param unit
|
**/
|
||||||
*/
|
|
||||||
//% blockId=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s"
|
//% blockId=motorDrive block="drive %chassis|at %speed|cm/s|turning %rotationSpeed|deg/s"
|
||||||
//% inlineInputMode=inline
|
//% inlineInputMode=inline
|
||||||
//% weight=95 blockGap=8
|
//% weight=95 blockGap=8
|
||||||
drive(speed: number, rotationSpeed: number, value: number = 0, unit: MoveUnit = MoveUnit.MilliSeconds) {
|
drive(speed: number, rotationSpeed: number, distance: number = 0) {
|
||||||
|
if (!speed) {
|
||||||
|
this.motors.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// speed is expressed in %
|
// speed is expressed in %
|
||||||
const R = this.wheelRadius; // cm
|
const R = this.wheelRadius; // cm
|
||||||
const L = this.baseLength; // cm
|
const L = this.baseLength; // cm
|
||||||
@ -52,26 +53,30 @@ namespace chassis {
|
|||||||
const sr = vr / maxw * 100; // %
|
const sr = vr / maxw * 100; // %
|
||||||
const sl = vl / maxw * 100; // %
|
const sl = vl / maxw * 100; // %
|
||||||
|
|
||||||
this.motors.tank(sr, sl, value, unit)
|
// cm / (cm/s) = s
|
||||||
|
const seconds = distance / speed;
|
||||||
|
|
||||||
|
this.motors.tank(sr, sl, seconds, MoveUnit.Seconds)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a property of the robot
|
* Sets the wheel radius in centimeters
|
||||||
* @param property the property to set
|
* @param cm
|
||||||
* @param value the value to set
|
|
||||||
*/
|
*/
|
||||||
//% blockId=chassisSetProperty block="set %chassis|%property|to %value"
|
//% blockId=chassisSetWheelRadius block="set %chassis|wheel radius to %cm|(cm)"
|
||||||
//% blockGap=8
|
setWheelRadius(cm: number) {
|
||||||
//% weight=10
|
this.wheelRadius = cm;
|
||||||
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 base length in centimeters
|
||||||
|
* @param cm
|
||||||
|
*/
|
||||||
|
//% blockId=chassisSetBaseLength block="set %chassis|base length to %cm|(cm)"
|
||||||
|
setBaseLength(cm: number) {
|
||||||
|
this.baseLength = cm;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the motors used by the chassis, default is B+C
|
* Sets the motors used by the chassis, default is B+C
|
||||||
* @param motors
|
* @param motors
|
||||||
@ -81,6 +86,10 @@ namespace chassis {
|
|||||||
setMotors(motors: motors.SynchedMotorPair) {
|
setMotors(motors: motors.SynchedMotorPair) {
|
||||||
this.motors = motors;
|
this.motors = motors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
return `chassis base ${this.baseLength}, wheel ${this.wheelRadius}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//% fixedInstance whenUsed
|
//% fixedInstance whenUsed
|
||||||
|
@ -17,5 +17,6 @@
|
|||||||
"sensors.ColorSensor.setThreshold|param|condition": "the dark or bright light condition",
|
"sensors.ColorSensor.setThreshold|param|condition": "the dark or bright light condition",
|
||||||
"sensors.ColorSensor.setThreshold|param|value": "the value threshold",
|
"sensors.ColorSensor.setThreshold|param|value": "the value threshold",
|
||||||
"sensors.ColorSensor.threshold": "Gets the threshold value",
|
"sensors.ColorSensor.threshold": "Gets the threshold value",
|
||||||
"sensors.ColorSensor.threshold|param|condition": "the light condition"
|
"sensors.ColorSensor.threshold|param|condition": "the light condition",
|
||||||
|
"sensors.color": "Returns a color that the sensor can detect"
|
||||||
}
|
}
|
@ -26,6 +26,7 @@
|
|||||||
"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.color|block": "color %color",
|
||||||
"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",
|
||||||
|
@ -19,21 +19,21 @@ enum LightIntensityMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const enum ColorSensorColor {
|
const enum ColorSensorColor {
|
||||||
//% block="none"
|
//% block="none" blockIdentity=sensors.color
|
||||||
None,
|
None,
|
||||||
//% block="black"
|
//% block="black" blockIdentity=sensors.color
|
||||||
Black,
|
Black,
|
||||||
//% block="blue"
|
//% block="blue" blockIdentity=sensors.color
|
||||||
Blue,
|
Blue,
|
||||||
//% block="green"
|
//% block="green" blockIdentity=sensors.color
|
||||||
Green,
|
Green,
|
||||||
//% block="yellow"
|
//% block="yellow" blockIdentity=sensors.color
|
||||||
Yellow,
|
Yellow,
|
||||||
//% block="red"
|
//% block="red" blockIdentity=sensors.color
|
||||||
Red,
|
Red,
|
||||||
//% block="white"
|
//% block="white" blockIdentity=sensors.color
|
||||||
White,
|
White,
|
||||||
//% block="brown"
|
//% block="brown" blockIdentity=sensors.color
|
||||||
Brown,
|
Brown,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,6 +157,7 @@ namespace sensors {
|
|||||||
//% sensor.fieldEditor="ports"
|
//% sensor.fieldEditor="ports"
|
||||||
//% weight=98
|
//% weight=98
|
||||||
//% group="Color Sensor"
|
//% group="Color Sensor"
|
||||||
|
//% blockGap=8
|
||||||
color(): ColorSensorColor {
|
color(): ColorSensorColor {
|
||||||
this.setMode(ColorSensorMode.Color)
|
this.setMode(ColorSensorMode.Color)
|
||||||
return this.getNumber(NumberFormat.UInt8LE, 0)
|
return this.getNumber(NumberFormat.UInt8LE, 0)
|
||||||
@ -263,45 +264,57 @@ namespace sensors {
|
|||||||
|
|
||||||
this.light(mode); // trigger a read
|
this.light(mode); // trigger a read
|
||||||
pauseUntil(() => this.isActive()); // ensure sensor is live
|
pauseUntil(() => this.isActive()); // ensure sensor is live
|
||||||
|
|
||||||
|
|
||||||
let vold = 0;
|
let vold = 0;
|
||||||
let vcount = 0;
|
let vcount = 0;
|
||||||
let min = 200;
|
let min = 200;
|
||||||
let max = -200;
|
let max = -200;
|
||||||
let k = 0;
|
let k = 0;
|
||||||
while(k++ < 1000 && vcount < 50) {
|
while (k++ < 1000 && vcount < 50) {
|
||||||
let v = this.light(mode);
|
let v = this.light(mode);
|
||||||
min = Math.min(min, v);
|
min = Math.min(min, v);
|
||||||
max = Math.max(max, v);
|
max = Math.max(max, v);
|
||||||
// detect if nothing has changed and stop calibration
|
// detect if nothing has changed and stop calibration
|
||||||
if (Math.abs(v - vold) <= 2)
|
if (Math.abs(v - vold) <= 2)
|
||||||
vcount ++;
|
vcount++;
|
||||||
else {
|
else {
|
||||||
vold = v;
|
vold = v;
|
||||||
vcount = 1;
|
vcount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait a bit
|
// wait a bit
|
||||||
loops.pause(50);
|
loops.pause(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply tolerance
|
// apply tolerance
|
||||||
const minDist = 10;
|
const minDist = 10;
|
||||||
min = Math.max(minDist / 2, Math.min(min + deviation / 2, max - deviation / 2 - minDist / 2));
|
min = Math.max(minDist / 2, Math.min(min + deviation / 2, max - deviation / 2 - minDist / 2));
|
||||||
max = Math.min(100 - minDist / 2, Math.max(min + minDist, max - deviation / 2));
|
max = Math.min(100 - minDist / 2, Math.max(min + minDist, max - deviation / 2));
|
||||||
|
|
||||||
// apply thresholds
|
// apply thresholds
|
||||||
this.thresholdDetector.setLowThreshold(min);
|
this.thresholdDetector.setLowThreshold(min);
|
||||||
this.thresholdDetector.setHighThreshold(max);
|
this.thresholdDetector.setHighThreshold(max);
|
||||||
|
|
||||||
this.calibrating = false;
|
this.calibrating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a color that the sensor can detect
|
||||||
|
*/
|
||||||
|
//% shim=TD_ID
|
||||||
|
//% blockId=colorSensorColor block="color %color"
|
||||||
|
//% group="Color Sensor"
|
||||||
|
//% weight=97
|
||||||
|
export function color(color: ColorSensorColor): ColorSensorColor {
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
//% whenUsed block="color 3" weight=95 fixedInstance jres=icons.port3
|
//% whenUsed block="color 3" weight=95 fixedInstance jres=icons.port3
|
||||||
export const color3: ColorSensor = new ColorSensor(3)
|
export const color3: ColorSensor = new ColorSensor(3)
|
||||||
|
|
||||||
//% whenUsed block="color 1" weight=90 fixedInstance jres=icons.port1
|
//% whenUsed block="color 1" weight=90 fixedInstance jres=icons.port1
|
||||||
export const color1: ColorSensor = new ColorSensor(1)
|
export const color1: ColorSensor = new ColorSensor(1)
|
||||||
|
|
||||||
|
@ -11,5 +11,7 @@
|
|||||||
"datalog.addValue|param|value": "value of the cell, eg: 0",
|
"datalog.addValue|param|value": "value of the cell, eg: 0",
|
||||||
"datalog.flush": "Commits any buffered row to disk",
|
"datalog.flush": "Commits any buffered row to disk",
|
||||||
"datalog.setEnabled": "Turns on or off datalogging",
|
"datalog.setEnabled": "Turns on or off datalogging",
|
||||||
|
"datalog.setSampleInterval": "Sets the minimum number of milli seconds between rows",
|
||||||
|
"datalog.setSampleInterval|param|millis": "milliseconds between each sample, eg: 50",
|
||||||
"datalog.setStorage": "* @param storage custom storage solution"
|
"datalog.setStorage": "* @param storage custom storage solution"
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
"datalog.addRow|block": "datalog add row",
|
"datalog.addRow|block": "datalog add row",
|
||||||
"datalog.addValue|block": "datalog add %name|=%value",
|
"datalog.addValue|block": "datalog add %name|=%value",
|
||||||
"datalog.setEnabled|block": "datalog %enabled=toggleOnOff",
|
"datalog.setEnabled|block": "datalog %enabled=toggleOnOff",
|
||||||
|
"datalog.setSampleInterval|block": "set datalog sampling interval to %millis|(ms)",
|
||||||
"datalog|block": "datalog",
|
"datalog|block": "datalog",
|
||||||
"{id:category}Datalog": "Datalog"
|
"{id:category}Datalog": "Datalog"
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ namespace datalog.ev3 {
|
|||||||
/**
|
/**
|
||||||
* A datalog storage for the EV3
|
* A datalog storage for the EV3
|
||||||
*/
|
*/
|
||||||
export class EV3DatalogStorage extends DatalogStorage { // implements DatalogStorage {
|
export class EV3DatalogStorage extends DatalogStorage {
|
||||||
private _filename: string;
|
private _filename: string;
|
||||||
private _buffer: string;
|
private _buffer: string;
|
||||||
private _storage: storage.Storage;
|
private _storage: storage.Storage;
|
||||||
@ -38,18 +38,18 @@ namespace datalog.ev3 {
|
|||||||
// commit row data
|
// commit row data
|
||||||
this._buffer += storage.toCSV(values, this._storage.csvSeparator);
|
this._buffer += storage.toCSV(values, this._storage.csvSeparator);
|
||||||
// buffered writes
|
// buffered writes
|
||||||
if (this._buffer.length > 1024)
|
if (this._buffer.length > 512)
|
||||||
this.flush();
|
this.flush();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Flushes any buffered data
|
* Flushes any buffered data
|
||||||
*/
|
*/
|
||||||
flush(): void {
|
flush(): void {
|
||||||
if (this._buffer) {
|
if (this._buffer) {
|
||||||
const b = this._buffer;
|
const b = this._buffer;
|
||||||
this._buffer = "";
|
this._buffer = "";
|
||||||
this._storage.append(this._filename, b);
|
this._storage.append(this._filename, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// automatic hook up
|
// automatic hook up
|
||||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pxt-ev3",
|
"name": "pxt-ev3",
|
||||||
"version": "0.0.75",
|
"version": "0.0.77",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pxt-ev3",
|
"name": "pxt-ev3",
|
||||||
"version": "0.0.75",
|
"version": "0.0.77",
|
||||||
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
|
"description": "LEGO Mindstorms EV3 for Microsoft MakeCode",
|
||||||
"private": true,
|
"private": true,
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@ -44,8 +44,8 @@
|
|||||||
"webfonts-generator": "^0.4.0"
|
"webfonts-generator": "^0.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pxt-common-packages": "0.17.12",
|
"pxt-common-packages": "0.17.13",
|
||||||
"pxt-core": "3.0.26"
|
"pxt-core": "3.0.29"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
"test": "node node_modules/pxt-core/built/pxt.js travis"
|
||||||
|
Reference in New Issue
Block a user