2017-12-18 22:04:17 +01:00
|
|
|
namespace pxsim {
|
|
|
|
|
|
|
|
export class EV3OutputState {
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
let data = new Uint8Array(10)
|
|
|
|
MMapMethods.register("/dev/lms_pwm", {
|
|
|
|
data,
|
|
|
|
beforeMemRead: () => {
|
|
|
|
//console.log("pwm before read");
|
|
|
|
for (let i = 0; i < 10; ++i)
|
|
|
|
data[i] = 0
|
|
|
|
},
|
|
|
|
read: buf => {
|
2018-01-06 09:00:04 +01:00
|
|
|
// console.log("pwm read");
|
|
|
|
if (buf.data.length == 0) return 2;
|
|
|
|
const cmd = buf.data[0];
|
|
|
|
switch (cmd) {
|
|
|
|
case DAL.opOutputTest:
|
|
|
|
const port = buf.data[1];
|
|
|
|
let r = 0;
|
|
|
|
ev3board().getMotor(port)
|
|
|
|
.filter(motor => !motor.isReady())
|
|
|
|
.forEach(motor => r |= (1 << motor.port));
|
|
|
|
pxsim.BufferMethods.setNumber(buf, BufferMethods.NumberFormat.UInt8LE, 2, r);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
let v = "vSIM"
|
|
|
|
for (let i = 0; i < buf.data.length; ++i)
|
|
|
|
buf.data[i] = v.charCodeAt(i) || 0
|
|
|
|
break;
|
|
|
|
}
|
2017-12-18 22:04:17 +01:00
|
|
|
return buf.data.length
|
|
|
|
},
|
|
|
|
write: buf => {
|
|
|
|
if (buf.data.length == 0) return 2;
|
|
|
|
const cmd = buf.data[0];
|
|
|
|
switch (cmd) {
|
|
|
|
case DAL.opProgramStart: {
|
|
|
|
// init
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
case DAL.opOutputReset: {
|
|
|
|
// reset
|
|
|
|
const port = buf.data[1];
|
|
|
|
const motors = ev3board().getMotor(port);
|
|
|
|
motors.forEach(motor => motor.reset());
|
|
|
|
return 2;
|
|
|
|
}
|
2017-12-28 02:05:15 +01:00
|
|
|
case DAL.opOutputClearCount:
|
|
|
|
const port = buf.data[1];
|
|
|
|
const motors = ev3board().getMotor(port);
|
|
|
|
motors.forEach(motor => motor.clearCount());
|
|
|
|
break;
|
|
|
|
case DAL.opOutputStepPower:
|
|
|
|
case DAL.opOutputStepSpeed:
|
|
|
|
case DAL.opOutputTimePower:
|
|
|
|
case DAL.opOutputTimeSpeed: {
|
2017-12-18 22:04:17 +01:00
|
|
|
// step speed
|
|
|
|
const port = buf.data[1];
|
2017-12-28 02:05:15 +01:00
|
|
|
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2); // signed byte
|
|
|
|
// note that b[3] is padding
|
|
|
|
const step1 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 4);
|
|
|
|
const step2 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 8);
|
|
|
|
const step3 = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int32LE, 12);
|
|
|
|
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 16);
|
2017-12-18 22:04:17 +01:00
|
|
|
//console.log(buf);
|
|
|
|
const motors = ev3board().getMotor(port);
|
2017-12-28 02:05:15 +01:00
|
|
|
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed, step1, step2, step3, brake]));
|
2017-12-18 22:04:17 +01:00
|
|
|
return 2;
|
|
|
|
}
|
2018-01-03 01:20:00 +01:00
|
|
|
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);
|
2019-08-29 22:11:01 +02:00
|
|
|
// cancel any other sync command
|
|
|
|
for(const motor of ev3board().getMotors().filter(motor => motors.indexOf(motor) < 0)) {
|
|
|
|
motor.clearSyncCmd()
|
|
|
|
}
|
|
|
|
|
|
|
|
// apply commands to all motors
|
2018-01-03 01:20:00 +01:00
|
|
|
for (const motor of motors) {
|
|
|
|
const otherMotor = motors.filter(m => m.port != motor.port)[0];
|
|
|
|
motor.setSyncCmd(
|
2018-01-05 17:40:49 +01:00
|
|
|
otherMotor,
|
2018-01-03 01:20:00 +01:00
|
|
|
cmd, [speed, turnRatio, stepsOrTime, brake]);
|
|
|
|
}
|
|
|
|
return 2;
|
|
|
|
}
|
2017-12-18 22:04:17 +01:00
|
|
|
case DAL.opOutputStop: {
|
|
|
|
// stop
|
|
|
|
const port = buf.data[1];
|
2017-12-28 02:05:15 +01:00
|
|
|
const brake = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
|
2017-12-18 22:04:17 +01:00
|
|
|
const motors = ev3board().getMotor(port);
|
|
|
|
motors.forEach(motor => motor.stop());
|
|
|
|
return 2;
|
|
|
|
}
|
2018-01-12 22:33:25 +01:00
|
|
|
case DAL.opOutputPower:
|
2017-12-18 22:04:17 +01:00
|
|
|
case DAL.opOutputSpeed: {
|
|
|
|
// setSpeed
|
|
|
|
const port = buf.data[1];
|
2017-12-28 02:05:15 +01:00
|
|
|
const speed = pxsim.BufferMethods.getNumber(buf, BufferMethods.NumberFormat.Int8LE, 2);
|
2017-12-18 22:04:17 +01:00
|
|
|
const motors = ev3board().getMotor(port);
|
2017-12-28 02:05:15 +01:00
|
|
|
motors.forEach(motor => motor.setSpeedCmd(cmd, [speed]));
|
2017-12-18 22:04:17 +01:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
case DAL.opOutputStart: {
|
|
|
|
// start
|
|
|
|
const port = buf.data[1];
|
|
|
|
const motors = ev3board().getMotor(port);
|
|
|
|
motors.forEach(motor => motor.start());
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
case DAL.opOutputPolarity: {
|
2019-10-19 07:53:30 +02:00
|
|
|
console.error("opOutputPolarity not supported");
|
2017-12-18 22:04:17 +01:00
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
case DAL.opOutputSetType: {
|
2018-04-11 16:48:07 +02:00
|
|
|
const portIndex = buf.data[1]; // not a port but a port index 0..3
|
2017-12-18 22:04:17 +01:00
|
|
|
const large = buf.data[2] == 0x07;
|
2018-04-11 16:48:07 +02:00
|
|
|
const motor = ev3board().getMotors()[portIndex];
|
|
|
|
if (motor)
|
|
|
|
motor.setLarge(large);
|
2017-12-18 22:04:17 +01:00
|
|
|
return 2;
|
|
|
|
}
|
2017-12-28 02:05:15 +01:00
|
|
|
default:
|
|
|
|
console.warn('unknown cmd: ' + cmd);
|
|
|
|
break;
|
2017-12-18 22:04:17 +01:00
|
|
|
}
|
|
|
|
return 2
|
|
|
|
},
|
|
|
|
ioctl: (id, buf) => {
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|