Skip to content

Commit

Permalink
Merge pull request #783 from RoborisenDev/develop-hw
Browse files Browse the repository at this point in the history
[Roborisen] 슬래이브 큐브 연결 끊김 대응
  • Loading branch information
Tnks2U authored Oct 24, 2024
2 parents 3ef3c78 + 2cfcee6 commit 7634591
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 105 deletions.
179 changes: 102 additions & 77 deletions app/modules/pingpong_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ class PingpongBase extends BaseModule {

console.log('PINGPONG construct : G%d', this.cubeCount);
}

//#region makePackets
makePackets(method, grpid = 0) {
console.log('makePackets');
//console.log('..make_packet: ' + method);

// CUBE_ID[0:3] / ASSIGNED_ID[4:5] / OPCODE[6] / SIZE[7:8] / OPT[9..11]
// virtual

Expand Down Expand Up @@ -91,7 +88,30 @@ class PingpongBase extends BaseModule {
10, // interval //YIM's 30->10
0x01,
]);
} else if (method === 'dongleReset') {
result = Buffer.from([
0xdd,
0xdd,
0xdd,
0xdd,
0x00,
0x00,
0xda,
0x00,
0x0b,
0x00,
0xcd,
]);
}
console.log(
'make_packet: ' +
result
.toString('hex')
.match(/.{1,2}/g)
.join(' ') +
' ' +
method
);
return result;
}

