Compare commits

..

5 Commits

Author SHA1 Message Date
437c36b983 0.0.77 2018-01-30 16:16:07 -08:00
3d73f193a8 fix for #260 (#279) 2018-01-30 16:14:54 -08:00
a71dee2923 rebuild for sampling (#261)
* rebuild for sampling

* bump pxt
2018-01-30 16:01:12 -08:00
9ef5b8d4ad 0.0.76 2018-01-30 11:05:29 -08:00
8aa47f3d1e updated chassis (#250) 2018-01-30 08:49:10 -08:00
11 changed files with 82 additions and 57 deletions

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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

View File

@ -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"
} }

View File

@ -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",

View File

@ -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)

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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
View File

@ -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": {

View File

@ -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"