Motor sync support in simulator (#159)

* parse sync motor command

* better sim support

* sync support

* fixing tank
This commit is contained in:
Peli de Halleux
2018-01-02 16:20:00 -08:00
committed by GitHub
parent 1bc93013e6
commit c35dbdd38f
6 changed files with 4758 additions and 19 deletions

View File

@ -15,6 +15,7 @@ namespace pxsim {
private speedCmdValues: number[];
private speedCmdTacho: number;
private speedCmdTime: number;
private _synchedMotor: MotorNode; // non-null if master motor
constructor(port: number, large: boolean) {
super(port);
@ -22,22 +23,34 @@ namespace pxsim {
}
getSpeed() {
return this.speed * (this.polarity == 0 ? -1 : 1);
return this.speed * (this.polarity == 0 ? -1 : 1);
}
getAngle() {
return this.angle;
}
// returns the slave motor if any
getSynchedMotor() {
return this._synchedMotor;
}
setSpeedCmd(cmd: DAL, values: number[]) {
this.speedCmd = cmd;
this.speedCmdValues = values;
this.speedCmdTacho = this.angle;
this.speedCmdTime = pxsim.U.now();
delete this._synchedMotor;
}
setSyncCmd(motor: MotorNode, cmd: DAL, values: number[]) {
this.setSpeedCmd(cmd, values);
this._synchedMotor = motor;
}
clearSpeedCmd() {
delete this.speedCmd;
delete this._synchedMotor;
}
setLarge(large: boolean) {
@ -77,7 +90,7 @@ namespace pxsim {
console.log(`motor: ${elapsed}ms - ${this.speed}% - ${this.angle}> - ${this.tacho}|`)
const interval = Math.min(20, elapsed);
let t = 0;
while(t < elapsed) {
while (t < elapsed) {
let dt = interval;
if (t + dt > elapsed) dt = elapsed - t;
this.updateStateStep(dt);
@ -97,14 +110,14 @@ namespace pxsim {
case DAL.opOutputTimeSpeed:
case DAL.opOutputTimePower:
case DAL.opOutputStepPower:
case DAL.opOutputStepSpeed:
case DAL.opOutputStepSpeed: {
// ramp up, run, ramp down, <brake> using time
const speed = this.speedCmdValues[0];
const step1 = this.speedCmdValues[1];
const step2 = this.speedCmdValues[2];
const step3 = this.speedCmdValues[3];
const brake = this.speedCmdValues[4];
const dstep = (this.speedCmd == DAL.opOutputTimePower || this.speedCmd == DAL.opOutputTimeSpeed)
const dstep = (this.speedCmd == DAL.opOutputTimePower || this.speedCmd == DAL.opOutputTimeSpeed)
? pxsim.U.now() - this.speedCmdTime
: this.tacho - this.speedCmdTacho;
if (dstep < step1) // rampup
@ -117,9 +130,33 @@ namespace pxsim {
if (brake) this.speed = 0;
this.clearSpeedCmd();
}
this.speed = Math.round(this.speed); // integer only
break;
}
case DAL.opOutputStepSync:
case DAL.opOutputTimeSync: {
if (!this._synchedMotor) // handled in other motor code
break;
const otherMotor = this._synchedMotor;
const speed = this.speedCmdValues[0];
const turnRatio = this.speedCmdValues[1];
const stepsOrTime = this.speedCmdValues[2];
const brake = this.speedCmdValues[3];
const dstep = this.speedCmd == DAL.opOutputTimeSync
? pxsim.U.now() - this.speedCmdTime
: this.tacho - this.speedCmdTacho;
if (dstep < stepsOrTime)
this.speed = speed;
else {
if (brake) this.speed = 0;
this.clearSpeedCmd();
}
// send synched motor state
otherMotor.speed = Math.floor(this.speed * turnRatio / 100);
break;
}
}
this.speed = Math.round(this.speed); // integer only
// compute delta angle
const rotations = this.getSpeed() / 100 * this.rotationsPerMilliSecond * elapsed;

View File

@ -56,6 +56,25 @@ namespace pxsim {
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed, step1, step2, step3, brake]));
return 2;
}
case DAL.opOutputStepSync:
case DAL.opOutputTimeSync: {
const port = buf.data[1];
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2); // signed byte
// note that b[3] is padding
const turnRatio = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int16LE, 4);
// b[6], b[7] is padding
const stepsOrTime = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 8);
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 12);
const motors = ev3board().getMotor(port);
for (const motor of motors) {
const otherMotor = motors.filter(m => m.port != motor.port)[0];
motor.setSyncCmd(
motor.port < otherMotor.port ? otherMotor : undefined,
cmd, [speed, turnRatio, stepsOrTime, brake]);
}
return 2;
}
case DAL.opOutputStop: {
// stop
const port = buf.data[1];