Expand All @@ -106,7 +126,7 @@ class PingpongBase extends BaseModule {

// 연결 후 초기에 송신할 데이터가 필요한 경우 사용합니다.
requestInitialData(sp, payload) {
console.log('requestInitialData');
// console.log('requestInitialData');
const grpid = payload.match(/[0-7]{1,2}$/g);
if (grpid == null) {
console.warn('Wrong group id inputted', payload);
Expand All @@ -116,10 +136,10 @@ class PingpongBase extends BaseModule {

if (checkMultiroleAction == false) {
checkMultiroleAction = true;
return this.makePackets('setMultirole', grpno);
return this.makePackets('setMultirole', grpno);
} else {
return null;
}
}
}

dbgHexstr(data) {
Expand All @@ -136,6 +156,7 @@ class PingpongBase extends BaseModule {
}

// 연결 후 초기에 수신받아서 정상연결인지를 확인해야하는 경우 사용합니다.
//#region checkInitialData
checkInitialData(data, config) {
console.log('P:checkInitialData: / data(%d)', data.length);

Expand All @@ -160,7 +181,7 @@ class PingpongBase extends BaseModule {
this.sp.write(this.makePackets('getSensorData'), (err) => {
console.log('send get Sensor Data.');
});
}, 500);
}, 500);
// YIM's getsensor 명령얼 보내야 할 곳으로 보임..
return true;
} //YIM's G2~4 까지는 checkInitialData 리턴이 true 가 되지 않음 , 이 때 firmwarecheck 설정이 true이면 문제가 됨 ???
Expand All @@ -175,14 +196,14 @@ class PingpongBase extends BaseModule {

// optional. 하드웨어에서 받은 데이터의 검증이 필요한 경우 사용합니다.
validateLocalData(data) {
console.log('validateLocalData');
//console.log('P:validateLocalData: '+data.length);
return true;
}

// 엔트리에서 받은 데이터에 대한 처리
//#region handleRemoteData 엔->
handleRemoteData(handler) {
console.log('handleRemoteData');
// console.log('handleRemoteData');
this.send_cmd = handler.read('COMMAND');
if (this.send_cmd) {
if (this.send_cmd.id == -1) {
Expand All @@ -197,8 +218,9 @@ class PingpongBase extends BaseModule {
}

// 하드웨어 기기에 전달할 데이터
//#region requestLocalData 하<-
requestLocalData() {
console.log('requestLocalData');
// console.log('requestLocalData');
const self = this;
if (!this.isDraing && this.sendBuffer.length > 0) {
this.isDraing = true;
Expand All @@ -214,70 +236,61 @@ class PingpongBase extends BaseModule {

return null;
}

// 하드웨어에서 온 데이터 처리
//#region handleLocalData 하->
handleLocalData(data) {
console.log('handleLocalData');
if (!this.isConnected) {
}

console.log('handleLocalData '+data.toString('hex').match(/.{1,2}/g).join(' '));
this.slicingAnalyzingData(data);
if (data.length >= 9) {
const packetSize = data.readInt16BE(7);
const opcode = data[6];

if (opcode == 0xb8 && this.cubeCount * 20 == data.length) {
for (let x = 0; x < this.cubeCount; x++) {
// 센서 패킷은 20개씩 들어옴
const cubeid = Number(data[0+(20*x)].toString(16).slice(1, 2));

console.log("handleLocalData x : ", x);
console.log("handleLocalData cubeid : ", data[0+(20*x)]);
console.log("handleLocalData cubeid : ", cubeid);

if (cubeid >= this.cubeCount) {
return;
}

const sensor = this._sensorData[cubeid];

sensor.MOVE_X = data.readInt8(12+(20*x));
sensor.MOVE_Y = data.readInt8(13+(20*x));
sensor.MOVE_Z = data.readInt8(14+(20*x));

const xx = Math.max(Math.min(data.readInt8(15+(20*x)), 90), -90);
let yy = Math.max(Math.min(data.readInt8(16+(20*x)), 90), -90);
yy *= -1;
const zz = Math.max(Math.min(data.readInt8(17+(20*x)), 90), -90);
sensor.TILT_X = xx;
sensor.TILT_Y = yy;
sensor.TILT_Z = zz;

sensor.BUTTON = data[11+(20*x)];

sensor.PROXIMITY = data.readUInt8(18+(20*x));

// 기존 FW 70 버전 = data length 19 bytes (ANALOG IN 미지원)
if (packetSize > 19) {
sensor.AIN = data.readUInt8(19+(20*x)) * 4;
} else {
sensor.AIN = 0;
}
// 센서 패킷은 20개씩 들어옴
const cubeid = Number(data[0 + 20 * x].toString(16).slice(1, 2));
// console.log("handleLocalData x : ", x);
// console.log("handleLocalData cubeid : ", data[0+(20*x)]);
// console.log("handleLocalData cubeid : ", cubeid);

if (cubeid >= this.cubeCount) {
return;
}

const sensor = this._sensorData[cubeid];

sensor.MOVE_X = data.readInt8(12 + 20 * x);
sensor.MOVE_Y = data.readInt8(13 + 20 * x);
sensor.MOVE_Z = data.readInt8(14 + 20 * x);

sensor.TILT_X = Math.max(Math.min(data.readInt8(15 + 20 * x), 90), -90);
sensor.TILT_Y = -Math.max(Math.min(data.readInt8(16 + 20 * x), 90), -90);
sensor.TILT_Z = Math.max(Math.min(data.readInt8(17 + 20 * x), 90), -90);

sensor.BUTTON = data[11 + 20 * x];

sensor.PROXIMITY = data.readUInt8(18 + 20 * x);

// 기존 FW 70 버전 = data length 19 bytes (ANALOG IN 미지원)
if (packetSize > 19) {
sensor.AIN = data.readUInt8(19 + 20 * x) * 4;
} else {
sensor.AIN = 0;
}
}
console.log('handleLocalData : ', this._sensorData);
}
}
}

// 엔트리로 전달할 데이터
//#region requestRemoteData 엔<-
requestRemoteData(handler) {
console.log('requestRemoteData');
// console.log('requestRemoteData');
const self = this;
Object.keys(this.readValue).forEach((key) => {
if (self.readValue[key] !== undefined) {
handler.write(key, self.readValue[key]);
}
});

//XXX: entryjs의 monitorTemplate 사용하려면 트리상단에 PORT 정보 보내야함
// wooms 첫번째 큐브만 정상적으로 들어옴
for (let cubeid = 0; cubeid < this.cubeCount; cubeid++) {
Expand All @@ -304,43 +317,55 @@ class PingpongBase extends BaseModule {
}

// 하드웨어 연결 해제 시 호출됩니다.
//#region disconnect
disconnect(connect) {
console.log('P:disconnect: ');

console.log('P:disconnect');
if (this.sp) {
this.sp.write(this.makePackets('disconnect'));
this.sp.write(this.makePackets('dongleReset'));
this.sp = null;
}
dialog.showMessageBox({
title: '핑퐁 로봇',
message: '3초 후 재시작 됩니다.',
});

checkMultiroleAction = false;

if (this.sp) {
this.sp.write(this.makePackets('disconnect'), (err) => {
console.log('disconnect error', err);
if (this.sp.isOpen) {
console.log('Disconnect');
setTimeout(() => {
connect.close();
}, 1000);
}
this.sp = null;
});
} else {
setTimeout(() => {
setTimeout(() => {
if (connect) {
connect.close();
}, 1000);
}

}
checkMultiroleAction = false;
}, 1000);
setTimeout(() => {
app.relaunch();
app.exit(0);
app.exit(0);
}, 3000);
}

// 엔트리와의 연결 종료 후 처리 코드입니다.
reset() {
console.log('P:reset: ');
}

//#region slicingAnalyzingData
slicingAnalyzingData(data) {
let packet = 0;
for (let i = 0; i < data.length; i += packet) {
packet = data[i + 7] + data[i + 8];
if (packet == 0) {
//센서값이 패킷중 00로 들어오는경우가 있음
console.log('zero issue');
packet = 20;
}
let cutData = data.slice(i, i + packet);
if (cutData[6] === 0xad) {
console.error(
'Disconnection is detected packet:opcode=' + packet + ':' + cutData[6]
);
this.disconnect();
break;
}
}
}
}

module.exports = PingpongBase;
62 changes: 38 additions & 24 deletions app/modules/pingpong_g1.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const BaseModule = require('./baseModule');
const PingpongBase = require('./pingpong_base');

class PingpongG1 extends BaseModule {
class PingpongG1 extends PingpongBase {
constructor() {
super();

Expand Down Expand Up @@ -72,9 +72,23 @@ class PingpongG1 extends BaseModule {
0xff, 0xff, 0xff, 0xff, 0x00, 0xc8 /* continuous sampling*/, 0xb8, 0x00, 0x0b, 20,
0x01,
]);
} else if (method === 'dongleReset') {
result = Buffer.from([
0xDD,
0xDD,
0xDD,
0xDD,
0x00,
0x00,
0xDA,
0x00,
0x0B,
0x00,
0xCD,
]);
}
return result;
}
}

/*
sendRemoteRequest() {
Expand Down Expand Up @@ -275,27 +289,27 @@ class PingpongG1 extends BaseModule {
}

// 하드웨어 연결 해제 시 호출됩니다.
disconnect(connect) {
console.log('P:disconnect: ');

//console.log('.. ', this.sp.isOpen);
if (this.sp) {
// set led
//this.sp.write( Buffer.from('ffffffff0000ce000e0200000150', 'hex') );
// getSensor disable
//this.sp.write( Buffer.from('ffffffff00c8b8000b0001', 'hex') );

this.sp.write(this.makePackets('disconnect'), (err) => {
if (this.sp.isOpen) {
console.log('Disconnect');
connect.close();
}
this.sp = null;
});
} else {
connect.close();
}
}
// disconnect(connect) {
// console.log('P:disconnect: ');

// //console.log('.. ', this.sp.isOpen);
// if (this.sp) {
// // set led
// //this.sp.write( Buffer.from('ffffffff0000ce000e0200000150', 'hex') );
// // getSensor disable
// //this.sp.write( Buffer.from('ffffffff00c8b8000b0001', 'hex') );

// this.sp.write(this.makePackets('disconnect'), (err) => {
// if (this.sp.isOpen) {
// console.log('Disconnect');
// connect.close();
// }
// this.sp = null;
// });
// } else {
// connect.close();
// }
// }

// 엔트리와의 연결 종료 후 처리 코드입니다.
reset() {
Expand Down
2 changes: 1 addition & 1 deletion app/modules/pingpong_g1.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"type": "bluetooth",
"control": "slave",
"duration": 50,
"lostTimer": 1000,
"vendor": "Microsoft",
"lostTimer": 5000,
"firmwarecheck": false,
"baudRate": 115200
}
Expand Down
2 changes: 1 addition & 1 deletion app/modules/pingpong_g2.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"type": "bluetooth",
"control": "slave",
"duration": 50,
"lostTimer": 5000,
"lostTimer": 1000,
"vendor": "Microsoft",
"baudRate": 115200
}
Expand Down
Loading

0 comments on commit 7634591

Please sign in to comment.