From 9c7193734e9c0c36b4eee3a4cc2889ed09a5be14 Mon Sep 17 00:00:00 2001 From: hakueon Date: Wed, 21 May 2025 14:38:37 +0900 Subject: [PATCH 01/10] =?UTF-8?q?=EC=BB=A4=EB=84=A5=ED=8A=B8=20lite=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hardwareLite/block_alux_connect_lite.js | 248 +++++++++++------- .../metadata_alux_connect_lite.json | 2 +- 2 files changed, 147 insertions(+), 103 deletions(-) diff --git a/src/playground/blocks/hardwareLite/block_alux_connect_lite.js b/src/playground/blocks/hardwareLite/block_alux_connect_lite.js index a664da4c39..8c6c6be99f 100644 --- a/src/playground/blocks/hardwareLite/block_alux_connect_lite.js +++ b/src/playground/blocks/hardwareLite/block_alux_connect_lite.js @@ -83,7 +83,17 @@ const _throttle = require('lodash/throttle'); } this.remoteEvent = _throttle( () => { - Entry.engine.fireEvent('connectlite_event_remote_input'); + // 통신 상태를 저장하고 이벤트 후에 복원 + const prevFlag = this.sendFlag; + try { + + Entry.engine.fireEvent('connectlite_event_remote_input'); + } catch (e) { + + } finally { + // 이벤트 처리 후 원래 통신 상태 복원 + this.sendFlag = prevFlag; + } }, EVENT_INTERVAL, eventSetting @@ -100,13 +110,13 @@ const _throttle = require('lodash/throttle'); this.qRear = 0; this.qFront = 0; this.qSize = 128; - this.qBuffer = new Uint8Array(this.qSize + 2).fill(-1); + this.qBuffer = new Uint8Array(this.qSize + 2).fill(-1); this.inputPacket = new Uint8Array(RECEIVED_PACKET_LENGTH).fill(-1); this.pLength = 0; // packet length this.process = false; // packet process this.version = 0; - this.sendFlag = true; + this.sendFlag = true; this.blockMenuBlocks = [ //dropdown @@ -169,7 +179,7 @@ const _throttle = require('lodash/throttle'); 'connectlite_play_melody_sec_output', 'connectlite_play_melody_output', 'connectlite_play_value_sec_output', - 'connectlite_play_value_output', + 'connectlite_play_value_output', 'connectlite_play_melody_track_output', 'connectlite_play_melody_off', 'connectlite_set_rgbled_on_output', @@ -182,7 +192,7 @@ const _throttle = require('lodash/throttle'); //EEPROM 'connectlite_set_eeprom_write', ]; - } + } setLanguage() { return { @@ -255,12 +265,12 @@ const _throttle = require('lodash/throttle'); connectlite_item_error: '오류', connectlite_item_nothing: '없음', - + connectlite_when_press_remote_key: '%1 리모컨 %2 키를 눌렀을 때', connectlite_when_input_digital_value: '%1 디지털 입력 %2 이(가) 들어왔을 때', - + connectlite_set_sensor_setting: '입력포트 %1 을(를) %2 센서로 설정 %3', - + connectlite_is_remote_key: '리모컨 입력 %1', connectlite_is_digital_value: '디지털 입력 %1', connectlite_is_extension_digital_input: '확장 디지털 입력 %1 의 %2', @@ -278,8 +288,8 @@ const _throttle = require('lodash/throttle'); connectlite_is_multi_sensor: '멀티키 센서 %1의 %2', connectlite_is_multi_switch: '분배 스위치 %1의 %2', connectlite_set_eeprom_call: 'EEPROM %1 주소의 값 호출하기 %2', - connectlite_get_eeprom_address_value: 'EEPROM 주소의 값', - + connectlite_get_eeprom_address_value: 'EEPROM 주소의 값', + connectlite_set_port_output: '출력핀 %1 을(를) %2 %3', connectlite_set_servo_output: '서보 모터 %1 의 위치를 %2 로 이동 %3', connectlite_set_s_dc_output: 'S 모터 %1 을(를) %2 속도로 회전 %3', @@ -373,7 +383,7 @@ const _throttle = require('lodash/throttle'); connectlite_item_melody_end: 'End', connectlite_item_melody_level_up: 'Level up', connectlite_item_melody_level_down: 'Level down', - + connectlite_item_error: 'error', connectlite_item_nothing: 'nothing', @@ -445,7 +455,7 @@ const _throttle = require('lodash/throttle'); AA3: 0, AA4: 0 }, - Start: { + Start: { AA1: 0, AA2: 0, AA3: 0, @@ -564,7 +574,7 @@ const _throttle = require('lodash/throttle'); Buff: 0, Count: 0 }; - + if (Entry.hwLite && Entry.hwLite.serial) { Entry.hwLite.serial.update(); }; @@ -593,11 +603,19 @@ const _throttle = require('lodash/throttle'); Entry.addEventListener('run', this.handleRemoteEventInterval.bind(this)); Entry.addEventListener('run', this.handleDigitalEventInterval.bind(this)); - Entry.addEventListener('beforeStop', clearInterval(this.remoteEventIntervalId)); - Entry.addEventListener('beforeStop', clearInterval(this.digitalEventIntervalId)); + Entry.addEventListener('beforeStop', () => { + if (this.remoteEventIntervalId) { + clearInterval(this.remoteEventIntervalId); + this.remoteEventIntervalId = null; + } + if (this.digitalEventIntervalId) { + clearInterval(this.digitalEventIntervalId); + this.digitalEventIntervalId = null; + } + }); this.setZero(); - + if (this.version === 0) { const packet = await Entry.hwLite.serial.reader.read(); this.version = packet.value[0]; @@ -613,17 +631,32 @@ const _throttle = require('lodash/throttle'); } handleRemoteEventInterval() { - this.remoteEventIntervalId = setInterval(this.remoteEvent.bind(this), EVENT_INTERVAL); + // 기존 인터벌이 있으면 제거 + if (this.remoteEventIntervalId) { + clearInterval(this.remoteEventIntervalId); + } + this.remoteEventIntervalId = setInterval(() => { + // sendFlag 확인 후 이벤트 발생 + const currentState = this.remoteEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); } handleDigitalEventInterval() { this.digitalEventIntervalId = setInterval(this.digitalEvent.bind(this), EVENT_INTERVAL); } + // 디바이스에서 값을 읽어온다. // 디바이스에서 값을 읽어온다. handleLocalData(buffer) { + + // 데이터가 들어왔으므로 통신 타임아웃 초기화 + if (this._recoverTimeoutId) { + clearTimeout(this._recoverTimeoutId); + } + buffer.forEach(b => this.qEnqueue(b)); - + while(this.qCount() >= this.inputPacket.length) { if (!this.process) { while(this.qCount() > 0) { @@ -639,7 +672,7 @@ const _throttle = require('lodash/throttle'); } } } - + if (this.process && (this.qCount() >= this.pLength)) { for (let i = 3; i < this.pLength; i++) { this.inputPacket[i] = this.qDequeue(); @@ -656,16 +689,26 @@ const _throttle = require('lodash/throttle'); } if (this.sendFlag) { - setTimeout( - () => { + // 기존 대기중인 타임아웃 취소 + if (this._requestTimeoutId) { + clearTimeout(this._requestTimeoutId); + } + + this._requestTimeoutId = setTimeout( + () => { if (Entry.hwLite && Entry.hwLite.serial) { Entry.hwLite.serial.update(); this.sendFlag = false; + + // 응답 타임아웃 처리: 일정 시간 후에도 응답이 없으면 복구 + this._recoverTimeoutId = setTimeout(() => { + this.sendFlag = true; + }, SERIAL_INTERVAL * 3); } }, SERIAL_INTERVAL ); - }; + } } //디바이스에 값을 쓴다. @@ -675,6 +718,7 @@ const _throttle = require('lodash/throttle'); } } + qEnqueue(data) { this.qBuffer[this.qRear] = data; this.qRear = (this.qRear + 1) % this.qSize @@ -702,7 +746,7 @@ const _throttle = require('lodash/throttle'); return (checker & 0xFF); } - + checksumHandle(packet) { let checker = 0; const length = packet[2] + 2; @@ -744,7 +788,7 @@ const _throttle = require('lodash/throttle'); this.InputData.Remote.R_3 = (remoteByte1 >> 7) & 0x01; this.InputData.Remote.R_2 = (remoteByte1 >> 6) & 0x01; this.InputData.Remote.R_4 = (remoteByte1 >> 5) & 0x01; - this.InputData.Remote.R_1 = (remoteByte1 >> 4) & 0x01; + this.InputData.Remote.R_1 = (remoteByte1 >> 4) & 0x01; this.InputData.Remote.R_7 = (remoteByte2 >> 7) & 0x01; this.InputData.Remote.R_6 = (remoteByte2 >> 6) & 0x01; this.InputData.Remote.R_8 = (remoteByte2 >> 5) & 0x01; @@ -779,7 +823,7 @@ const _throttle = require('lodash/throttle'); this.InputData.Acceler.AXIS_Z4 = packet[24]; } - generateOutputPacket(remoteData) { + generateOutputPacket(remoteData) { const outputPacket = new Uint8Array(SEND_PACKET_LENGTH).fill(-1); @@ -802,7 +846,7 @@ const _throttle = require('lodash/throttle'); outputPacket[12] = remoteData.MEL2; outputPacket[13] = remoteData.MEL1; - outputPacket[14] = remoteData.FND; + outputPacket[14] = remoteData.FND; outputPacket[15] = remoteData.EEPR4; outputPacket[16] = remoteData.EEPR3; @@ -816,14 +860,14 @@ const _throttle = require('lodash/throttle'); return outputPacket; } - + getMonitorPort() { return { ...this.InputData.Analog }; } getRemoteKey(data) { - const num = Number(data); - + const num = Number(data); + if (1 <= num && num <= 8) { return `R_${num}`; } else if (9 <= num && num <= 10) { @@ -900,7 +944,7 @@ const _throttle = require('lodash/throttle'); case '7': // 조도 case '9': // 초음파 case Lang.template.connectlite_item_rotation: // 회전 - case Lang.template.connectlite_item_illuminance: // 조도 + case Lang.template.connectlite_item_illuminance: // 조도 case Lang.template.connectlite_item_ultrasonic: // 초음파 return 2; case '10': // 소리 @@ -923,7 +967,7 @@ const _throttle = require('lodash/throttle'); return 8; case '14': // 나침반 case '15': // 3축 가속도 - case '17': // 확장 입력 + case '17': // 확장 입력 case Lang.template.connectlite_item_compass: case Lang.template.connectlite_item_tri_acceleration: case Lang.template.connectlite_item_extension_input: @@ -982,7 +1026,7 @@ const _throttle = require('lodash/throttle'); const num = Number(key); if (1 <= num && num <= 8) { return (num - 1); - } else if (9 <= num && num <= 16) { + } else if (9 <= num && num <= 16) { return (num - 9); } else { switch (key) { @@ -1243,7 +1287,7 @@ const _throttle = require('lodash/throttle'); return this.Rgb.Dimming.Blue; case '4': case Lang.template.technicpowerlite_item_color_cyan: - return this.Rgb.Dimming.Cyan; + return this.Rgb.Dimming.Cyan; case '5': case Lang.template.technicpowerlite_item_color_magenta: return this.Rgb.Dimming.Magenta; @@ -1938,7 +1982,7 @@ const _throttle = require('lodash/throttle'); }, ], }, - }, + }, connectlite_dropdown_extension_analog_key: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -2163,7 +2207,7 @@ const _throttle = require('lodash/throttle'); }, func: function(sprite, script) { return script.getStringField('PARAM0'); - }, + }, syntax: { js: [], py: [ @@ -2250,7 +2294,7 @@ const _throttle = require('lodash/throttle'); }, ], }, - }, + }, connectlite_dropdown_on_off_key: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -2580,7 +2624,7 @@ const _throttle = require('lodash/throttle'); [Lang.template.connectlite_item_pitch_ra + ' (45)', '45'], [Lang.template.connectlite_item_pitch_ra_sharp + ' (46)', '46'], [Lang.template.connectlite_item_pitch_si + ' (47)', '47'], - + [Lang.template.connectlite_item_pitch_do + ' (48)', '48'], [Lang.template.connectlite_item_pitch_do_sharp + ' (49)', '49'], [Lang.template.connectlite_item_pitch_re + ' (50)', '50'], @@ -2593,7 +2637,7 @@ const _throttle = require('lodash/throttle'); [Lang.template.connectlite_item_pitch_ra + ' (57)', '57'], [Lang.template.connectlite_item_pitch_ra_sharp + ' (58)', '58'], [Lang.template.connectlite_item_pitch_si + ' (59)', '59'], - + [Lang.template.connectlite_item_pitch_do + ' (60)', '60'], [Lang.template.connectlite_item_pitch_do_sharp + ' (61)', '61'], [Lang.template.connectlite_item_pitch_re + ' (62)', '62'], @@ -2606,7 +2650,7 @@ const _throttle = require('lodash/throttle'); [Lang.template.connectlite_item_pitch_ra + ' (69)', '69'], [Lang.template.connectlite_item_pitch_ra_sharp + ' (70)', '70'], [Lang.template.connectlite_item_pitch_si + ' (71)', '71'], - + [Lang.template.connectlite_item_pitch_do + ' (72)', '72'], [Lang.template.connectlite_item_pitch_do_sharp + ' (73)', '73'], [Lang.template.connectlite_item_pitch_re + ' (74)', '74'], @@ -2661,7 +2705,7 @@ const _throttle = require('lodash/throttle'); [Lang.template.connectlite_item_pitch_ra + ' (45)', '45'], [Lang.template.connectlite_item_pitch_ra_sharp + ' (46)', '46'], [Lang.template.connectlite_item_pitch_si + ' (47)', '47'], - + [Lang.template.connectlite_item_pitch_do + ' (48)', '48'], [Lang.template.connectlite_item_pitch_do_sharp + ' (49)', '49'], [Lang.template.connectlite_item_pitch_re + ' (50)', '50'], @@ -2674,7 +2718,7 @@ const _throttle = require('lodash/throttle'); [Lang.template.connectlite_item_pitch_ra + ' (57)', '57'], [Lang.template.connectlite_item_pitch_ra_sharp + ' (58)', '58'], [Lang.template.connectlite_item_pitch_si + ' (59)', '59'], - + [Lang.template.connectlite_item_pitch_do + ' (60)', '60'], [Lang.template.connectlite_item_pitch_do_sharp + ' (61)', '61'], [Lang.template.connectlite_item_pitch_re + ' (62)', '62'], @@ -2687,7 +2731,7 @@ const _throttle = require('lodash/throttle'); [Lang.template.connectlite_item_pitch_ra + ' (69)', '69'], [Lang.template.connectlite_item_pitch_ra_sharp + ' (70)', '70'], [Lang.template.connectlite_item_pitch_si + ' (71)', '71'], - + [Lang.template.connectlite_item_pitch_do + ' (72)', '72'], [Lang.template.connectlite_item_pitch_do_sharp + ' (73)', '73'], [Lang.template.connectlite_item_pitch_re + ' (74)', '74'], @@ -2773,7 +2817,7 @@ const _throttle = require('lodash/throttle'); }, ///======================================================================================== /// Event block - ///======================================================================================== + ///======================================================================================== // %1 리모컨 %2 키를 눌렀을 때 connectlite_when_press_remote_key: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -2901,7 +2945,7 @@ const _throttle = require('lodash/throttle'); }, ///======================================================================================== /// Setting Block - ///======================================================================================== + ///======================================================================================== // 입력포트 %1 을(를) %2 센서로 설정 %3 connectlite_set_sensor_setting: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -3165,7 +3209,7 @@ const _throttle = require('lodash/throttle'); }, ], }, - }, + }, // 3가속도 %1의 Y축 connectlite_get_tri_axis_acceler_y: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -3266,7 +3310,7 @@ const _throttle = require('lodash/throttle'); ], }, }, - + // %1 의 %2 ~ %3 값을 %4 ~ %5 (으)로 변환 connectlite_get_value_mapping: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -3377,7 +3421,7 @@ const _throttle = require('lodash/throttle'); }, ], }, - }, + }, // 컬러 센서 %1 이(가) %2 인가? connectlite_is_color_value: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -3458,7 +3502,7 @@ const _throttle = require('lodash/throttle'); ], events: {}, def: { - params: [ + params: [ { type: 'connectlite_dropdown_analog_key', }, @@ -3474,7 +3518,7 @@ const _throttle = require('lodash/throttle'); const key0 = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM0')); const value = Entry.ProboConnectLite.InputData.Analog[key0]; const color = Entry.ProboConnectLite.Color; - + for (let i = 1; i < 7; i++) { const key1 = Entry.ProboConnectLite.getColorSensorKey(i.toString()); if ((color[key1].Min <= value) && (value <= color[key1].Max)) { @@ -3568,15 +3612,15 @@ const _throttle = require('lodash/throttle'); const key = Entry.ProboConnectLite.getAnalogKey(script.getStringValue('PARAM1')); let count = 0; let value = script.getNumberValue('PARAM2'); - + if (value != 0) { - count = Number(value / 255).toFixed(0); + count = Math.floor(value / 255); value = value % 255; } else { - count = 0; value = 0; + count = 0; } - + Entry.ProboConnectLite.Infinite.Buff[key] = Entry.ProboConnectLite.InputData.Analog[key]; Entry.ProboConnectLite.Infinite.Start[key] = Entry.ProboConnectLite.InputData.Analog[key] - value; Entry.ProboConnectLite.Infinite.Count[key] = count; @@ -3660,7 +3704,7 @@ const _throttle = require('lodash/throttle'); infinite.Count[key]++; } else if (value > infinite.Buff[key] + 150) { infinite.Count[key]--; - } + } infinite.Buff[key] = value; value = (infinite.Buff[key] - infinite.Start[key]) + (infinite.Count[key] * 255); @@ -3713,7 +3757,7 @@ const _throttle = require('lodash/throttle'); ], events: {}, def: { - params: [ + params: [ { type: 'connectlite_dropdown_inNcom_sensor_key', }, @@ -3888,14 +3932,14 @@ const _throttle = require('lodash/throttle'); const value = Entry.ProboConnectLite.getMultiKeyValue(script.getStringValue('PARAM1')); const analog = Entry.ProboConnectLite.InputData.Analog[key0]; const multySwitch = Entry.ProboConnectLite.MultiSwitch; - + for (let i = 0; i < 8; i++) { const key = 'Key' + (i + 1).toString(); if (multySwitch[key].Min <= analog && analog <= multySwitch[key].Max) { return (value === i); } } - + return false; }, syntax: { @@ -3978,7 +4022,7 @@ const _throttle = require('lodash/throttle'); }, ], }, - }, + }, // 확장 아날로그 입력 %1 의 %2 connectlite_get_extension_analog_input: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -4014,7 +4058,7 @@ const _throttle = require('lodash/throttle'); }, class: 'connectlite_input', isNotFor: ['ProboConnectLite'], - func: function(sprite, script) { + func: function(sprite, script) { const key = Entry.ProboConnectLite.getAxisKey( script.getStringValue('PARAM0'), Entry.ProboConnectLite.getExtentionAnalogKey(script.getStringValue('PARAM1')) @@ -4047,7 +4091,7 @@ const _throttle = require('lodash/throttle'); color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, fontColor: '#fff', - skeleton: 'basic', + skeleton: 'basic', statements: [], params: [ { @@ -4101,7 +4145,7 @@ const _throttle = require('lodash/throttle'); return script; } else { Entry.ProboConnectLite.EEPROM.Buff = - (Entry.ProboConnectLite.InputData.EEPROM.EEPR2 << 8) + + (Entry.ProboConnectLite.InputData.EEPROM.EEPR2 << 8) + Entry.ProboConnectLite.InputData.EEPROM.EEPR1; Entry.ProboConnectLite.RemoteData['EEPR4'] = 0; Entry.ProboConnectLite.RemoteData['EEPR3'] = 0; @@ -4160,7 +4204,7 @@ const _throttle = require('lodash/throttle'); ], }, }, - + ///======================================================================================== /// output block ///======================================================================================== @@ -4189,7 +4233,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_dc_1_all_key', }, { @@ -4206,7 +4250,7 @@ const _throttle = require('lodash/throttle'); class: 'connectlite_output', isNotFor: ['ProboConnectLite'], func: function(sprite, script) { - const key = Entry.ProboConnectLite.getDckey(script.getStringValue('PARAM0')); + const key = Entry.ProboConnectLite.getDckey(script.getStringValue('PARAM0')); const value = script.getNumberValue('PARAM1'); switch (key) { @@ -4275,7 +4319,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, { @@ -4341,7 +4385,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, { @@ -4422,7 +4466,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, { @@ -4441,7 +4485,7 @@ const _throttle = require('lodash/throttle'); func: function(sprite, script) { const key = Entry.ProboConnectLite.getPortKey(script.getStringValue('PARAM0')); const value = Entry.ProboConnectLite.getPortToggleValue(script.getStringValue('PARAM1')); - + Entry.ProboConnectLite.RemoteData[key] = value; return script.callReturn(); @@ -4490,7 +4534,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_pitch_key', }, { @@ -4514,9 +4558,9 @@ const _throttle = require('lodash/throttle'); const note = Entry.ProboConnectLite.getNoteKey(script.getStringValue('PARAM1')); const ms = Entry.ProboConnectLite.Note[note]; const fps = Entry.FPS || 60; - + Entry.ProboConnectLite.RemoteData['MEL2'] = pitch >> 8; - Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; + Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; Entry.TimeWaitManager.add( script.block.id, function() { @@ -4530,7 +4574,7 @@ const _throttle = require('lodash/throttle'); } else { Entry.ProboConnectLite.RemoteData['MEL2'] = 0; Entry.ProboConnectLite.RemoteData['MEL1'] = 0; - + delete script.timeFlag; delete script.isStart; Entry.engine.isContinue = false; @@ -4582,7 +4626,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_pitch_key', }, { @@ -4603,11 +4647,11 @@ const _throttle = require('lodash/throttle'); script.isStart = true; script.timeFlag = 1; const pitch = Entry.ProboConnectLite.getPitchValue(script.getNumberValue('PARAM0')); - const sec = script.getNumberValue('PARAM1'); + const sec = script.getNumberValue('PARAM1'); const fps = Entry.FPS || 60; - + Entry.ProboConnectLite.RemoteData['MEL2'] = pitch >> 8; - Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; + Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; Entry.TimeWaitManager.add( script.block.id, function() { @@ -4622,7 +4666,7 @@ const _throttle = require('lodash/throttle'); } else { Entry.ProboConnectLite.RemoteData['MEL2'] = 0; Entry.ProboConnectLite.RemoteData['MEL1'] = 0; - + delete script.timeFlag; delete script.isStart; Entry.engine.isContinue = false; @@ -4656,7 +4700,7 @@ const _throttle = require('lodash/throttle'); fontColor: '#fff', skeleton: 'basic', statements: [], - params: [ + params: [ { type: 'Block', accept: 'string', @@ -4670,7 +4714,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_pitch_key', }, null @@ -4683,7 +4727,7 @@ const _throttle = require('lodash/throttle'); class: 'connectlite_output', isNotFor: ['ProboConnectLite'], func: function(sprite, script) { - const pitch = Entry.ProboConnectLite.getPitchValue(script.getNumberValue('PARAM0')); + const pitch = Entry.ProboConnectLite.getPitchValue(script.getNumberValue('PARAM0')); Entry.ProboConnectLite.RemoteData['MEL2'] = pitch >> 8; Entry.ProboConnectLite.RemoteData['MEL1'] = pitch; return script.callReturn(); @@ -4749,13 +4793,13 @@ const _throttle = require('lodash/throttle'); if (!script.isStart) { script.isStart = true; script.timeFlag = 1; - + const melody = script.getNumberValue('PARAM0'); const sec = script.getNumberValue('PARAM1'); const fps = Entry.FPS || 60; - + Entry.ProboConnectLite.RemoteData['MEL2'] = (melody >> 8) & 0xff; - Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; + Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; Entry.TimeWaitManager.add( script.block.id, function() { @@ -4769,7 +4813,7 @@ const _throttle = require('lodash/throttle'); } else { Entry.ProboConnectLite.RemoteData['MEL2'] = 0; Entry.ProboConnectLite.RemoteData['MEL1'] = 0; - + delete script.timeFlag; delete script.isStart; Entry.engine.isContinue = false; @@ -4875,10 +4919,10 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_melody_key', }, - { + { type: 'connectlite_dropdown_time_2_key', }, null @@ -4905,8 +4949,8 @@ const _throttle = require('lodash/throttle'); const melody = Entry.ProboConnectLite.Track[track][script.trackStep]; Entry.ProboConnectLite.RemoteData['MEL2'] = (melody >> 8) & 0xff; - Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; - script.timeFlag = 1; + Entry.ProboConnectLite.RemoteData['MEL1'] = melody & 0xff; + script.timeFlag = 1; Entry.TimeWaitManager.add( script.block.id, function() { @@ -4943,7 +4987,7 @@ const _throttle = require('lodash/throttle'); } else { Entry.ProboConnectLite.RemoteData['MEL2'] = 0; Entry.ProboConnectLite.RemoteData['MEL1'] = 0; - + delete script.trackStep; delete script.maxStep; delete script.timeFlag; @@ -5032,7 +5076,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, { @@ -5072,7 +5116,7 @@ const _throttle = require('lodash/throttle'); }, ], }, - }, + }, // RGB LED %1 을(를) 끄기 %2 connectlite_set_rgbled_off_output: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -5094,7 +5138,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, null @@ -5155,13 +5199,13 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, - { + { type: 'connectlite_dropdown_rgb_color_key', }, - { + { type: 'connectlite_dropdown_time_3', }, null @@ -5232,10 +5276,10 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'connectlite_dropdown_port_1_4_key', }, - { + { type: 'connectlite_dropdown_rgb_color_key', }, null @@ -5369,7 +5413,7 @@ const _throttle = require('lodash/throttle'); color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, fontColor: '#fff', - skeleton: 'basic', + skeleton: 'basic', statements: [], params: [ { @@ -5389,7 +5433,7 @@ const _throttle = require('lodash/throttle'); events: {}, def: { params: [ - { + { type: 'number', params: [ 0 ] }, @@ -5411,7 +5455,7 @@ const _throttle = require('lodash/throttle'); const address = script.getNumberValue('PARAM0'); const value = script.getNumberValue('PARAM1'); - if (!script.isStart) { + if (!script.isStart) { script.isStart = true; script.timeFlag = 1; @@ -5437,14 +5481,14 @@ const _throttle = require('lodash/throttle'); Entry.ProboConnectLite.RemoteData['EEPR3'] = address; Entry.ProboConnectLite.RemoteData['EEPR2'] = 0; Entry.ProboConnectLite.RemoteData['EEPR1'] = 0; - + setTimeout(function() { Entry.ProboConnectLite.RemoteData['EEPR4'] = 0; Entry.ProboConnectLite.RemoteData['EEPR3'] = 0; Entry.ProboConnectLite.RemoteData['EEPR2'] = 0; Entry.ProboConnectLite.RemoteData['EEPR1'] = 0; }, 100); - + delete script.timeFlag; delete script.isStart; Entry.engine.isContinue = false; diff --git a/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json b/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json index c3ad4b08a8..d51e6b7a69 100644 --- a/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json +++ b/src/playground/blocks/hardwareLite/metadata_alux_connect_lite.json @@ -1,6 +1,6 @@ { "name": "ProboConnectLite", - "version": "1.0.0", + "version": "1.0.1", "type": "hardware", "title": "프로보 커넥트", "description": "에이럭스", From 85d8d78ef365f6b50e03fc5e955058919fee9ff6 Mon Sep 17 00:00:00 2001 From: hakueon Date: Wed, 21 May 2025 15:15:32 +0900 Subject: [PATCH 02/10] =?UTF-8?q?TechnicnormalLite=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block_alux_teachnic_normal_lite.js | 64 +++++++++++++++---- .../metadata_alux_teachnic_normal_lite.json | 2 +- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/playground/blocks/hardwareLite/block_alux_teachnic_normal_lite.js b/src/playground/blocks/hardwareLite/block_alux_teachnic_normal_lite.js index 9fc793c357..3c41bf41c2 100644 --- a/src/playground/blocks/hardwareLite/block_alux_teachnic_normal_lite.js +++ b/src/playground/blocks/hardwareLite/block_alux_teachnic_normal_lite.js @@ -141,14 +141,26 @@ const _throttle = require('lodash/throttle'); } this.remoteEvent = _throttle( () => { - Entry.engine.fireEvent('technicnormallite_event_remote_input'); + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('technicnormallite_event_remote_input'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } }, EVENT_INTERVAL, eventSetting ); this.digitalEvent = _throttle( - () => { - Entry.engine.fireEvent('technicnormallite_event_digital_input'); + () => { + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('technicnormallite_event_digital_input'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } } , EVENT_INTERVAL, @@ -656,8 +668,16 @@ const _throttle = require('lodash/throttle'); Entry.addEventListener('run', this.handleRemoteEventInterval.bind(this)); Entry.addEventListener('run', this.handleDigitalEventInterval.bind(this)); - Entry.addEventListener('beforeStop', clearInterval(this.remoteEventIntervalId)); - Entry.addEventListener('beforeStop', clearInterval(this.digitalEventIntervalId)); + Entry.addEventListener('beforeStop', () => { + if (this.remoteEventIntervalId) { + clearInterval(this.remoteEventIntervalId); + this.remoteEventIntervalId = null; + } + if (this.digitalEventIntervalId) { + clearInterval(this.digitalEventIntervalId); + this.digitalEventIntervalId = null; + } + }); this.setZero(); if (this.version === 0) { @@ -674,16 +694,32 @@ const _throttle = require('lodash/throttle'); } handleRemoteEventInterval() { - this.remoteEventIntervalId = setInterval(this.remoteEvent.bind(this), EVENT_INTERVAL); + if (this.remoteEventIntervalId) { + clearInterval(this.remoteEventIntervalId); + } + this.remoteEventIntervalId = setInterval(() => { + const currentState = this.remoteEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); } - handleDigitalEventInterval() { - this.digitalEventIntervalId = setInterval(this.digitalEvent.bind(this), EVENT_INTERVAL); + handleDigitalEventInterval() { + if (this.digitalEventIntervalId) { + clearInterval(this.digitalEventIntervalId); + } + this.digitalEventIntervalId = setInterval(() => { + const currentState = this.digitalEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); } // 디바이스에서 값을 읽어온다. handleLocalData(buffer) { buffer.forEach(b => this.qEnqueue(b)); + + if (this._recoverTimeoutId) { + clearTimeout(this._recoverTimeoutId); + } while(this.qCount() >= this.inputPacket.length) { if (!this.process) { @@ -717,11 +753,17 @@ const _throttle = require('lodash/throttle'); } if (this.sendFlag) { - setTimeout( - () => { + if (this._requestTimeoutId) { + clearTimeout(this._requestTimeoutId); + } + this._requestTimeoutId = setTimeout( + () => { if (Entry.hwLite && Entry.hwLite.serial) { Entry.hwLite.serial.update(); this.sendFlag = false; + this._recoverTimeoutId = setTimeout(() => { + this.sendFlag = true; + }, SERIAL_INTERVAL * 3); } }, SERIAL_INTERVAL @@ -3632,7 +3674,7 @@ const _throttle = require('lodash/throttle'); let value = script.getNumberValue('PARAM2'); if (value != 0) { - count = Number(value / 255).toFixed(0); + count = Math.floor(value / 255); value = value % 255; } else { count = 0; diff --git a/src/playground/blocks/hardwareLite/metadata_alux_teachnic_normal_lite.json b/src/playground/blocks/hardwareLite/metadata_alux_teachnic_normal_lite.json index a88fc00c0e..6c5025c704 100644 --- a/src/playground/blocks/hardwareLite/metadata_alux_teachnic_normal_lite.json +++ b/src/playground/blocks/hardwareLite/metadata_alux_teachnic_normal_lite.json @@ -1,6 +1,6 @@ { "name": "ProboTechnicNormalLite", - "version": "1.0.0", + "version": "1.0.1", "type": "hardware", "title": "프로보 테크닉(일반)", "description": "에이럭스", From 36820c8638e0e10a3c61c03844a5373c025e0ef0 Mon Sep 17 00:00:00 2001 From: hakueon Date: Wed, 21 May 2025 15:21:44 +0900 Subject: [PATCH 03/10] =?UTF-8?q?Technicpowerlite=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block_alux_teachnic_power_lite.js | 63 ++++++++++++++++--- .../metadata_alux_teachnic_power_lite.json | 2 +- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/playground/blocks/hardwareLite/block_alux_teachnic_power_lite.js b/src/playground/blocks/hardwareLite/block_alux_teachnic_power_lite.js index 39c572f00d..ae7792f66b 100644 --- a/src/playground/blocks/hardwareLite/block_alux_teachnic_power_lite.js +++ b/src/playground/blocks/hardwareLite/block_alux_teachnic_power_lite.js @@ -141,14 +141,26 @@ const _throttle = require('lodash/throttle'); } this.remoteEvent = _throttle( () => { - Entry.engine.fireEvent('technicpowerlite_event_remote_input'); + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('technicpowerlite_event_remote_input'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } }, EVENT_INTERVAL, eventSetting ); this.digitalEvent = _throttle( () => { - Entry.engine.fireEvent('technicpowerlite_event_digital_input'); + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('technicpowerlite_event_digital_input'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } } , EVENT_INTERVAL, @@ -656,8 +668,17 @@ const _throttle = require('lodash/throttle'); Entry.addEventListener('run', this.handleRemoteEventInterval.bind(this)); Entry.addEventListener('run', this.handleDigitalEventInterval.bind(this)); - Entry.addEventListener('beforeStop', clearInterval(this.remoteEventIntervalId)); - Entry.addEventListener('beforeStop', clearInterval(this.digitalEventIntervalId)); + Entry.addEventListener('beforeStop', () => { + if (this.remoteEventIntervalId) { + clearInterval(this.remoteEventIntervalId); + this.remoteEventIntervalId = null; + } + if (this.digitalEventIntervalId) { + clearInterval(this.digitalEventIntervalId); + this.digitalEventIntervalId = null; + } + }); + this.setZero(); if (this.version === 0) { @@ -675,17 +696,33 @@ const _throttle = require('lodash/throttle'); } handleRemoteEventInterval() { - this.remoteEventIntervalId = setInterval(this.remoteEvent.bind(this), EVENT_INTERVAL); + if (this.remoteEventIntervalId) { + clearInterval(this.remoteEventIntervalId); + } + this.remoteEventIntervalId = setInterval(() => { + const currentState = this.remoteEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); } handleDigitalEventInterval() { - this.digitalEventIntervalId = setInterval(this.digitalEvent.bind(this), EVENT_INTERVAL); + if (this.digitalEventIntervalId) { + clearInterval(this.digitalEventIntervalId); + } + this.digitalEventIntervalId = setInterval(() => { + const currentState = this.digitalEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); } // 디바이스에서 값을 읽어온다. handleLocalData(buffer) { buffer.forEach(b => this.qEnqueue(b)); + if (this._recoverTimeoutId) { + clearTimeout(this._recoverTimeoutId); + } + while(this.qCount() >= this.inputPacket.length) { if (!this.process) { while(this.qCount() > 0) { @@ -718,16 +755,22 @@ const _throttle = require('lodash/throttle'); } if (this.sendFlag) { - setTimeout( - () => { + if (this._requestTimeoutId) { + clearTimeout(this._requestTimeoutId); + } + this._requestTimeoutId = setTimeout( + () => { if (Entry.hwLite && Entry.hwLite.serial) { Entry.hwLite.serial.update(); this.sendFlag = false; + this._recoverTimeoutId = setTimeout(() => { + this.sendFlag = true; + }, SERIAL_INTERVAL * 3); } }, SERIAL_INTERVAL ); - }; + } } //디바이스에 값을 쓴다. @@ -3633,7 +3676,7 @@ const _throttle = require('lodash/throttle'); let value = script.getNumberValue('PARAM2'); if (value != 0) { - count = Number(value / 255).toFixed(0); + count = Math.floor(value / 255); value = value % 255; } else { count = 0; diff --git a/src/playground/blocks/hardwareLite/metadata_alux_teachnic_power_lite.json b/src/playground/blocks/hardwareLite/metadata_alux_teachnic_power_lite.json index f7fc6d89b5..ad7d30a845 100644 --- a/src/playground/blocks/hardwareLite/metadata_alux_teachnic_power_lite.json +++ b/src/playground/blocks/hardwareLite/metadata_alux_teachnic_power_lite.json @@ -1,6 +1,6 @@ { "name": "ProboTechnicPowerLite", - "version": "1.0.0", + "version": "1.0.1", "type": "hardware", "title": "프로보 테크닉(파워)", "description": "에이럭스", From ab68ae08877e9187838c792a6807714004a52a0b Mon Sep 17 00:00:00 2001 From: hakueon Date: Wed, 21 May 2025 15:28:44 +0900 Subject: [PATCH 04/10] =?UTF-8?q?connectlite=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hardwareLite/block_alux_connect_lite.js | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/playground/blocks/hardwareLite/block_alux_connect_lite.js b/src/playground/blocks/hardwareLite/block_alux_connect_lite.js index 8c6c6be99f..de747aed32 100644 --- a/src/playground/blocks/hardwareLite/block_alux_connect_lite.js +++ b/src/playground/blocks/hardwareLite/block_alux_connect_lite.js @@ -83,15 +83,11 @@ const _throttle = require('lodash/throttle'); } this.remoteEvent = _throttle( () => { - // 통신 상태를 저장하고 이벤트 후에 복원 const prevFlag = this.sendFlag; try { - Entry.engine.fireEvent('connectlite_event_remote_input'); } catch (e) { - } finally { - // 이벤트 처리 후 원래 통신 상태 복원 this.sendFlag = prevFlag; } }, @@ -100,9 +96,14 @@ const _throttle = require('lodash/throttle'); ); this.digitalEvent = _throttle( () => { - Entry.engine.fireEvent('connectlite_event_digital_input'); - } - , + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('connectlite_event_digital_input'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } + }, EVENT_INTERVAL, eventSetting ); @@ -631,32 +632,32 @@ const _throttle = require('lodash/throttle'); } handleRemoteEventInterval() { - // 기존 인터벌이 있으면 제거 if (this.remoteEventIntervalId) { clearInterval(this.remoteEventIntervalId); } this.remoteEventIntervalId = setInterval(() => { - // sendFlag 확인 후 이벤트 발생 const currentState = this.remoteEvent.bind(this); currentState(); }, EVENT_INTERVAL); } handleDigitalEventInterval() { - this.digitalEventIntervalId = setInterval(this.digitalEvent.bind(this), EVENT_INTERVAL); + if (this.digitalEventIntervalId) { + clearInterval(this.digitalEventIntervalId); + } + this.digitalEventIntervalId = setInterval(() => { + const currentState = this.digitalEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); } - // 디바이스에서 값을 읽어온다. - // 디바이스에서 값을 읽어온다. handleLocalData(buffer) { + buffer.forEach(b => this.qEnqueue(b)); - // 데이터가 들어왔으므로 통신 타임아웃 초기화 if (this._recoverTimeoutId) { clearTimeout(this._recoverTimeoutId); } - buffer.forEach(b => this.qEnqueue(b)); - while(this.qCount() >= this.inputPacket.length) { if (!this.process) { while(this.qCount() > 0) { @@ -689,18 +690,14 @@ const _throttle = require('lodash/throttle'); } if (this.sendFlag) { - // 기존 대기중인 타임아웃 취소 if (this._requestTimeoutId) { clearTimeout(this._requestTimeoutId); } - this._requestTimeoutId = setTimeout( () => { if (Entry.hwLite && Entry.hwLite.serial) { Entry.hwLite.serial.update(); this.sendFlag = false; - - // 응답 타임아웃 처리: 일정 시간 후에도 응답이 없으면 복구 this._recoverTimeoutId = setTimeout(() => { this.sendFlag = true; }, SERIAL_INTERVAL * 3); @@ -718,7 +715,6 @@ const _throttle = require('lodash/throttle'); } } - qEnqueue(data) { this.qBuffer[this.qRear] = data; this.qRear = (this.qRear + 1) % this.qSize @@ -744,7 +740,6 @@ const _throttle = require('lodash/throttle'); checker += packet[i]; } return (checker & 0xFF); - } checksumHandle(packet) { From 5f9efea57eb502511c502691bddd6bf168e41251 Mon Sep 17 00:00:00 2001 From: hakueon Date: Wed, 21 May 2025 16:27:27 +0900 Subject: [PATCH 05/10] =?UTF-8?q?nemoLite=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hardwareLite/block_alux_nemo_lite.js | 90 ++++++++++++++----- .../hardwareLite/metadata_alux_nemo_lite.json | 2 +- 2 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/playground/blocks/hardwareLite/block_alux_nemo_lite.js b/src/playground/blocks/hardwareLite/block_alux_nemo_lite.js index 58545de322..a4f4a59a97 100644 --- a/src/playground/blocks/hardwareLite/block_alux_nemo_lite.js +++ b/src/playground/blocks/hardwareLite/block_alux_nemo_lite.js @@ -37,14 +37,26 @@ const _throttle = require('lodash/throttle'); }; this.buttonEvent = _throttle( () => { - Entry.engine.fireEvent('nemolite_event_button'); + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('nemolite_event_button'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } }, EVENT_INTERVAL, eventSetting ); this.motionEvent = _throttle( () => { - Entry.engine.fireEvent('nemolite_event_motion'); + const prevFlag = this.sendFlag; + try { + Entry.engine.fireEvent('nemolite_event_motion'); + } catch (e) { + } finally { + this.sendFlag = prevFlag; + } }, EVENT_INTERVAL, eventSetting @@ -621,11 +633,11 @@ const _throttle = require('lodash/throttle'); ledClear: 1, extension: 0, melody: { - play: 0, + play: 1, title: 0, }, note: { - play: 0, + play: 1, pitch: 0, }, ledRead: 0, @@ -657,7 +669,7 @@ const _throttle = require('lodash/throttle'); this.state = { led: 0, - sound: 0, + sound: 'm'.charCodeAt(), note: 0, soundBlockId: 0, noteBlockId: 0, @@ -687,6 +699,7 @@ const _throttle = require('lodash/throttle'); if (Entry.hwLite && Entry.hwLite.serial) { Entry.hwLite.serial.update(); + this.state.sound = 0; } } //endregion @@ -713,8 +726,16 @@ const _throttle = require('lodash/throttle'); Entry.addEventListener('run', this.handleButtonEventInterval.bind(this)); Entry.addEventListener('run', this.handleMotionlEventInterval.bind(this)); - Entry.addEventListener('beforeStop', clearInterval(this.buttonEventIntervalId)); - Entry.addEventListener('beforeStop', clearInterval(this.motionEventIntervalId)); + Entry.addEventListener('beforeStop', () => { + if (this.buttonEventIntervalId) { + clearInterval(this.buttonEventIntervalId); + this.buttonEventIntervalId = null; + } + if (this.motionEventIntervalId) { + clearInterval(this.motionEventIntervalId); + this.motionEventIntervalId = null; + } + }); this.setZero(); @@ -733,11 +754,35 @@ const _throttle = require('lodash/throttle'); } //endregion + handleButtonEventInterval() { + if (this.buttonEventIntervalId) { + clearInterval(this.buttonEventIntervalId); + } + this.buttonEventIntervalId = setInterval(() => { + const currentState = this.buttonEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); + } + + handleMotionlEventInterval() { + if (this.motionEventIntervalId) { + clearInterval(this.motionEventIntervalId); + } + this.motionEventIntervalId = setInterval(() => { + const currentState = this.motionEvent.bind(this); + currentState(); + }, EVENT_INTERVAL); + } + // 디바이스에서 값을 읽어온다. //region handleLocalData handleLocalData(buffer) { buffer.forEach((b) => this.qEnqueue(b)); + if (this._recoverTimeoutId) { + clearTimeout(this._recoverTimeoutId); + } + while (this.qCount() >= this.receivedPacket.length) { if (!this.process) { while (this.qCount() > 0) { @@ -788,12 +833,21 @@ const _throttle = require('lodash/throttle'); } if (this.sendFlag) { - setTimeout(() => { - if (Entry.hwLite && Entry.hwLite.serial) { - Entry.hwLite.serial.update(); - this.sendFlag = false; - } - }, SERIAL_INTERVAL); + if (this._requestTimeoutId) { + clearTimeout(this._requestTimeoutId); + } + this._requestTimeoutId = setTimeout( + () => { + if (Entry.hwLite && Entry.hwLite.serial) { + Entry.hwLite.serial.update(); + this.sendFlag = false; + this._recoverTimeoutId = setTimeout(() => { + this.sendFlag = true; + }, SERIAL_INTERVAL * 3); + } + }, + SERIAL_INTERVAL + ); } } //endregion @@ -851,14 +905,6 @@ const _throttle = require('lodash/throttle'); : this.qSize - this.qFront + this.qRear; } - handleButtonEventInterval() { - this.buttonEventIntervalId = setInterval(this.buttonEvent.bind(this), EVENT_INTERVAL); - } - - handleMotionlEventInterval() { - this.motionEventIntervalId = setInterval(this.motionEvent.bind(this), EVENT_INTERVAL); - } - checksum(packet) { let checker = 0; const length = packet[2] + 2; @@ -1040,7 +1086,7 @@ const _throttle = require('lodash/throttle'); for (let i = 0; i < 14; i++) { const index = this.sendIndex.led7x1 + i; this.sendPacket[index] = this.setData.ledColumm.pixel[i]; - if (index > 6 && this.sendPacket[index] > 0) { + if (index > 7 && this.sendPacket[index] > 0) { nextPage = true; } } diff --git a/src/playground/blocks/hardwareLite/metadata_alux_nemo_lite.json b/src/playground/blocks/hardwareLite/metadata_alux_nemo_lite.json index 1dd1f2b18d..8c79805ddf 100644 --- a/src/playground/blocks/hardwareLite/metadata_alux_nemo_lite.json +++ b/src/playground/blocks/hardwareLite/metadata_alux_nemo_lite.json @@ -1,6 +1,6 @@ { "name": "ProboNemoLite", - "version": "1.0.0", + "version": "1.0.1", "type": "hardware", "title": "네모", "description": "에이럭스", From 4909cbfea0e9d906295c2a74b061e6cc65f47c6f Mon Sep 17 00:00:00 2001 From: poqopo Date: Tue, 27 May 2025 12:48:35 +0900 Subject: [PATCH 06/10] Add Timborobot --- src/playground/blocks/hardware/block_timbo.js | 309 ++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 src/playground/blocks/hardware/block_timbo.js diff --git a/src/playground/blocks/hardware/block_timbo.js b/src/playground/blocks/hardware/block_timbo.js new file mode 100644 index 0000000000..84d6811392 --- /dev/null +++ b/src/playground/blocks/hardware/block_timbo.js @@ -0,0 +1,309 @@ +'use strict'; + +Entry.Timbo = { + id: '6A.1', + name: 'Timbo', + title: { + ko: '팀보 커뮤니케이션 블록', + en: 'Timbo Communication Block', + }, + setZero() { + Entry.hw.sendQueue.readablePorts = []; + for (let port = 0; port < 20; port++) { + Entry.hw.sendQueue[port] = 0; + Entry.hw.sendQueue.readablePorts.push(port); + } + Entry.hw.update(); + }, +}; + +Entry.Timbo.setLanguage = function () { + return { + ko: { + template: { + timbo_queen_play: '퀸의 %1켜기', + timbo_queen_stop: '퀸의 동작 끄기', + timbo_motion_play: '모션 %1의 %2 켜기', + timbo_motion_stop: '모션 %1의 동작 끄기', + timbo_check_queen: '퀸의 동작여부 체크', + timbo_check_motion: '모션 %1의 동작여부 체크', + }, + Device: { + timbo: '팀보', + }, + Menus: { + timbo: '팀보', + }, + Helper: { + timbo_queen_play: '퀸의 %1켜기', + timbo_queen_stop: '퀸의 동작 끄기', + timbo_motion_play: '모션 %1의 %2 켜기', + timbo_motion_stop: '모션 %1의 동작 끄기', + timbo_check_queen: '퀸의 동작여부 체크', + timbo_check_motion: '모션 %1의 동작여부 체크', + }, + }, + en: { + template: { + timbo_queen_play: 'Turn on Queen %1', + timbo_queen_stop: 'Turn off Queen action', + timbo_motion_play: 'Turn on Motion %1 of %2', + timbo_motion_stop: 'Turn off Motion %1 action', + timbo_check_queen: 'Check if Queen is operating', + timbo_check_motion: 'Check if Motion %1 is operating', + }, + Device: { + timbo: 'Timbo', + }, + Menus: { + timbo: 'Timbo', + }, + Helper: { + timbo_queen_play: 'Turn on Queen %1', + timbo_queen_stop: 'Turn off Queen action', + timbo_motion_play: 'Turn on Motion %1 of %2', + timbo_motion_stop: 'Turn off Motion %1 action', + timbo_check_queen: 'Check if Queen is operating', + timbo_check_motion: 'Check if Motion %1 is operating', + }, + }, + }; +}; + +Entry.Timbo.blockMenuBlocks = [ + 'timbo_queen_play', + 'timbo_queen_stop', + 'timbo_motion_play', + 'timbo_motion_stop', + 'timbo_check_queen', + 'timbo_check_motion', +]; + +Entry.Timbo.getBlocks = function () { + return { + timbo_queen_play: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['동작', '1'], + ['반복동작', '2'], + ['한번동작', '3'], + ['거꾸로동작', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [], + type: 'timbo_queen_play', + }, + paramsKeyMap: { + ACTION: 0, + }, + class: 'timbo_queen', + isNotFor: ['Timbo'], + func(sprite, script) { + const action = script.getNumberValue('ACTION'); + Entry.hw.setDigitalPortValue(1, action); + return script.callReturn(); + }, + }, + timbo_queen_stop: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [], + events: {}, + def: { + params: [], + type: 'timbo_queen_stop', + }, + paramsKeyMap: {}, + class: 'timbo_queen', + isNotFor: ['Timbo'], + func(sprite, script) { + Entry.hw.setDigitalPortValue(1, 0); + return script.callReturn(); + }, + }, + timbo_motion_play: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['동작', '1'], + ['반복동작', '2'], + ['한번동작', '3'], + ['거꾸로동작', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'timbo_motion_play', + }, + paramsKeyMap: { + PORT: 0, + ACTION: 1, + }, + class: 'timbo_motion', + isNotFor: ['Timbo'], + func(sprite, script) { + const port = script.getNumberValue('PORT'); + const action = script.getNumberValue('ACTION'); + Entry.hw.setDigitalPortValue(port + 1, action); + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'Arduino.pin_digital(%1, 1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + timbo_motion_stop: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'timbo_motion_stop', + }, + paramsKeyMap: { + PORT: 0, + }, + class: 'timbo_motion', + isNotFor: ['Timbo'], + func(sprite, script) { + const port = script.getNumberValue('PORT'); + Entry.hw.setDigitalPortValue(port + 1, 0); + return script.callReturn(); + }, + }, + + timbo_check_motion: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'timbo_check_motion', + }, + paramsKeyMap: { + PORT: 1, + }, + class: 'timbo_motion_value', + isNotFor: ['Timbo'], + func(sprite, script) { + const port = script.getNumberValue('PORT'); + return Entry.hw.getDigitalPortValue(port + 1); + }, + }, + + timbo_check_queen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [], + events: {}, + def: { + params: [], + type: 'timbo_check_queen', + }, + + class: 'timbo_motion_value', + isNotFor: ['Timbo'], + func(sprite, script) { + return Entry.hw.getDigitalPortValue(1); + }, + }, + }; +}; + +module.exports = Entry.Timbo; From 34f176fdd45849e8524a207eb44d0d0caace4e96 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 10 Jun 2025 15:46:43 +0900 Subject: [PATCH 07/10] =?UTF-8?q?=EC=BD=94=EC=95=8C=EB=9D=BC=EB=B4=87=20?= =?UTF-8?q?=EB=8C=80=ED=91=9C=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20/=20=EC=BD=94=EC=95=8C=EB=9D=BC=EB=B4=87=20?= =?UTF-8?q?=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/hw_lite/robotis_koalabot_lite.png | Bin 83622 -> 84795 bytes .../block_robotis_koalabot_lite.js | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/images/hw_lite/robotis_koalabot_lite.png b/images/hw_lite/robotis_koalabot_lite.png index 3658a1aff2918acbe43935bb3ec6d047c29bacea..78c9a6fae55c1e4ca883ad597397ab69b0e3a145 100644 GIT binary patch literal 84795 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

==^gO<` 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 literal 83622 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 Hw=)ip@R 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 diff --git a/src/playground/blocks/hardwareLite/block_robotis_koalabot_lite.js b/src/playground/blocks/hardwareLite/block_robotis_koalabot_lite.js index 8b9c9da644..634dce3c40 100644 --- a/src/playground/blocks/hardwareLite/block_robotis_koalabot_lite.js +++ b/src/playground/blocks/hardwareLite/block_robotis_koalabot_lite.js @@ -2230,7 +2230,7 @@ let camera_id_for_use = 0; //DEFAULT_DELAY ); }, - syntax: { js: [], py: ['Koalabot.dxl_each_control(%1)'] }, + syntax: { js: [], py: ['Koalabot.go_distance(%1)'] }, }, robotis_koalabot_lite_turn_angle: { @@ -2308,7 +2308,7 @@ let camera_id_for_use = 0; //DEFAULT_DELAY ); }, - syntax: { js: [], py: ['Koalabot.dxl_each_control(%1)'] }, + syntax: { js: [], py: ['Koalabot.turn_angle(%1)'] }, }, robotis_koalabot_lite_follow_line: { color: EntryStatic.colorSet.block.default.HARDWARE, From 7e02a8a577e4bd42b5b9eb857787118410b1ec1c Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 10 Jun 2025 15:47:53 +0900 Subject: [PATCH 08/10] =?UTF-8?q?=EB=A1=9C=EB=B3=B4=ED=8B=B0=EC=A6=88=20?= =?UTF-8?q?=EC=95=8C=EC=A5=90=20=EB=B8=8C=EB=9D=BC=EC=9A=B0=EC=A0=80?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/hw_lite/robotis_rgee_lite.png | Bin 0 -> 18944 bytes .../hardwareLite/block_robotis_rgee_lite.js | 3582 +++++++++++++++++ .../metadata_robotis_rgee_lite.json | 9 + 3 files changed, 3591 insertions(+) create mode 100644 images/hw_lite/robotis_rgee_lite.png create mode 100644 src/playground/blocks/hardwareLite/block_robotis_rgee_lite.js create mode 100644 src/playground/blocks/hardwareLite/metadata_robotis_rgee_lite.json diff --git a/images/hw_lite/robotis_rgee_lite.png b/images/hw_lite/robotis_rgee_lite.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1d99f3e1547432e8361315eb6fdd923179a70b GIT binary patch literal 18944 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 0) { + this.timeouts.splice(idx, 1); + } + } + + __removeAllTimeouts() { + const timeouts = this.timeouts; + for (const i in timeouts) { + clearTimeout(timeouts[i]); + } + this.timeouts = []; + } + + getMonitorPort() { + return { ...this.sensory, ...this.motoring, ...this.lineTracer }; + } + + writePacket(id, address, length, value) { + if (length > 256) { + console.log(`######### invalid length: ${length}`); + return null; + } + console.log('######### writePacket'); + const packet = []; + let i = 0; + packet.push(0xff); + packet.push(0xff); + packet.push(0xfd); + packet.push(0x00); + packet.push(id); + packet.push(length + 5); + packet.push(0x00); + packet.push(INST_WRITE); + packet.push(this.getLowByte(address)); + packet.push(this.getHighByte(address)); + switch (length) { + case 1: + packet.push(this.getLowByte(value)); + break; + case 2: + packet.push(this.getLowByte(value)); + packet.push(this.getHighByte(value)); + break; + case 4: + packet.push(this.getLowByte(this.getLowWord(value))); + packet.push(this.getHighByte(this.getLowWord(value))); + packet.push(this.getLowByte(this.getHighWord(value))); + packet.push(this.getHighByte(this.getHighWord(value))); + break; + default: + for (i = 0; i < length; i++) { + if (typeof value[i] == 'number') { + packet.push(value[i]); + } else if (typeof value[i] == 'string') { + packet.push(value[i].charCodeAt(0)); + } + } + break; + } + const crc = this.updateCRC(0, packet, packet.length); + packet.push(this.getLowByte(crc)); + packet.push(this.getHighByte(crc)); + return packet; + } + + makeWord(a, b) { + return (a & 0xff) | ((b & 0xff) << 8); + } + + getLowByte(a) { + return a & 0xff; + } + + getHighByte(a) { + return (a >> 8) & 0xff; + } + + getLowWord(a) { + return a & 0xffff; + } + + getHighWord(a) { + return (a >> 16) & 0xffff; + } + + updateCRC(crcAccum, dataBlkPtr, dataBlkSize) { + let i = 0; + let j = 0; + let crc = crcAccum; + + for (j = 0; j < dataBlkSize; j++) { + i = ((crc >> 8) ^ dataBlkPtr[j]) & 0xff; + crc = (crc << 8) ^ crcTable[i]; + } + + return crc; + } + + removeStuffing(buffer, length) { + let i = 0; + let stuffLength = 0; + let index = 0; + + for (i = 0; i < length; i++) { + if (i >= 2) { + if (buffer[i - 2] == 0xff && buffer[i - 1] == 0xff && buffer[i] == 0xfd) { + i++; + stuffLength++; + } + } + buffer[index++] = buffer[i]; + } + + return stuffLength; + } + + postCallReturn(script, data, ms) { + /* + if (data == null) { + Entry.engine.isContinue = false; + return script.callReturn(); + } else if (data.length == 0) { + Entry.engine.isContinue = false; + return script.callReturn(); + } + */ + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + for (let i = 0; i < data.length; i++) { + this.robotisBuffer.push(data[i]); + } + //delay ms + setTimeout(() => { + script.timeFlag = 0; + }, ms); + return script; + } else if (script.timeFlag) { + return script; + } else { + delete script.isStart; + delete script.timeFlag; + Entry.engine.isContinue = false; + return script.callReturn(); + } + } + + setLanguage() { + return { + ko: { + template: { + // 값 블록 + robotis_rgee_lite_cm_ir_value: '%1 번 IR 센서 값', + robotis_rgee_lite_cm_ir_compare: '%1 번 IR 센서 값이 %2 %3이면', + robotis_rgee_lite_detectFrontObj: '앞에 물체가 있으면', + robotis_rgee_lite_cm_btn_value: '%1 버튼이 %2 이면', + robotis_rgee_lite_cm_joystick_value: + '조이스틱 위치가 %1 이면', + robotis_rgee_lite_mic: '마이크 음량(dB)', + robotis_rgee_lite_detectSound_compare: '소리가 %1에서 나면', + robotis_rgee_lite_imu: '%1축의 %2 값', + robotis_rgee_lite_roll_pitch: '제어기 각도 %1 값', + + // 음계 + robotis_rgee_lite_buzzer_index: '제어기 음계값 %1 을(를) %2 옥타브로 %3 초 동안 %4 %5', + + // LCD 제어 + robotis_rgee_lite_rgee_screen: '제어기 화면 배경을 알쥐 %1 (으)로 선택 %2', + robotis_rgee_lite_rgee_anim_screen: + '제어기 화면 애니메이션을 알쥐 %1 (으)로 선택 %2', + robotis_rgee_lite_icon: + "제어기 화면에 %1 출력하기 %5", + robotis_rgee_lite_LCDBright: '제어기 화면 밝기를 %1 (으)로 정하기 %2', + robotis_rgee_lite_LCDColor: '제어기 화면 색상을 %1 (으)로 정하기 %2', + + // LED 제어 + robotis_rgee_lite_led_brightness: '제어기 %1 LED 밝기를 %2(으)로 정하기 %3', + robotis_rgee_lite_led_pattern: '제어기 %1 LED %2 %3', + + // 소리 + robotis_rgee_lite_Hello: '%1 말하기 %2', + robotis_rgee_lite_effectSound: '효과음 %1 재생하기 %2', + robotis_rgee_lite_record: '%1 번 방에 녹음하기 %2', + robotis_rgee_lite_playRecord: '%1 번 방 소리 재생하기 %2', + + // 다른 로봇 LCD 제어 + robotis_rgee_lite_rla_screen: '제어기 화면 배경을 알라 %1 (으)로 선택 %2', + robotis_rgee_lite_rla_anim_screen: + '제어기 화면 애니메이션을 알라 %1 (으)로 선택 %2', + robotis_rgee_lite_kkokdu_screen: '제어기 화면 배경을 꼭두 %1 (으)로 선택 %2', + robotis_rgee_lite_kkokdu_anim_screen: + '제어기 화면 애니메이션을 꼭두 %1 (으)로 선택 %2', + robotis_rgee_lite_text_screen: + '제어기 화면에 %1을(를) (%2, %3)위치에 %4 로 %5(으)로 출력하기 %6', + + + // 주행 제어 + robotis_rgee_lite_drive_simple: '알쥐 %1 속도로 %2 하기 %3', + robotis_rgee_lite_drive_stop: '알쥐 정지하기 %1', + robotis_rgee_lite_motion: '알쥐 %1 %2', + robotis_rgee_lite_follow_line: '%1 속도로 라인 따라가기 %2', + robotis_rgee_lite_stop_follow_line: '라인 따라가기 종료 %1', + }, + Helper: { + // 값 블록 + robotis_rgee_lite_cm_ir_value: + '지정한 번호의 IR 센서 값(범위: 0 ~ 400)', + robotis_rgee_lite_cm_ir_compare: + "지정한 번호의 IR 센서 값과 지정한 값의 비교식이 맞으면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rgee_lite_detectFrontObj: + "지정한 센서 앞에 물체가 감지되면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rgee_lite_cm_btn_value: + "지정한 버튼이 눌렸다가 해제되면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rgee_lite_cm_joystick_value: + "조이스틱 위치가 지정한 상태이면 '참', 아니면 '거짓'으로 판단합니다..", + robotis_rgee_lite_mic: + '마이크로 감지된 소리의 세기를 데시벨(dB)로 표시합니다.', + robotis_rgee_lite_detectSound_compare: + "소리가 나는 방향이 지정한 방향과 동일하면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rgee_lite_imu: + '지정한 축의 지정한 가속도센서/자이로센서의 값\n범위: -100 ~ 100', + robotis_rgee_lite_roll_pitch: + 'roll/pitch 값\nroll: -180° ~ 180°, pitch: -90° ~ 90°', + + // 소리 + robotis_rgee_lite_buzzer_index: '지정한 음계, 옥타브, 시간만큼 연주하기', + + // LCD 제어 + robotis_rgee_lite_rgee_screen: '제어기 화면배경을 알쥐의 지정한 표정으로 설정', + robotis_rgee_lite_rgee_anim_screen: + '제어기 화면 애니메이션을 알쥐의 지정한 표정으로 설정', + robotis_rgee_lite_icon: + '화면 중앙에 지정한 아이콘을 표시', + robotis_rgee_lite_LCDBright: '화면 밝기를 설정\n밝기범위: 1% ~ 100%', + robotis_rgee_lite_LCDColor: '화면 색상을 설정', + + // LED 제어 + robotis_rgee_lite_led_brightness: '제어기의 지정한 LED의 밝기를 설정정', + robotis_rgee_lite_led_pattern: '제어기의 LED의 깜박임 패턴 설정', + + // 소리 + robotis_rgee_lite_Hello: '지정한 문장을 말하기', + robotis_rgee_lite_effectSound: '지정한 효과음 재생하기', + robotis_rgee_lite_record: '제어기의 지정한 번호에 녹음하기', + robotis_rgee_lite_playRecord: '제어기의 지정한 번호의 녹음음성 재생하기기', + + // 다른 로봇 LCD 제어 + robotis_rgee_lite_rla_screen: '제어기 화면배경을 알라의 지정한 표정으로 설정', + robotis_rgee_lite_rla_anim_screen: + '제어기 화면 애니메이션을 알라의 지정한 표정으로 설정', + robotis_rgee_lite_kkokdu_screen: '제어기 화면배경을 꼭두의 지정한 표정으로 설정', + robotis_rgee_lite_kkokdu_anim_screen: + '제어기 화면 애니메이션을 꼭두두의 지정한 표정으로 설정', + robotis_rgee_lite_text_screen: + '화면에 지정한 문구를 표시할 위치와 폰트크기, 색상을 설정\nX좌표: -160 ~ 160\nY좌표: -120 ~ 120', + + // 주행 제어 + robotis_rgee_lite_drive_simple: '알쥐를 지정한 속도와 방향으로 주행', + robotis_rgee_lite_drive_stop: '알쥐 정지하기', + robotis_rgee_lite_motion: '알쥐 지정한 동작을 하기', + robotis_rgee_lite_follow_line: '지정한 속도로 라인 따라가기', + robotis_rgee_lite_stop_follow_line: '라인 따라가기 종료', + + }, + Blocks: { + robotis_white: "흰색", + robotis_gray: "회색", + robotis_darkgray: "진회색", + robotis_black: "검정", + robotis_purple: "보라", + robotis_pink: "분홍색", + robotis_red: "빨강", + robotis_orange: "주황", + robotis_brown: "갈색", + robotis_yellow: "노랑", + robotis_green: "초록", + robotis_blue: "파랑", + robotis_lightblue: "연파랑", + robotis_darkblue: "남색", + robotis_left: "왼쪽", + robotis_center: "중앙", + robotis_right: "오른쪽", + robotis_both: "양쪽", + robotis_korean1: "안녕하세요", + robotis_korean2: "반가워요", + robotis_korean3: "알겠어요", + robotis_korean4: "아니에요", + robotis_korean5: "모르겠어요", + robotis_korean6: "좋아요", + robotis_korean7: "싫어요", + robotis_korean8: "이름을말하세요", + robotis_korean9: "무엇을도와줄까?", + robotis_korean10: "잘했어", + robotis_korean11: "괜찮아", + robotis_korean12: "다시해보자", + robotis_korean13: "고마워", + robotis_korean14: "다시말해줄래?", + robotis_korean15: "최고야!", + robotis_korean16: "신나요", + robotis_korean17: "즐거워요", + robotis_korean18: "미안해요", + robotis_korean19: "화나요", + robotis_korean20: "부끄러워요", + robotis_korean21: "무서워요", + robotis_korean22: "속상해요", + robotis_korean23: "사랑해요", + robotis_korean24: "예뻐요", + robotis_korean25: "신기해요", + robotis_korean26: "초조해요", + robotis_korean27: "앞으로가자", + robotis_korean28: "뒤로가자", + robotis_korean29: "일어나자", + robotis_korean30: "넘어졌네?", + robotis_korean31: "오예", + robotis_korean32: "아싸", + robotis_korean33: "어머", + robotis_korean34: "이런", + robotis_korean35: "오호", + robotis_korean36: "하하하", + robotis_korean37: "호호호", + robotis_korean38: "졸려", + robotis_korean39: "자장가를들려줘", + robotis_korean40: "안녕", + robotis_korean41: "배고프다", + robotis_korean42: "도토리땡긴다", + robotis_korean43: "아.씻고싶어", + robotis_korean44: "비누목욕시간이야", + robotis_korean45: "심심한데", + robotis_korean46: "간식먹을까", + robotis_korean47: "아파요", + robotis_korean48: "약은없나요?", + robotis_korean49: "어디로가야하지?", + robotis_korean50: "와아도착이다", + robotis_korean51: "왼쪽으로가자", + robotis_korean52: "오른쪽으로가자", + robotis_korean53: "깜짝이야", + robotis_korean54: "찾았다", + robotis_korean55: "여긴없네", + robotis_korean56: "혹시나불렀어?", + robotis_korean57: "내려주세요", + robotis_korean58: "앗", + robotis_korean59: "힝", + robotis_korean60: "이익", + robotis_dog: "개", + robotis_frog: "개구리", + robotis_cat: "고양이", + robotis_chicken: "닭", + robotis_tiger: "호랑이", + robotis_mouse: "쥐", + robotis_ambul: "앰뷸런스", + robotis_Horn: "경적(빵빵)", + robotis_siren: "사이렌(경찰차)", + robotis_whistle: "호루라기", + robotis_gun: "총소리", + robotis_clap: "박수소리", + robotis_melody1: "멜로디1", + robotis_melody2: "멜로디2", + robotis_melody3: "멜로디3", + robotis_melody4: "멜로디4", + robotis_forward: "앞으로", + robotis_backward: "뒤로", + robotis_acceleration: "가속도", + robotis_gyro: "자이로", + robotis_run: "실행", + robotis_cancel: "취소", + robotis_push: "눌림", + robotis_notPush: "안눌림", + robotis_play: "연주", + robotis_rest: "쉼표", + robotis_face01: "와하하", + robotis_face02: "싱글벙글", + robotis_face03: "큭큭큭", + robotis_face04: "냠냠", + robotis_face05: "겁먹음", + robotis_face06: "답답", + robotis_face07: "갸우뚱", + robotis_face08: "어벙벙", + robotis_face09: "고함", + robotis_face10: "화남", + robotis_face11: "킁킁(왼쪽)", + robotis_face12: "킁킁(오른쪽)", + robotis_face13: "킁킁(아래)", + robotis_face14: "안심", + robotis_face15: "기절", + robotis_face16: "헤롱헤롱", + robotis_face17: "하품", + robotis_face18: "졸림", + robotis_face19: "잠듦", + robotis_face20: "마음앓이", + robotis_face21: "폭풍눈물", + robotis_face22: "목욕", + robotis_face23: "햐트뿅뿅", + + robotis_car_anim01: "기본 표정", + robotis_car_anim02: "감동", + robotis_car_anim03: "미소", + robotis_car_anim04: "웃음", + robotis_car_anim05: "기쁨", + robotis_car_anim06: "행복", + robotis_car_anim07: "자신감", + robotis_car_anim08: "화남", + robotis_car_anim09: "우울", + robotis_car_anim10: "슬픔", + robotis_car_anim11: "고통", + robotis_car_anim12: "기절", + robotis_car_anim13: "공포", + robotis_car_anim14: "하품", + robotis_car_anim15: "졸림", + robotis_car_anim16: "오른쪽보기", + robotis_car_anim17: "왼쪽보기", + robotis_car_anim18: "앞쪽보기", + robotis_car_anim19: "깜짝놀람", + + robotis_flashing1: "점멸1", + robotis_flashing2: "점멸2", + robotis_flashing3: "점멸3", + robotis_flashing4: "점멸4", + robotis_flashing5: "점멸5", + robotis_flashing6: "점멸6", + robotis_flashing7: "점멸7", + robotis_flashing8: "점멸8", + robotis_flashing9: "점멸9", + robotis_moveF: "전진", + robotis_moveB: "후진", + robotis_moveL: "좌회전", + robotis_moveR: "우회전", + robotis_moveU: 'U턴', + robotis_moveL_in_place: '제자리 좌회전', + robotis_moveR_in_place: '제자리 우회전', + robotis_moveU_in_place: '제자리 U턴', + robotis_moveRG1: "일어서기", + robotis_moveRG2: "앉기", + robotis_moveRG3: "발버둥", + robotis_moveRG4: "발들기", + robotis_stMotion1: "기본자세", + robotis_stMotion2: "전진", + robotis_stMotion3: "우전진", + robotis_stMotion4: "좌전진", + robotis_stMotion5: "후진", + robotis_stMotion6: "오른쪽으로", + robotis_stMotion7: "왼쪽으로", + robotis_stMotion8: "우회전", + robotis_stMotion9: "좌회전", + robotis_spMotion1: "오른손 들기", + robotis_spMotion2: "오른손 내리기", + robotis_spMotion3: "왼손 들기", + robotis_spMotion4: "왼손 내리기", + robotis_spMotion5: "양손 들기", + robotis_spMotion6: "양손 내리기", + robotis_spMotion7: "뒤로 넘어지기", + robotis_spMotion8: "앞으로 넘어지기", + robotis_spMotion9: "앞으로 일어서기", + robotis_spMotion10: "뒤로 일어서기", + robotis_spMotion11: "방어", + robotis_spMotion12: "공격1", + robotis_spMotion13: "공격2", + robotis_spMotion14: "공격3", + robotis_spMotion15: "공격4", + robotis_screen1: "가위", + robotis_screen2: "바위", + robotis_screen3: "보", + robotis_screen_text_font_small: "작은 폰트", + robotis_screen_text_font_big: "큰 폰트", + robotis_sensing_temperature: "온도센서", + robotis_sensing_humidity: "습도센서", + robotis_sensing_brightness: "밝기센서", + robotis_sensing_motion: "움직임센서", + robotis_sensing_button: "버튼센서", + robotis_sensing_distance: "거리센서", + robotis_sensing_ir_left: "왼쪽 적외선센서", + robotis_sensing_ir_right: "오른쪽 적외선센서", + }, + }, + en: { + template: { + // Value Blocks + robotis_rgee_lite_cm_ir_value: 'IR sensor value of No. %1', + robotis_rgee_lite_cm_ir_compare: 'If the IR sensor value of No. %1 is %2 %3', + robotis_rgee_lite_detectFrontObj: 'If there is an object in front', + robotis_rgee_lite_cm_btn_value: 'If button %1 is %2', + robotis_rgee_lite_cm_joystick_value: 'If joystick is at %1', + robotis_rgee_lite_mic: 'Microphone volume (dB)', + robotis_rgee_lite_detectSound_compare: 'If the sound comes from %1', + robotis_rgee_lite_imu: '%2 value of %1 axis', + robotis_rgee_lite_roll_pitch: 'Controller angle %1 value', + + // Musical Scale + robotis_rgee_lite_buzzer_index: 'Play note %1 on controller in octave %2 for %3 seconds %4 %5', + + // LCD Control + robotis_rgee_lite_rgee_screen: 'Set controller screen background to R-Gee %1 %2', + robotis_rgee_lite_rgee_anim_screen: 'Set controller screen animation to R-Gee %1 %2', + robotis_rgee_lite_icon: 'Display %1 on controller screen %5', + robotis_rgee_lite_LCDBright: 'Set controller screen brightness to %1 %2', + robotis_rgee_lite_LCDColor: 'Set controller screen color to %1 %2', + + // LED Control + robotis_rgee_lite_led_brightness: 'Set controller LED %1 brightness to %2 %3', + robotis_rgee_lite_led_pattern: 'Controller LED %1 %2 %3', + + // Sound + robotis_rgee_lite_Hello: 'Say "%1" %2', + robotis_rgee_lite_effectSound: 'Play sound effect %1 %2', + robotis_rgee_lite_record: 'Record in slot %1 %2', + robotis_rgee_lite_playRecord: 'Play sound from slot %1 %2', + + // Other Robot LCD Control + robotis_rgee_lite_rla_screen: 'Set controller screen background to Kodala %1 %2', + robotis_rgee_lite_rla_anim_screen: 'Set controller screen animation to Kodala %1 %2', + robotis_rgee_lite_kkokdu_screen: 'Set controller screen background to TIG %1 %2', + robotis_rgee_lite_kkokdu_anim_screen: 'Set controller screen animation to TIG %1 %2', + robotis_rgee_lite_text_screen: 'Display "%1" on screen at (%2, %3) with font %4 and color %5 %6', + + // Driving Control + robotis_rgee_lite_drive_simple: 'Move R-Gee at speed %1 in direction %2 %3', + robotis_rgee_lite_drive_stop: 'Stop R-Gee %1', + robotis_rgee_lite_motion: 'R-Gee %1 %2', + robotis_rgee_lite_follow_line: 'Follow line at speed %1 %2', + robotis_rgee_lite_stop_follow_line: 'Stop following line %1', + }, + Helper: { + // Value blocks + robotis_rgee_lite_cm_ir_value: 'IR sensor value of the specified number (Range: 0 ~ 400)', + robotis_rgee_lite_cm_ir_compare: "Returns 'true' if the comparison of the IR sensor value of the specified number and the given value is correct; otherwise returns 'false'.", + robotis_rgee_lite_detectFrontObj: "Returns 'true' if an object is detected in front of the specified sensor; otherwise returns 'false'.", + robotis_rgee_lite_cm_btn_value: "Returns 'true' if the specified button was pressed and released; otherwise returns 'false'.", + robotis_rgee_lite_cm_joystick_value: "Returns 'true' if the joystick position matches the specified state; otherwise returns 'false'.", + robotis_rgee_lite_mic: 'Displays the intensity of sound detected by the microphone in decibels (dB).', + robotis_rgee_lite_detectSound_compare: "Returns 'true' if the direction of the sound matches the specified direction; otherwise returns 'false'.", + robotis_rgee_lite_imu: 'Value of the specified axis of the accelerometer/gyroscope sensor\nRange: -100 ~ 100', + robotis_rgee_lite_roll_pitch: 'Roll/pitch values\nRoll: -180° ~ 180°, Pitch: -90° ~ 90°', + + // Sound + robotis_rgee_lite_buzzer_index: 'Play the specified scale, octave, and duration', + + // LCD control + robotis_rgee_lite_rgee_screen: 'Set the controller screen background to the specified R-Gee expression', + robotis_rgee_lite_rgee_anim_screen: 'Set the controller screen animation to the specified R-Gee expression', + robotis_rgee_lite_icon: 'Display the specified icon at the center of the screen', + robotis_rgee_lite_LCDBright: 'Set the screen brightness\nBrightness range: 1% ~ 100%', + robotis_rgee_lite_LCDColor: 'Set the screen color', + + // LED control + robotis_rgee_lite_led_brightness: 'Set the brightness of the specified LED on the controller', + robotis_rgee_lite_led_pattern: 'Set the blinking pattern of the LED on the controller', + + // Sound + robotis_rgee_lite_Hello: 'Speak the specified sentence', + robotis_rgee_lite_effectSound: 'Play the specified sound effect', + robotis_rgee_lite_record: 'Record on the specified number of the controller', + robotis_rgee_lite_playRecord: 'Play the recorded voice of the specified number on the controller', + + // Other robot LCD control + robotis_rgee_lite_rla_screen: 'Set the controller screen background to the specified expression of R-LA', + robotis_rgee_lite_rla_anim_screen: 'Set the controller screen animation to the specified expression of R-LA', + robotis_rgee_lite_kkokdu_screen: 'Set the controller screen background to the specified expression of Kkokdu', + robotis_rgee_lite_kkokdu_anim_screen: 'Set the controller screen animation to the specified expression of Kkokdu', + robotis_rgee_lite_text_screen: 'Set the location, font size, and color of the specified phrase to be displayed on the screen\nX coordinate: -160 ~ 160\nY coordinate: -120 ~ 120', + + // Driving control (duplicate entries for R-Gee) + robotis_rgee_lite_drive_simple: 'Drive R-Gee at the specified speed and direction', + robotis_rgee_lite_drive_stop: 'Stop R-Gee', + robotis_rgee_lite_motion: 'Make R-Gee perform the specified motion', + robotis_rgee_lite_follow_line: 'Start following the line at the specified speed', + robotis_rgee_lite_stop_follow_line: 'Stop following the line' + }, + + Blocks: { + robotis_white: 'White', + robotis_gray: 'Gray', + robotis_darkgray: 'Darkgray', + robotis_black: 'Black', + robotis_purple: 'Purple', + robotis_pink: 'Pink', + robotis_red: 'Red', + robotis_orange: 'Orange', + robotis_brown: 'Brown', + robotis_yellow: 'Yellow', + robotis_green: 'Green', + robotis_blue: 'Blue', + robotis_lightblue: 'Lightblue', + robotis_darkblue: 'Darkblue', + robotis_brown: 'Brown', + robotis_left: 'Left', + robotis_center: 'Center', + robotis_right: 'Right', + robotis_both: 'Both', + + robotis_rgee: 'R-GEE', + robotis_rla: 'KODALA', + robotis_kkokdu: 'TIG', + + robotis_korean1: 'Hello!', + robotis_korean2: 'Great to see you.', + robotis_korean3: 'Okay ~', + robotis_korean4: 'No!', + robotis_korean5: "I don't know.", + robotis_korean6: 'I like it.', + robotis_korean7: "I don't like it.", + robotis_korean8: 'What is your name? ', + robotis_korean9: 'How can I help you? ', + robotis_korean10: 'Great job! ', + robotis_korean11: "It's alright.", + robotis_korean12: "Let's do it again! ", + robotis_korean13: 'Thank you! ', + robotis_korean14: 'Can you say that one more time?', + robotis_korean15: 'Awesome!', + robotis_korean16: "I'm excited! ", + robotis_korean17: "I'm having a great time! ", + robotis_korean18: "I'm sorry.", + robotis_korean19: "I'm angry! ", + robotis_korean20: "I'm embarassed.", + robotis_korean21: "I'm scared.", + robotis_korean22: "I'm upset.", + robotis_korean23: 'I love you.', + robotis_korean24: 'Very pretty! ', + robotis_korean25: 'Interesting.', + robotis_korean26: "I'm nervous.", + robotis_korean27: "Let's move forward! ", + robotis_korean28: "Let's move backward! ", + robotis_korean29: "Let's stand up! ", + robotis_korean30: 'Did you fall down? ', + robotis_korean31: 'Oh Yeah~', + robotis_korean32: 'Sweet! ', + robotis_korean33: 'Oh no', + robotis_korean34: 'My My ', + robotis_korean35: 'Whoo hoo! ', + robotis_korean36: 'Ha Ha Ha', + robotis_korean37: 'Ho Ho Ho ', + robotis_korean38: "I'm sleepy.", + robotis_korean39: 'Sing me a bedtime song! ', + robotis_korean40: 'Hello!', + robotis_korean41: "I'm hungry.", + robotis_korean42: "I'm craving an acorn! ", + robotis_korean43: 'I want to take a bath! ', + robotis_korean44: 'Time for a bath! ', + robotis_korean45: "I'm bored. ", + robotis_korean46: 'Do you want a snack? ', + robotis_korean47: "I'm sick.", + robotis_korean48: 'Do you have any medicine? ', + robotis_korean49: 'Where do we have to go? ', + robotis_korean50: "We're here! ", + robotis_korean51: "Let's go to the left side! ", + robotis_korean52: "Let's go to the right side! ", + robotis_korean53: 'Oh my, you scared me! ', + robotis_korean54: 'Found you! ', + robotis_korean55: "There's nothing here. ", + robotis_korean56: 'Did you call me?', + robotis_korean57: 'Please let me down. ', + robotis_korean58: 'Oops! ', + robotis_korean59: 'Hmmph! ', + robotis_korean60: 'Eek! ', + robotis_dog: 'Dog', + robotis_frog: 'Frog', + robotis_cat: 'Cat', + robotis_chicken: 'Rooster', + robotis_tiger: 'Tiger', + robotis_mouse: 'Mouse', + robotis_whistle: 'Whistle', + robotis_ambul: 'Ambulance', + robotis_Horn: 'CarHorn', + robotis_siren: 'Siren', + robotis_gun: 'Gunshot', + robotis_clap: 'Clap', + robotis_melody1: 'Melody1', + robotis_melody2: 'Melody2', + robotis_melody3: 'Melody3', + robotis_melody4: 'Melody4', + robotis_forward: 'Forward', + robotis_backward: 'Backward', + robotis_acceleration: 'acceleration', + robotis_gyro: 'gyro', + robotis_run: 'Run', + robotis_cancel: 'Cancel', + robotis_push: 'Pressed', + robotis_notPush: 'Unpressed', + robotis_play: 'Play', + robotis_rest: 'Rest', + robotis_face01: 'Haha', + robotis_face02: 'Smile', + robotis_face03: 'Laugh', + robotis_face04: 'Yum Yum', + robotis_face05: 'Scared', + robotis_face06: 'Uncomfortable', + robotis_face07: 'Confused', + robotis_face08: 'Dazed', + robotis_face09: 'Yell', + robotis_face10: 'Angry', + robotis_face11: 'Sniff (Left)', + robotis_face12: 'Sniff (Right)', + robotis_face13: 'Sniff (Down)', + robotis_face14: 'Whew', + robotis_face15: 'Faint', + robotis_face16: 'Dizzy', + robotis_face17: 'Yawn', + robotis_face18: 'Sleepy', + robotis_face19: 'Sleep', + robotis_face20: 'Sad', + robotis_face21: 'Cry', + robotis_face22: 'Bath', + robotis_face23: 'Heart-Eyes', + + robotis_car_anim01: "Default", + robotis_car_anim02: "Touched", + robotis_car_anim03: "Smile", + robotis_car_anim04: "Laugh", + robotis_car_anim05: "Joy", + robotis_car_anim06: "Happiness", + robotis_car_anim07: "Confidence", + robotis_car_anim08: "Anger", + robotis_car_anim09: "Depressed", + robotis_car_anim10: "Sadness", + robotis_car_anim11: "Pain", + robotis_car_anim12: "Fainting", + robotis_car_anim13: "Fear", + robotis_car_anim14: "Yawn", + robotis_car_anim15: "Sleepy", + robotis_car_anim16: "Looking Right", + robotis_car_anim17: "Looking Left", + robotis_car_anim18: "Looking Forward", + robotis_car_anim19: "Surprised", + + + robotis_flashing1: "Flashing1", + robotis_flashing2: "Flashing2", + robotis_flashing3: "Flashing3", + robotis_flashing4: "Flashing4", + robotis_flashing5: "Flashing5", + robotis_flashing6: "Flashing6", + robotis_flashing7: "Flashing7", + robotis_flashing8: "Flashing8", + robotis_flashing9: "Flashing9", + + + + robotis_moveF: 'Forward', + robotis_moveB: 'Backward', + robotis_moveL: 'LeftTurn', + robotis_moveR: 'RightTurn', + robotis_moveU: 'U-turn', + robotis_moveL_in_place: 'Turn left in place', + robotis_moveR_in_place: 'Trun right in place', + robotis_moveU_in_place: 'U-turn in place', + robotis_moveRG1: 'Stand', + robotis_moveRG2: 'Sit', + robotis_moveRG3: 'Struggle', + robotis_moveRG4: 'RaiseFeet', + robotis_fast: 'Fast', + robotis_normal: 'Normal', + robotis_slow: 'Slow', + robotis_stop: 'Stop', + robotis_roll: 'Left-right rotate angle (roll)', + robotis_pitch: 'Forward-backward rotate angle (pitch)', + robotis_stMotion1: 'Standard', + robotis_stMotion2: 'Forward', + robotis_stMotion3: 'TurnRight', + robotis_stMotion4: 'TurnLeft', + robotis_stMotion5: 'Backward', + robotis_stMotion6: 'ToRight', + robotis_stMotion7: 'ToLeft', + robotis_stMotion8: 'TurnAroundRight', + robotis_stMotion9: 'TurnAroundLeft', + robotis_spMotion1: 'RightHandUp', + robotis_spMotion2: 'RightHandDown', + robotis_spMotion3: 'LeftHandUp', + robotis_spMotion4: 'LeftHandDown', + robotis_spMotion5: 'BothHandsUp', + robotis_spMotion6: 'BothHandsDown', + robotis_spMotion7: 'FallBackward', + robotis_spMotion8: 'FallForward', + robotis_spMotion9: 'StandForward', + robotis_spMotion10: 'StandBackward', + robotis_spMotion11: 'Defence', + robotis_spMotion12: 'Offense1', + robotis_spMotion13: 'Offense2', + robotis_spMotion14: 'Offense3', + robotis_spMotion15: 'Offense4', + robotis_screen1: 'Sissor', + robotis_screen2: 'Rock', + robotis_screen3: 'Paper', + robotis_screen_text_font_small: "Small font", + robotis_screen_text_font_big: "Big font", + }, + }, + }; + } + getBlocks() { + return { + robotis_rgee_lite_cm_ir_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '360'], + ['2', '362'], + ['3', '364'], + ['4', '366'], + ['5', '368'], + ['6', '370'], + ], + value: '360', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_cm_ir_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + const scope = script.executor.scope; + + const data_default_address = script.getNumberValue('VALUE'); + + let result = Entry.RobotisRgeeLite.dataBuffer[data_default_address]; + if (result == undefined) { + result = rb100_last_valid_value[data_default_address]; + } else { + rb100_last_valid_value[data_default_address] = result; + } + if (typeof result == 'undefined') { + return 0; + } + return Math.round(result % 65536); + }, + syntax: { + js: [], + py: ['RgeeLite.ir_value(%1)'], + }, + }, + robotis_rgee_lite_cm_ir_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '360'], + ['2', '362'], + ['3', '364'], + ['4', '366'], + ['5', '368'], + ['6', '370'], + ], + value: '360', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['>', '0'], + ['<', '1'], + ['=', '2'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null, null, 200], + type: 'robotis_rgee_lite_cm_ir_compare', + }, + paramsKeyMap: { + VALUE: 0, + COMPARE_OP: 1, + COMPARE_VAL: 2, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('VALUE'); + let compareValue = script.getNumberValue('COMPARE_VAL'); + let compareOP = script.getNumberValue('COMPARE_OP'); + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + + if (result == undefined) { + return false; + } + + result = Math.round(result % 65536); + + switch (compareOP) { + case 0: + return result > compareValue; + case 1: + return result < compareValue; + default: + return false; + } + }, + syntax: { + js: [], + py: ['RgeeLite.ir_compare(%1)'], + }, + }, + robotis_rgee_lite_detectFrontObj: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + + ], + events: {}, + def: { + params: [ + + ], + type: 'robotis_rgee_lite_detectFrontObj', + }, + paramsKeyMap: { + + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + + // instruction / address / length / value / default length + let ir_1 = 0; + let ir_2 = 0; + + + + ir_1 = Entry.RobotisRgeeLite.dataBuffer[360]; + ir_2 = Entry.RobotisRgeeLite.dataBuffer[362]; + if (ir_1 == undefined) { + ir_1 = 0; + } + if (ir_2 == undefined) { + ir_2 = 0; + } + return ir_1 > 100 || ir_2 > 100; + + }, + syntax: { + js: [], + py: ['RgeeLite.detectFrontObj()'], + }, + }, + robotis_rgee_lite_cm_btn_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_run, '45'], + [Lang.Blocks.robotis_cancel, '42'], + ], + value: '45', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_push, '1'], + [Lang.Blocks.robotis_notPush, '0'], + + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_cm_btn_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('VALUE'); + let compareValue = 1; + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['RgeeLite.btn_value(%1)'], + }, + }, + robotis_rgee_lite_cm_joystick_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_center, '0'], + ['←', '1'], + ['→', '2'], + ['↑', '3'], + ['↓', '4'], + ['↖', '5'], + ['↗', '6'], + ['↙', '7'], + ['↘', '8'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_cm_joystick_value', + }, + paramsKeyMap: { + COMPARE_VAL: 0, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = 50; + let compareValue = script.getNumberValue('COMPARE_VAL', script); + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['RgeeLite.joystick_value()'], + }, + }, + robotis_rgee_lite_mic: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_mic', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + async func(sprite, script) { + let scope = script.executor.scope; + let data_address = 119; + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['RgeeLite.mic()'], + }, + }, + robotis_rgee_lite_detectSound_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_right, '255'], + [Lang.Blocks.robotis_center, '0'], + [Lang.Blocks.robotis_left, '1'], + ], + value: '255', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_detectSound_compare', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = 5031; + let compareValue = script.getNumberValue('VALUE'); + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['RgeeLite.detectSound_compare(%1)'], + }, + }, + robotis_rgee_lite_imu: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['x', '78'], //72 + ['y', '80'], //74 + ['z', '82'], //76 + ], + value: '78', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_acceleration, '0'], //72 + [Lang.Blocks.robotis_gyro, '6'], //74 + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_imu', + }, + paramsKeyMap: { + AXIS: 0, + MODE: 1, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = + script.getField('AXIS', script) - script.getField('MODE', script); + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['RgeeLite.imu()'], + }, + }, + robotis_rgee_lite_roll_pitch: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_roll, '70'], //72 + [Lang.Blocks.robotis_pitch, '88'], //74 + ], + value: '70', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_roll_pitch', + }, + paramsKeyMap: { + AXIS: 0, + }, + class: 'robotis_rgee_lite_value', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('AXIS'); + + let result = Entry.RobotisRgeeLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['RgeeLite.roll_pitch(%1)'], + }, + }, + + + robotis_rgee_lite_buzzer_index: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.General.note_c + '', '1'], + [Lang.General.note_c + '#', '2'], + [Lang.General.note_d + '', '3'], + [Lang.General.note_d + '#', '4'], + [Lang.General.note_e + '', '5'], + [Lang.General.note_f + '', '6'], + [Lang.General.note_f + '#', '7'], + [Lang.General.note_g + '', '8'], + [Lang.General.note_g + '#', '9'], + [Lang.General.note_a + '', '10'], + [Lang.General.note_a + '#', '11'], + [Lang.General.note_b + '', '12'], + ], + value: '11', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['3', '3'], + ['4', '4'], + ['5', '5'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_play, '1'], + [Lang.Blocks.robotis_rest, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, 1, null, null], + type: 'robotis_rgee_lite_buzzer_index', + }, + paramsKeyMap: { + CM_BUZZER_INDEX: 0, + CM_BUZZER_OCTAV: 1, + CM_BUZZER_DELAY: 2, + CM_BUZZER_PLAY: 3 + }, + class: 'robotis_rgee_lite_sound', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmBuzzerIndex = script.getNumberValue('CM_BUZZER_INDEX', script); + let cmBuzzerOffset = script.getNumberValue('CM_BUZZER_OCTAV', script); + let cmBuzzerTime = script.getNumberValue('CM_BUZZER_DELAY', script); + let cmBuzzerPlay = script.getNumberValue('CM_BUZZER_PLAY', script); + + let data_instruction = INST_WRITE; + let data_address = 0; + let data_value = 0; + let interval = 0; + let data_buf = []; + + cmBuzzerTime = Math.round(cmBuzzerTime * 1000); + + data_address = 740; + // data_value_1 = cmBuzzerTime * 10; + // TODO 텍스트 입력으로 바꾸고 최대는 5초 : 0.5 초 하려면 5를 입력 - console.log(parseInt(0.59 * 10)); max 는 5초 + + if (cmBuzzerTime < 0) { + cmBuzzerTime = 0; + } + if (cmBuzzerTime > 50000) { + cmBuzzerTime = 50000; + } + + data_buf.push(cmBuzzerTime % 256); + data_buf.push(Math.floor(cmBuzzerTime / 256)); + + data_value = cmBuzzerIndex + (cmBuzzerOffset - 1) * 12; + data_buf.push(Math.floor(data_value)); + + // console.log("buzzer send"); + let data_sendqueue = [[data_instruction, data_address, 3, data_buf]]; + + if(cmBuzzerPlay == '2') { + data_sendqueue = []; + } + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + cmBuzzerTime + interval + ); + }, + syntax: { + js: [], + py: ['RgeeLite.buzzer_index(%1, %2, %3)'], + }, + }, + + + robotis_rgee_lite_rgee_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_face01, '2817'], + [Lang.Blocks.robotis_face02, '2818'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face03, '2819'], + [Lang.Blocks.robotis_face04, '2820'], + [Lang.Blocks.robotis_face05, '2821'], + + [Lang.Blocks.robotis_face06, '2822'], + [Lang.Blocks.robotis_face07, '2823'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face08, '2824'], + [Lang.Blocks.robotis_face09, '2825'], + [Lang.Blocks.robotis_face10, '2826'], + + [Lang.Blocks.robotis_face11, '2827'], + [Lang.Blocks.robotis_face12, '2828'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face13, '2829'], + + [Lang.Blocks.robotis_face14, '2830'], + [Lang.Blocks.robotis_face15, '2831'], + [Lang.Blocks.robotis_face16, '2832'], + [Lang.Blocks.robotis_face17, '2833'], + [Lang.Blocks.robotis_face18, '2834'], + + [Lang.Blocks.robotis_face19, '2835'], + [Lang.Blocks.robotis_face20, '2836'], + [Lang.Blocks.robotis_face21, '2837'], + [Lang.Blocks.robotis_face22, '2838'], + [Lang.Blocks.robotis_face23, '2839'], + ], + value: '2817', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_rgee_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['RgeeLite.rgee_screen(%1)'] }, + }, + + robotis_rgee_lite_rgee_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_face01, '30748'], + [Lang.Blocks.robotis_face02, '30749'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face03, '30750'], + [Lang.Blocks.robotis_face04, '30756'], + [Lang.Blocks.robotis_face05, '30754'], + + [Lang.Blocks.robotis_face06, '30741'], + [Lang.Blocks.robotis_face07, '30747'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face08, '30738'], + [Lang.Blocks.robotis_face09, '30740'], + [Lang.Blocks.robotis_face10, '30739'], + + [Lang.Blocks.robotis_face11, '30733'], + [Lang.Blocks.robotis_face12, '30734'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face13, '30732'], + + [Lang.Blocks.robotis_face14, '30757'], + [Lang.Blocks.robotis_face15, '30736'], + [Lang.Blocks.robotis_face16, '30731'], + [Lang.Blocks.robotis_face17, '30742'], + [Lang.Blocks.robotis_face18, '30743'], + + [Lang.Blocks.robotis_face19, '30744'], + [Lang.Blocks.robotis_face20, '30751'], + [Lang.Blocks.robotis_face21, '30752'], + [Lang.Blocks.robotis_face22, '30755'], + [Lang.Blocks.robotis_face23, '30758'], + ], + value: '30748', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_rgee_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['RgeeLite.rgee_animation_screen(%1)'] }, + }, + + + + + robotis_rgee_lite_icon: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_screen1, '11545'], + [Lang.Blocks.robotis_screen2, '11546'], + [Lang.Blocks.robotis_screen3, '11547'], + ['0', '11283'], + ['1', '11284'], + ['2', '11285'], + ['3', '11286'], + ['4', '11287'], + ['5', '11288'], + ['6', '11289'], + ['7', '11290'], + ['8', '11291'], + ['9', '11292'], + ['10', '11293'], + ], + value: '11545', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + 50, + null, + ], + type: 'robotis_rgee_lite_icon', + }, + paramsKeyMap: { + ICON: 0, + X: 1, + Y: 2, + SIZE: 3, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let iconNum = script.getField('ICON', script); + let x = script.getNumberValue('X', script); + let y = script.getNumberValue('Y', script); + let size = script.getNumberValue('SIZE', script) * 2; + + let data_instruction = INST_WRITE; + let data_address = 166; + let data_length = 2; + let data_value = 10496; + + if (x < -160) { + x = -160; + } else if (x > 160) { + x = 160; + } + + if (y < -120) { + y = -120; + } else if (y > 120) { + y = 120; + } + + if (size < 0) { + size = 0; + } else if (size > 400) { + size = 400; + } + + data_value = iconNum; + + let data_sendqueue = [ + [INST_WRITE, 130, 2, x], + [INST_WRITE, 132, 2, y], + [INST_WRITE, 149, 2, size], + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { + js: [], + py: ['RgeeLite.icon_screen(%1,%2,%3,%4)'], + }, + }, + + + robotis_rgee_lite_LCDBright: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [10], + type: 'robotis_rgee_lite_LCDBright', + }, + paramsKeyMap: { + BRIGHT: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let bright = script.getNumberValue('BRIGHT', script); + + let data_instruction = INST_WRITE; + let data_address = 180; + let data_length = 1; + let data_value = 0; + + bright = Math.min(Math.max(bright, 0), 100); + + data_value = bright; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RgeeLite.LCDBright(%1)'], + }, + }, + robotis_rgee_lite_LCDColor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_red, '224'], + [Lang.Blocks.robotis_orange, '244'], + [Lang.Blocks.robotis_yellow, '252'], + [Lang.Blocks.robotis_green, '28'], + [Lang.Blocks.robotis_blue, '3'], + [Lang.Blocks.robotis_darkblue, '2'], + [Lang.Blocks.robotis_purple, '130'], + [Lang.Blocks.robotis_brown, '173'], + [Lang.Blocks.robotis_black, '0'], + [Lang.Blocks.robotis_white, '255'], + ], + value: '224', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_LCDColor', + }, + paramsKeyMap: { + COLOR: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let color = script.getNumberValue('COLOR', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = 0; + + data_value = color; + bg_color = color; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 100 + ); + }, + syntax: { + js: [], + py: ['RgeeLite.LCDColor(%1)'], + }, + }, + + robotis_rgee_lite_led_brightness: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_left, '1'], + [Lang.Blocks.robotis_right, '2'], + [Lang.Blocks.robotis_both, '3'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: [100] + } + ], + type: 'robotis_rgee_lite_led_brightness', + }, + paramsKeyMap: { + RB_LED: 0, + BRIGHT: 1, + }, + class: 'robotis_rgee_lite_led', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmLed = script.getNumberValue('RB_LED', script); + let bright = script.getNumberValue('BRIGHT', script); + + let data_instruction = INST_WRITE; + let data_address = 0; + let data_length = 1; + let data_value = 0; + + if(bright < 0){ + bright = 0; + } else if(bright > 100) { + bright = 100 + } + data_value = 100+bright; + + if (cmLed == 1) { + data_address = 40; + data_length = 1; + } else if (cmLed == 2) { + data_address = 41; + data_length = 1; + } else if (cmLed == 3) { + data_address = 40; + data_length = 2; + data_value = data_value * 257 + } + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['RgeeLite.led_brightness(%1, %2)'] }, + }, + robotis_rgee_lite_led_pattern: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_flashing1, '11'], + [Lang.Blocks.robotis_flashing2, '12'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing3, '13'], + + [Lang.Blocks.robotis_flashing4, '21'], + [Lang.Blocks.robotis_flashing5, '22'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing6, '23'], + + [Lang.Blocks.robotis_flashing7, '31'], + [Lang.Blocks.robotis_flashing8, '32'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing9, '33'], + + ], + value: '11', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_common_on, '1'], + [Lang.Blocks.robotis_common_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, null], + type: 'robotis_rgee_lite_led_pattern', + }, + paramsKeyMap: { + RB_LED: 0, + VALUE: 1, + }, + class: 'robotis_rgee_lite_led', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmLed = script.getNumberValue('RB_LED', script); + let value = script.getNumberValue('VALUE', script); + + let data_instruction = INST_WRITE; + let data_address = 40; + let data_length = 1; + let data_value = 0; + + data_value = value * cmLed; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['RgeeLite.led_pattern(%1, %2)'] }, + }, + + + + robotis_rgee_lite_Hello: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_korean1, '0'], + [Lang.Blocks.robotis_korean2, '1'], + [Lang.Blocks.robotis_korean3, '2'], + [Lang.Blocks.robotis_korean4, '3'], + [Lang.Blocks.robotis_korean5, '4'], + [Lang.Blocks.robotis_korean6, '5'], + [Lang.Blocks.robotis_korean7, '6'], + [Lang.Blocks.robotis_korean8, '7'], + [Lang.Blocks.robotis_korean9, '8'], + [Lang.Blocks.robotis_korean10, '9'], + [Lang.Blocks.robotis_korean11, '10'], + [Lang.Blocks.robotis_korean12, '11'], + [Lang.Blocks.robotis_korean13, '12'], + [Lang.Blocks.robotis_korean14, '13'], + [Lang.Blocks.robotis_korean15, '14'], + [Lang.Blocks.robotis_korean16, '15'], + [Lang.Blocks.robotis_korean17, '16'], + [Lang.Blocks.robotis_korean18, '17'], + [Lang.Blocks.robotis_korean19, '18'], + [Lang.Blocks.robotis_korean20, '19'], + [Lang.Blocks.robotis_korean21, '20'], + [Lang.Blocks.robotis_korean22, '21'], + [Lang.Blocks.robotis_korean23, '22'], + [Lang.Blocks.robotis_korean24, '23'], + [Lang.Blocks.robotis_korean25, '24'], + [Lang.Blocks.robotis_korean26, '25'], + [Lang.Blocks.robotis_korean27, '26'], + [Lang.Blocks.robotis_korean28, '27'], + [Lang.Blocks.robotis_korean29, '28'], + [Lang.Blocks.robotis_korean30, '29'], + [Lang.Blocks.robotis_korean31, '30'], + [Lang.Blocks.robotis_korean32, '31'], + [Lang.Blocks.robotis_korean33, '32'], + [Lang.Blocks.robotis_korean34, '33'], + [Lang.Blocks.robotis_korean35, '34'], + [Lang.Blocks.robotis_korean36, '35'], + [Lang.Blocks.robotis_korean37, '36'], + [Lang.Blocks.robotis_korean38, '37'], + [Lang.Blocks.robotis_korean39, '38'], + [Lang.Blocks.robotis_korean40, '39'], + [Lang.Blocks.robotis_korean41, '40'], + [Lang.Blocks.robotis_korean42, '41'], + [Lang.Blocks.robotis_korean43, '42'], + [Lang.Blocks.robotis_korean44, '43'], + [Lang.Blocks.robotis_korean45, '44'], + [Lang.Blocks.robotis_korean46, '45'], + [Lang.Blocks.robotis_korean47, '46'], + [Lang.Blocks.robotis_korean48, '47'], + [Lang.Blocks.robotis_korean49, '48'], + [Lang.Blocks.robotis_korean50, '49'], + [Lang.Blocks.robotis_korean51, '50'], + [Lang.Blocks.robotis_korean52, '51'], + [Lang.Blocks.robotis_korean53, '52'], + [Lang.Blocks.robotis_korean54, '53'], + [Lang.Blocks.robotis_korean55, '54'], + [Lang.Blocks.robotis_korean56, '55'], + [Lang.Blocks.robotis_korean57, '56'], + [Lang.Blocks.robotis_korean58, '57'], + [Lang.Blocks.robotis_korean59, '58'], + [Lang.Blocks.robotis_korean60, '59'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_Hello', + }, + paramsKeyMap: { + HELLO: 0, + }, + class: 'robotis_rgee_lite_sound', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmHello = script.getField('HELLO', script); + + let data_instruction = INST_WRITE; + let data_address = 110; + let data_length = 2; + let data_value = 0; + + data_value = 25601 + Number(cmHello); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [data_instruction, 0, 2, 0], + ]; + + let extraTime = 0; + + if (cmHello == '38' || cmHello == '55') { + extraTime = 2000; + } + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + 2000 + extraTime + ); + }, + syntax: { + js: [], + py: ['RgeeLite.speak(%1)'], + }, + }, + robotis_rgee_lite_effectSound: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dog, '0'], + [Lang.Blocks.robotis_frog, '1'], + [Lang.Blocks.robotis_cat, '2'], + [Lang.Blocks.robotis_chicken, '7'], + [Lang.Blocks.robotis_tiger, '19'], + [Lang.Blocks.robotis_mouse, '17'], + + [Lang.Blocks.robotis_ambul, '773'], + [Lang.Blocks.robotis_Horn, '781'], + [Lang.Blocks.robotis_siren, '774'], + [Lang.Blocks.robotis_whistle, '274'], + [Lang.Blocks.robotis_gun, '775'], + [Lang.Blocks.robotis_clap, '260'], + + [Lang.Blocks.robotis_melody1, '786'], + [Lang.Blocks.robotis_melody2, '787'], + [Lang.Blocks.robotis_melody3, '788'], + [Lang.Blocks.robotis_melody4, '789'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_effectSound', + }, + paramsKeyMap: { + HELLO: 0, + }, + class: 'robotis_rgee_lite_sound', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmHello = script.getField('HELLO', script); + + let data_instruction = INST_WRITE; + let data_address = 110; + let data_length = 2; + let data_value = 0; + + data_value = Number(cmHello); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [data_instruction, 0, 2, 0], + ]; + + let extraTime = 0; + if ( + cmHello == '272' || + cmHello == '786' || + cmHello == '787' || + cmHello == '788' || + cmHello == '789' + ) { + //오리 + extraTime = 0; + if (cmHello == '788' || cmHello == '789') { + extraTime += 500; + } + } + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + 3000 + extraTime + ); + }, + syntax: { + js: [], + py: ['RgeeLite.effect_sound(%1)'], + }, + }, + robotis_rgee_lite_record: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_record', + }, + paramsKeyMap: { + ROOM: 0, + }, + class: 'robotis_rgee_lite_sound', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let roomNum = script.getField('ROOM', script); + + let data_instruction = INST_WRITE; + let data_address = 115; + let data_length = 1; + let data_value = 0; + + data_value = roomNum; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + 6000 + ); + }, + syntax: { + js: [], + py: ['RgeeLite.record(%1)'], + }, + }, + robotis_rgee_lite_playRecord: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_playRecord', + }, + paramsKeyMap: { + ROOM: 0, + }, + class: 'robotis_rgee_lite_sound', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let roomNum = script.getField('ROOM', script); + + let data_instruction = INST_WRITE; + let data_address = 116; + let data_length = 1; + let data_value = 0; + + data_value = roomNum; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + 6000 + ); + }, + syntax: { + js: [], + py: ['RgeeLite.playRecord(%1)'], + }, + }, + + + + + robotis_rgee_lite_rla_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '3329'], + [Lang.Blocks.robotis_car_anim02, '3330'], + [Lang.Blocks.robotis_car_anim03, '3331'], + [Lang.Blocks.robotis_car_anim04, '3332'], + [Lang.Blocks.robotis_car_anim05, '3333'], + + [Lang.Blocks.robotis_car_anim06, '3334'], + [Lang.Blocks.robotis_car_anim07, '3335'], + [Lang.Blocks.robotis_car_anim08, '3336'], + [Lang.Blocks.robotis_car_anim09, '3337'], + [Lang.Blocks.robotis_car_anim10, '3338'], + + [Lang.Blocks.robotis_car_anim11, '3339'], + [Lang.Blocks.robotis_car_anim12, '3340'], + [Lang.Blocks.robotis_car_anim13, '3341'], + [Lang.Blocks.robotis_car_anim14, '3342'], + [Lang.Blocks.robotis_car_anim15, '3343'], + + [Lang.Blocks.robotis_car_anim16, '3344'], + [Lang.Blocks.robotis_car_anim17, '3345'], + [Lang.Blocks.robotis_car_anim18, '3346'], + [Lang.Blocks.robotis_car_anim19, '3347'], + ], + value: '3329', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_rla_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['RgeeLite.rla_screen(%1)'] }, + }, + + robotis_rgee_lite_rla_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '30978'], + [Lang.Blocks.robotis_car_anim02, '30981'], + [Lang.Blocks.robotis_car_anim03, '30982'], + [Lang.Blocks.robotis_car_anim04, '30983'], + [Lang.Blocks.robotis_car_anim05, '30984'], + + [Lang.Blocks.robotis_car_anim06, '30985'], + [Lang.Blocks.robotis_car_anim07, '30986'], + [Lang.Blocks.robotis_car_anim08, '30987'], + [Lang.Blocks.robotis_car_anim09, '30988'], + [Lang.Blocks.robotis_car_anim10, '30989'], + + [Lang.Blocks.robotis_car_anim11, '30990'], + [Lang.Blocks.robotis_car_anim12, '30991'], + [Lang.Blocks.robotis_car_anim13, '30992'], + [Lang.Blocks.robotis_car_anim14, '30993'], + [Lang.Blocks.robotis_car_anim15, '30994'], + + [Lang.Blocks.robotis_car_anim16, '30995'], + [Lang.Blocks.robotis_car_anim17, '30996'], + [Lang.Blocks.robotis_car_anim18, '30997'], + [Lang.Blocks.robotis_car_anim19, '30998'], + ], + value: '30978', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_rla_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['RgeeLite.rla_animation_screen(%1)'] }, + }, + + robotis_rgee_lite_kkokdu_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '3585'], + [Lang.Blocks.robotis_car_anim02, '3586'], + [Lang.Blocks.robotis_car_anim03, '3587'], + [Lang.Blocks.robotis_car_anim04, '3588'], + [Lang.Blocks.robotis_car_anim05, '3589'], + + [Lang.Blocks.robotis_car_anim06, '3590'], + [Lang.Blocks.robotis_car_anim07, '3591'], + [Lang.Blocks.robotis_car_anim08, '3592'], + [Lang.Blocks.robotis_car_anim09, '3593'], + [Lang.Blocks.robotis_car_anim10, '3594'], + + [Lang.Blocks.robotis_car_anim11, '3595'], + [Lang.Blocks.robotis_car_anim12, '3596'], + [Lang.Blocks.robotis_car_anim13, '3597'], + [Lang.Blocks.robotis_car_anim14, '3598'], + [Lang.Blocks.robotis_car_anim15, '3599'], + + [Lang.Blocks.robotis_car_anim16, '3600'], + [Lang.Blocks.robotis_car_anim17, '3601'], + [Lang.Blocks.robotis_car_anim18, '3602'], + [Lang.Blocks.robotis_car_anim19, '3603'], + ], + value: '3585', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_kkokdu_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['RgeeLite.kkokdu_screen(%1)'] }, + }, + + robotis_rgee_lite_kkokdu_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '31234'], + [Lang.Blocks.robotis_car_anim02, '31237'], + [Lang.Blocks.robotis_car_anim03, '31238'], + [Lang.Blocks.robotis_car_anim04, '31239'], + [Lang.Blocks.robotis_car_anim05, '31240'], + + [Lang.Blocks.robotis_car_anim06, '31241'], + [Lang.Blocks.robotis_car_anim07, '31242'], + [Lang.Blocks.robotis_car_anim08, '31243'], + [Lang.Blocks.robotis_car_anim09, '31244'], + [Lang.Blocks.robotis_car_anim10, '31245'], + + [Lang.Blocks.robotis_car_anim11, '31246'], + [Lang.Blocks.robotis_car_anim12, '31247'], + [Lang.Blocks.robotis_car_anim13, '31248'], + [Lang.Blocks.robotis_car_anim14, '31249'], + [Lang.Blocks.robotis_car_anim15, '31250'], + + [Lang.Blocks.robotis_car_anim16, '31251'], + [Lang.Blocks.robotis_car_anim17, '31252'], + [Lang.Blocks.robotis_car_anim18, '31253'], + [Lang.Blocks.robotis_car_anim19, '31254'], + ], + value: '31234', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_kkokdu_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['RgeeLite.kkokdu_animation_screen(%1)'] }, + }, + robotis_rgee_lite_text_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_screen_text_font_small, '0'], + [Lang.Blocks.robotis_screen_text_font_big, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_red, '224'], + [Lang.Blocks.robotis_orange, '244'], + [Lang.Blocks.robotis_yellow, '252'], + [Lang.Blocks.robotis_green, '28'], + [Lang.Blocks.robotis_blue, '3'], + [Lang.Blocks.robotis_darkblue, '2'], + [Lang.Blocks.robotis_purple, '130'], + [Lang.Blocks.robotis_brown, '173'], + [Lang.Blocks.robotis_black, '0'], + [Lang.Blocks.robotis_white, '255'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + ' ', + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + null, + null, + ], + type: 'robotis_rgee_lite_text_screen', + }, + paramsKeyMap: { + TEXT: 0, + X: 1, + Y: 2, + FONT: 3, + COLOR: 4, + }, + class: 'robotis_rgee_lite_lcd', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let text = script.getStringValue('TEXT', script); + let x = script.getNumberValue('X', script); + let y = script.getNumberValue('Y', script); + let font = script.getNumberValue('FONT', script); + let color = script.getNumberValue('COLOR', script); + let data_buf = []; + let i = 0; + + let data_instruction = INST_WRITE; + let data_address = 900; + let data_length = 2; + + if (x < -160) { + x = -160; + } else if (x > 160) { + x = 160; + } + + if (y < -120) { + y = -120; + } else if (y > 120) { + y = 120; + } + + let encoder = new TextEncoder('utf-8'); + let byteArray = encoder.encode(text); + + data_buf.push(x % 256); + data_buf.push(Math.floor(x / 256)); + data_buf.push(y % 256); + data_buf.push(Math.floor(y / 256)); + data_buf.push(font); + data_buf.push(0); + data_buf.push(0); + data_buf.push(color); + data_buf.push(byteArray.length); + for (i = 0; i < byteArray.length; i++) { + data_buf.push(byteArray[i]); + } + + data_length = 9 + byteArray.length; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_buf], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { + js: [], + py: ['RgeeLite.text_screen(%1,%2,%3,%4,%5)'], + }, + }, + + + + robotis_rgee_lite_drive_simple: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_moveF, '1'], + [Lang.Blocks.robotis_moveB, '2'], + [Lang.Blocks.robotis_moveL, '3'], + [Lang.Blocks.robotis_moveR, '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [10, null, null], + type: 'robotis_rgee_lite_drive_simple', + }, + paramsKeyMap: { + SPEED: 0, + DIRECTION: 1, + }, + class: 'robotis_rgee_lite_move', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + const speed = script.getNumberValue('SPEED', script); + const direction = script.getField('DIRECTION', script); + + const data_instruction = INST_WRITE; + const data_address = 710; + const data_length = 2; + let data_value = 0; + + switch (direction) { + case '1': + data_value = speed * 256 + speed; + break; + case '2': + data_value = (256 - speed) * 256 + (256 - speed); + break; + case '3': + data_value = speed * 256 + (256 - speed); + break; + case '4': + data_value = (256 - speed) * 256 + speed; + break; + default: + data_value = 0; + break; + } + + const data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RgeeLite.go_simple(%1, %2)'], + }, + }, + + robotis_rgee_lite_drive_stop: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_drive_stop', + }, + paramsKeyMap: { + DIRECTION: 0, + }, + class: 'robotis_rgee_lite_move', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + + let data_instruction = INST_WRITE; + let data_address = 710; + let data_length = 2; + let data_value = 0; + + let data_sendqueue = [ + [data_instruction, 5200, 1, 0], + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RgeeLite.stop(%1, %2)'], + }, + }, + robotis_rgee_lite_motion: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_moveRG1, '50007'], + [Lang.Blocks.robotis_moveRG2, '50008'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_moveRG3, '50071'], + [Lang.Blocks.robotis_moveRG4, '50072'], + ], + value: '50007', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_motion', + }, + paramsKeyMap: { + MotionNumber: 0, + }, + class: 'robotis_rgee_lite_move', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + const data_instruction = INST_WRITE; + const data_address = 66; + const data_length = 2; + let data_value = script.getField('MotionNumber', script); + + const data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + data_value > 50070 ? 2000 : 1000 + ); + }, + syntax: { + js: [], + py: ['RgeeLite.run_motion(%1)'], + }, + }, + robotis_rgee_lite_follow_line: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1단계', '1'], + ['2단계', '2'], + ['3단계', '3'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rgee_lite_follow_line', + }, + paramsKeyMap: { + SPEED: 0, + }, + class: 'robotis_rgee_lite_move', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let speed_level = script.getNumberValue('SPEED', script); + + let data_instruction = INST_WRITE; + let data_address = 5200; + let data_length = 1; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, speed_level], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RgeeLite.follow_line(%1)'], + }, + }, + + robotis_rgee_lite_stop_follow_line: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rgee_lite_stop_follow_line', + }, + paramsKeyMap: { + }, + class: 'robotis_rgee_lite_move', + isNotFor: ['RobotisRgeeLite'], + func(sprite, script) { + // instruction / address / length / value / default length + + let data_instruction = INST_WRITE; + let data_address = 710; + let data_length = 2; + let data_value = 0; + + let data_sendqueue = [ + [data_instruction, 5200, 1, 0], + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRgeeLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RgeeLite.stop_follow_line()'], + }, + }, + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + }; + } + + requestLocalData() { + let packets = []; + while (this.robotisBuffer.length > 0) { + const data = this.robotisBuffer.shift(); + const instruction = data[0]; + const address = data[1]; + const length = data[2]; + const value = data[3]; + const dataBuffer = data[4]; + let id = 0; + let packet = null; + + switch (instruction) { + case INST_WRITE: + id = 200; + packet = this.writePacket(id, address, length, value); + break; + case INST_BYPASS_WRITE: + id = value; + packet = this.writePacket(id, address, length, dataBuffer); + break; + } + + if (packet !== null && Array.isArray(packet)) { + packets.push(...packet); + } + } + return packets; + } + + handleLocalData(data) { + let stuffLength = 0; + //console.log(`length: ${data.length}`); + for (let i = 0; i < data.length; i++) { + //this.receiveBuffer.push(data[i]); + const dataIn = data[i]; + + switch (this.packetReceiveState) { + case PACKET_STATE_IDLE: + if (this.headerCount >= 2) { + rxPacket.header[2] = dataIn; + + if ( + rxPacket.header[0] == 0xff && + rxPacket.header[1] == 0xff && + rxPacket.header[2] == 0xfd + ) { + this.headerCount = 0; + this.packetReceiveState = PACKET_STATE_RESERVED; + } else { + rxPacket.header[0] = rxPacket.header[1]; + rxPacket.header[1] = rxPacket.header[2]; + rxPacket.header[2] = 0; + } + } else { + rxPacket.header[this.headerCount] = dataIn; + this.headerCount++; + } + break; + + case PACKET_STATE_RESERVED: + if (dataIn == 0xfd) { + this.packetReceiveState = PACKET_STATE_IDLE; + } else { + rxPacket.reserved = dataIn; + this.packetReceiveState = PACKET_STATE_ID; + } + break; + + case PACKET_STATE_ID: + rxPacket.id = dataIn; + this.packetReceiveState = PACKET_STATE_LENGTH_L; + break; + + case PACKET_STATE_LENGTH_L: + rxPacket.packetLength = dataIn; + this.packetReceiveState = PACKET_STATE_LENGTH_H; + break; + + case PACKET_STATE_LENGTH_H: + rxPacket.packetLength |= dataIn << 8; + if (rxPacket.packetLength < 1000) { + this.packetReceiveState = PACKET_STATE_DATA; + } else { + this.packetReceiveState = PACKET_STATE_IDLE; + } + rxPacket.index = 0; + break; + + case PACKET_STATE_DATA: + rxPacket.data[rxPacket.index] = dataIn; + rxPacket.index++; + + if (rxPacket.index >= rxPacket.packetLength - 2) { + this.packetReceiveState = PACKET_STATE_CRC_L; + } + break; + + case PACKET_STATE_CRC_L: + rxPacket.crcReceived = dataIn; + this.packetReceiveState = PACKET_STATE_CRC_H; + break; + + case PACKET_STATE_CRC_H: + rxPacket.crcReceived |= dataIn << 8; + + stuffLength = this.removeStuffing(rxPacket.data, rxPacket.packetLength); + rxPacket.packetLength -= stuffLength; + + rxPacket.cmd = rxPacket.data[0]; + rxPacket.error = rxPacket.data[1]; + + if (rxPacket.cmd == INST_STATUS) { + //console.log(`rx length: ${rxPacket.packetLength}`); + if (rxPacket.packetLength >= 147) { + let tempValue = 0; + for (let i = 0; i < addrMap.length; i++) { + switch (addrMap[i][1]) { + case 1: + this.dataBuffer[addrMap[i][2]] = + rxPacket.data[2 + addrMap[i][0]]; + break; + + case 2: + tempValue = + rxPacket.data[2 + addrMap[i][0]] + + (rxPacket.data[2 + addrMap[i][0] + 1] << 8); + if (tempValue >= 32768) { + tempValue = tempValue - 65536; + } + this.dataBuffer[addrMap[i][2]] = tempValue; + break; + + case 4: + this.dataBuffer[addrMap[i][2]] = + rxPacket.data[2 + addrMap[i][0]] + + (rxPacket.data[2 + addrMap[i][0] + 1] << 8) + + (rxPacket.data[2 + addrMap[i][0] + 2] << 16) + + (rxPacket.data[2 + addrMap[i][0] + 3] << 24); + break; + } + } + + const dxlPositionStartAddr = + addrMap[addrMap.length - 1][0] + addrMap[addrMap.length - 1][1]; + + // DXL Position + for (let i = 0; i < 20; i++) { + const currentId = + rxPacket.data[2 + dxlPositionStartAddr + 3 * i]; + const currentPos = + rxPacket.data[2 + dxlPositionStartAddr + 3 * i + 1] + + (rxPacket.data[2 + dxlPositionStartAddr + 3 * i + 2] << 8); + if (currentId != 0xff && currentPos != 0xffff) { + this.dxlPositions[currentId] = currentPos; + } + } + + const lineCategoryStartAddr = dxlPositionStartAddr + 3 * 20; + // line category + this.dataBuffer[5201] = rxPacket.data[2 + lineCategoryStartAddr]; + + const sensorStartAddr = lineCategoryStartAddr + 1; + + // 온습도+조도+동작감지센서값 + this.pirPir[0] = rxPacket.data[2 + sensorStartAddr]; + this.pirTemperature[0] = rxPacket.data[2 + sensorStartAddr + 1]; + this.pirHumidity[0] = rxPacket.data[2 + sensorStartAddr + 2]; + this.pirBrightness[0] = rxPacket.data[2 + sensorStartAddr + 3]; + + // 거리+버튼+조도센서값 + this.distanceDistance[0] = + rxPacket.data[2 + sensorStartAddr + 4] + + (rxPacket.data[2 + sensorStartAddr + 5] << 8); + this.distanceButton[0] = rxPacket.data[2 + sensorStartAddr + 6]; + this.distanceBrightness[0] = rxPacket.data[2 + sensorStartAddr + 7]; + + for (let i = 0; i < addrMap2.length; i++) { + switch (addrMap2[i][1]) { + case 1: + this.dataBuffer[addrMap2[i][2]] = + rxPacket.data[2 + addrMap2[i][0]]; + break; + + case 2: + tempValue = + rxPacket.data[2 + addrMap2[i][0]] + + (rxPacket.data[2 + addrMap2[i][0] + 1] << 8); + if (tempValue >= 32768) { + tempValue = tempValue - 65536; + } + this.dataBuffer[addrMap2[i][2]] = tempValue; + break; + + case 4: + this.dataBuffer[addrMap2[i][2]] = + rxPacket.data[2 + addrMap2[i][0]] + + (rxPacket.data[2 + addrMap2[i][0] + 1] << 8) + + (rxPacket.data[2 + addrMap2[i][0] + 2] << 16) + + (rxPacket.data[2 + addrMap2[i][0] + 3] << 24); + break; + } + } + } + } + + this.packetReceiveState = PACKET_STATE_IDLE; + break; + + default: + // code block + } + } + } + + requestInitialData() { + this.robotisBuffer = []; + this.robotisBuffer.push([INST_WRITE, 21, 2, 20]); + this.robotisBuffer.push([INST_WRITE, 19, 1, 1]); // bypass 모드 켜기 + this.robotisBuffer.push([INST_WRITE, 20, 1, 0]); // bypass port를 BLE로 설정 + this.robotisBuffer.push([INST_WRITE, 23, 1, 1]); // auto report 기능 켜기 + this.robotisBuffer.push([INST_WRITE, 4250, 1, 1]); // ai_camera 텍스트 지우기 + this.robotisBuffer.push([INST_WRITE, 722, 1, 0]); // dxl 토크 끄기 + //this.robotisBuffer.push([INST_WRITE, 63, 1, 1]); // 부저음 시간 설정 + //this.robotisBuffer.push([INST_WRITE, 60, 1, 70]); // 부저음 발생 + this.robotisBuffer.push([INST_WRITE, 113, 2, 1040]); // "띵" 효과음 발생 + /* + //const ping = [0xff, 0xff, 0xfd, 0x00, 0xc8, 0x03, 0x00, 0x01, 0x3b, 0xfa]; + // run entry mode + const packet = [ + 0xff, 0xff, 0xfd, 0x00, 0xc8, 0x07, 0x00, 0x03, 0x15, 0x00, 0x14, 0x00, 0xc1, 0xb3, + ]; + return packet; + */ + } + + async initialHandshake() { + const status = true; + let sendBuffer = null; + this.requestInitialData(); + while (this.robotisBuffer.length) { + const data = this.robotisBuffer.shift(); + const instruction = data[0]; + const address = data[1]; + const length = data[2]; + const value = data[3]; + const dataBuffer = data[4]; + let id = 0; + + switch (instruction) { + case INST_WRITE: + id = 200; + sendBuffer = this.writePacket(id, address, length, value); + break; + case INST_BYPASS_WRITE: + id = value; + sendBuffer = this.writePacket(id, address, length, dataBuffer); + break; + } + Entry.hwLite.serial.sendAsciiAsBuffer(sendBuffer); + if (instruction == INST_WRITE && address == 2100 && length == 1 && value == 1) { + this.robotisBuffer = []; + } + } + return status; + } + })(); +})(); + +module.exports = Entry.RobotisRgeeLite; diff --git a/src/playground/blocks/hardwareLite/metadata_robotis_rgee_lite.json b/src/playground/blocks/hardwareLite/metadata_robotis_rgee_lite.json new file mode 100644 index 0000000000..9b8675cad7 --- /dev/null +++ b/src/playground/blocks/hardwareLite/metadata_robotis_rgee_lite.json @@ -0,0 +1,9 @@ +{ + "name": "RobotisRgeeLite", + "version": "1.0.0", + "type": "hardware", + "title": "로보티즈 알쥐", + "description": "로보티즈", + "imageName": "robotis_rgee_lite", + "moduleId": "070501" +} From 9c2ef6a0d405a85b593734c59f3800e219bc881a Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 10 Jun 2025 15:50:28 +0900 Subject: [PATCH 09/10] =?UTF-8?q?=EB=A1=9C=EB=B3=B4=ED=8B=B0=EC=A6=88=20?= =?UTF-8?q?=EC=95=8C=EB=9D=BC=20=EB=B8=8C=EB=9D=BC=EC=9A=B0=EC=A0=80?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/hw_lite/robotis_rla_lite.png | Bin 0 -> 216272 bytes .../hardwareLite/block_robotis_rla_lite.js | 3962 +++++++++++++++++ .../metadata_robotis_rla_lite.json | 9 + 3 files changed, 3971 insertions(+) create mode 100644 images/hw_lite/robotis_rla_lite.png create mode 100644 src/playground/blocks/hardwareLite/block_robotis_rla_lite.js create mode 100644 src/playground/blocks/hardwareLite/metadata_robotis_rla_lite.json diff --git a/images/hw_lite/robotis_rla_lite.png b/images/hw_lite/robotis_rla_lite.png new file mode 100644 index 0000000000000000000000000000000000000000..d03451d38d900433576191e7089db6c87c1aeb71 GIT binary patch literal 216272 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 -rsr!TzuPly^!fS0cc(S#e!O>Q(4tadsItKckq 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

tU+$wD~w|B!rk}37Qc+b|x{kZ+ilMC>*W~%U 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�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 HN@xNA96P$g literal 0 HcmV?d00001 diff --git a/src/playground/blocks/hardwareLite/block_robotis_rla_lite.js b/src/playground/blocks/hardwareLite/block_robotis_rla_lite.js new file mode 100644 index 0000000000..8b7bc41f0b --- /dev/null +++ b/src/playground/blocks/hardwareLite/block_robotis_rla_lite.js @@ -0,0 +1,3962 @@ +'use strict'; + +const INST_NONE = 0; +const INST_READ = 2; +const INST_WRITE = 3; +const INST_DXL_SYNCWRITE = 4; +const INST_DXL_REGWRITE = 5; +const INST_DXL_ACTION = 6; +const INST_BYPASS_READ = 0xa2; +const INST_BYPASS_WRITE = 0xa3; + +const INST_STATUS = 0x55; + +const PACKET_STATE_IDLE = 0; +const PACKET_STATE_RESERVED = 1; +const PACKET_STATE_ID = 2; +const PACKET_STATE_LENGTH_L = 3; +const PACKET_STATE_LENGTH_H = 4; +const PACKET_STATE_DATA = 5; +const PACKET_STATE_CRC_L = 6; +const PACKET_STATE_CRC_H = 7; + +const DEFAULT_DELAY = 50; + +const rxPacket = { + header: [0, 0, 0], + reserved: 0, + id: 0, + cmd: 0, + error: 0, + type: 0, + index: 0, + packetLength: 0, + paramLength: 0, + crc: 0, + crcReceived: 0, + checksum: 0, + checksumReceived: 0, + data: [], +}; + +const addrMap = [ + [0, 4, 302], + [4, 1, 42], + [5, 1, 44], + [6, 1, 45], + [7, 1, 47], + [8, 1, 50], + [9, 1, 51], + [10, 1, 52], + [11, 1, 68], + [12, 2, 70], + [14, 2, 72], + [16, 2, 74], + [18, 2, 76], + [20, 2, 78], + [22, 2, 80], + [24, 2, 82], + [26, 2, 84], + [28, 1, 86], + [29, 1, 87], + [30, 2, 88], + [32, 2, 90], + [34, 1, 112], + [35, 1, 118], + [36, 1, 119], + [37, 1, 122], + [38, 1, 123], + [39, 1, 124], + [40, 1, 125], + [41, 1, 160], + [42, 1, 220], + [43, 2, 360], + [45, 2, 362], + [47, 2, 364], + [49, 2, 366], + [51, 2, 368], + [53, 2, 370], + [55, 1, 372], + [56, 1, 373], + [57, 1, 374], + [58, 1, 375], + [59, 1, 376], + [60, 1, 377], + [61, 1, 378], + [62, 1, 379], + [63, 1, 380], + [64, 1, 381], + [65, 1, 382], + [66, 1, 383], + [67, 1, 500], + [68, 1, 501], + [69, 8, 502], + [77, 1, 700], + [78, 1, 810], + [79, 1, 2134], + [80, 1, 5015], + [81, 1, 5030], + [82, 1, 5031], + [83, 1, 5040], +]; + +const addrMap2 = [ + [153, 1, 4000], + [154, 2, 4003], + [156, 1, 4005], + [157, 1, 4006], + [158, 2, 4009], + [160, 2, 4011], + [162, 2, 4013], + [164, 2, 4015], + [166, 2, 4017], + [168, 2, 4019], + [170, 2, 4021], + [172, 2, 4023], + [174, 2, 4025], + [176, 2, 4027], + [178, 1, 4031], + [179, 1, 4032], + [180, 1, 4033], + [181, 2, 4036], + [183, 2, 4038], + [185, 2, 4040], + [187, 2, 4042], + [189, 2, 4044], + [191, 2, 4046], + [193, 2, 4048], + [195, 2, 4050], +]; + +const crcTable = [ + 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, + 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, + 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, + 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, + 0x0088, 0x808d, 0x8087, 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, + 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0, 0x81e5, 0x81ef, 0x01ea, + 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, + 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179, + 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, + 0x0318, 0x831d, 0x8317, 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353, 0x0356, 0x035c, 0x8359, + 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, + 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9, + 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, + 0x02a8, 0x82ad, 0x82a7, 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, + 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243, 0x0246, 0x024c, 0x8249, + 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219, + 0x0208, 0x820d, 0x8207, 0x0202, +]; + +const rb100_last_valid_value = []; +let bg_color = 0; +let beat_per_minute = 75; +let camera_id_for_use = 0; + +(function () { + Entry.RobotisRlaLite = new (class RobotisRlaLite { + constructor() { + this.id = '070901'; + this.url = 'http://www.robotis.com'; + this.imageName = 'robotis_rla_lite.png'; + this.name = 'RobotisRlaLite'; + this.blockMenuBlocks = [ + // 값 블록 + 'robotis_rla_lite_cm_ir_value', + 'robotis_rla_lite_cm_ir_compare', + 'robotis_rla_lite_detectFrontObj', + 'robotis_rla_lite_cm_btn_value', + 'robotis_rla_lite_cm_joystick_value', + 'robotis_rla_lite_mic', + 'robotis_rla_lite_detectSound_compare', + 'robotis_rla_lite_imu', + 'robotis_rla_lite_roll_pitch', + + // 음계 + 'robotis_rla_lite_buzzer_index', + + // LCD 제어 + 'robotis_rla_lite_rgee_screen', + 'robotis_rla_lite_rgee_anim_screen', + 'robotis_rla_lite_icon', + 'robotis_rla_lite_LCDBright', + 'robotis_rla_lite_LCDColor', + + // LED 제어 + 'robotis_rla_lite_led_brightness', + 'robotis_rla_lite_led_pattern', + + + // 소리 + 'robotis_rla_lite_Hello', + 'robotis_rla_lite_effectSound', + 'robotis_rla_lite_record', + 'robotis_rla_lite_playRecord', + + // 다른 로봇 LCD 화면 제어 + 'robotis_rla_lite_rla_screen', + 'robotis_rla_lite_rla_anim_screen', + 'robotis_rla_lite_kkokdu_screen', + 'robotis_rla_lite_kkokdu_anim_screen', + + // 주행 제어 + 'robotis_rla_lite_drive_simple', + 'robotis_rla_lite_drive_stop', + 'robotis_rla_lite_wheel_rotate', + 'robotis_rla_lite_wheel_stop', + 'robotis_rla_lite_go_distance', + 'robotis_rla_lite_turn_angle', + 'robotis_rla_lite_motion', + + // 텍스트 출력 + 'robotis_rla_lite_text_screen', + + // 라인 따라가기 + 'robotis_rla_lite_follow_line', + 'robotis_rla_lite_stop_follow_line', + ]; + this.portData = { + baudRate: 57600, + dataBits: 8, + parity: 'none', + stopBits: 1, + connectionType: 'bytestream', + bufferSize: 128, + constantServing: true, + }; + this.duration = 15; + this.setZero(); + + this.timeouts = []; + + this.robotisBuffer = []; // buffer to transmit to H/W + this.receiveBuffer = []; // buffer to receive from H/W + this.dataBuffer = []; // saved control table value buffer + + this.packetReceiveState = 0; + this.headerCount = 0; + + this.dxlPositions = []; + + this.pirPir = []; + this.pirTemperature = []; + this.pirHumidity = []; + this.pirBrightness = []; + this.distanceDistance = []; + this.distanceButton = []; + this.distanceBrightness = []; + } + + setZero() { + this.timeouts = []; + this.__removeAllTimeouts(); + this.robotisBuffer = []; + this.robotisBuffer.push([INST_WRITE, 21, 2, 7]); // App Coding 모드 + this.robotisBuffer.push([INST_WRITE, 40, 2, 0]); // LED 끄기 + this.robotisBuffer.push([INST_WRITE, 66, 2, 0]); // 모션 종료 + this.robotisBuffer.push([INST_WRITE, 710, 2, 0]); // 바퀴 정지 + this.robotisBuffer.push([INST_WRITE, 21, 2, 20]); // App Coding 모드 + this.robotisBuffer.push([INST_WRITE, 19, 1, 1]); // bypass 모드 켜기 + camera_id_for_use = 0; + if (Entry.hwLite && Entry.hwLite.serial) { + Entry.hwLite.serial.update(); + } + } + + __removeTimeout(id) { + clearTimeout(id); + const idx = this.timeouts.indexOf(id); + if (idx >= 0) { + this.timeouts.splice(idx, 1); + } + } + + __removeAllTimeouts() { + const timeouts = this.timeouts; + for (const i in timeouts) { + clearTimeout(timeouts[i]); + } + this.timeouts = []; + } + + getMonitorPort() { + return { ...this.sensory, ...this.motoring, ...this.lineTracer }; + } + + writePacket(id, address, length, value) { + if (length > 256) { + console.log(`######### invalid length: ${length}`); + return null; + } + console.log('######### writePacket'); + const packet = []; + let i = 0; + packet.push(0xff); + packet.push(0xff); + packet.push(0xfd); + packet.push(0x00); + packet.push(id); + packet.push(length + 5); + packet.push(0x00); + packet.push(INST_WRITE); + packet.push(this.getLowByte(address)); + packet.push(this.getHighByte(address)); + switch (length) { + case 1: + packet.push(this.getLowByte(value)); + break; + case 2: + packet.push(this.getLowByte(value)); + packet.push(this.getHighByte(value)); + break; + case 4: + packet.push(this.getLowByte(this.getLowWord(value))); + packet.push(this.getHighByte(this.getLowWord(value))); + packet.push(this.getLowByte(this.getHighWord(value))); + packet.push(this.getHighByte(this.getHighWord(value))); + break; + default: + for (i = 0; i < length; i++) { + if (typeof value[i] == 'number') { + packet.push(value[i]); + } else if (typeof value[i] == 'string') { + packet.push(value[i].charCodeAt(0)); + } + } + break; + } + const crc = this.updateCRC(0, packet, packet.length); + packet.push(this.getLowByte(crc)); + packet.push(this.getHighByte(crc)); + return packet; + } + + makeWord(a, b) { + return (a & 0xff) | ((b & 0xff) << 8); + } + + getLowByte(a) { + return a & 0xff; + } + + getHighByte(a) { + return (a >> 8) & 0xff; + } + + getLowWord(a) { + return a & 0xffff; + } + + getHighWord(a) { + return (a >> 16) & 0xffff; + } + + updateCRC(crcAccum, dataBlkPtr, dataBlkSize) { + let i = 0; + let j = 0; + let crc = crcAccum; + + for (j = 0; j < dataBlkSize; j++) { + i = ((crc >> 8) ^ dataBlkPtr[j]) & 0xff; + crc = (crc << 8) ^ crcTable[i]; + } + + return crc; + } + + removeStuffing(buffer, length) { + let i = 0; + let stuffLength = 0; + let index = 0; + + for (i = 0; i < length; i++) { + if (i >= 2) { + if (buffer[i - 2] == 0xff && buffer[i - 1] == 0xff && buffer[i] == 0xfd) { + i++; + stuffLength++; + } + } + buffer[index++] = buffer[i]; + } + + return stuffLength; + } + + postCallReturn(script, data, ms) { + /* + if (data == null) { + Entry.engine.isContinue = false; + return script.callReturn(); + } else if (data.length == 0) { + Entry.engine.isContinue = false; + return script.callReturn(); + } + */ + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + for (let i = 0; i < data.length; i++) { + this.robotisBuffer.push(data[i]); + } + //delay ms + setTimeout(() => { + script.timeFlag = 0; + }, ms); + return script; + } else if (script.timeFlag) { + return script; + } else { + delete script.isStart; + delete script.timeFlag; + Entry.engine.isContinue = false; + return script.callReturn(); + } + } + + setLanguage() { + return { + ko: { + template: { + // 값 블록 + robotis_rla_lite_cm_ir_value: '%1 번 IR 센서 값', + robotis_rla_lite_cm_ir_compare: '%1 번 IR 센서 값이 %2 %3이면', + robotis_rla_lite_detectFrontObj: '앞에 물체가 있으면', + robotis_rla_lite_cm_btn_value: '%1 버튼이 %2 이면', + robotis_rla_lite_cm_joystick_value: + '조이스틱 위치가 %1 이면', + robotis_rla_lite_mic: '마이크 음량(dB)', + robotis_rla_lite_detectSound_compare: '소리가 %1에서 나면', + robotis_rla_lite_imu: '%1축의 %2 값', + robotis_rla_lite_roll_pitch: '제어기 각도 %1 값', + + // 음계 + robotis_rla_lite_buzzer_index: '제어기 음계값 %1 을(를) %2 옥타브로 %3 초 동안 %4 %5', + + // LCD 제어 + robotis_rla_lite_rla_screen: '제어기 화면 배경을 알라 %1 (으)로 선택 %2', + robotis_rla_lite_rla_anim_screen: + '제어기 화면 애니메이션을 알라 %1 (으)로 선택 %2', + robotis_rla_lite_icon: + "제어기 화면에 %1 출력하기 %5", + robotis_rla_lite_LCDBright: '제어기 화면 밝기를 %1 (으)로 정하기 %2', + robotis_rla_lite_LCDColor: '제어기 화면 색상을 %1 (으)로 정하기 %2', + + // LED 제어 + robotis_rla_lite_led_brightness: '제어기 %1 LED 밝기를 %2(으)로 정하기 %3', + robotis_rla_lite_led_pattern: '제어기 %1 LED %2 %3', + + // 소리 + robotis_rla_lite_Hello: '%1 말하기 %2', + robotis_rla_lite_effectSound: '효과음 %1 재생하기 %2', + robotis_rla_lite_record: '%1 번 방에 녹음하기 %2', + robotis_rla_lite_playRecord: '%1 번 방 소리 재생하기 %2', + + // 다른 로봇 LCD 제어 + robotis_rla_lite_rgee_screen: '제어기 화면 배경을 알쥐 %1 (으)로 선택 %2', + robotis_rla_lite_rgee_anim_screen: + '제어기 화면 애니메이션을 알쥐 %1 (으)로 선택 %2', + robotis_rla_lite_kkokdu_screen: '제어기 화면 배경을 꼭두 %1 (으)로 선택 %2', + robotis_rla_lite_kkokdu_anim_screen: + '제어기 화면 애니메이션을 꼭두 %1 (으)로 선택 %2', + robotis_rla_lite_text_screen: + '제어기 화면에 %1을(를) (%2, %3)위치에 %4 로 %5(으)로 출력하기 %6', + + + // 주행 제어 + robotis_rla_lite_drive_simple: '알라 %1 속도로 %2 하기 %3', + robotis_rla_lite_drive_stop: '알라 정지하기 %1', + robotis_rla_lite_wheel_rotate: + '%1 모터 %2의 속도로 %3 회전하기 %4', + robotis_rla_lite_wheel_stop: + '%1 모터 정지하기 %2', + robotis_rla_lite_go_distance: '알라 로봇 %1 cm %2 하기 %3', + robotis_rla_lite_turn_angle: '알라 로봇 제자리 %1 도 회전하기%3', + robotis_rla_lite_motion: '알라 로봇 펜 %1 %2', + + // 라인 따라가기기 + robotis_rla_lite_follow_line: '%1 속도로 라인 따라가기 %2', + robotis_rla_lite_stop_follow_line: '라인 따라가기 종료 %1', + }, + Helper: { + // 값 블록 + robotis_rla_lite_cm_ir_value: + '지정한 번호의 IR 센서 값(범위: 0 ~ 400)', + robotis_rla_lite_cm_ir_compare: + "지정한 번호의 IR 센서 값과 지정한 값의 비교식이 맞으면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rla_lite_detectFrontObj: + "지정한 센서 앞에 물체가 감지되면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rla_lite_cm_btn_value: + "지정한 버튼이 눌렸다가 해제되면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rla_lite_cm_joystick_value: + "조이스틱 위치가 지정한 상태이면 '참', 아니면 '거짓'으로 판단합니다..", + robotis_rla_lite_mic: + '마이크로 감지된 소리의 세기를 데시벨(dB)로 표시합니다.', + robotis_rla_lite_detectSound_compare: + "소리가 나는 방향이 지정한 방향과 동일하면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_rla_lite_imu: + '지정한 축의 지정한 가속도센서/자이로센서의 값\n범위: -100 ~ 100', + robotis_rla_lite_roll_pitch: + 'roll/pitch 값\nroll: -180° ~ 180°, pitch: -90° ~ 90°', + + // 소리 + robotis_rla_lite_buzzer_index: '지정한 음계, 옥타브, 시간만큼 연주하기', + + // LCD 제어 + robotis_rla_lite_rgee_screen: '제어기 화면배경을 알쥐의 지정한 표정으로 설정', + robotis_rla_lite_rgee_anim_screen: + '제어기 화면 애니메이션을 알쥐의 지정한 표정으로 설정', + robotis_rla_lite_icon: + '화면 중앙에 지정한 아이콘을 표시', + robotis_rla_lite_LCDBright: '화면 밝기를 설정\n밝기범위: 1% ~ 100%', + robotis_rla_lite_LCDColor: '화면 색상을 설정', + + // LED 제어 + robotis_rla_lite_led_brightness: '제어기의 지정한 LED의 밝기를 설정정', + robotis_rla_lite_led_pattern: '제어기의 LED의 깜박임 패턴 설정', + + // 소리 + robotis_rla_lite_Hello: '지정한 문장을 말하기', + robotis_rla_lite_effectSound: '지정한 효과음 재생하기', + robotis_rla_lite_record: '제어기의 지정한 번호에 녹음하기', + robotis_rla_lite_playRecord: '제어기의 지정한 번호의 녹음음성 재생하기기', + + // 다른 로봇 LCD 제어 + robotis_rla_lite_rla_screen: '제어기 화면배경을 알라의 지정한 표정으로 설정', + robotis_rla_lite_rla_anim_screen: + '제어기 화면 애니메이션을 알라의 지정한 표정으로 설정', + robotis_rla_lite_kkokdu_screen: '제어기 화면배경을 꼭두의 지정한 표정으로 설정', + robotis_rla_lite_kkokdu_anim_screen: + '제어기 화면 애니메이션을 꼭두두의 지정한 표정으로 설정', + robotis_rla_lite_text_screen: + '화면에 지정한 문구를 표시할 위치와 폰트크기, 색상을 설정\nX좌표: -160 ~ 160\nY좌표: -120 ~ 120', + + // 주행 제어 + robotis_rla_lite_drive_simple: '알라를 지정한 속도와 방향으로 주행', + robotis_rla_lite_drive_stop: '알라 정지하기', + robotis_rla_lite_wheel_rotate: '알라의 지정한 바퀴를 지정한 속도와 방향으로 회전', + robotis_rla_lite_wheel_stop: '알라의 지정한 바퀴를 정지', + robotis_rla_lite_go_distance: '알라 지정한 거리만큼 주행', + robotis_rla_lite_turn_angle: '알라 지정한 각도만큼 제자리 회전', + robotis_rla_lite_motion: '알라 지정한 동작을 하기', + + // 라인 따라가기 + robotis_rla_lite_follow_line: '지정한 속도로 라인 따라가기', + robotis_rla_lite_stop_follow_line: '라인 따라가기 종료', + + }, + Blocks: { + robotis_white: "흰색", + robotis_gray: "회색", + robotis_darkgray: "진회색", + robotis_black: "검정", + robotis_purple: "보라", + robotis_pink: "분홍색", + robotis_red: "빨강", + robotis_orange: "주황", + robotis_brown: "갈색", + robotis_yellow: "노랑", + robotis_green: "초록", + robotis_blue: "파랑", + robotis_lightblue: "연파랑", + robotis_darkblue: "남색", + robotis_left: "왼쪽", + robotis_center: "중앙", + robotis_right: "오른쪽", + robotis_both: "양쪽", + robotis_korean1: "안녕하세요", + robotis_korean2: "반가워요", + robotis_korean3: "알겠어요", + robotis_korean4: "아니에요", + robotis_korean5: "모르겠어요", + robotis_korean6: "좋아요", + robotis_korean7: "싫어요", + robotis_korean8: "이름을말하세요", + robotis_korean9: "무엇을도와줄까?", + robotis_korean10: "잘했어", + robotis_korean11: "괜찮아", + robotis_korean12: "다시해보자", + robotis_korean13: "고마워", + robotis_korean14: "다시말해줄래?", + robotis_korean15: "최고야!", + robotis_korean16: "신나요", + robotis_korean17: "즐거워요", + robotis_korean18: "미안해요", + robotis_korean19: "화나요", + robotis_korean20: "부끄러워요", + robotis_korean21: "무서워요", + robotis_korean22: "속상해요", + robotis_korean23: "사랑해요", + robotis_korean24: "예뻐요", + robotis_korean25: "신기해요", + robotis_korean26: "초조해요", + robotis_korean27: "앞으로가자", + robotis_korean28: "뒤로가자", + robotis_korean29: "일어나자", + robotis_korean30: "넘어졌네?", + robotis_korean31: "오예", + robotis_korean32: "아싸", + robotis_korean33: "어머", + robotis_korean34: "이런", + robotis_korean35: "오호", + robotis_korean36: "하하하", + robotis_korean37: "호호호", + robotis_korean38: "졸려", + robotis_korean39: "자장가를들려줘", + robotis_korean40: "안녕", + robotis_korean41: "배고프다", + robotis_korean42: "도토리땡긴다", + robotis_korean43: "아.씻고싶어", + robotis_korean44: "비누목욕시간이야", + robotis_korean45: "심심한데", + robotis_korean46: "간식먹을까", + robotis_korean47: "아파요", + robotis_korean48: "약은없나요?", + robotis_korean49: "어디로가야하지?", + robotis_korean50: "와아도착이다", + robotis_korean51: "왼쪽으로가자", + robotis_korean52: "오른쪽으로가자", + robotis_korean53: "깜짝이야", + robotis_korean54: "찾았다", + robotis_korean55: "여긴없네", + robotis_korean56: "혹시나불렀어?", + robotis_korean57: "내려주세요", + robotis_korean58: "앗", + robotis_korean59: "힝", + robotis_korean60: "이익", + robotis_dog: "개", + robotis_frog: "개구리", + robotis_cat: "고양이", + robotis_chicken: "닭", + robotis_tiger: "호랑이", + robotis_mouse: "쥐", + robotis_ambul: "앰뷸런스", + robotis_Horn: "경적(빵빵)", + robotis_siren: "사이렌(경찰차)", + robotis_whistle: "호루라기", + robotis_gun: "총소리", + robotis_clap: "박수소리", + robotis_melody1: "멜로디1", + robotis_melody2: "멜로디2", + robotis_melody3: "멜로디3", + robotis_melody4: "멜로디4", + robotis_forward: "앞으로", + robotis_backward: "뒤로", + robotis_acceleration: "가속도", + robotis_gyro: "자이로", + robotis_run: "실행", + robotis_cancel: "취소", + robotis_push: "눌림", + robotis_notPush: "안눌림", + robotis_play: "연주", + robotis_rest: "쉼표", + robotis_face01: "와하하", + robotis_face02: "싱글벙글", + robotis_face03: "큭큭큭", + robotis_face04: "냠냠", + robotis_face05: "겁먹음", + robotis_face06: "답답", + robotis_face07: "갸우뚱", + robotis_face08: "어벙벙", + robotis_face09: "고함", + robotis_face10: "화남", + robotis_face11: "킁킁(왼쪽)", + robotis_face12: "킁킁(오른쪽)", + robotis_face13: "킁킁(아래)", + robotis_face14: "안심", + robotis_face15: "기절", + robotis_face16: "헤롱헤롱", + robotis_face17: "하품", + robotis_face18: "졸림", + robotis_face19: "잠듦", + robotis_face20: "마음앓이", + robotis_face21: "폭풍눈물", + robotis_face22: "목욕", + robotis_face23: "햐트뿅뿅", + + robotis_car_anim01: "기본 표정", + robotis_car_anim02: "감동", + robotis_car_anim03: "미소", + robotis_car_anim04: "웃음", + robotis_car_anim05: "기쁨", + robotis_car_anim06: "행복", + robotis_car_anim07: "자신감", + robotis_car_anim08: "화남", + robotis_car_anim09: "우울", + robotis_car_anim10: "슬픔", + robotis_car_anim11: "고통", + robotis_car_anim12: "기절", + robotis_car_anim13: "공포", + robotis_car_anim14: "하품", + robotis_car_anim15: "졸림", + robotis_car_anim16: "오른쪽보기", + robotis_car_anim17: "왼쪽보기", + robotis_car_anim18: "앞쪽보기", + robotis_car_anim19: "깜짝놀람", + + robotis_flashing1: "점멸1", + robotis_flashing2: "점멸2", + robotis_flashing3: "점멸3", + robotis_flashing4: "점멸4", + robotis_flashing5: "점멸5", + robotis_flashing6: "점멸6", + robotis_flashing7: "점멸7", + robotis_flashing8: "점멸8", + robotis_flashing9: "점멸9", + robotis_moveF: "전진", + robotis_moveB: "후진", + robotis_moveL: "좌회전", + robotis_moveR: "우회전", + robotis_moveU: 'U턴', + robotis_moveL_in_place: '제자리 좌회전', + robotis_moveR_in_place: '제자리 우회전', + robotis_moveU_in_place: '제자리 U턴', + robotis_moveRG1: "일어서기", + robotis_moveRG2: "앉기", + robotis_moveRG3: "발버둥", + robotis_moveRG4: "발들기", + robotis_stMotion1: "기본자세", + robotis_stMotion2: "전진", + robotis_stMotion3: "우전진", + robotis_stMotion4: "좌전진", + robotis_stMotion5: "후진", + robotis_stMotion6: "오른쪽으로", + robotis_stMotion7: "왼쪽으로", + robotis_stMotion8: "우회전", + robotis_stMotion9: "좌회전", + robotis_spMotion1: "오른손 들기", + robotis_spMotion2: "오른손 내리기", + robotis_spMotion3: "왼손 들기", + robotis_spMotion4: "왼손 내리기", + robotis_spMotion5: "양손 들기", + robotis_spMotion6: "양손 내리기", + robotis_spMotion7: "뒤로 넘어지기", + robotis_spMotion8: "앞으로 넘어지기", + robotis_spMotion9: "앞으로 일어서기", + robotis_spMotion10: "뒤로 일어서기", + robotis_spMotion11: "방어", + robotis_spMotion12: "공격1", + robotis_spMotion13: "공격2", + robotis_spMotion14: "공격3", + robotis_spMotion15: "공격4", + robotis_screen1: "가위", + robotis_screen2: "바위", + robotis_screen3: "보", + robotis_clockwise: "시계방향", + robotis_counterclockwise: "반시계방향", + robotis_up: "들기", + robotis_down: "내리기", + robotis_screen_text_font_small: "작은 폰트", + robotis_screen_text_font_big: "큰 폰트", + robotis_sensing_temperature: "온도센서", + robotis_sensing_humidity: "습도센서", + robotis_sensing_brightness: "밝기센서", + robotis_sensing_motion: "움직임센서", + robotis_sensing_button: "버튼센서", + robotis_sensing_distance: "거리센서", + robotis_sensing_ir_left: "왼쪽 적외선센서", + robotis_sensing_ir_right: "오른쪽 적외선센서", + robotis_stage_1: "1단계", + robotis_stage_2: "2단계", + robotis_stage_3: "3단계", + }, + }, + en: { + template: { + // Value Blocks + robotis_rla_lite_cm_ir_value: 'IR sensor value of No. %1', + robotis_rla_lite_cm_ir_compare: 'If the IR sensor value of No. %1 is %2 %3', + robotis_rla_lite_detectFrontObj: 'If there is an object in front', + robotis_rla_lite_cm_btn_value: 'If button %1 is %2', + robotis_rla_lite_cm_joystick_value: 'If joystick is at %1', + robotis_rla_lite_mic: 'Microphone volume (dB)', + robotis_rla_lite_detectSound_compare: 'If the sound comes from %1', + robotis_rla_lite_imu: '%2 value of %1 axis', + robotis_rla_lite_roll_pitch: 'Controller angle %1 value', + + // Musical Scale + robotis_rla_lite_buzzer_index: 'Play note %1 on controller in octave %2 for %3 seconds %4 %5', + + // LCD Control + robotis_rla_lite_rgee_screen: 'Set controller screen background to R-Gee %1 %2', + robotis_rla_lite_rgee_anim_screen: 'Set controller screen animation to R-Gee %1 %2', + robotis_rla_lite_icon: 'Display %1 on controller screen %5', + robotis_rla_lite_LCDBright: 'Set controller screen brightness to %1 %2', + robotis_rla_lite_LCDColor: 'Set controller screen color to %1 %2', + + // LED Control + robotis_rla_lite_led_brightness: 'Set controller LED %1 brightness to %2 %3', + robotis_rla_lite_led_pattern: 'Controller LED %1 %2 %3', + + // Sound + robotis_rla_lite_Hello: 'Say "%1" %2', + robotis_rla_lite_effectSound: 'Play sound effect %1 %2', + robotis_rla_lite_record: 'Record in slot %1 %2', + robotis_rla_lite_playRecord: 'Play sound from slot %1 %2', + + // Other Robot LCD Control + robotis_rla_lite_rla_screen: 'Set controller screen background to Kodala %1 %2', + robotis_rla_lite_rla_anim_screen: 'Set controller screen animation to Kodala %1 %2', + robotis_rla_lite_kkokdu_screen: 'Set controller screen background to TIG %1 %2', + robotis_rla_lite_kkokdu_anim_screen: 'Set controller screen animation to TIG %1 %2', + robotis_rla_lite_text_screen: 'Display "%1" on screen at (%2, %3) with font %4 and color %5 %6', + + // Driving Control + robotis_rla_lite_drive_simple: 'Move Kodala at speed %1 in direction %2 %3', + robotis_rla_lite_drive_stop: 'Stop Kodala %1', + robotis_rla_lite_wheel_rotate: + 'Rotate motor %1 at speed %2 in %3 direction %4', + robotis_rla_lite_wheel_stop: + 'Stop motor %1 %2', + robotis_rla_lite_go_distance: 'Move Kodala robot %1 cm in %2 direction %3', + robotis_rla_lite_turn_angle: 'Rotate Kodala robot in place by %1 degrees %3', + robotis_rla_lite_motion: 'Kodala %1 %2', + + // Line following + robotis_rla_lite_follow_line: 'Follow line at speed %1 %2', + robotis_rla_lite_stop_follow_line: 'Stop following line %1', + }, + Helper: { + // Value blocks + robotis_rla_lite_cm_ir_value: 'IR sensor value of the specified number (Range: 0 ~ 400)', + robotis_rla_lite_cm_ir_compare: "Returns 'true' if the comparison of the IR sensor value of the specified number and the given value is correct; otherwise returns 'false'.", + robotis_rla_lite_detectFrontObj: "Returns 'true' if an object is detected in front of the specified sensor; otherwise returns 'false'.", + robotis_rla_lite_cm_btn_value: "Returns 'true' if the specified button was pressed and released; otherwise returns 'false'.", + robotis_rla_lite_cm_joystick_value: "Returns 'true' if the joystick position matches the specified state; otherwise returns 'false'.", + robotis_rla_lite_mic: 'Displays the intensity of sound detected by the microphone in decibels (dB).', + robotis_rla_lite_detectSound_compare: "Returns 'true' if the direction of the sound matches the specified direction; otherwise returns 'false'.", + robotis_rla_lite_imu: 'Value of the specified axis of the accelerometer/gyroscope sensor\nRange: -100 ~ 100', + robotis_rla_lite_roll_pitch: 'Roll/pitch values\nRoll: -180° ~ 180°, Pitch: -90° ~ 90°', + + // Sound + robotis_rla_lite_buzzer_index: 'Play the specified scale, octave, and duration', + + // LCD control + robotis_rla_lite_rgee_screen: 'Set the controller screen background to the specified R-Gee expression', + robotis_rla_lite_rgee_anim_screen: 'Set the controller screen animation to the specified R-Gee expression', + robotis_rla_lite_icon: 'Display the specified icon at the center of the screen', + robotis_rla_lite_LCDBright: 'Set the screen brightness\nBrightness range: 1% ~ 100%', + robotis_rla_lite_LCDColor: 'Set the screen color', + + // LED control + robotis_rla_lite_led_brightness: 'Set the brightness of the specified LED on the controller', + robotis_rla_lite_led_pattern: 'Set the blinking pattern of the LED on the controller', + + // Sound + robotis_rla_lite_Hello: 'Speak the specified sentence', + robotis_rla_lite_effectSound: 'Play the specified sound effect', + robotis_rla_lite_record: 'Record on the specified number of the controller', + robotis_rla_lite_playRecord: 'Play the recorded voice of the specified number on the controller', + + // Other robot LCD control + robotis_rla_lite_rla_screen: 'Set the controller screen background to the specified expression of Kodala', + robotis_rla_lite_rla_anim_screen: 'Set the controller screen animation to the specified expression of Kodala', + robotis_rla_lite_kkokdu_screen: 'Set the controller screen background to the specified expression of Kkokdu', + robotis_rla_lite_kkokdu_anim_screen: 'Set the controller screen animation to the specified expression of Kkokdu', + robotis_rla_lite_text_screen: 'Set the location, font size, and color of the specified phrase to be displayed on the screen\nX coordinate: -160 ~ 160\nY coordinate: -120 ~ 120', + + // Driving control (duplicate entries for R-Gee) + robotis_rla_lite_drive_simple: 'Drive Kodala at the specified speed and direction', + robotis_rla_lite_drive_stop: 'Stop Kodala', + robotis_rla_lite_wheel_rotate: 'Rotate the specified wheel of Kodala at the given speed and direction', + robotis_rla_lite_wheel_stop: 'Stop the specified wheel of Kodala', + robotis_rla_lite_go_distance: 'Move Kodala forward/backward by the specified distance', + robotis_rla_lite_turn_angle: 'Rotate Kodala in place by the specified angle', + robotis_rla_lite_motion: 'Make Kodala perform the specified motion', + robotis_rla_lite_follow_line: 'Start following the line at the specified speed', + robotis_rla_lite_stop_follow_line: 'Stop following the line' + }, + + Blocks: { + robotis_white: 'White', + robotis_gray: 'Gray', + robotis_darkgray: 'Darkgray', + robotis_black: 'Black', + robotis_purple: 'Purple', + robotis_pink: 'Pink', + robotis_red: 'Red', + robotis_orange: 'Orange', + robotis_brown: 'Brown', + robotis_yellow: 'Yellow', + robotis_green: 'Green', + robotis_blue: 'Blue', + robotis_lightblue: 'Lightblue', + robotis_darkblue: 'Darkblue', + robotis_brown: 'Brown', + robotis_left: 'Left', + robotis_center: 'Center', + robotis_right: 'Right', + robotis_both: 'Both', + + robotis_rla: 'R-GEE', + robotis_rla: 'KODALA', + robotis_kkokdu: 'TIG', + + robotis_korean1: 'Hello!', + robotis_korean2: 'Great to see you.', + robotis_korean3: 'Okay ~', + robotis_korean4: 'No!', + robotis_korean5: "I don't know.", + robotis_korean6: 'I like it.', + robotis_korean7: "I don't like it.", + robotis_korean8: 'What is your name? ', + robotis_korean9: 'How can I help you? ', + robotis_korean10: 'Great job! ', + robotis_korean11: "It's alright.", + robotis_korean12: "Let's do it again! ", + robotis_korean13: 'Thank you! ', + robotis_korean14: 'Can you say that one more time?', + robotis_korean15: 'Awesome!', + robotis_korean16: "I'm excited! ", + robotis_korean17: "I'm having a great time! ", + robotis_korean18: "I'm sorry.", + robotis_korean19: "I'm angry! ", + robotis_korean20: "I'm embarassed.", + robotis_korean21: "I'm scared.", + robotis_korean22: "I'm upset.", + robotis_korean23: 'I love you.', + robotis_korean24: 'Very pretty! ', + robotis_korean25: 'Interesting.', + robotis_korean26: "I'm nervous.", + robotis_korean27: "Let's move forward! ", + robotis_korean28: "Let's move backward! ", + robotis_korean29: "Let's stand up! ", + robotis_korean30: 'Did you fall down? ', + robotis_korean31: 'Oh Yeah~', + robotis_korean32: 'Sweet! ', + robotis_korean33: 'Oh no', + robotis_korean34: 'My My ', + robotis_korean35: 'Whoo hoo! ', + robotis_korean36: 'Ha Ha Ha', + robotis_korean37: 'Ho Ho Ho ', + robotis_korean38: "I'm sleepy.", + robotis_korean39: 'Sing me a bedtime song! ', + robotis_korean40: 'Hello!', + robotis_korean41: "I'm hungry.", + robotis_korean42: "I'm craving an acorn! ", + robotis_korean43: 'I want to take a bath! ', + robotis_korean44: 'Time for a bath! ', + robotis_korean45: "I'm bored. ", + robotis_korean46: 'Do you want a snack? ', + robotis_korean47: "I'm sick.", + robotis_korean48: 'Do you have any medicine? ', + robotis_korean49: 'Where do we have to go? ', + robotis_korean50: "We're here! ", + robotis_korean51: "Let's go to the left side! ", + robotis_korean52: "Let's go to the right side! ", + robotis_korean53: 'Oh my, you scared me! ', + robotis_korean54: 'Found you! ', + robotis_korean55: "There's nothing here. ", + robotis_korean56: 'Did you call me?', + robotis_korean57: 'Please let me down. ', + robotis_korean58: 'Oops! ', + robotis_korean59: 'Hmmph! ', + robotis_korean60: 'Eek! ', + robotis_dog: 'Dog', + robotis_frog: 'Frog', + robotis_cat: 'Cat', + robotis_chicken: 'Rooster', + robotis_tiger: 'Tiger', + robotis_mouse: 'Mouse', + robotis_whistle: 'Whistle', + robotis_ambul: 'Ambulance', + robotis_Horn: 'CarHorn', + robotis_siren: 'Siren', + robotis_gun: 'Gunshot', + robotis_clap: 'Clap', + robotis_melody1: 'Melody1', + robotis_melody2: 'Melody2', + robotis_melody3: 'Melody3', + robotis_melody4: 'Melody4', + robotis_forward: 'Forward', + robotis_backward: 'Backward', + robotis_acceleration: 'acceleration', + robotis_gyro: 'gyro', + robotis_run: 'Run', + robotis_cancel: 'Cancel', + robotis_push: 'Pressed', + robotis_notPush: 'Unpressed', + robotis_play: 'Play', + robotis_rest: 'Rest', + robotis_face01: 'Haha', + robotis_face02: 'Smile', + robotis_face03: 'Laugh', + robotis_face04: 'Yum Yum', + robotis_face05: 'Scared', + robotis_face06: 'Uncomfortable', + robotis_face07: 'Confused', + robotis_face08: 'Dazed', + robotis_face09: 'Yell', + robotis_face10: 'Angry', + robotis_face11: 'Sniff (Left)', + robotis_face12: 'Sniff (Right)', + robotis_face13: 'Sniff (Down)', + robotis_face14: 'Whew', + robotis_face15: 'Faint', + robotis_face16: 'Dizzy', + robotis_face17: 'Yawn', + robotis_face18: 'Sleepy', + robotis_face19: 'Sleep', + robotis_face20: 'Sad', + robotis_face21: 'Cry', + robotis_face22: 'Bath', + robotis_face23: 'Heart-Eyes', + + robotis_car_anim01: "Default", + robotis_car_anim02: "Touched", + robotis_car_anim03: "Smile", + robotis_car_anim04: "Laugh", + robotis_car_anim05: "Joy", + robotis_car_anim06: "Happiness", + robotis_car_anim07: "Confidence", + robotis_car_anim08: "Anger", + robotis_car_anim09: "Depressed", + robotis_car_anim10: "Sadness", + robotis_car_anim11: "Pain", + robotis_car_anim12: "Fainting", + robotis_car_anim13: "Fear", + robotis_car_anim14: "Yawn", + robotis_car_anim15: "Sleepy", + robotis_car_anim16: "Looking Right", + robotis_car_anim17: "Looking Left", + robotis_car_anim18: "Looking Forward", + robotis_car_anim19: "Surprised", + + + robotis_flashing1: "Flashing1", + robotis_flashing2: "Flashing2", + robotis_flashing3: "Flashing3", + robotis_flashing4: "Flashing4", + robotis_flashing5: "Flashing5", + robotis_flashing6: "Flashing6", + robotis_flashing7: "Flashing7", + robotis_flashing8: "Flashing8", + robotis_flashing9: "Flashing9", + + + + robotis_moveF: 'Forward', + robotis_moveB: 'Backward', + robotis_moveL: 'LeftTurn', + robotis_moveR: 'RightTurn', + robotis_moveU: 'U-turn', + robotis_moveL_in_place: 'Turn left in place', + robotis_moveR_in_place: 'Trun right in place', + robotis_moveU_in_place: 'U-turn in place', + robotis_moveRG1: 'Stand', + robotis_moveRG2: 'Sit', + robotis_moveRG3: 'Struggle', + robotis_moveRG4: 'RaiseFeet', + robotis_fast: 'Fast', + robotis_normal: 'Normal', + robotis_slow: 'Slow', + robotis_stop: 'Stop', + robotis_roll: 'Left-right rotate angle (roll)', + robotis_pitch: 'Forward-backward rotate angle (pitch)', + robotis_stMotion1: 'Standard', + robotis_stMotion2: 'Forward', + robotis_stMotion3: 'TurnRight', + robotis_stMotion4: 'TurnLeft', + robotis_stMotion5: 'Backward', + robotis_stMotion6: 'ToRight', + robotis_stMotion7: 'ToLeft', + robotis_stMotion8: 'TurnAroundRight', + robotis_stMotion9: 'TurnAroundLeft', + robotis_spMotion1: 'RightHandUp', + robotis_spMotion2: 'RightHandDown', + robotis_spMotion3: 'LeftHandUp', + robotis_spMotion4: 'LeftHandDown', + robotis_spMotion5: 'BothHandsUp', + robotis_spMotion6: 'BothHandsDown', + robotis_spMotion7: 'FallBackward', + robotis_spMotion8: 'FallForward', + robotis_spMotion9: 'StandForward', + robotis_spMotion10: 'StandBackward', + robotis_spMotion11: 'Defence', + robotis_spMotion12: 'Offense1', + robotis_spMotion13: 'Offense2', + robotis_spMotion14: 'Offense3', + robotis_spMotion15: 'Offense4', + robotis_screen1: 'Sissor', + robotis_screen2: 'Rock', + robotis_screen3: 'Paper', + robotis_clockwise: "clockwise", + robotis_counterclockwise: "counterclockwise", + robotis_up: "up", + robotis_down: "down", + robotis_screen_text_font_small: "Small font", + robotis_screen_text_font_big: "Big font", + robotis_stage_1: "Stage 1", + robotis_stage_2: "Stage 2", + robotis_stage_3: "Stage 3", + }, + }, + }; + } + getBlocks() { + return { + robotis_rla_lite_cm_ir_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '360'], + ['2', '362'], + ['3', '364'], + ['4', '366'], + ['5', '368'], + ['6', '370'], + ], + value: '360', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_cm_ir_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + const scope = script.executor.scope; + + const data_default_address = script.getNumberValue('VALUE'); + + let result = Entry.RobotisRlaLite.dataBuffer[data_default_address]; + if (result == undefined) { + result = rb100_last_valid_value[data_default_address]; + } else { + rb100_last_valid_value[data_default_address] = result; + } + if (typeof result == 'undefined') { + return 0; + } + return Math.round(result % 65536); + }, + syntax: { + js: [], + py: ['RlaLite.ir_value(%1)'], + }, + }, + robotis_rla_lite_cm_ir_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '360'], + ['2', '362'], + ['3', '364'], + ['4', '366'], + ['5', '368'], + ['6', '370'], + ], + value: '360', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['>', '0'], + ['<', '1'], + ['=', '2'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null, null, 200], + type: 'robotis_rla_lite_cm_ir_compare', + }, + paramsKeyMap: { + VALUE: 0, + COMPARE_OP: 1, + COMPARE_VAL: 2, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('VALUE'); + let compareValue = script.getNumberValue('COMPARE_VAL'); + let compareOP = script.getNumberValue('COMPARE_OP'); + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + + if (result == undefined) { + return false; + } + + result = Math.round(result % 65536); + + switch (compareOP) { + case 0: + return result > compareValue; + case 1: + return result < compareValue; + default: + return false; + } + }, + syntax: { + js: [], + py: ['RlaLite.ir_compare(%1)'], + }, + }, + robotis_rla_lite_detectFrontObj: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + + ], + events: {}, + def: { + params: [ + + ], + type: 'robotis_rla_lite_detectFrontObj', + }, + paramsKeyMap: { + + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + + // instruction / address / length / value / default length + let ir_1 = 0; + let ir_2 = 0; + + + + ir_1 = Entry.RobotisRlaLite.dataBuffer[360]; + ir_2 = Entry.RobotisRlaLite.dataBuffer[362]; + if (ir_1 == undefined) { + ir_1 = 0; + } + if (ir_2 == undefined) { + ir_2 = 0; + } + return ir_1 > 100 || ir_2 > 100; + + }, + syntax: { + js: [], + py: ['RlaLite.detectFrontObj()'], + }, + }, + robotis_rla_lite_cm_btn_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_run, '45'], + [Lang.Blocks.robotis_cancel, '42'], + ], + value: '45', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_push, '1'], + [Lang.Blocks.robotis_notPush, '0'], + + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_cm_btn_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('VALUE'); + let compareValue = 1; + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['RlaLite.btn_value(%1)'], + }, + }, + robotis_rla_lite_cm_joystick_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_center, '0'], + ['←', '1'], + ['→', '2'], + ['↑', '3'], + ['↓', '4'], + ['↖', '5'], + ['↗', '6'], + ['↙', '7'], + ['↘', '8'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_cm_joystick_value', + }, + paramsKeyMap: { + COMPARE_VAL: 0, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = 50; + let compareValue = script.getNumberValue('COMPARE_VAL', script); + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['RlaLite.joystick_value()'], + }, + }, + robotis_rla_lite_mic: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_mic', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + async func(sprite, script) { + let scope = script.executor.scope; + let data_address = 119; + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['RlaLite.mic()'], + }, + }, + robotis_rla_lite_detectSound_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_right, '255'], + [Lang.Blocks.robotis_center, '0'], + [Lang.Blocks.robotis_left, '1'], + ], + value: '255', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_detectSound_compare', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = 5031; + let compareValue = script.getNumberValue('VALUE'); + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['RlaLite.detectSound_compare(%1)'], + }, + }, + robotis_rla_lite_imu: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['x', '78'], //72 + ['y', '80'], //74 + ['z', '82'], //76 + ], + value: '78', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_acceleration, '0'], //72 + [Lang.Blocks.robotis_gyro, '6'], //74 + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_imu', + }, + paramsKeyMap: { + AXIS: 0, + MODE: 1, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = + script.getField('AXIS', script) - script.getField('MODE', script); + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['RlaLite.imu()'], + }, + }, + robotis_rla_lite_roll_pitch: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_roll, '70'], //72 + [Lang.Blocks.robotis_pitch, '88'], //74 + ], + value: '70', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_roll_pitch', + }, + paramsKeyMap: { + AXIS: 0, + }, + class: 'robotis_rla_lite_value', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('AXIS'); + + let result = Entry.RobotisRlaLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['RlaLite.roll_pitch(%1)'], + }, + }, + + + robotis_rla_lite_buzzer_index: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.General.note_c + '', '1'], + [Lang.General.note_c + '#', '2'], + [Lang.General.note_d + '', '3'], + [Lang.General.note_d + '#', '4'], + [Lang.General.note_e + '', '5'], + [Lang.General.note_f + '', '6'], + [Lang.General.note_f + '#', '7'], + [Lang.General.note_g + '', '8'], + [Lang.General.note_g + '#', '9'], + [Lang.General.note_a + '', '10'], + [Lang.General.note_a + '#', '11'], + [Lang.General.note_b + '', '12'], + ], + value: '11', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['3', '3'], + ['4', '4'], + ['5', '5'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_play, '1'], + [Lang.Blocks.robotis_rest, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, 1, null, null], + type: 'robotis_rla_lite_buzzer_index', + }, + paramsKeyMap: { + CM_BUZZER_INDEX: 0, + CM_BUZZER_OCTAV: 1, + CM_BUZZER_DELAY: 2, + CM_BUZZER_PLAY: 3 + }, + class: 'robotis_rla_lite_sound', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmBuzzerIndex = script.getNumberValue('CM_BUZZER_INDEX', script); + let cmBuzzerOffset = script.getNumberValue('CM_BUZZER_OCTAV', script); + let cmBuzzerTime = script.getNumberValue('CM_BUZZER_DELAY', script); + let cmBuzzerPlay = script.getNumberValue('CM_BUZZER_PLAY', script); + + let data_instruction = INST_WRITE; + let data_address = 0; + let data_value = 0; + let interval = 0; + let data_buf = []; + + cmBuzzerTime = Math.round(cmBuzzerTime * 1000); + + data_address = 740; + // data_value_1 = cmBuzzerTime * 10; + // TODO 텍스트 입력으로 바꾸고 최대는 5초 : 0.5 초 하려면 5를 입력 - console.log(parseInt(0.59 * 10)); max 는 5초 + + if (cmBuzzerTime < 0) { + cmBuzzerTime = 0; + } + if (cmBuzzerTime > 50000) { + cmBuzzerTime = 50000; + } + + data_buf.push(cmBuzzerTime % 256); + data_buf.push(Math.floor(cmBuzzerTime / 256)); + + data_value = cmBuzzerIndex + (cmBuzzerOffset - 1) * 12; + data_buf.push(Math.floor(data_value)); + + // console.log("buzzer send"); + let data_sendqueue = [[data_instruction, data_address, 3, data_buf]]; + + if(cmBuzzerPlay == '2') { + data_sendqueue = []; + } + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + cmBuzzerTime + interval + ); + }, + syntax: { + js: [], + py: ['RlaLite.buzzer_index(%1, %2, %3)'], + }, + }, + + + robotis_rla_lite_rgee_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_face01, '2817'], + [Lang.Blocks.robotis_face02, '2818'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face03, '2819'], + [Lang.Blocks.robotis_face04, '2820'], + [Lang.Blocks.robotis_face05, '2821'], + + [Lang.Blocks.robotis_face06, '2822'], + [Lang.Blocks.robotis_face07, '2823'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face08, '2824'], + [Lang.Blocks.robotis_face09, '2825'], + [Lang.Blocks.robotis_face10, '2826'], + + [Lang.Blocks.robotis_face11, '2827'], + [Lang.Blocks.robotis_face12, '2828'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face13, '2829'], + + [Lang.Blocks.robotis_face14, '2830'], + [Lang.Blocks.robotis_face15, '2831'], + [Lang.Blocks.robotis_face16, '2832'], + [Lang.Blocks.robotis_face17, '2833'], + [Lang.Blocks.robotis_face18, '2834'], + + [Lang.Blocks.robotis_face19, '2835'], + [Lang.Blocks.robotis_face20, '2836'], + [Lang.Blocks.robotis_face21, '2837'], + [Lang.Blocks.robotis_face22, '2838'], + [Lang.Blocks.robotis_face23, '2839'], + ], + value: '2817', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_rgee_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['RlaLite.rgee_screen(%1)'] }, + }, + + robotis_rla_lite_rgee_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_face01, '30748'], + [Lang.Blocks.robotis_face02, '30749'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face03, '30750'], + [Lang.Blocks.robotis_face04, '30756'], + [Lang.Blocks.robotis_face05, '30754'], + + [Lang.Blocks.robotis_face06, '30741'], + [Lang.Blocks.robotis_face07, '30747'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face08, '30738'], + [Lang.Blocks.robotis_face09, '30740'], + [Lang.Blocks.robotis_face10, '30739'], + + [Lang.Blocks.robotis_face11, '30733'], + [Lang.Blocks.robotis_face12, '30734'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face13, '30732'], + + [Lang.Blocks.robotis_face14, '30757'], + [Lang.Blocks.robotis_face15, '30736'], + [Lang.Blocks.robotis_face16, '30731'], + [Lang.Blocks.robotis_face17, '30742'], + [Lang.Blocks.robotis_face18, '30743'], + + [Lang.Blocks.robotis_face19, '30744'], + [Lang.Blocks.robotis_face20, '30751'], + [Lang.Blocks.robotis_face21, '30752'], + [Lang.Blocks.robotis_face22, '30755'], + [Lang.Blocks.robotis_face23, '30758'], + ], + value: '30748', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_rgee_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['RlaLite.rgee_animation_screen(%1)'] }, + }, + + + + + robotis_rla_lite_icon: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_screen1, '11545'], + [Lang.Blocks.robotis_screen2, '11546'], + [Lang.Blocks.robotis_screen3, '11547'], + ['0', '11283'], + ['1', '11284'], + ['2', '11285'], + ['3', '11286'], + ['4', '11287'], + ['5', '11288'], + ['6', '11289'], + ['7', '11290'], + ['8', '11291'], + ['9', '11292'], + ['10', '11293'], + ], + value: '11545', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + 50, + null, + ], + type: 'robotis_rla_lite_icon', + }, + paramsKeyMap: { + ICON: 0, + X: 1, + Y: 2, + SIZE: 3, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let iconNum = script.getField('ICON', script); + let x = script.getNumberValue('X', script); + let y = script.getNumberValue('Y', script); + let size = script.getNumberValue('SIZE', script) * 2; + + let data_instruction = INST_WRITE; + let data_address = 166; + let data_length = 2; + let data_value = 10496; + + if (x < -160) { + x = -160; + } else if (x > 160) { + x = 160; + } + + if (y < -120) { + y = -120; + } else if (y > 120) { + y = 120; + } + + if (size < 0) { + size = 0; + } else if (size > 400) { + size = 400; + } + + data_value = iconNum; + + let data_sendqueue = [ + [INST_WRITE, 130, 2, x], + [INST_WRITE, 132, 2, y], + [INST_WRITE, 149, 2, size], + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { + js: [], + py: ['RlaLite.icon_screen(%1,%2,%3,%4)'], + }, + }, + + + robotis_rla_lite_LCDBright: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [10], + type: 'robotis_rla_lite_LCDBright', + }, + paramsKeyMap: { + BRIGHT: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let bright = script.getNumberValue('BRIGHT', script); + + let data_instruction = INST_WRITE; + let data_address = 180; + let data_length = 1; + let data_value = 0; + + bright = Math.min(Math.max(bright, 0), 100); + + data_value = bright; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.LCDBright(%1)'], + }, + }, + robotis_rla_lite_LCDColor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_red, '224'], + [Lang.Blocks.robotis_orange, '244'], + [Lang.Blocks.robotis_yellow, '252'], + [Lang.Blocks.robotis_green, '28'], + [Lang.Blocks.robotis_blue, '3'], + [Lang.Blocks.robotis_darkblue, '2'], + [Lang.Blocks.robotis_purple, '130'], + [Lang.Blocks.robotis_brown, '173'], + [Lang.Blocks.robotis_black, '0'], + [Lang.Blocks.robotis_white, '255'], + ], + value: '224', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_LCDColor', + }, + paramsKeyMap: { + COLOR: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let color = script.getNumberValue('COLOR', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = 0; + + data_value = color; + bg_color = color; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 100 + ); + }, + syntax: { + js: [], + py: ['RlaLite.LCDColor(%1)'], + }, + }, + + robotis_rla_lite_led_brightness: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_left, '1'], + [Lang.Blocks.robotis_right, '2'], + [Lang.Blocks.robotis_both, '3'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: [100] + } + ], + type: 'robotis_rla_lite_led_brightness', + }, + paramsKeyMap: { + RB_LED: 0, + BRIGHT: 1, + }, + class: 'robotis_rla_lite_led', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmLed = script.getNumberValue('RB_LED', script); + let bright = script.getNumberValue('BRIGHT', script); + + let data_instruction = INST_WRITE; + let data_address = 0; + let data_length = 1; + let data_value = 0; + + if(bright < 0){ + bright = 0; + } else if(bright > 100) { + bright = 100 + } + data_value = 100+bright; + + if (cmLed == 1) { + data_address = 40; + data_length = 1; + } else if (cmLed == 2) { + data_address = 41; + data_length = 1; + } else if (cmLed == 3) { + data_address = 40; + data_length = 2; + data_value = data_value * 257 + } + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['RlaLite.led_brightness(%1, %2)'] }, + }, + robotis_rla_lite_led_pattern: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_flashing1, '11'], + [Lang.Blocks.robotis_flashing2, '12'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing3, '13'], + + [Lang.Blocks.robotis_flashing4, '21'], + [Lang.Blocks.robotis_flashing5, '22'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing6, '23'], + + [Lang.Blocks.robotis_flashing7, '31'], + [Lang.Blocks.robotis_flashing8, '32'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing9, '33'], + + ], + value: '11', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_common_on, '1'], + [Lang.Blocks.robotis_common_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, null], + type: 'robotis_rla_lite_led_pattern', + }, + paramsKeyMap: { + RB_LED: 0, + VALUE: 1, + }, + class: 'robotis_rla_lite_led', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmLed = script.getNumberValue('RB_LED', script); + let value = script.getNumberValue('VALUE', script); + + let data_instruction = INST_WRITE; + let data_address = 40; + let data_length = 1; + let data_value = 0; + + data_value = value * cmLed; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['RlaLite.led_pattern(%1, %2)'] }, + }, + + + + robotis_rla_lite_Hello: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_korean1, '0'], + [Lang.Blocks.robotis_korean2, '1'], + [Lang.Blocks.robotis_korean3, '2'], + [Lang.Blocks.robotis_korean4, '3'], + [Lang.Blocks.robotis_korean5, '4'], + [Lang.Blocks.robotis_korean6, '5'], + [Lang.Blocks.robotis_korean7, '6'], + [Lang.Blocks.robotis_korean8, '7'], + [Lang.Blocks.robotis_korean9, '8'], + [Lang.Blocks.robotis_korean10, '9'], + [Lang.Blocks.robotis_korean11, '10'], + [Lang.Blocks.robotis_korean12, '11'], + [Lang.Blocks.robotis_korean13, '12'], + [Lang.Blocks.robotis_korean14, '13'], + [Lang.Blocks.robotis_korean15, '14'], + [Lang.Blocks.robotis_korean16, '15'], + [Lang.Blocks.robotis_korean17, '16'], + [Lang.Blocks.robotis_korean18, '17'], + [Lang.Blocks.robotis_korean19, '18'], + [Lang.Blocks.robotis_korean20, '19'], + [Lang.Blocks.robotis_korean21, '20'], + [Lang.Blocks.robotis_korean22, '21'], + [Lang.Blocks.robotis_korean23, '22'], + [Lang.Blocks.robotis_korean24, '23'], + [Lang.Blocks.robotis_korean25, '24'], + [Lang.Blocks.robotis_korean26, '25'], + [Lang.Blocks.robotis_korean27, '26'], + [Lang.Blocks.robotis_korean28, '27'], + [Lang.Blocks.robotis_korean29, '28'], + [Lang.Blocks.robotis_korean30, '29'], + [Lang.Blocks.robotis_korean31, '30'], + [Lang.Blocks.robotis_korean32, '31'], + [Lang.Blocks.robotis_korean33, '32'], + [Lang.Blocks.robotis_korean34, '33'], + [Lang.Blocks.robotis_korean35, '34'], + [Lang.Blocks.robotis_korean36, '35'], + [Lang.Blocks.robotis_korean37, '36'], + [Lang.Blocks.robotis_korean38, '37'], + [Lang.Blocks.robotis_korean39, '38'], + [Lang.Blocks.robotis_korean40, '39'], + [Lang.Blocks.robotis_korean41, '40'], + [Lang.Blocks.robotis_korean42, '41'], + [Lang.Blocks.robotis_korean43, '42'], + [Lang.Blocks.robotis_korean44, '43'], + [Lang.Blocks.robotis_korean45, '44'], + [Lang.Blocks.robotis_korean46, '45'], + [Lang.Blocks.robotis_korean47, '46'], + [Lang.Blocks.robotis_korean48, '47'], + [Lang.Blocks.robotis_korean49, '48'], + [Lang.Blocks.robotis_korean50, '49'], + [Lang.Blocks.robotis_korean51, '50'], + [Lang.Blocks.robotis_korean52, '51'], + [Lang.Blocks.robotis_korean53, '52'], + [Lang.Blocks.robotis_korean54, '53'], + [Lang.Blocks.robotis_korean55, '54'], + [Lang.Blocks.robotis_korean56, '55'], + [Lang.Blocks.robotis_korean57, '56'], + [Lang.Blocks.robotis_korean58, '57'], + [Lang.Blocks.robotis_korean59, '58'], + [Lang.Blocks.robotis_korean60, '59'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_Hello', + }, + paramsKeyMap: { + HELLO: 0, + }, + class: 'robotis_rla_lite_sound', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmHello = script.getField('HELLO', script); + + let data_instruction = INST_WRITE; + let data_address = 110; + let data_length = 2; + let data_value = 0; + + data_value = 25601 + Number(cmHello); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [data_instruction, 0, 2, 0], + ]; + + let extraTime = 0; + + if (cmHello == '38' || cmHello == '55') { + extraTime = 2000; + } + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + 2000 + extraTime + ); + }, + syntax: { + js: [], + py: ['RlaLite.speak(%1)'], + }, + }, + robotis_rla_lite_effectSound: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dog, '0'], + [Lang.Blocks.robotis_frog, '1'], + [Lang.Blocks.robotis_cat, '2'], + [Lang.Blocks.robotis_chicken, '7'], + [Lang.Blocks.robotis_tiger, '19'], + [Lang.Blocks.robotis_mouse, '17'], + + [Lang.Blocks.robotis_ambul, '773'], + [Lang.Blocks.robotis_Horn, '781'], + [Lang.Blocks.robotis_siren, '774'], + [Lang.Blocks.robotis_whistle, '274'], + [Lang.Blocks.robotis_gun, '775'], + [Lang.Blocks.robotis_clap, '260'], + + [Lang.Blocks.robotis_melody1, '786'], + [Lang.Blocks.robotis_melody2, '787'], + [Lang.Blocks.robotis_melody3, '788'], + [Lang.Blocks.robotis_melody4, '789'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_effectSound', + }, + paramsKeyMap: { + HELLO: 0, + }, + class: 'robotis_rla_lite_sound', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmHello = script.getField('HELLO', script); + + let data_instruction = INST_WRITE; + let data_address = 110; + let data_length = 2; + let data_value = 0; + + data_value = Number(cmHello); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [data_instruction, 0, 2, 0], + ]; + + let extraTime = 0; + if ( + cmHello == '272' || + cmHello == '786' || + cmHello == '787' || + cmHello == '788' || + cmHello == '789' + ) { + //오리 + extraTime = 0; + if (cmHello == '788' || cmHello == '789') { + extraTime += 500; + } + } + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + 3000 + extraTime + ); + }, + syntax: { + js: [], + py: ['RlaLite.effect_sound(%1)'], + }, + }, + robotis_rla_lite_record: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_record', + }, + paramsKeyMap: { + ROOM: 0, + }, + class: 'robotis_rla_lite_sound', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let roomNum = script.getField('ROOM', script); + + let data_instruction = INST_WRITE; + let data_address = 115; + let data_length = 1; + let data_value = 0; + + data_value = roomNum; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + 6000 + ); + }, + syntax: { + js: [], + py: ['RlaLite.record(%1)'], + }, + }, + robotis_rla_lite_playRecord: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_playRecord', + }, + paramsKeyMap: { + ROOM: 0, + }, + class: 'robotis_rla_lite_sound', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let roomNum = script.getField('ROOM', script); + + let data_instruction = INST_WRITE; + let data_address = 116; + let data_length = 1; + let data_value = 0; + + data_value = roomNum; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + 6000 + ); + }, + syntax: { + js: [], + py: ['RlaLite.playRecord(%1)'], + }, + }, + + + + + robotis_rla_lite_rla_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '3329'], + [Lang.Blocks.robotis_car_anim02, '3330'], + [Lang.Blocks.robotis_car_anim03, '3331'], + [Lang.Blocks.robotis_car_anim04, '3332'], + [Lang.Blocks.robotis_car_anim05, '3333'], + + [Lang.Blocks.robotis_car_anim06, '3334'], + [Lang.Blocks.robotis_car_anim07, '3335'], + [Lang.Blocks.robotis_car_anim08, '3336'], + [Lang.Blocks.robotis_car_anim09, '3337'], + [Lang.Blocks.robotis_car_anim10, '3338'], + + [Lang.Blocks.robotis_car_anim11, '3339'], + [Lang.Blocks.robotis_car_anim12, '3340'], + [Lang.Blocks.robotis_car_anim13, '3341'], + [Lang.Blocks.robotis_car_anim14, '3342'], + [Lang.Blocks.robotis_car_anim15, '3343'], + + [Lang.Blocks.robotis_car_anim16, '3344'], + [Lang.Blocks.robotis_car_anim17, '3345'], + [Lang.Blocks.robotis_car_anim18, '3346'], + [Lang.Blocks.robotis_car_anim19, '3347'], + ], + value: '3329', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_rla_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['RlaLite.rla_screen(%1)'] }, + }, + + robotis_rla_lite_rla_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '30978'], + [Lang.Blocks.robotis_car_anim02, '30981'], + [Lang.Blocks.robotis_car_anim03, '30982'], + [Lang.Blocks.robotis_car_anim04, '30983'], + [Lang.Blocks.robotis_car_anim05, '30984'], + + [Lang.Blocks.robotis_car_anim06, '30985'], + [Lang.Blocks.robotis_car_anim07, '30986'], + [Lang.Blocks.robotis_car_anim08, '30987'], + [Lang.Blocks.robotis_car_anim09, '30988'], + [Lang.Blocks.robotis_car_anim10, '30989'], + + [Lang.Blocks.robotis_car_anim11, '30990'], + [Lang.Blocks.robotis_car_anim12, '30991'], + [Lang.Blocks.robotis_car_anim13, '30992'], + [Lang.Blocks.robotis_car_anim14, '30993'], + [Lang.Blocks.robotis_car_anim15, '30994'], + + [Lang.Blocks.robotis_car_anim16, '30995'], + [Lang.Blocks.robotis_car_anim17, '30996'], + [Lang.Blocks.robotis_car_anim18, '30997'], + [Lang.Blocks.robotis_car_anim19, '30998'], + ], + value: '30978', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_rla_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['RlaLite.rla_animation_screen(%1)'] }, + }, + + robotis_rla_lite_kkokdu_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '3585'], + [Lang.Blocks.robotis_car_anim02, '3586'], + [Lang.Blocks.robotis_car_anim03, '3587'], + [Lang.Blocks.robotis_car_anim04, '3588'], + [Lang.Blocks.robotis_car_anim05, '3589'], + + [Lang.Blocks.robotis_car_anim06, '3590'], + [Lang.Blocks.robotis_car_anim07, '3591'], + [Lang.Blocks.robotis_car_anim08, '3592'], + [Lang.Blocks.robotis_car_anim09, '3593'], + [Lang.Blocks.robotis_car_anim10, '3594'], + + [Lang.Blocks.robotis_car_anim11, '3595'], + [Lang.Blocks.robotis_car_anim12, '3596'], + [Lang.Blocks.robotis_car_anim13, '3597'], + [Lang.Blocks.robotis_car_anim14, '3598'], + [Lang.Blocks.robotis_car_anim15, '3599'], + + [Lang.Blocks.robotis_car_anim16, '3600'], + [Lang.Blocks.robotis_car_anim17, '3601'], + [Lang.Blocks.robotis_car_anim18, '3602'], + [Lang.Blocks.robotis_car_anim19, '3603'], + ], + value: '3585', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_kkokdu_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['RlaLite.kkokdu_screen(%1)'] }, + }, + + robotis_rla_lite_kkokdu_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '31234'], + [Lang.Blocks.robotis_car_anim02, '31237'], + [Lang.Blocks.robotis_car_anim03, '31238'], + [Lang.Blocks.robotis_car_anim04, '31239'], + [Lang.Blocks.robotis_car_anim05, '31240'], + + [Lang.Blocks.robotis_car_anim06, '31241'], + [Lang.Blocks.robotis_car_anim07, '31242'], + [Lang.Blocks.robotis_car_anim08, '31243'], + [Lang.Blocks.robotis_car_anim09, '31244'], + [Lang.Blocks.robotis_car_anim10, '31245'], + + [Lang.Blocks.robotis_car_anim11, '31246'], + [Lang.Blocks.robotis_car_anim12, '31247'], + [Lang.Blocks.robotis_car_anim13, '31248'], + [Lang.Blocks.robotis_car_anim14, '31249'], + [Lang.Blocks.robotis_car_anim15, '31250'], + + [Lang.Blocks.robotis_car_anim16, '31251'], + [Lang.Blocks.robotis_car_anim17, '31252'], + [Lang.Blocks.robotis_car_anim18, '31253'], + [Lang.Blocks.robotis_car_anim19, '31254'], + ], + value: '31234', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_kkokdu_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['RlaLite.kkokdu_animation_screen(%1)'] }, + }, + robotis_rla_lite_text_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_screen_text_font_small, '0'], + [Lang.Blocks.robotis_screen_text_font_big, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_red, '224'], + [Lang.Blocks.robotis_orange, '244'], + [Lang.Blocks.robotis_yellow, '252'], + [Lang.Blocks.robotis_green, '28'], + [Lang.Blocks.robotis_blue, '3'], + [Lang.Blocks.robotis_darkblue, '2'], + [Lang.Blocks.robotis_purple, '130'], + [Lang.Blocks.robotis_brown, '173'], + [Lang.Blocks.robotis_black, '0'], + [Lang.Blocks.robotis_white, '255'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + ' ', + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + null, + null, + ], + type: 'robotis_rla_lite_text_screen', + }, + paramsKeyMap: { + TEXT: 0, + X: 1, + Y: 2, + FONT: 3, + COLOR: 4, + }, + class: 'robotis_rla_lite_lcd', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let text = script.getStringValue('TEXT', script); + let x = script.getNumberValue('X', script); + let y = script.getNumberValue('Y', script); + let font = script.getNumberValue('FONT', script); + let color = script.getNumberValue('COLOR', script); + let data_buf = []; + let i = 0; + + let data_instruction = INST_WRITE; + let data_address = 900; + let data_length = 2; + + if (x < -160) { + x = -160; + } else if (x > 160) { + x = 160; + } + + if (y < -120) { + y = -120; + } else if (y > 120) { + y = 120; + } + + let encoder = new TextEncoder('utf-8'); + let byteArray = encoder.encode(text); + + data_buf.push(x % 256); + data_buf.push(Math.floor(x / 256)); + data_buf.push(y % 256); + data_buf.push(Math.floor(y / 256)); + data_buf.push(font); + data_buf.push(0); + data_buf.push(0); + data_buf.push(color); + data_buf.push(byteArray.length); + for (i = 0; i < byteArray.length; i++) { + data_buf.push(byteArray[i]); + } + + data_length = 9 + byteArray.length; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_buf], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { + js: [], + py: ['RlaLite.text_screen(%1,%2,%3,%4,%5)'], + }, + }, + + + + robotis_rla_lite_drive_simple: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_moveF, '1'], + [Lang.Blocks.robotis_moveB, '2'], + [Lang.Blocks.robotis_moveL, '3'], + [Lang.Blocks.robotis_moveR, '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [10, null, null], + type: 'robotis_rla_lite_drive_simple', + }, + paramsKeyMap: { + SPEED: 0, + DIRECTION: 1, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + const speed = script.getNumberValue('SPEED', script); + const direction = script.getField('DIRECTION', script); + + const data_instruction = INST_WRITE; + const data_address = 710; + const data_length = 2; + let data_value = 0; + + switch (direction) { + case '1': + data_value = speed * 256 + speed; + break; + case '2': + data_value = (256 - speed) * 256 + (256 - speed); + break; + case '3': + data_value = speed * 256 + (256 - speed); + break; + case '4': + data_value = (256 - speed) * 256 + speed; + break; + default: + data_value = 0; + break; + } + + const data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.go_simple(%1, %2)'], + }, + }, + + robotis_rla_lite_drive_stop: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_drive_stop', + }, + paramsKeyMap: { + DIRECTION: 0, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + + let data_instruction = INST_WRITE; + let data_address = 710; + let data_length = 2; + let data_value = 0; + + let data_sendqueue = [ + [data_instruction, 5200, 1, 0], + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.stop(%1, %2)'], + }, + }, + robotis_rla_lite_motion: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_up, '50007'], + [Lang.Blocks.robotis_down, '50008'], //Lang.Blocks.robotis_robotis_common_green_color + ], + value: '50007', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_motion', + }, + paramsKeyMap: { + MotionNumber: 0, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + const data_instruction = INST_WRITE; + const data_address = 66; + const data_length = 2; + let data_value = script.getField('MotionNumber', script); + + const data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + data_value > 50070 ? 2000 : 1000 + ); + }, + syntax: { + js: [], + py: ['RlaLite.run_motion(%1)'], + }, + }, + robotis_rla_lite_wheel_rotate: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_left, '1'], + [Lang.Blocks.robotis_right, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_clockwise, '1'], + [Lang.Blocks.robotis_counterclockwise, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['10'], + }, + null, + ], + type: 'robotis_rla_lite_wheel_rotate', + }, + paramsKeyMap: { + WHEEL_SIDE: 0, + WHEEL_SPEED: 1, + WHEEL_DIRECTION: 2, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let wheelSide = script.getNumberValue('WHEEL_SIDE', script); + let wheelSpeed = script.getNumberValue('WHEEL_SPEED', script); + let wheelDirection = script.getNumberValue('WHEEL_DIRECTION', script); + + let leftSpeed = 0; + let rightSpeed = 0; + let data_instruction = INST_WRITE; + let data_address = 710; + let data_length = 2; + let data_value = 0; + + if (wheelSpeed < -100) { + wheelSpeed = -100; + } else if (wheelSpeed > 100) { + wheelSpeed = 100; + } + if (wheelSide == 1) { + wheelSpeed = wheelSpeed * (-1); + } + + wheelSpeed = (wheelSpeed + 256) % 256; + if (wheelDirection == '2') { + wheelSpeed = (256 - wheelSpeed) % 256; + } + + if (wheelSide == 1) { + leftSpeed = wheelSpeed; + rightSpeed = 127; // 속도제어 안함 + } else if (wheelSide == 0) { + leftSpeed = 127; // 속도제어 안함 + rightSpeed = wheelSpeed; + } + + data_value = leftSpeed + rightSpeed * 256; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + 25 //DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.go_seperate(%1, %2)'], + }, + }, + robotis_rla_lite_wheel_stop: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_left, '1'], + [Lang.Blocks.robotis_right, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + ], + type: 'robotis_rla_lite_wheel_stop', + }, + paramsKeyMap: { + WHEEL_SIDE: 0, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let wheelSide = script.getNumberValue('WHEEL_SIDE', script); + + let leftSpeed = 0; + let rightSpeed = 0; + let data_instruction = INST_WRITE; + let data_address = 710; + let data_length = 2; + let data_value = 0; + + if (wheelSide == 1) { + leftSpeed = 0; + rightSpeed = 127; // 속도제어 안함 + } else if (wheelSide == 0) { + leftSpeed = 127; // 속도제어 안함 + rightSpeed = 0; + } + + data_value = leftSpeed + rightSpeed * 256; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + 25 //DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.stop_seperate(%1)'], + }, + }, + robotis_rla_lite_go_distance: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_moveF, '1'], + [Lang.Blocks.robotis_moveB, '-1'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['10'], + }, + null, + ], + type: 'robotis_rla_lite_go_distance', + }, + + paramsKeyMap: { + DISTANCE: 0, + DIRECTION: 1, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(entity, script) { + let distance = script.getNumberValue('DISTANCE', script); + let direction = script.getField('DIRECTION', script); + + if (distance > 1000) { + distance = 1000; + } else if (distance < -1000) { + distance = -1000; + } + + let data_instruction = INST_WRITE; + let data_address = 270; + let data_length = 4; + let data_value = Math.floor(10 * distance * direction); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + data_sendqueue.push([data_instruction, 66, 2, 50491]); + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 150 * Math.abs(distance) + 1200 + //DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['RlaLite.go_distance(%1)'] }, + }, + + robotis_rla_lite_turn_angle: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_moveL_in_place, '1'], + [Lang.Blocks.robotis_moveR_in_place, '-1'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['90'], + }, + null, + ], + type: 'robotis_rla_lite_turn_angle', + }, + + paramsKeyMap: { + ANGLE: 0, + DIRECTION: 1, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(entity, script) { + let angle = script.getNumberValue('ANGLE', script); + let direction = script.getNumberValue('DIRECTION', script); + + angle *= direction; + + if (angle > 360) { + angle = 360; + } else if (angle < -360) { + angle = -360; + } + + let data_instruction = INST_WRITE; + let data_address = 270; + let data_length = 4; + let data_value = Math.floor(angle); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + data_sendqueue.push([data_instruction, 66, 2, 50492]); + + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + Math.abs(angle) * 16 + 1500 + //DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['RlaLite.turn_angle(%1)'] }, + }, + + + robotis_rla_lite_follow_line: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_stage_1, '1'], + [Lang.Blocks.robotis_stage_2, '2'], + [Lang.Blocks.robotis_stage_3, '3'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_rla_lite_follow_line', + }, + paramsKeyMap: { + SPEED: 0, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let speed_level = script.getNumberValue('SPEED', script); + + let data_instruction = INST_WRITE; + let data_address = 5200; + let data_length = 1; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, speed_level], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.follow_line(%1)'], + }, + }, + + robotis_rla_lite_stop_follow_line: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_rla_lite_stop_follow_line', + }, + paramsKeyMap: { + DIRECTION: 0, + }, + class: 'robotis_rla_lite_move', + isNotFor: ['RobotisRlaLite'], + func(sprite, script) { + // instruction / address / length / value / default length + + let data_instruction = INST_WRITE; + let data_address = 710; + let data_length = 2; + let data_value = 0; + + let data_sendqueue = [ + [data_instruction, 5200, 1, 0], + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisRlaLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['RlaLite.stop_follow_line()'], + }, + }, + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + }; + } + + requestLocalData() { + let packets = []; + while (this.robotisBuffer.length > 0) { + const data = this.robotisBuffer.shift(); + const instruction = data[0]; + const address = data[1]; + const length = data[2]; + const value = data[3]; + const dataBuffer = data[4]; + let id = 0; + let packet = null; + + switch (instruction) { + case INST_WRITE: + id = 200; + packet = this.writePacket(id, address, length, value); + break; + case INST_BYPASS_WRITE: + id = value; + packet = this.writePacket(id, address, length, dataBuffer); + break; + } + + if (packet !== null && Array.isArray(packet)) { + packets.push(...packet); + } + } + return packets; + } + + handleLocalData(data) { + let stuffLength = 0; + //console.log(`length: ${data.length}`); + for (let i = 0; i < data.length; i++) { + //this.receiveBuffer.push(data[i]); + const dataIn = data[i]; + + switch (this.packetReceiveState) { + case PACKET_STATE_IDLE: + if (this.headerCount >= 2) { + rxPacket.header[2] = dataIn; + + if ( + rxPacket.header[0] == 0xff && + rxPacket.header[1] == 0xff && + rxPacket.header[2] == 0xfd + ) { + this.headerCount = 0; + this.packetReceiveState = PACKET_STATE_RESERVED; + } else { + rxPacket.header[0] = rxPacket.header[1]; + rxPacket.header[1] = rxPacket.header[2]; + rxPacket.header[2] = 0; + } + } else { + rxPacket.header[this.headerCount] = dataIn; + this.headerCount++; + } + break; + + case PACKET_STATE_RESERVED: + if (dataIn == 0xfd) { + this.packetReceiveState = PACKET_STATE_IDLE; + } else { + rxPacket.reserved = dataIn; + this.packetReceiveState = PACKET_STATE_ID; + } + break; + + case PACKET_STATE_ID: + rxPacket.id = dataIn; + this.packetReceiveState = PACKET_STATE_LENGTH_L; + break; + + case PACKET_STATE_LENGTH_L: + rxPacket.packetLength = dataIn; + this.packetReceiveState = PACKET_STATE_LENGTH_H; + break; + + case PACKET_STATE_LENGTH_H: + rxPacket.packetLength |= dataIn << 8; + if (rxPacket.packetLength < 1000) { + this.packetReceiveState = PACKET_STATE_DATA; + } else { + this.packetReceiveState = PACKET_STATE_IDLE; + } + rxPacket.index = 0; + break; + + case PACKET_STATE_DATA: + rxPacket.data[rxPacket.index] = dataIn; + rxPacket.index++; + + if (rxPacket.index >= rxPacket.packetLength - 2) { + this.packetReceiveState = PACKET_STATE_CRC_L; + } + break; + + case PACKET_STATE_CRC_L: + rxPacket.crcReceived = dataIn; + this.packetReceiveState = PACKET_STATE_CRC_H; + break; + + case PACKET_STATE_CRC_H: + rxPacket.crcReceived |= dataIn << 8; + + stuffLength = this.removeStuffing(rxPacket.data, rxPacket.packetLength); + rxPacket.packetLength -= stuffLength; + + rxPacket.cmd = rxPacket.data[0]; + rxPacket.error = rxPacket.data[1]; + + if (rxPacket.cmd == INST_STATUS) { + //console.log(`rx length: ${rxPacket.packetLength}`); + if (rxPacket.packetLength >= 147) { + let tempValue = 0; + for (let i = 0; i < addrMap.length; i++) { + switch (addrMap[i][1]) { + case 1: + this.dataBuffer[addrMap[i][2]] = + rxPacket.data[2 + addrMap[i][0]]; + break; + + case 2: + tempValue = + rxPacket.data[2 + addrMap[i][0]] + + (rxPacket.data[2 + addrMap[i][0] + 1] << 8); + if (tempValue >= 32768) { + tempValue = tempValue - 65536; + } + this.dataBuffer[addrMap[i][2]] = tempValue; + break; + + case 4: + this.dataBuffer[addrMap[i][2]] = + rxPacket.data[2 + addrMap[i][0]] + + (rxPacket.data[2 + addrMap[i][0] + 1] << 8) + + (rxPacket.data[2 + addrMap[i][0] + 2] << 16) + + (rxPacket.data[2 + addrMap[i][0] + 3] << 24); + break; + } + } + + const dxlPositionStartAddr = + addrMap[addrMap.length - 1][0] + addrMap[addrMap.length - 1][1]; + + // DXL Position + for (let i = 0; i < 20; i++) { + const currentId = + rxPacket.data[2 + dxlPositionStartAddr + 3 * i]; + const currentPos = + rxPacket.data[2 + dxlPositionStartAddr + 3 * i + 1] + + (rxPacket.data[2 + dxlPositionStartAddr + 3 * i + 2] << 8); + if (currentId != 0xff && currentPos != 0xffff) { + this.dxlPositions[currentId] = currentPos; + } + } + + const lineCategoryStartAddr = dxlPositionStartAddr + 3 * 20; + // line category + this.dataBuffer[5201] = rxPacket.data[2 + lineCategoryStartAddr]; + + const sensorStartAddr = lineCategoryStartAddr + 1; + + // 온습도+조도+동작감지센서값 + this.pirPir[0] = rxPacket.data[2 + sensorStartAddr]; + this.pirTemperature[0] = rxPacket.data[2 + sensorStartAddr + 1]; + this.pirHumidity[0] = rxPacket.data[2 + sensorStartAddr + 2]; + this.pirBrightness[0] = rxPacket.data[2 + sensorStartAddr + 3]; + + // 거리+버튼+조도센서값 + this.distanceDistance[0] = + rxPacket.data[2 + sensorStartAddr + 4] + + (rxPacket.data[2 + sensorStartAddr + 5] << 8); + this.distanceButton[0] = rxPacket.data[2 + sensorStartAddr + 6]; + this.distanceBrightness[0] = rxPacket.data[2 + sensorStartAddr + 7]; + + for (let i = 0; i < addrMap2.length; i++) { + switch (addrMap2[i][1]) { + case 1: + this.dataBuffer[addrMap2[i][2]] = + rxPacket.data[2 + addrMap2[i][0]]; + break; + + case 2: + tempValue = + rxPacket.data[2 + addrMap2[i][0]] + + (rxPacket.data[2 + addrMap2[i][0] + 1] << 8); + if (tempValue >= 32768) { + tempValue = tempValue - 65536; + } + this.dataBuffer[addrMap2[i][2]] = tempValue; + break; + + case 4: + this.dataBuffer[addrMap2[i][2]] = + rxPacket.data[2 + addrMap2[i][0]] + + (rxPacket.data[2 + addrMap2[i][0] + 1] << 8) + + (rxPacket.data[2 + addrMap2[i][0] + 2] << 16) + + (rxPacket.data[2 + addrMap2[i][0] + 3] << 24); + break; + } + } + } + } + + this.packetReceiveState = PACKET_STATE_IDLE; + break; + + default: + // code block + } + } + } + + requestInitialData() { + this.robotisBuffer = []; + this.robotisBuffer.push([INST_WRITE, 21, 2, 20]); + this.robotisBuffer.push([INST_WRITE, 19, 1, 1]); // bypass 모드 켜기 + this.robotisBuffer.push([INST_WRITE, 20, 1, 0]); // bypass port를 BLE로 설정 + this.robotisBuffer.push([INST_WRITE, 23, 1, 1]); // auto report 기능 켜기 + this.robotisBuffer.push([INST_WRITE, 4250, 1, 1]); // ai_camera 텍스트 지우기 + this.robotisBuffer.push([INST_WRITE, 722, 1, 0]); // dxl 토크 끄기 + //this.robotisBuffer.push([INST_WRITE, 63, 1, 1]); // 부저음 시간 설정 + //this.robotisBuffer.push([INST_WRITE, 60, 1, 70]); // 부저음 발생 + this.robotisBuffer.push([INST_WRITE, 113, 2, 1040]); // "띵" 효과음 발생 + /* + //const ping = [0xff, 0xff, 0xfd, 0x00, 0xc8, 0x03, 0x00, 0x01, 0x3b, 0xfa]; + // run entry mode + const packet = [ + 0xff, 0xff, 0xfd, 0x00, 0xc8, 0x07, 0x00, 0x03, 0x15, 0x00, 0x14, 0x00, 0xc1, 0xb3, + ]; + return packet; + */ + } + + async initialHandshake() { + const status = true; + let sendBuffer = null; + this.requestInitialData(); + while (this.robotisBuffer.length) { + const data = this.robotisBuffer.shift(); + const instruction = data[0]; + const address = data[1]; + const length = data[2]; + const value = data[3]; + const dataBuffer = data[4]; + let id = 0; + + switch (instruction) { + case INST_WRITE: + id = 200; + sendBuffer = this.writePacket(id, address, length, value); + break; + case INST_BYPASS_WRITE: + id = value; + sendBuffer = this.writePacket(id, address, length, dataBuffer); + break; + } + Entry.hwLite.serial.sendAsciiAsBuffer(sendBuffer); + if (instruction == INST_WRITE && address == 2100 && length == 1 && value == 1) { + this.robotisBuffer = []; + } + } + return status; + } + })(); +})(); + +module.exports = Entry.RobotisRlaLite; diff --git a/src/playground/blocks/hardwareLite/metadata_robotis_rla_lite.json b/src/playground/blocks/hardwareLite/metadata_robotis_rla_lite.json new file mode 100644 index 0000000000..22dd14bcbe --- /dev/null +++ b/src/playground/blocks/hardwareLite/metadata_robotis_rla_lite.json @@ -0,0 +1,9 @@ +{ + "name": "RobotisRgeeLite", + "version": "1.0.0", + "type": "hardware", + "title": "로보티즈 알라", + "description": "로보티즈", + "imageName": "robotis_rla_lite", + "moduleId": "070901" +} From 70e978a5a3939789812f19d0bec5561a811451bc Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 10 Jun 2025 15:51:20 +0900 Subject: [PATCH 10/10] =?UTF-8?q?=EB=A1=9C=EB=B3=B4=ED=8B=B0=EC=A6=88=20?= =?UTF-8?q?=EA=BC=AD=EB=91=90=20=EB=B8=8C=EB=9D=BC=EC=9A=B0=EC=A0=80?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/hw_lite/robotis_kkokdu_lite.png | Bin 0 -> 24629 bytes .../hardwareLite/block_robotis_kkokdu_lite.js | 4488 +++++++++++++++++ .../metadata_robotis_kkokdu_lite.json | 9 + 3 files changed, 4497 insertions(+) create mode 100644 images/hw_lite/robotis_kkokdu_lite.png create mode 100644 src/playground/blocks/hardwareLite/block_robotis_kkokdu_lite.js create mode 100644 src/playground/blocks/hardwareLite/metadata_robotis_kkokdu_lite.json diff --git a/images/hw_lite/robotis_kkokdu_lite.png b/images/hw_lite/robotis_kkokdu_lite.png new file mode 100644 index 0000000000000000000000000000000000000000..0edba7f83d60fdbaab381e655e7b12dcde76e0c6 GIT binary patch literal 24629 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 literal 0 HcmV?d00001 diff --git a/src/playground/blocks/hardwareLite/block_robotis_kkokdu_lite.js b/src/playground/blocks/hardwareLite/block_robotis_kkokdu_lite.js new file mode 100644 index 0000000000..408327e07a --- /dev/null +++ b/src/playground/blocks/hardwareLite/block_robotis_kkokdu_lite.js @@ -0,0 +1,4488 @@ +'use strict'; + +const INST_NONE = 0; +const INST_READ = 2; +const INST_WRITE = 3; +const INST_DXL_REGWRITE = 4; +const INST_DXL_ACTION = 5; +const INST_DXL_SYNCWRITE = 0x83; +const INST_BYPASS_READ = 0xa2; +const INST_BYPASS_WRITE = 0xa3; + +const INST_STATUS = 0x55; + +const PACKET_STATE_IDLE = 0; +const PACKET_STATE_RESERVED = 1; +const PACKET_STATE_ID = 2; +const PACKET_STATE_LENGTH_L = 3; +const PACKET_STATE_LENGTH_H = 4; +const PACKET_STATE_DATA = 5; +const PACKET_STATE_CRC_L = 6; +const PACKET_STATE_CRC_H = 7; + +const DEFAULT_DELAY = 50; + +const rxPacket = { + header: [0, 0, 0], + reserved: 0, + id: 0, + cmd: 0, + error: 0, + type: 0, + index: 0, + packetLength: 0, + paramLength: 0, + crc: 0, + crcReceived: 0, + checksum: 0, + checksumReceived: 0, + data: [], +}; + +const addrMap = [ + [0, 4, 302], + [4, 1, 42], + [5, 1, 44], + [6, 1, 45], + [7, 1, 47], + [8, 1, 50], + [9, 1, 51], + [10, 1, 52], + [11, 1, 68], + [12, 2, 70], + [14, 2, 72], + [16, 2, 74], + [18, 2, 76], + [20, 2, 78], + [22, 2, 80], + [24, 2, 82], + [26, 2, 84], + [28, 1, 86], + [29, 1, 87], + [30, 2, 88], + [32, 2, 90], + [34, 1, 112], + [35, 1, 118], + [36, 1, 119], + [37, 1, 122], + [38, 1, 123], + [39, 1, 124], + [40, 1, 125], + [41, 1, 160], + [42, 1, 220], + [43, 2, 360], + [45, 2, 362], + [47, 2, 364], + [49, 2, 366], + [51, 2, 368], + [53, 2, 370], + [55, 1, 372], + [56, 1, 373], + [57, 1, 374], + [58, 1, 375], + [59, 1, 376], + [60, 1, 377], + [61, 1, 378], + [62, 1, 379], + [63, 1, 380], + [64, 1, 381], + [65, 1, 382], + [66, 1, 383], + [67, 1, 500], + [68, 1, 501], + [69, 8, 502], + [77, 1, 700], + [78, 1, 810], + [79, 1, 2134], + [80, 1, 5015], + [81, 1, 5030], + [82, 1, 5031], + [83, 1, 5040], +]; + +const addrMap2 = [ + [153, 1, 4000], + [154, 2, 4003], + [156, 1, 4005], + [157, 1, 4006], + [158, 2, 4009], + [160, 2, 4011], + [162, 2, 4013], + [164, 2, 4015], + [166, 2, 4017], + [168, 2, 4019], + [170, 2, 4021], + [172, 2, 4023], + [174, 2, 4025], + [176, 2, 4027], + [178, 1, 4031], + [179, 1, 4032], + [180, 1, 4033], + [181, 2, 4036], + [183, 2, 4038], + [185, 2, 4040], + [187, 2, 4042], + [189, 2, 4044], + [191, 2, 4046], + [193, 2, 4048], + [195, 2, 4050], +]; + +const crcTable = [ + 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, + 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, + 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, + 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, + 0x0088, 0x808d, 0x8087, 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, + 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0, 0x81e5, 0x81ef, 0x01ea, + 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, + 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179, + 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, + 0x0318, 0x831d, 0x8317, 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353, 0x0356, 0x035c, 0x8359, + 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, + 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9, + 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, + 0x02a8, 0x82ad, 0x82a7, 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, + 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243, 0x0246, 0x024c, 0x8249, + 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219, + 0x0208, 0x820d, 0x8207, 0x0202, +]; + +const rb100_last_valid_value = []; +let bg_color = 0; +let beat_per_minute = 75; +let camera_id_for_use = 0; + +(function () { + Entry.RobotisKkokduLite = new (class RobotisKkokduLite { + constructor() { + this.id = '070701'; + this.url = 'http://www.robotis.com'; + this.imageName = 'robotis_kkokdu_lite.png'; + this.name = 'RobotisKkokduLite'; + this.blockMenuBlocks = [ + // 다이나믹셀 제어 + 'robotis_kkokdu_lite_dxl_set_mode', + 'robotis_kkokdu_lite_dxl_set_position', + 'robotis_kkokdu_lite_dxl_set_rotate', + 'robotis_kkokdu_lite_dxl_set_multiturn_round', + + // 값 블록 + 'robotis_kkokdu_lite_cm_ir_value', + 'robotis_kkokdu_lite_cm_ir_compare', + 'robotis_kkokdu_lite_detectFrontObj', + 'robotis_kkokdu_lite_cm_btn_value', + 'robotis_kkokdu_lite_cm_joystick_value', + 'robotis_kkokdu_lite_mic', + 'robotis_kkokdu_lite_detectSound_compare', + 'robotis_kkokdu_lite_imu', + 'robotis_kkokdu_lite_roll_pitch', + + // 음계 + 'robotis_kkokdu_lite_buzzer_index', + + // LCD 제어 + 'robotis_kkokdu_lite_rgee_screen', + 'robotis_kkokdu_lite_rgee_anim_screen', + 'robotis_kkokdu_lite_icon', + 'robotis_kkokdu_lite_LCDBright', + 'robotis_kkokdu_lite_LCDColor', + + // LED 제어 + 'robotis_kkokdu_lite_led_brightness', + 'robotis_kkokdu_lite_led_pattern', + + + // 소리 + 'robotis_kkokdu_lite_Hello', + 'robotis_kkokdu_lite_effectSound', + 'robotis_kkokdu_lite_record', + 'robotis_kkokdu_lite_playRecord', + + // 다른 로봇 LCD 화면 제어 + 'robotis_kkokdu_lite_rla_screen', + 'robotis_kkokdu_lite_rla_anim_screen', + 'robotis_kkokdu_lite_kkokdu_screen', + 'robotis_kkokdu_lite_kkokdu_anim_screen', + + // 모션 제어 + 'robotis_kkokdu_lite_motion', + 'robotis_kkokdu_lite_motion_other', + 'robotis_kkokdu_lite_motion_custom', + 'robotis_kkokdu_lite_dxl_control', + 'robotis_kkokdu_lite_dxl_position_time', + + // 텍스트 출력 + 'robotis_kkokdu_lite_text_screen', + ]; + this.portData = { + baudRate: 57600, + dataBits: 8, + parity: 'none', + stopBits: 1, + connectionType: 'bytestream', + bufferSize: 128, + constantServing: true, + }; + this.duration = 15; + this.setZero(); + + this.timeouts = []; + + this.robotisBuffer = []; // buffer to transmit to H/W + this.receiveBuffer = []; // buffer to receive from H/W + this.dataBuffer = []; // saved control table value buffer + + this.packetReceiveState = 0; + this.headerCount = 0; + + this.dxlPositions = []; + + this.pirPir = []; + this.pirTemperature = []; + this.pirHumidity = []; + this.pirBrightness = []; + this.distanceDistance = []; + this.distanceButton = []; + this.distanceBrightness = []; + } + + setZero() { + this.timeouts = []; + this.__removeAllTimeouts(); + this.robotisBuffer = []; + this.robotisBuffer.push([INST_WRITE, 21, 2, 7]); // App Coding 모드 + this.robotisBuffer.push([INST_WRITE, 40, 2, 0]); // LED 끄기 + this.robotisBuffer.push([INST_WRITE, 66, 2, 0]); // 모션 종료 + this.robotisBuffer.push([INST_WRITE, 710, 2, 0]); // 바퀴 정지 + this.robotisBuffer.push([INST_WRITE, 21, 2, 20]); // App Coding 모드 + this.robotisBuffer.push([INST_WRITE, 19, 1, 1]); // bypass 모드 켜기 + camera_id_for_use = 0; + if (Entry.hwLite && Entry.hwLite.serial) { + Entry.hwLite.serial.update(); + } + } + + __removeTimeout(id) { + clearTimeout(id); + const idx = this.timeouts.indexOf(id); + if (idx >= 0) { + this.timeouts.splice(idx, 1); + } + } + + __removeAllTimeouts() { + const timeouts = this.timeouts; + for (const i in timeouts) { + clearTimeout(timeouts[i]); + } + this.timeouts = []; + } + + getMonitorPort() { + return { ...this.sensory, ...this.motoring, ...this.lineTracer }; + } + + writePacket(id, address, length, value) { + if (length > 256) { + console.log(`######### invalid length: ${length}`); + return null; + } + console.log('######### writePacket'); + const packet = []; + let i = 0; + packet.push(0xff); + packet.push(0xff); + packet.push(0xfd); + packet.push(0x00); + packet.push(id); + packet.push(length + 5); + packet.push(0x00); + packet.push(INST_WRITE); + packet.push(this.getLowByte(address)); + packet.push(this.getHighByte(address)); + switch (length) { + case 1: + packet.push(this.getLowByte(value)); + break; + case 2: + packet.push(this.getLowByte(value)); + packet.push(this.getHighByte(value)); + break; + case 4: + packet.push(this.getLowByte(this.getLowWord(value))); + packet.push(this.getHighByte(this.getLowWord(value))); + packet.push(this.getLowByte(this.getHighWord(value))); + packet.push(this.getHighByte(this.getHighWord(value))); + break; + default: + for (i = 0; i < length; i++) { + if (typeof value[i] == 'number') { + packet.push(value[i]); + } else if (typeof value[i] == 'string') { + packet.push(value[i].charCodeAt(0)); + } + } + break; + } + const crc = this.updateCRC(0, packet, packet.length); + packet.push(this.getLowByte(crc)); + packet.push(this.getHighByte(crc)); + return packet; + } + + registWritePacket(id, address, length, value) { + if (length > 256) { + console.log(`######### invalid length: ${length}`); + return null; + } + console.log('######### registWritePacket'); + const packet = []; + let i = 0; + packet.push(0xff); + packet.push(0xff); + packet.push(0xfd); + packet.push(0x00); + packet.push(id); + packet.push(length + 5); + packet.push(0x00); + packet.push(INST_DXL_REGWRITE); + packet.push(this.getLowByte(address)); + packet.push(this.getHighByte(address)); + switch (length) { + case 1: + packet.push(this.getLowByte(value)); + break; + case 2: + packet.push(this.getLowByte(value)); + packet.push(this.getHighByte(value)); + break; + case 4: + packet.push(this.getLowByte(this.getLowWord(value))); + packet.push(this.getHighByte(this.getLowWord(value))); + packet.push(this.getLowByte(this.getHighWord(value))); + packet.push(this.getHighByte(this.getHighWord(value))); + break; + default: + for (i = 0; i < length; i++) { + if (typeof value[i] == 'number') { + packet.push(value[i]); + } else if (typeof value[i] == 'string') { + packet.push(value[i].charCodeAt(0)); + } + } + break; + } + const crc = this.updateCRC(0, packet, packet.length); + packet.push(this.getLowByte(crc)); + packet.push(this.getHighByte(crc)); + return packet; + } + + actionPacket(id) { + console.log('######### actionPacket'); + const packet = []; + packet.push(0xff); + packet.push(0xff); + packet.push(0xfd); + packet.push(0x00); + packet.push(id); + packet.push(0x03); + packet.push(0x00); + packet.push(INST_DXL_ACTION); + const crc = this.updateCRC(0, packet, packet.length); + packet.push(this.getLowByte(crc)); + packet.push(this.getHighByte(crc)); + return packet; + } + + makeWord(a, b) { + return (a & 0xff) | ((b & 0xff) << 8); + } + + getLowByte(a) { + return a & 0xff; + } + + getHighByte(a) { + return (a >> 8) & 0xff; + } + + getLowWord(a) { + return a & 0xffff; + } + + getHighWord(a) { + return (a >> 16) & 0xffff; + } + + updateCRC(crcAccum, dataBlkPtr, dataBlkSize) { + let i = 0; + let j = 0; + let crc = crcAccum; + + for (j = 0; j < dataBlkSize; j++) { + i = ((crc >> 8) ^ dataBlkPtr[j]) & 0xff; + crc = (crc << 8) ^ crcTable[i]; + } + + return crc; + } + + makeWord(a, b) { + return (a & 0xff) | ((b & 0xff) << 8); + } + + getLowByte(a) { + return a & 0xff; + } + + getHighByte(a) { + return (a >> 8) & 0xff; + } + + getLowWord(a) { + return a & 0xffff; + } + + getHighWord(a) { + return (a >> 16) & 0xffff; + } + + updateCRC(crcAccum, dataBlkPtr, dataBlkSize) { + let i = 0; + let j = 0; + let crc = crcAccum; + + for (j = 0; j < dataBlkSize; j++) { + i = ((crc >> 8) ^ dataBlkPtr[j]) & 0xff; + crc = (crc << 8) ^ crcTable[i]; + } + + return crc; + } + + removeStuffing(buffer, length) { + let i = 0; + let stuffLength = 0; + let index = 0; + + for (i = 0; i < length; i++) { + if (i >= 2) { + if (buffer[i - 2] == 0xff && buffer[i - 1] == 0xff && buffer[i] == 0xfd) { + i++; + stuffLength++; + } + } + buffer[index++] = buffer[i]; + } + + return stuffLength; + } + + postCallReturn(script, data, ms) { + /* + if (data == null) { + Entry.engine.isContinue = false; + return script.callReturn(); + } else if (data.length == 0) { + Entry.engine.isContinue = false; + return script.callReturn(); + } + */ + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + for (let i = 0; i < data.length; i++) { + this.robotisBuffer.push(data[i]); + } + //delay ms + setTimeout(() => { + script.timeFlag = 0; + }, ms); + return script; + } else if (script.timeFlag) { + return script; + } else { + delete script.isStart; + delete script.timeFlag; + Entry.engine.isContinue = false; + return script.callReturn(); + } + } + + setLanguage() { + return { + ko: { + template: { + // DXL 제어 + robotis_kkokdu_lite_dxl_set_mode: "%1 모터 %2 모드로 설정 %3", + robotis_kkokdu_lite_dxl_each_control: "%1 모터 %2°로 %3 초 동안 움직이기 %4", + robotis_kkokdu_lite_dxl_set_position: "%1 모터 %2 속도로 %3° 위치로 회전 %4", + robotis_kkokdu_lite_dxl_set_rotate: "%1 모터 %2 속도로 %3 으로 %4 %5", + robotis_kkokdu_lite_dxl_set_multiturn_round: + '%1 모터 %2 속도로 %3 바퀴 %4으로 회전 %5', + + // 값 블록 + robotis_kkokdu_lite_cm_ir_value: '%1 번 IR 센서 값', + robotis_kkokdu_lite_cm_ir_compare: '%1 번 IR 센서 값이 %2 %3이면', + robotis_kkokdu_lite_detectFrontObj: '앞에 물체가 있으면', + robotis_kkokdu_lite_cm_btn_value: '%1 버튼이 %2 이면', + robotis_kkokdu_lite_cm_joystick_value: + '조이스틱 위치가 %1 이면', + robotis_kkokdu_lite_mic: '마이크 음량(dB)', + robotis_kkokdu_lite_detectSound_compare: '소리가 %1에서 나면', + robotis_kkokdu_lite_imu: '%1축의 %2 값', + robotis_kkokdu_lite_roll_pitch: '제어기 각도 %1 값', + + // 음계 + robotis_kkokdu_lite_buzzer_index: '제어기 음계값 %1 을(를) %2 옥타브로 %3 초 동안 %4 %5', + + // LCD 제어 + robotis_kkokdu_lite_rla_screen: '제어기 화면 배경을 알라 %1 (으)로 선택 %2', + robotis_kkokdu_lite_rla_anim_screen: + '제어기 화면 애니메이션을 알라 %1 (으)로 선택 %2', + robotis_kkokdu_lite_icon: + "제어기 화면에 %1 출력하기 %5", + robotis_kkokdu_lite_LCDBright: '제어기 화면 밝기를 %1 (으)로 정하기 %2', + robotis_kkokdu_lite_LCDColor: '제어기 화면 색상을 %1 (으)로 정하기 %2', + + // LED 제어 + robotis_kkokdu_lite_led_brightness: '제어기 %1 LED 밝기를 %2(으)로 정하기 %3', + robotis_kkokdu_lite_led_pattern: '제어기 %1 LED %2 %3', + + // 소리 + robotis_kkokdu_lite_Hello: '%1 말하기 %2', + robotis_kkokdu_lite_effectSound: '효과음 %1 재생하기 %2', + robotis_kkokdu_lite_record: '%1 번 방에 녹음하기 %2', + robotis_kkokdu_lite_playRecord: '%1 번 방 소리 재생하기 %2', + + // 다른 로봇 LCD 제어 + robotis_kkokdu_lite_rgee_screen: '제어기 화면 배경을 알쥐 %1 (으)로 선택 %2', + robotis_kkokdu_lite_rgee_anim_screen: + '제어기 화면 애니메이션을 알쥐 %1 (으)로 선택 %2', + robotis_kkokdu_lite_kkokdu_screen: '제어기 화면 배경을 꼭두 %1 (으)로 선택 %2', + robotis_kkokdu_lite_kkokdu_anim_screen: + '제어기 화면 애니메이션을 꼭두 %1 (으)로 선택 %2', + robotis_kkokdu_lite_text_screen: + '제어기 화면에 %1을(를) (%2, %3)위치에 %4 로 %5(으)로 출력하기 %6', + + + // 모션 & DXL 제어 + robotis_kkokdu_lite_motion: "휴머노이드 이동 모션 %1 실행 %2", + robotis_kkokdu_lite_motion_other: "휴머노이드 기타 모션 %1 실행 %2", + robotis_kkokdu_lite_motion_custom: "휴머노이드 커스텀 모션 %1 실행 %2", + robotis_kkokdu_lite_dxl_control: "1번 모터 %1° 2번 모터 %2° 3번 모터 %3° 4번 모터 %4° 5번 모터 %5° 6번 모터 %6° 7번 모터 %7° 8번 모터 %8° %9초 동안 움직이기 %10", + robotis_kkokdu_lite_dxl_position_time: "%1 모터 %2° %3 초 동안 움직이기 %4", + }, + Helper: { + // DXL 제어 + robotis_kkokdu_lite_dxl_set_mode: "지정한 ID의 모터의 동작모드를 설정", + robotis_kkokdu_lite_dxl_set_position: "지정한 ID의 모터가 지정한 속도로 지정한 각도로 움직이도록 설정", + robotis_kkokdu_lite_dxl_set_rotate: "지정한 ID의 모터의 회전 속도와 방향을 설정", + robotis_kkokdu_lite_dxl_set_multiturn_round: + '지정한 ID의 모터가 지정한 속도와 방향으로 지정한 바퀴만큼 회전', + + // 값 블록 + robotis_kkokdu_lite_cm_ir_value: + '지정한 번호의 IR 센서 값(범위: 0 ~ 400)', + robotis_kkokdu_lite_cm_ir_compare: + "지정한 번호의 IR 센서 값과 지정한 값의 비교식이 맞으면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_kkokdu_lite_detectFrontObj: + "지정한 센서 앞에 물체가 감지되면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_kkokdu_lite_cm_btn_value: + "지정한 버튼이 눌렸다가 해제되면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_kkokdu_lite_cm_joystick_value: + "조이스틱 위치가 지정한 상태이면 '참', 아니면 '거짓'으로 판단합니다..", + robotis_kkokdu_lite_mic: + '마이크로 감지된 소리의 세기를 데시벨(dB)로 표시합니다.', + robotis_kkokdu_lite_detectSound_compare: + "소리가 나는 방향이 지정한 방향과 동일하면 '참', 아니면 '거짓'으로 판단합니다.", + robotis_kkokdu_lite_imu: + '지정한 축의 지정한 가속도센서/자이로센서의 값\n범위: -100 ~ 100', + robotis_kkokdu_lite_roll_pitch: + 'roll/pitch 값\nroll: -180° ~ 180°, pitch: -90° ~ 90°', + + // 소리 + robotis_kkokdu_lite_buzzer_index: '지정한 음계, 옥타브, 시간만큼 연주하기', + + // LCD 제어 + robotis_kkokdu_lite_rgee_screen: '제어기 화면배경을 알쥐의 지정한 표정으로 설정', + robotis_kkokdu_lite_rgee_anim_screen: + '제어기 화면 애니메이션을 알쥐의 지정한 표정으로 설정', + robotis_kkokdu_lite_icon: + '화면 중앙에 지정한 아이콘을 표시', + robotis_kkokdu_lite_LCDBright: '화면 밝기를 설정\n밝기범위: 1% ~ 100%', + robotis_kkokdu_lite_LCDColor: '화면 색상을 설정', + + // LED 제어 + robotis_kkokdu_lite_led_brightness: '제어기의 지정한 LED의 밝기를 설정정', + robotis_kkokdu_lite_led_pattern: '제어기의 LED의 깜박임 패턴 설정', + + // 소리 + robotis_kkokdu_lite_Hello: '지정한 문장을 말하기', + robotis_kkokdu_lite_effectSound: '지정한 효과음 재생하기', + robotis_kkokdu_lite_record: '제어기의 지정한 번호에 녹음하기', + robotis_kkokdu_lite_playRecord: '제어기의 지정한 번호의 녹음음성 재생하기기', + + // 다른 로봇 LCD 제어 + robotis_kkokdu_lite_rla_screen: '제어기 화면배경을 알라의 지정한 표정으로 설정', + robotis_kkokdu_lite_rla_anim_screen: + '제어기 화면 애니메이션을 알라의 지정한 표정으로 설정', + robotis_kkokdu_lite_kkokdu_screen: '제어기 화면배경을 꼭두의 지정한 표정으로 설정', + robotis_kkokdu_lite_kkokdu_anim_screen: + '제어기 화면 애니메이션을 꼭두두의 지정한 표정으로 설정', + robotis_kkokdu_lite_text_screen: + '화면에 지정한 문구를 표시할 위치와 폰트크기, 색상을 설정\nX좌표: -160 ~ 160\nY좌표: -120 ~ 120', + + // 모션 제어 + robotis_kkokdu_lite_motion: "지정한 이동 모션 실행", + robotis_kkokdu_lite_motion_other: "지정한 기타 모션 실행", + robotis_kkokdu_lite_motion_custom: "지정한 번호의 모션 실행", + robotis_kkokdu_lite_dxl_control: "1 ~ 8번 관절을 각각 지정한 위치로 지정한 시간내에 이동", + robotis_kkokdu_lite_dxl_position_time: "지정한 관절을 지정한 시간동안 지정한 위치로 이동", + }, + Blocks: { + robotis_white: "흰색", + robotis_gray: "회색", + robotis_darkgray: "진회색", + robotis_black: "검정", + robotis_purple: "보라", + robotis_pink: "분홍색", + robotis_red: "빨강", + robotis_orange: "주황", + robotis_brown: "갈색", + robotis_yellow: "노랑", + robotis_green: "초록", + robotis_blue: "파랑", + robotis_lightblue: "연파랑", + robotis_darkblue: "남색", + robotis_left: "왼쪽", + robotis_center: "중앙", + robotis_right: "오른쪽", + robotis_both: "양쪽", + robotis_korean1: "안녕하세요", + robotis_korean2: "반가워요", + robotis_korean3: "알겠어요", + robotis_korean4: "아니에요", + robotis_korean5: "모르겠어요", + robotis_korean6: "좋아요", + robotis_korean7: "싫어요", + robotis_korean8: "이름을말하세요", + robotis_korean9: "무엇을도와줄까?", + robotis_korean10: "잘했어", + robotis_korean11: "괜찮아", + robotis_korean12: "다시해보자", + robotis_korean13: "고마워", + robotis_korean14: "다시말해줄래?", + robotis_korean15: "최고야!", + robotis_korean16: "신나요", + robotis_korean17: "즐거워요", + robotis_korean18: "미안해요", + robotis_korean19: "화나요", + robotis_korean20: "부끄러워요", + robotis_korean21: "무서워요", + robotis_korean22: "속상해요", + robotis_korean23: "사랑해요", + robotis_korean24: "예뻐요", + robotis_korean25: "신기해요", + robotis_korean26: "초조해요", + robotis_korean27: "앞으로가자", + robotis_korean28: "뒤로가자", + robotis_korean29: "일어나자", + robotis_korean30: "넘어졌네?", + robotis_korean31: "오예", + robotis_korean32: "아싸", + robotis_korean33: "어머", + robotis_korean34: "이런", + robotis_korean35: "오호", + robotis_korean36: "하하하", + robotis_korean37: "호호호", + robotis_korean38: "졸려", + robotis_korean39: "자장가를들려줘", + robotis_korean40: "안녕", + robotis_korean41: "배고프다", + robotis_korean42: "도토리땡긴다", + robotis_korean43: "아.씻고싶어", + robotis_korean44: "비누목욕시간이야", + robotis_korean45: "심심한데", + robotis_korean46: "간식먹을까", + robotis_korean47: "아파요", + robotis_korean48: "약은없나요?", + robotis_korean49: "어디로가야하지?", + robotis_korean50: "와아도착이다", + robotis_korean51: "왼쪽으로가자", + robotis_korean52: "오른쪽으로가자", + robotis_korean53: "깜짝이야", + robotis_korean54: "찾았다", + robotis_korean55: "여긴없네", + robotis_korean56: "혹시나불렀어?", + robotis_korean57: "내려주세요", + robotis_korean58: "앗", + robotis_korean59: "힝", + robotis_korean60: "이익", + robotis_dog: "개", + robotis_frog: "개구리", + robotis_cat: "고양이", + robotis_chicken: "닭", + robotis_tiger: "호랑이", + robotis_mouse: "쥐", + robotis_ambul: "앰뷸런스", + robotis_Horn: "경적(빵빵)", + robotis_siren: "사이렌(경찰차)", + robotis_whistle: "호루라기", + robotis_gun: "총소리", + robotis_clap: "박수소리", + robotis_melody1: "멜로디1", + robotis_melody2: "멜로디2", + robotis_melody3: "멜로디3", + robotis_melody4: "멜로디4", + robotis_forward: "앞으로", + robotis_backward: "뒤로", + robotis_acceleration: "가속도", + robotis_gyro: "자이로", + robotis_run: "실행", + robotis_cancel: "취소", + robotis_push: "눌림", + robotis_notPush: "안눌림", + robotis_play: "연주", + robotis_rest: "쉼표", + robotis_face01: "와하하", + robotis_face02: "싱글벙글", + robotis_face03: "큭큭큭", + robotis_face04: "냠냠", + robotis_face05: "겁먹음", + robotis_face06: "답답", + robotis_face07: "갸우뚱", + robotis_face08: "어벙벙", + robotis_face09: "고함", + robotis_face10: "화남", + robotis_face11: "킁킁(왼쪽)", + robotis_face12: "킁킁(오른쪽)", + robotis_face13: "킁킁(아래)", + robotis_face14: "안심", + robotis_face15: "기절", + robotis_face16: "헤롱헤롱", + robotis_face17: "하품", + robotis_face18: "졸림", + robotis_face19: "잠듦", + robotis_face20: "마음앓이", + robotis_face21: "폭풍눈물", + robotis_face22: "목욕", + robotis_face23: "햐트뿅뿅", + + robotis_car_anim01: "기본 표정", + robotis_car_anim02: "감동", + robotis_car_anim03: "미소", + robotis_car_anim04: "웃음", + robotis_car_anim05: "기쁨", + robotis_car_anim06: "행복", + robotis_car_anim07: "자신감", + robotis_car_anim08: "화남", + robotis_car_anim09: "우울", + robotis_car_anim10: "슬픔", + robotis_car_anim11: "고통", + robotis_car_anim12: "기절", + robotis_car_anim13: "공포", + robotis_car_anim14: "하품", + robotis_car_anim15: "졸림", + robotis_car_anim16: "오른쪽보기", + robotis_car_anim17: "왼쪽보기", + robotis_car_anim18: "앞쪽보기", + robotis_car_anim19: "깜짝놀람", + + robotis_flashing1: "점멸1", + robotis_flashing2: "점멸2", + robotis_flashing3: "점멸3", + robotis_flashing4: "점멸4", + robotis_flashing5: "점멸5", + robotis_flashing6: "점멸6", + robotis_flashing7: "점멸7", + robotis_flashing8: "점멸8", + robotis_flashing9: "점멸9", + robotis_moveF: "전진", + robotis_moveB: "후진", + robotis_moveL: "좌회전", + robotis_moveR: "우회전", + robotis_moveU: 'U턴', + robotis_moveL_in_place: '제자리 좌회전', + robotis_moveR_in_place: '제자리 우회전', + robotis_moveU_in_place: '제자리 U턴', + robotis_moveRG1: "일어서기", + robotis_moveRG2: "앉기", + robotis_moveRG3: "발버둥", + robotis_moveRG4: "발들기", + robotis_stMotion1: "기본자세", + robotis_stMotion2: "전진", + robotis_stMotion3: "우전진", + robotis_stMotion4: "좌전진", + robotis_stMotion5: "후진", + robotis_stMotion6: "오른쪽으로", + robotis_stMotion7: "왼쪽으로", + robotis_stMotion8: "우회전", + robotis_stMotion9: "좌회전", + robotis_spMotion1: "오른손 들기", + robotis_spMotion2: "오른손 내리기", + robotis_spMotion3: "왼손 들기", + robotis_spMotion4: "왼손 내리기", + robotis_spMotion5: "양손 들기", + robotis_spMotion6: "양손 내리기", + robotis_spMotion7: "뒤로 넘어지기", + robotis_spMotion8: "앞으로 넘어지기", + robotis_spMotion9: "앞으로 일어서기", + robotis_spMotion10: "뒤로 일어서기", + robotis_spMotion11: "방어", + robotis_spMotion12: "공격1", + robotis_spMotion13: "공격2", + robotis_spMotion14: "공격3", + robotis_spMotion15: "공격4", + robotis_screen1: "가위", + robotis_screen2: "바위", + robotis_screen3: "보", + robotis_clockwise: "시계방향", + robotis_counterclockwise: "반시계방향", + robotis_up: "들기", + robotis_down: "내리기", + robotis_screen_text_font_small: "작은 폰트", + robotis_screen_text_font_big: "큰 폰트", + robotis_sensing_temperature: "온도센서", + robotis_sensing_humidity: "습도센서", + robotis_sensing_brightness: "밝기센서", + robotis_sensing_motion: "움직임센서", + robotis_sensing_button: "버튼센서", + robotis_sensing_distance: "거리센서", + robotis_sensing_ir_left: "왼쪽 적외선센서", + robotis_sensing_ir_right: "오른쪽 적외선센서", + robotis_stage_1: "1단계", + robotis_stage_2: "2단계", + robotis_stage_3: "3단계", + }, + }, + en: { + template: { + // DXL 제어 + robotis_kkokdu_lite_dxl_set_mode: "Set ID %1 motor as %2 mode %3", + robotis_kkokdu_lite_dxl_set_position: "Rotate ID %1 motor to angle %3° at speed %2 %4", + robotis_kkokdu_lite_dxl_set_rotate: "%4 ID %1 motor %3 at speed %2 %4", + robotis_kkokdu_lite_dxl_set_multiturn_round: + 'Rotate ID %1 motor %3 times %4 at speed %2 %5', + + // Value Blocks + robotis_kkokdu_lite_cm_ir_value: 'IR sensor value of No. %1', + robotis_kkokdu_lite_cm_ir_compare: 'If the IR sensor value of No. %1 is %2 %3', + robotis_kkokdu_lite_detectFrontObj: 'If there is an object in front', + robotis_kkokdu_lite_cm_btn_value: 'If button %1 is %2', + robotis_kkokdu_lite_cm_joystick_value: 'If joystick is at %1', + robotis_kkokdu_lite_mic: 'Microphone volume (dB)', + robotis_kkokdu_lite_detectSound_compare: 'If the sound comes from %1', + robotis_kkokdu_lite_imu: '%2 value of %1 axis', + robotis_kkokdu_lite_roll_pitch: 'Controller angle %1 value', + + // Musical Scale + robotis_kkokdu_lite_buzzer_index: 'Play note %1 on controller in octave %2 for %3 seconds %4 %5', + + // LCD Control + robotis_kkokdu_lite_rgee_screen: 'Set controller screen background to R-Gee %1 %2', + robotis_kkokdu_lite_rgee_anim_screen: 'Set controller screen animation to R-Gee %1 %2', + robotis_kkokdu_lite_icon: 'Display %1 on controller screen %5', + robotis_kkokdu_lite_LCDBright: 'Set controller screen brightness to %1 %2', + robotis_kkokdu_lite_LCDColor: 'Set controller screen color to %1 %2', + + // LED Control + robotis_kkokdu_lite_led_brightness: 'Set controller LED %1 brightness to %2 %3', + robotis_kkokdu_lite_led_pattern: 'Controller LED %1 %2 %3', + + // Sound + robotis_kkokdu_lite_Hello: 'Say "%1" %2', + robotis_kkokdu_lite_effectSound: 'Play sound effect %1 %2', + robotis_kkokdu_lite_record: 'Record in slot %1 %2', + robotis_kkokdu_lite_playRecord: 'Play sound from slot %1 %2', + + // Other Robot LCD Control + robotis_kkokdu_lite_rla_screen: 'Set controller screen background to Kodala %1 %2', + robotis_kkokdu_lite_rla_anim_screen: 'Set controller screen animation to Kodala %1 %2', + robotis_kkokdu_lite_kkokdu_screen: 'Set controller screen background to TIG %1 %2', + robotis_kkokdu_lite_kkokdu_anim_screen: 'Set controller screen animation to TIG %1 %2', + robotis_kkokdu_lite_text_screen: 'Display "%1" on screen at (%2, %3) with font %4 and color %5 %6', + + // Motion & DXL Control + robotis_kkokdu_lite_motion: "Execute humanoid movement motion %1 %2", + robotis_kkokdu_lite_motion_other: "Execute humanoid other motion %1 %2", + robotis_kkokdu_lite_motion_custom: "Execute humanoid custom motion %1 %2", + robotis_kkokdu_lite_dxl_control: "Move motor 1 to %1°, motor 2 to %2°, motor 3 to %3°, motor 4 to %4°, motor 5 to %5°, motor 6 to %6°, motor 7 to %7°, motor 8 to %8° over %9 seconds %10", + robotis_kkokdu_lite_dxl_position_time: "Move motor %1 to %2° over %3 seconds %4", + + }, + Helper: { + // DXL 제어 + robotis_kkokdu_lite_dxl_set_mode: "Set the operating mode of the motor with the specified ID", + robotis_kkokdu_lite_dxl_set_position: "Set the motor with the specified ID to move to the specified angle at the specified speed", + robotis_kkokdu_lite_dxl_set_rotate: "Set the rotation speed and direction of the motor with the specified ID", + robotis_kkokdu_lite_dxl_set_multiturn_round: + 'Set the motor with the specified ID to rotate the specified number of turns at the specified speed and direction', + + // Value blocks + robotis_kkokdu_lite_cm_ir_value: 'IR sensor value of the specified number (Range: 0 ~ 400)', + robotis_kkokdu_lite_cm_ir_compare: "Returns 'true' if the comparison of the IR sensor value of the specified number and the given value is correct; otherwise returns 'false'.", + robotis_kkokdu_lite_detectFrontObj: "Returns 'true' if an object is detected in front of the specified sensor; otherwise returns 'false'.", + robotis_kkokdu_lite_cm_btn_value: "Returns 'true' if the specified button was pressed and released; otherwise returns 'false'.", + robotis_kkokdu_lite_cm_joystick_value: "Returns 'true' if the joystick position matches the specified state; otherwise returns 'false'.", + robotis_kkokdu_lite_mic: 'Displays the intensity of sound detected by the microphone in decibels (dB).', + robotis_kkokdu_lite_detectSound_compare: "Returns 'true' if the direction of the sound matches the specified direction; otherwise returns 'false'.", + robotis_kkokdu_lite_imu: 'Value of the specified axis of the accelerometer/gyroscope sensor\nRange: -100 ~ 100', + robotis_kkokdu_lite_roll_pitch: 'Roll/pitch values\nRoll: -180° ~ 180°, Pitch: -90° ~ 90°', + + // Sound + robotis_kkokdu_lite_buzzer_index: 'Play the specified scale, octave, and duration', + + // LCD control + robotis_kkokdu_lite_rgee_screen: 'Set the controller screen background to the specified R-Gee expression', + robotis_kkokdu_lite_rgee_anim_screen: 'Set the controller screen animation to the specified R-Gee expression', + robotis_kkokdu_lite_icon: 'Display the specified icon at the center of the screen', + robotis_kkokdu_lite_LCDBright: 'Set the screen brightness\nBrightness range: 1% ~ 100%', + robotis_kkokdu_lite_LCDColor: 'Set the screen color', + + // LED control + robotis_kkokdu_lite_led_brightness: 'Set the brightness of the specified LED on the controller', + robotis_kkokdu_lite_led_pattern: 'Set the blinking pattern of the LED on the controller', + + // Sound + robotis_kkokdu_lite_Hello: 'Speak the specified sentence', + robotis_kkokdu_lite_effectSound: 'Play the specified sound effect', + robotis_kkokdu_lite_record: 'Record on the specified number of the controller', + robotis_kkokdu_lite_playRecord: 'Play the recorded voice of the specified number on the controller', + + // Other robot LCD control + robotis_kkokdu_lite_rla_screen: 'Set the controller screen background to the specified expression of R-LA', + robotis_kkokdu_lite_rla_anim_screen: 'Set the controller screen animation to the specified expression of R-LA', + robotis_kkokdu_lite_kkokdu_screen: 'Set the controller screen background to the specified expression of Kkokdu', + robotis_kkokdu_lite_kkokdu_anim_screen: 'Set the controller screen animation to the specified expression of Kkokdu', + robotis_kkokdu_lite_text_screen: 'Set the location, font size, and color of the specified phrase to be displayed on the screen\nX coordinate: -160 ~ 160\nY coordinate: -120 ~ 120', + + + // Motion & DXL control + robotis_kkokdu_lite_motion: "Execute specified movement motion", + robotis_kkokdu_lite_motion_other: "Execute specified other motion", + robotis_kkokdu_lite_motion_custom: "Execute motion with specified number", + robotis_kkokdu_lite_dxl_control: "Move joints 1 to 8 to specified positions within specified time", + robotis_kkokdu_lite_dxl_position_time: "Move specified joint to specified position over specified time", + + }, + + Blocks: { + robotis_white: 'White', + robotis_gray: 'Gray', + robotis_darkgray: 'Darkgray', + robotis_black: 'Black', + robotis_purple: 'Purple', + robotis_pink: 'Pink', + robotis_red: 'Red', + robotis_orange: 'Orange', + robotis_brown: 'Brown', + robotis_yellow: 'Yellow', + robotis_green: 'Green', + robotis_blue: 'Blue', + robotis_lightblue: 'Lightblue', + robotis_darkblue: 'Darkblue', + robotis_brown: 'Brown', + robotis_left: 'Left', + robotis_center: 'Center', + robotis_right: 'Right', + robotis_both: 'Both', + + robotis_rla: 'R-GEE', + robotis_rla: 'KODALA', + robotis_kkokdu: 'TIG', + + robotis_korean1: 'Hello!', + robotis_korean2: 'Great to see you.', + robotis_korean3: 'Okay ~', + robotis_korean4: 'No!', + robotis_korean5: "I don't know.", + robotis_korean6: 'I like it.', + robotis_korean7: "I don't like it.", + robotis_korean8: 'What is your name? ', + robotis_korean9: 'How can I help you? ', + robotis_korean10: 'Great job! ', + robotis_korean11: "It's alright.", + robotis_korean12: "Let's do it again! ", + robotis_korean13: 'Thank you! ', + robotis_korean14: 'Can you say that one more time?', + robotis_korean15: 'Awesome!', + robotis_korean16: "I'm excited! ", + robotis_korean17: "I'm having a great time! ", + robotis_korean18: "I'm sorry.", + robotis_korean19: "I'm angry! ", + robotis_korean20: "I'm embarassed.", + robotis_korean21: "I'm scared.", + robotis_korean22: "I'm upset.", + robotis_korean23: 'I love you.', + robotis_korean24: 'Very pretty! ', + robotis_korean25: 'Interesting.', + robotis_korean26: "I'm nervous.", + robotis_korean27: "Let's move forward! ", + robotis_korean28: "Let's move backward! ", + robotis_korean29: "Let's stand up! ", + robotis_korean30: 'Did you fall down? ', + robotis_korean31: 'Oh Yeah~', + robotis_korean32: 'Sweet! ', + robotis_korean33: 'Oh no', + robotis_korean34: 'My My ', + robotis_korean35: 'Whoo hoo! ', + robotis_korean36: 'Ha Ha Ha', + robotis_korean37: 'Ho Ho Ho ', + robotis_korean38: "I'm sleepy.", + robotis_korean39: 'Sing me a bedtime song! ', + robotis_korean40: 'Hello!', + robotis_korean41: "I'm hungry.", + robotis_korean42: "I'm craving an acorn! ", + robotis_korean43: 'I want to take a bath! ', + robotis_korean44: 'Time for a bath! ', + robotis_korean45: "I'm bored. ", + robotis_korean46: 'Do you want a snack? ', + robotis_korean47: "I'm sick.", + robotis_korean48: 'Do you have any medicine? ', + robotis_korean49: 'Where do we have to go? ', + robotis_korean50: "We're here! ", + robotis_korean51: "Let's go to the left side! ", + robotis_korean52: "Let's go to the right side! ", + robotis_korean53: 'Oh my, you scared me! ', + robotis_korean54: 'Found you! ', + robotis_korean55: "There's nothing here. ", + robotis_korean56: 'Did you call me?', + robotis_korean57: 'Please let me down. ', + robotis_korean58: 'Oops! ', + robotis_korean59: 'Hmmph! ', + robotis_korean60: 'Eek! ', + robotis_dog: 'Dog', + robotis_frog: 'Frog', + robotis_cat: 'Cat', + robotis_chicken: 'Rooster', + robotis_tiger: 'Tiger', + robotis_mouse: 'Mouse', + robotis_whistle: 'Whistle', + robotis_ambul: 'Ambulance', + robotis_Horn: 'CarHorn', + robotis_siren: 'Siren', + robotis_gun: 'Gunshot', + robotis_clap: 'Clap', + robotis_melody1: 'Melody1', + robotis_melody2: 'Melody2', + robotis_melody3: 'Melody3', + robotis_melody4: 'Melody4', + robotis_forward: 'Forward', + robotis_backward: 'Backward', + robotis_acceleration: 'acceleration', + robotis_gyro: 'gyro', + robotis_run: 'Run', + robotis_cancel: 'Cancel', + robotis_push: 'Pressed', + robotis_notPush: 'Unpressed', + robotis_play: 'Play', + robotis_rest: 'Rest', + robotis_face01: 'Haha', + robotis_face02: 'Smile', + robotis_face03: 'Laugh', + robotis_face04: 'Yum Yum', + robotis_face05: 'Scared', + robotis_face06: 'Uncomfortable', + robotis_face07: 'Confused', + robotis_face08: 'Dazed', + robotis_face09: 'Yell', + robotis_face10: 'Angry', + robotis_face11: 'Sniff (Left)', + robotis_face12: 'Sniff (Right)', + robotis_face13: 'Sniff (Down)', + robotis_face14: 'Whew', + robotis_face15: 'Faint', + robotis_face16: 'Dizzy', + robotis_face17: 'Yawn', + robotis_face18: 'Sleepy', + robotis_face19: 'Sleep', + robotis_face20: 'Sad', + robotis_face21: 'Cry', + robotis_face22: 'Bath', + robotis_face23: 'Heart-Eyes', + + robotis_car_anim01: "Default", + robotis_car_anim02: "Touched", + robotis_car_anim03: "Smile", + robotis_car_anim04: "Laugh", + robotis_car_anim05: "Joy", + robotis_car_anim06: "Happiness", + robotis_car_anim07: "Confidence", + robotis_car_anim08: "Anger", + robotis_car_anim09: "Depressed", + robotis_car_anim10: "Sadness", + robotis_car_anim11: "Pain", + robotis_car_anim12: "Fainting", + robotis_car_anim13: "Fear", + robotis_car_anim14: "Yawn", + robotis_car_anim15: "Sleepy", + robotis_car_anim16: "Looking Right", + robotis_car_anim17: "Looking Left", + robotis_car_anim18: "Looking Forward", + robotis_car_anim19: "Surprised", + + + robotis_flashing1: "Flashing1", + robotis_flashing2: "Flashing2", + robotis_flashing3: "Flashing3", + robotis_flashing4: "Flashing4", + robotis_flashing5: "Flashing5", + robotis_flashing6: "Flashing6", + robotis_flashing7: "Flashing7", + robotis_flashing8: "Flashing8", + robotis_flashing9: "Flashing9", + + + + robotis_moveF: 'Forward', + robotis_moveB: 'Backward', + robotis_moveL: 'LeftTurn', + robotis_moveR: 'RightTurn', + robotis_moveU: 'U-turn', + robotis_moveL_in_place: 'Turn left in place', + robotis_moveR_in_place: 'Trun right in place', + robotis_moveU_in_place: 'U-turn in place', + robotis_moveRG1: 'Stand', + robotis_moveRG2: 'Sit', + robotis_moveRG3: 'Struggle', + robotis_moveRG4: 'RaiseFeet', + robotis_fast: 'Fast', + robotis_normal: 'Normal', + robotis_slow: 'Slow', + robotis_stop: 'Stop', + robotis_roll: 'Left-right rotate angle (roll)', + robotis_pitch: 'Forward-backward rotate angle (pitch)', + robotis_stMotion1: 'Standard', + robotis_stMotion2: 'Forward', + robotis_stMotion3: 'TurnRight', + robotis_stMotion4: 'TurnLeft', + robotis_stMotion5: 'Backward', + robotis_stMotion6: 'ToRight', + robotis_stMotion7: 'ToLeft', + robotis_stMotion8: 'TurnAroundRight', + robotis_stMotion9: 'TurnAroundLeft', + robotis_spMotion1: 'RightHandUp', + robotis_spMotion2: 'RightHandDown', + robotis_spMotion3: 'LeftHandUp', + robotis_spMotion4: 'LeftHandDown', + robotis_spMotion5: 'BothHandsUp', + robotis_spMotion6: 'BothHandsDown', + robotis_spMotion7: 'FallBackward', + robotis_spMotion8: 'FallForward', + robotis_spMotion9: 'StandForward', + robotis_spMotion10: 'StandBackward', + robotis_spMotion11: 'Defence', + robotis_spMotion12: 'Offense1', + robotis_spMotion13: 'Offense2', + robotis_spMotion14: 'Offense3', + robotis_spMotion15: 'Offense4', + robotis_screen1: 'Sissor', + robotis_screen2: 'Rock', + robotis_screen3: 'Paper', + robotis_clockwise: "clockwise", + robotis_counterclockwise: "counterclockwise", + robotis_up: "up", + robotis_down: "down", + robotis_screen_text_font_small: "Small font", + robotis_screen_text_font_big: "Big font", + robotis_stage_1: "Stage 1", + robotis_stage_2: "Stage 2", + robotis_stage_3: "Stage 3", + }, + }, + }; + } + getBlocks() { + return { + robotis_kkokdu_lite_dxl_set_mode: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['ID 1', '1'], + ['ID 2', '2'], + ['ID 3', '3'], + ['ID 4', '4'], + ['ID 5', '5'], + ['ID 6', '6'], + ['ID 7', '7'], + ['ID 8', '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dxl_mode_joint, '3'], + [Lang.Blocks.robotis_dxl_mode_wheel, '1'], + [Lang.Blocks.robotis_dxl_mode_multi_turn, '4'], + ], + value: '3', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: ['1', null, null], + type: 'robotis_kkokdu_lite_dxl_set_mode', + }, + paramsKeyMap: { + DXL_ID: 0, + DXL_MODE: 1, + }, + class: 'robotis_kkokdu_lite_dxl', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let dxl_id = script.getNumberValue('DXL_ID', script); + let dxl_mode = script.getField('DXL_MODE', script); + + let data_instruction = Entry.Robotis_rb.INSTRUCTION.BYPASS_WRITE; + let data_address = 0; + let data_length = 0; + let data_value = 0; + + data_address = Entry.Robotis_rb.CONTROL_TABLE.DXL_OPERATING_MODE[0]; + data_length = Entry.Robotis_rb.CONTROL_TABLE.DXL_OPERATING_MODE[1]; + + data_value = dxl_mode; + + let data_sendqueue = [ + [ + data_instruction, + Entry.Robotis_rb.CONTROL_TABLE.DXL_TORQUE_ENABLE[0], + Entry.Robotis_rb.CONTROL_TABLE.DXL_TORQUE_ENABLE[1], + dxl_id, + 0, + ], + [data_instruction, data_address, data_length, dxl_id, data_value], + [ + data_instruction, + Entry.Robotis_rb.CONTROL_TABLE.DXL_TORQUE_ENABLE[0], + Entry.Robotis_rb.CONTROL_TABLE.DXL_TORQUE_ENABLE[1], + dxl_id, + 1, + ], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['KkokduLite..set_dxl_mode(%1, %2)'], + }, + }, + robotis_kkokdu_lite_dxl_set_position: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['ID 1', '1'], + ['ID 2', '2'], + ['ID 3', '3'], + ['ID 4', '4'], + ['ID 5', '5'], + ['ID 6', '6'], + ['ID 7', '7'], + ['ID 8', '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: ['1', '50', '0', null], + type: 'robotis_kkokdu_lite_dxl_set_position', + }, + paramsKeyMap: { + DXL_ID: 0, + DXL_SPEED: 1, + DXL_ANGLE: 2, + }, + class: 'robotis_kkokdu_lite_dxl', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let dxl_id = script.getNumberValue('DXL_ID', script); + let dxl_speed = script.getNumberValue('DXL_SPEED', script); + let dxl_angle = script.getNumberValue('DXL_ANGLE', script); + + let data_instruction = Entry.Robotis_rb.INSTRUCTION.BYPASS_WRITE; + let data_address = 0; + let data_length = 0; + let data_buf = []; + + data_address = Entry.Robotis_rb.CONTROL_TABLE.DXL_PROFILE_VELOCITY[0]; + data_length = + Entry.Robotis_rb.CONTROL_TABLE.DXL_PROFILE_VELOCITY[1] + + Entry.Robotis_rb.CONTROL_TABLE.DXL_GOAL_POSITION[1]; + + if (dxl_speed < 0) { + dxl_speed = 0; + } else if (dxl_speed > 100) { + dxl_speed = 100; + } + + data_buf.push((dxl_speed * 10) % 256); + data_buf.push(Math.floor((dxl_speed * 10) / 256)); + data_buf.push(0); + data_buf.push(0); + + if (dxl_angle < -179) { + dxl_angle = -179; + } else if (dxl_angle > 180) { + dxl_angle = 180; + } + + dxl_angle = 180 - dxl_angle; + + data_buf.push(Math.floor((dxl_angle * 4096) / 360) % 256); + data_buf.push(Math.floor((dxl_angle * 4096) / 360 / 256)); + data_buf.push(0); + data_buf.push(0); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, dxl_id, data_buf], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['KkokduLite..set_dxl_position(%1, %2, %3)'], + }, + }, + robotis_kkokdu_lite_dxl_set_rotate: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['ID 1', '1'], + ['ID 2', '2'], + ['ID 3', '3'], + ['ID 4', '4'], + ['ID 5', '5'], + ['ID 6', '6'], + ['ID 7', '7'], + ['ID 8', '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dxl_rotate_cw, '1'], + [Lang.Blocks.robotis_dxl_rotate_ccw, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dxl_move_rotate, '1'], + [Lang.Blocks.robotis_dxl_move_stop, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: ['1', '50', null, null, null], + type: 'robotis_kkokdu_lite_dxl_set_rotate', + }, + paramsKeyMap: { + DXL_ID: 0, + DXL_SPEED: 1, + DXL_DIRECTION: 2, + DXL_MOVE: 3, + }, + class: 'robotis_kkokdu_lite_dxl', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let dxl_id = script.getNumberValue('DXL_ID', script); + let dxl_speed = script.getNumberValue('DXL_SPEED', script); + let dxl_direction = script.getNumberValue('DXL_DIRECTION', script); + let dxl_move = script.getNumberValue('DXL_MOVE', script); + + let data_instruction = Entry.Robotis_rb.INSTRUCTION.BYPASS_WRITE; + let data_address = 0; + let data_length = 0; + let data_value = 0; + + data_address = Entry.Robotis_rb.CONTROL_TABLE.DXL_GOAL_VELOCITY[0]; + data_length = Entry.Robotis_rb.CONTROL_TABLE.DXL_GOAL_VELOCITY[1]; + + if (dxl_speed < 0) { + dxl_speed = 0; + } else if (dxl_speed > 100) { + dxl_speed = 100; + } + + data_value = dxl_speed * 10; + + // cw일 경우 음수처리 + if (dxl_direction == 1) { + data_value = -data_value; + } + + // 바퀴형 로봇 우측 바퀴인 경우 reverse mode이므로 방향 반대 + if (dxl_id == 33 || dxl_id == 35 || dxl_id == 51) { + data_value = -data_value; + } + + data_value = data_value * dxl_move; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, dxl_id, data_value], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['KkokduLite..set_dxl_rotate(%1, %2, %3, %4)'], + }, + }, + robotis_kkokdu_lite_dxl_set_multiturn_round: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['ID 1', '1'], + ['ID 2', '2'], + ['ID 3', '3'], + ['ID 4', '4'], + ['ID 5', '5'], + ['ID 6', '6'], + ['ID 7', '7'], + ['ID 8', '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dxl_rotate_cw, '1'], + [Lang.Blocks.robotis_dxl_rotate_ccw, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: ['1', '50', '1', null, null], + type: 'robotis_kkokdu_lite_dxl_set_multiturn_round', + }, + paramsKeyMap: { + DXL_ID: 0, + DXL_SPEED: 1, + DXL_ROUND: 2, + DXL_DIRECTION: 3, + }, + class: 'robotis_kkokdu_lite_dxl', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let dxl_id = script.getNumberValue('DXL_ID', script); + let dxl_speed = script.getNumberValue('DXL_SPEED', script); + let dxl_round = script.getNumberValue('DXL_ROUND', script); + let dxl_direction = script.getNumberValue('DXL_DIRECTION', script); + + let data_instruction = INST_WRITE; + let data_address_1 = 0; + let data_length_1 = 0; + let data_value_1 = 0; + let data_address_2 = 0; + let data_length_2 = 0; + let data_value_2 = 0; + let data_address_3 = 0; + let data_length_3 = 0; + let data_value_3 = 0; + + let data_sendqueue = []; + let result = undefined; + + if (dxl_id == 0 || dxl_speed == 0 || dxl_round == 0) { + return; + } + + data_address_1 = Entry.Robotis_rb.CONTROL_TABLE.CM_DXL_MULTITURN_ID[0]; + data_length_1 = Entry.Robotis_rb.CONTROL_TABLE.CM_DXL_MULTITURN_ID[1]; + + data_address_2 = Entry.Robotis_rb.CONTROL_TABLE.CM_DXL_MULTITURN_SPEED[0]; + data_length_2 = Entry.Robotis_rb.CONTROL_TABLE.CM_DXL_MULTITURN_SPEED[1]; + + if (dxl_speed < 0) { + dxl_speed = 0; + } else if (dxl_speed > 100) { + dxl_speed = 100; + } + + data_value_2 = dxl_speed * 10; + + data_address_3 = + Entry.Robotis_rb.CONTROL_TABLE.CM_DXL_MULTITURN_DISTANCE[0]; + data_length_3 = Entry.Robotis_rb.CONTROL_TABLE.CM_DXL_MULTITURN_DISTANCE[1]; + + if (dxl_round < 0) { + dxl_round = 0; + } else if (dxl_round > 100) { + dxl_round = 100; + } + + // 바퀴형 로봇 우측 바퀴인 경우 reverse mode이므로 방향 반대 + if (dxl_id == 33 || dxl_id == 35 || dxl_id == 51) { + dxl_round = -dxl_round; + } + + data_value_3 = dxl_round * 4096; + + if (dxl_direction == 1) { + data_value_3 = -data_value_3; + } + + data_sendqueue = [ + [data_instruction, data_address_1, data_length_1, dxl_id], + [data_instruction, data_address_2, data_length_2, data_value_2], + [data_instruction, data_address_3, data_length_3, data_value_3], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['KkokduLite.set_dxl_multiturn_round(%1, %2, %3, %4)'], + }, + }, + + robotis_kkokdu_lite_cm_ir_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '360'], + ['2', '362'], + ['3', '364'], + ['4', '366'], + ['5', '368'], + ['6', '370'], + ], + value: '360', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_cm_ir_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + const scope = script.executor.scope; + + const data_default_address = script.getNumberValue('VALUE'); + + let result = Entry.RobotisKkokduLite.dataBuffer[data_default_address]; + if (result == undefined) { + result = rb100_last_valid_value[data_default_address]; + } else { + rb100_last_valid_value[data_default_address] = result; + } + if (typeof result == 'undefined') { + return 0; + } + return Math.round(result % 65536); + }, + syntax: { + js: [], + py: ['KkokduLite.ir_value(%1)'], + }, + }, + robotis_kkokdu_lite_cm_ir_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '360'], + ['2', '362'], + ['3', '364'], + ['4', '366'], + ['5', '368'], + ['6', '370'], + ], + value: '360', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['>', '0'], + ['<', '1'], + ['=', '2'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null, null, 200], + type: 'robotis_kkokdu_lite_cm_ir_compare', + }, + paramsKeyMap: { + VALUE: 0, + COMPARE_OP: 1, + COMPARE_VAL: 2, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('VALUE'); + let compareValue = script.getNumberValue('COMPARE_VAL'); + let compareOP = script.getNumberValue('COMPARE_OP'); + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + + if (result == undefined) { + return false; + } + + result = Math.round(result % 65536); + + switch (compareOP) { + case 0: + return result > compareValue; + case 1: + return result < compareValue; + default: + return false; + } + }, + syntax: { + js: [], + py: ['KkokduLite.ir_compare(%1)'], + }, + }, + robotis_kkokdu_lite_detectFrontObj: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + + ], + events: {}, + def: { + params: [ + + ], + type: 'robotis_kkokdu_lite_detectFrontObj', + }, + paramsKeyMap: { + + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + + // instruction / address / length / value / default length + let ir_1 = 0; + let ir_2 = 0; + + + + ir_1 = Entry.RobotisKkokduLite.dataBuffer[360]; + ir_2 = Entry.RobotisKkokduLite.dataBuffer[362]; + if (ir_1 == undefined) { + ir_1 = 0; + } + if (ir_2 == undefined) { + ir_2 = 0; + } + return ir_1 > 100 || ir_2 > 100; + + }, + syntax: { + js: [], + py: ['KkokduLite.detectFrontObj()'], + }, + }, + robotis_kkokdu_lite_cm_btn_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_run, '45'], + [Lang.Blocks.robotis_cancel, '42'], + ], + value: '45', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_push, '1'], + [Lang.Blocks.robotis_notPush, '0'], + + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_cm_btn_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('VALUE'); + let compareValue = 1; + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['KkokduLite.btn_value(%1)'], + }, + }, + robotis_kkokdu_lite_cm_joystick_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_center, '0'], + ['←', '1'], + ['→', '2'], + ['↑', '3'], + ['↓', '4'], + ['↖', '5'], + ['↗', '6'], + ['↙', '7'], + ['↘', '8'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_cm_joystick_value', + }, + paramsKeyMap: { + COMPARE_VAL: 0, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = 50; + let compareValue = script.getNumberValue('COMPARE_VAL', script); + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['KkokduLite.joystick_value()'], + }, + }, + robotis_kkokdu_lite_mic: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_mic', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + async func(sprite, script) { + let scope = script.executor.scope; + let data_address = 119; + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['KkokduLite.mic()'], + }, + }, + robotis_kkokdu_lite_detectSound_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_right, '255'], + [Lang.Blocks.robotis_center, '0'], + [Lang.Blocks.robotis_left, '1'], + ], + value: '255', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_detectSound_compare', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = 5031; + let compareValue = script.getNumberValue('VALUE'); + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + if (result == undefined) { + return false; + } + + return result == compareValue; + }, + syntax: { + js: [], + py: ['KkokduLite.detectSound_compare(%1)'], + }, + }, + robotis_kkokdu_lite_imu: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['x', '78'], //72 + ['y', '80'], //74 + ['z', '82'], //76 + ], + value: '78', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_acceleration, '0'], //72 + [Lang.Blocks.robotis_gyro, '6'], //74 + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_imu', + }, + paramsKeyMap: { + AXIS: 0, + MODE: 1, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = + script.getField('AXIS', script) - script.getField('MODE', script); + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['KkokduLite.imu()'], + }, + }, + robotis_kkokdu_lite_roll_pitch: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_roll, '70'], //72 + [Lang.Blocks.robotis_pitch, '88'], //74 + ], + value: '70', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_roll_pitch', + }, + paramsKeyMap: { + AXIS: 0, + }, + class: 'robotis_kkokdu_lite_value', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + let scope = script.executor.scope; + let data_address = script.getNumberValue('AXIS'); + + let result = Entry.RobotisKkokduLite.dataBuffer[data_address]; + + if (typeof result == 'undefined') { + return 0; + } + return result; + }, + syntax: { + js: [], + py: ['KkokduLite.roll_pitch(%1)'], + }, + }, + + + robotis_kkokdu_lite_buzzer_index: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.General.note_c + '', '1'], + [Lang.General.note_c + '#', '2'], + [Lang.General.note_d + '', '3'], + [Lang.General.note_d + '#', '4'], + [Lang.General.note_e + '', '5'], + [Lang.General.note_f + '', '6'], + [Lang.General.note_f + '#', '7'], + [Lang.General.note_g + '', '8'], + [Lang.General.note_g + '#', '9'], + [Lang.General.note_a + '', '10'], + [Lang.General.note_a + '#', '11'], + [Lang.General.note_b + '', '12'], + ], + value: '11', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['3', '3'], + ['4', '4'], + ['5', '5'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_play, '1'], + [Lang.Blocks.robotis_rest, '2'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, 1, null, null], + type: 'robotis_kkokdu_lite_buzzer_index', + }, + paramsKeyMap: { + CM_BUZZER_INDEX: 0, + CM_BUZZER_OCTAV: 1, + CM_BUZZER_DELAY: 2, + CM_BUZZER_PLAY: 3 + }, + class: 'robotis_kkokdu_lite_sound', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmBuzzerIndex = script.getNumberValue('CM_BUZZER_INDEX', script); + let cmBuzzerOffset = script.getNumberValue('CM_BUZZER_OCTAV', script); + let cmBuzzerTime = script.getNumberValue('CM_BUZZER_DELAY', script); + let cmBuzzerPlay = script.getNumberValue('CM_BUZZER_PLAY', script); + + let data_instruction = INST_WRITE; + let data_address = 0; + let data_value = 0; + let interval = 0; + let data_buf = []; + + cmBuzzerTime = Math.round(cmBuzzerTime * 1000); + + data_address = 740; + // data_value_1 = cmBuzzerTime * 10; + // TODO 텍스트 입력으로 바꾸고 최대는 5초 : 0.5 초 하려면 5를 입력 - console.log(parseInt(0.59 * 10)); max 는 5초 + + if (cmBuzzerTime < 0) { + cmBuzzerTime = 0; + } + if (cmBuzzerTime > 50000) { + cmBuzzerTime = 50000; + } + + data_buf.push(cmBuzzerTime % 256); + data_buf.push(Math.floor(cmBuzzerTime / 256)); + + data_value = cmBuzzerIndex + (cmBuzzerOffset - 1) * 12; + data_buf.push(Math.floor(data_value)); + + // console.log("buzzer send"); + let data_sendqueue = [[data_instruction, data_address, 3, data_buf]]; + + if (cmBuzzerPlay == '2') { + data_sendqueue = []; + } + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + cmBuzzerTime + interval + ); + }, + syntax: { + js: [], + py: ['KkokduLite.buzzer_index(%1, %2, %3)'], + }, + }, + + + robotis_kkokdu_lite_rgee_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_face01, '2817'], + [Lang.Blocks.robotis_face02, '2818'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face03, '2819'], + [Lang.Blocks.robotis_face04, '2820'], + [Lang.Blocks.robotis_face05, '2821'], + + [Lang.Blocks.robotis_face06, '2822'], + [Lang.Blocks.robotis_face07, '2823'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face08, '2824'], + [Lang.Blocks.robotis_face09, '2825'], + [Lang.Blocks.robotis_face10, '2826'], + + [Lang.Blocks.robotis_face11, '2827'], + [Lang.Blocks.robotis_face12, '2828'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face13, '2829'], + + [Lang.Blocks.robotis_face14, '2830'], + [Lang.Blocks.robotis_face15, '2831'], + [Lang.Blocks.robotis_face16, '2832'], + [Lang.Blocks.robotis_face17, '2833'], + [Lang.Blocks.robotis_face18, '2834'], + + [Lang.Blocks.robotis_face19, '2835'], + [Lang.Blocks.robotis_face20, '2836'], + [Lang.Blocks.robotis_face21, '2837'], + [Lang.Blocks.robotis_face22, '2838'], + [Lang.Blocks.robotis_face23, '2839'], + ], + value: '2817', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_rgee_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['KkokduLite.rgee_screen(%1)'] }, + }, + + robotis_kkokdu_lite_rgee_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_face01, '30748'], + [Lang.Blocks.robotis_face02, '30749'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face03, '30750'], + [Lang.Blocks.robotis_face04, '30756'], + [Lang.Blocks.robotis_face05, '30754'], + + [Lang.Blocks.robotis_face06, '30741'], + [Lang.Blocks.robotis_face07, '30747'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face08, '30738'], + [Lang.Blocks.robotis_face09, '30740'], + [Lang.Blocks.robotis_face10, '30739'], + + [Lang.Blocks.robotis_face11, '30733'], + [Lang.Blocks.robotis_face12, '30734'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_face13, '30732'], + + [Lang.Blocks.robotis_face14, '30757'], + [Lang.Blocks.robotis_face15, '30736'], + [Lang.Blocks.robotis_face16, '30731'], + [Lang.Blocks.robotis_face17, '30742'], + [Lang.Blocks.robotis_face18, '30743'], + + [Lang.Blocks.robotis_face19, '30744'], + [Lang.Blocks.robotis_face20, '30751'], + [Lang.Blocks.robotis_face21, '30752'], + [Lang.Blocks.robotis_face22, '30755'], + [Lang.Blocks.robotis_face23, '30758'], + ], + value: '30748', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_rgee_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['KkokduLite.rgee_animation_screen(%1)'] }, + }, + + + + + robotis_kkokdu_lite_icon: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_screen1, '11545'], + [Lang.Blocks.robotis_screen2, '11546'], + [Lang.Blocks.robotis_screen3, '11547'], + ['0', '11283'], + ['1', '11284'], + ['2', '11285'], + ['3', '11286'], + ['4', '11287'], + ['5', '11288'], + ['6', '11289'], + ['7', '11290'], + ['8', '11291'], + ['9', '11292'], + ['10', '11293'], + ], + value: '11545', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + 50, + null, + ], + type: 'robotis_kkokdu_lite_icon', + }, + paramsKeyMap: { + ICON: 0, + X: 1, + Y: 2, + SIZE: 3, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let iconNum = script.getField('ICON', script); + let x = script.getNumberValue('X', script); + let y = script.getNumberValue('Y', script); + let size = script.getNumberValue('SIZE', script) * 2; + + let data_instruction = INST_WRITE; + let data_address = 166; + let data_length = 2; + let data_value = 10496; + + if (x < -160) { + x = -160; + } else if (x > 160) { + x = 160; + } + + if (y < -120) { + y = -120; + } else if (y > 120) { + y = 120; + } + + if (size < 0) { + size = 0; + } else if (size > 400) { + size = 400; + } + + data_value = iconNum; + + let data_sendqueue = [ + [INST_WRITE, 130, 2, x], + [INST_WRITE, 132, 2, y], + [INST_WRITE, 149, 2, size], + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { + js: [], + py: ['KkokduLite.icon_screen(%1,%2,%3,%4)'], + }, + }, + + + robotis_kkokdu_lite_LCDBright: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [10], + type: 'robotis_kkokdu_lite_LCDBright', + }, + paramsKeyMap: { + BRIGHT: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let bright = script.getNumberValue('BRIGHT', script); + + let data_instruction = INST_WRITE; + let data_address = 180; + let data_length = 1; + let data_value = 0; + + bright = Math.min(Math.max(bright, 0), 100); + + data_value = bright; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { + js: [], + py: ['KkokduLite.LCDBright(%1)'], + }, + }, + robotis_kkokdu_lite_LCDColor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_red, '224'], + [Lang.Blocks.robotis_orange, '244'], + [Lang.Blocks.robotis_yellow, '252'], + [Lang.Blocks.robotis_green, '28'], + [Lang.Blocks.robotis_blue, '3'], + [Lang.Blocks.robotis_darkblue, '2'], + [Lang.Blocks.robotis_purple, '130'], + [Lang.Blocks.robotis_brown, '173'], + [Lang.Blocks.robotis_black, '0'], + [Lang.Blocks.robotis_white, '255'], + ], + value: '224', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_LCDColor', + }, + paramsKeyMap: { + COLOR: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let color = script.getNumberValue('COLOR', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = 0; + + data_value = color; + bg_color = color; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 100 + ); + }, + syntax: { + js: [], + py: ['KkokduLite.LCDColor(%1)'], + }, + }, + + robotis_kkokdu_lite_led_brightness: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_left, '1'], + [Lang.Blocks.robotis_right, '2'], + [Lang.Blocks.robotis_both, '3'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: [100] + } + ], + type: 'robotis_kkokdu_lite_led_brightness', + }, + paramsKeyMap: { + RB_LED: 0, + BRIGHT: 1, + }, + class: 'robotis_kkokdu_lite_led', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmLed = script.getNumberValue('RB_LED', script); + let bright = script.getNumberValue('BRIGHT', script); + + let data_instruction = INST_WRITE; + let data_address = 0; + let data_length = 1; + let data_value = 0; + + if (bright < 0) { + bright = 0; + } else if (bright > 100) { + bright = 100 + } + data_value = 100 + bright; + + if (cmLed == 1) { + data_address = 40; + data_length = 1; + } else if (cmLed == 2) { + data_address = 41; + data_length = 1; + } else if (cmLed == 3) { + data_address = 40; + data_length = 2; + data_value = data_value * 257 + } + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['KkokduLite.led_brightness(%1, %2)'] }, + }, + robotis_kkokdu_lite_led_pattern: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_flashing1, '11'], + [Lang.Blocks.robotis_flashing2, '12'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing3, '13'], + + [Lang.Blocks.robotis_flashing4, '21'], + [Lang.Blocks.robotis_flashing5, '22'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing6, '23'], + + [Lang.Blocks.robotis_flashing7, '31'], + [Lang.Blocks.robotis_flashing8, '32'], //Lang.Blocks.robotis_robotis_common_green_color + [Lang.Blocks.robotis_flashing9, '33'], + + ], + value: '11', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_common_on, '1'], + [Lang.Blocks.robotis_common_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, null], + type: 'robotis_kkokdu_lite_led_pattern', + }, + paramsKeyMap: { + RB_LED: 0, + VALUE: 1, + }, + class: 'robotis_kkokdu_lite_led', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmLed = script.getNumberValue('RB_LED', script); + let value = script.getNumberValue('VALUE', script); + + let data_instruction = INST_WRITE; + let data_address = 40; + let data_length = 1; + let data_value = 0; + + data_value = value * cmLed; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['KkokduLite.led_pattern(%1, %2)'] }, + }, + + + + robotis_kkokdu_lite_Hello: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_korean1, '0'], + [Lang.Blocks.robotis_korean2, '1'], + [Lang.Blocks.robotis_korean3, '2'], + [Lang.Blocks.robotis_korean4, '3'], + [Lang.Blocks.robotis_korean5, '4'], + [Lang.Blocks.robotis_korean6, '5'], + [Lang.Blocks.robotis_korean7, '6'], + [Lang.Blocks.robotis_korean8, '7'], + [Lang.Blocks.robotis_korean9, '8'], + [Lang.Blocks.robotis_korean10, '9'], + [Lang.Blocks.robotis_korean11, '10'], + [Lang.Blocks.robotis_korean12, '11'], + [Lang.Blocks.robotis_korean13, '12'], + [Lang.Blocks.robotis_korean14, '13'], + [Lang.Blocks.robotis_korean15, '14'], + [Lang.Blocks.robotis_korean16, '15'], + [Lang.Blocks.robotis_korean17, '16'], + [Lang.Blocks.robotis_korean18, '17'], + [Lang.Blocks.robotis_korean19, '18'], + [Lang.Blocks.robotis_korean20, '19'], + [Lang.Blocks.robotis_korean21, '20'], + [Lang.Blocks.robotis_korean22, '21'], + [Lang.Blocks.robotis_korean23, '22'], + [Lang.Blocks.robotis_korean24, '23'], + [Lang.Blocks.robotis_korean25, '24'], + [Lang.Blocks.robotis_korean26, '25'], + [Lang.Blocks.robotis_korean27, '26'], + [Lang.Blocks.robotis_korean28, '27'], + [Lang.Blocks.robotis_korean29, '28'], + [Lang.Blocks.robotis_korean30, '29'], + [Lang.Blocks.robotis_korean31, '30'], + [Lang.Blocks.robotis_korean32, '31'], + [Lang.Blocks.robotis_korean33, '32'], + [Lang.Blocks.robotis_korean34, '33'], + [Lang.Blocks.robotis_korean35, '34'], + [Lang.Blocks.robotis_korean36, '35'], + [Lang.Blocks.robotis_korean37, '36'], + [Lang.Blocks.robotis_korean38, '37'], + [Lang.Blocks.robotis_korean39, '38'], + [Lang.Blocks.robotis_korean40, '39'], + [Lang.Blocks.robotis_korean41, '40'], + [Lang.Blocks.robotis_korean42, '41'], + [Lang.Blocks.robotis_korean43, '42'], + [Lang.Blocks.robotis_korean44, '43'], + [Lang.Blocks.robotis_korean45, '44'], + [Lang.Blocks.robotis_korean46, '45'], + [Lang.Blocks.robotis_korean47, '46'], + [Lang.Blocks.robotis_korean48, '47'], + [Lang.Blocks.robotis_korean49, '48'], + [Lang.Blocks.robotis_korean50, '49'], + [Lang.Blocks.robotis_korean51, '50'], + [Lang.Blocks.robotis_korean52, '51'], + [Lang.Blocks.robotis_korean53, '52'], + [Lang.Blocks.robotis_korean54, '53'], + [Lang.Blocks.robotis_korean55, '54'], + [Lang.Blocks.robotis_korean56, '55'], + [Lang.Blocks.robotis_korean57, '56'], + [Lang.Blocks.robotis_korean58, '57'], + [Lang.Blocks.robotis_korean59, '58'], + [Lang.Blocks.robotis_korean60, '59'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_Hello', + }, + paramsKeyMap: { + HELLO: 0, + }, + class: 'robotis_kkokdu_lite_sound', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmHello = script.getField('HELLO', script); + + let data_instruction = INST_WRITE; + let data_address = 110; + let data_length = 2; + let data_value = 0; + + data_value = 25601 + Number(cmHello); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [data_instruction, 0, 2, 0], + ]; + + let extraTime = 0; + + if (cmHello == '38' || cmHello == '55') { + extraTime = 2000; + } + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + 2000 + extraTime + ); + }, + syntax: { + js: [], + py: ['KkokduLite.speak(%1)'], + }, + }, + robotis_kkokdu_lite_effectSound: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_dog, '0'], + [Lang.Blocks.robotis_frog, '1'], + [Lang.Blocks.robotis_cat, '2'], + [Lang.Blocks.robotis_chicken, '7'], + [Lang.Blocks.robotis_tiger, '19'], + [Lang.Blocks.robotis_mouse, '17'], + + [Lang.Blocks.robotis_ambul, '773'], + [Lang.Blocks.robotis_Horn, '781'], + [Lang.Blocks.robotis_siren, '774'], + [Lang.Blocks.robotis_whistle, '274'], + [Lang.Blocks.robotis_gun, '775'], + [Lang.Blocks.robotis_clap, '260'], + + [Lang.Blocks.robotis_melody1, '786'], + [Lang.Blocks.robotis_melody2, '787'], + [Lang.Blocks.robotis_melody3, '788'], + [Lang.Blocks.robotis_melody4, '789'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_effectSound', + }, + paramsKeyMap: { + HELLO: 0, + }, + class: 'robotis_kkokdu_lite_sound', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let cmHello = script.getField('HELLO', script); + + let data_instruction = INST_WRITE; + let data_address = 110; + let data_length = 2; + let data_value = 0; + + data_value = Number(cmHello); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [data_instruction, 0, 2, 0], + ]; + + let extraTime = 0; + if ( + cmHello == '272' || + cmHello == '786' || + cmHello == '787' || + cmHello == '788' || + cmHello == '789' + ) { + //오리 + extraTime = 0; + if (cmHello == '788' || cmHello == '789') { + extraTime += 500; + } + } + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + 3000 + extraTime + ); + }, + syntax: { + js: [], + py: ['KkokduLite.effect_sound(%1)'], + }, + }, + robotis_kkokdu_lite_record: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_record', + }, + paramsKeyMap: { + ROOM: 0, + }, + class: 'robotis_kkokdu_lite_sound', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let roomNum = script.getField('ROOM', script); + + let data_instruction = INST_WRITE; + let data_address = 115; + let data_length = 1; + let data_value = 0; + + data_value = roomNum; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + 6000 + ); + }, + syntax: { + js: [], + py: ['KkokduLite.record(%1)'], + }, + }, + robotis_kkokdu_lite_playRecord: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robotis_kkokdu_lite_playRecord', + }, + paramsKeyMap: { + ROOM: 0, + }, + class: 'robotis_kkokdu_lite_sound', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let roomNum = script.getField('ROOM', script); + + let data_instruction = INST_WRITE; + let data_address = 116; + let data_length = 1; + let data_value = 0; + + data_value = roomNum; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + 6000 + ); + }, + syntax: { + js: [], + py: ['KkokduLite.playRecord(%1)'], + }, + }, + + + + + robotis_kkokdu_lite_rla_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '3329'], + [Lang.Blocks.robotis_car_anim02, '3330'], + [Lang.Blocks.robotis_car_anim03, '3331'], + [Lang.Blocks.robotis_car_anim04, '3332'], + [Lang.Blocks.robotis_car_anim05, '3333'], + + [Lang.Blocks.robotis_car_anim06, '3334'], + [Lang.Blocks.robotis_car_anim07, '3335'], + [Lang.Blocks.robotis_car_anim08, '3336'], + [Lang.Blocks.robotis_car_anim09, '3337'], + [Lang.Blocks.robotis_car_anim10, '3338'], + + [Lang.Blocks.robotis_car_anim11, '3339'], + [Lang.Blocks.robotis_car_anim12, '3340'], + [Lang.Blocks.robotis_car_anim13, '3341'], + [Lang.Blocks.robotis_car_anim14, '3342'], + [Lang.Blocks.robotis_car_anim15, '3343'], + + [Lang.Blocks.robotis_car_anim16, '3344'], + [Lang.Blocks.robotis_car_anim17, '3345'], + [Lang.Blocks.robotis_car_anim18, '3346'], + [Lang.Blocks.robotis_car_anim19, '3347'], + ], + value: '3329', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_rla_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['KkokduLite.rla_screen(%1)'] }, + }, + + robotis_kkokdu_lite_rla_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '30978'], + [Lang.Blocks.robotis_car_anim02, '30981'], + [Lang.Blocks.robotis_car_anim03, '30982'], + [Lang.Blocks.robotis_car_anim04, '30983'], + [Lang.Blocks.robotis_car_anim05, '30984'], + + [Lang.Blocks.robotis_car_anim06, '30985'], + [Lang.Blocks.robotis_car_anim07, '30986'], + [Lang.Blocks.robotis_car_anim08, '30987'], + [Lang.Blocks.robotis_car_anim09, '30988'], + [Lang.Blocks.robotis_car_anim10, '30989'], + + [Lang.Blocks.robotis_car_anim11, '30990'], + [Lang.Blocks.robotis_car_anim12, '30991'], + [Lang.Blocks.robotis_car_anim13, '30992'], + [Lang.Blocks.robotis_car_anim14, '30993'], + [Lang.Blocks.robotis_car_anim15, '30994'], + + [Lang.Blocks.robotis_car_anim16, '30995'], + [Lang.Blocks.robotis_car_anim17, '30996'], + [Lang.Blocks.robotis_car_anim18, '30997'], + [Lang.Blocks.robotis_car_anim19, '30998'], + ], + value: '30978', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_rla_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['KkokduLite.rla_animation_screen(%1)'] }, + }, + + robotis_kkokdu_lite_kkokdu_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '3585'], + [Lang.Blocks.robotis_car_anim02, '3586'], + [Lang.Blocks.robotis_car_anim03, '3587'], + [Lang.Blocks.robotis_car_anim04, '3588'], + [Lang.Blocks.robotis_car_anim05, '3589'], + + [Lang.Blocks.robotis_car_anim06, '3590'], + [Lang.Blocks.robotis_car_anim07, '3591'], + [Lang.Blocks.robotis_car_anim08, '3592'], + [Lang.Blocks.robotis_car_anim09, '3593'], + [Lang.Blocks.robotis_car_anim10, '3594'], + + [Lang.Blocks.robotis_car_anim11, '3595'], + [Lang.Blocks.robotis_car_anim12, '3596'], + [Lang.Blocks.robotis_car_anim13, '3597'], + [Lang.Blocks.robotis_car_anim14, '3598'], + [Lang.Blocks.robotis_car_anim15, '3599'], + + [Lang.Blocks.robotis_car_anim16, '3600'], + [Lang.Blocks.robotis_car_anim17, '3601'], + [Lang.Blocks.robotis_car_anim18, '3602'], + [Lang.Blocks.robotis_car_anim19, '3603'], + ], + value: '3585', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_kkokdu_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { js: [], py: ['KkokduLite.kkokdu_screen(%1)'] }, + }, + + robotis_kkokdu_lite_kkokdu_anim_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_car_anim01, '31234'], + [Lang.Blocks.robotis_car_anim02, '31237'], + [Lang.Blocks.robotis_car_anim03, '31238'], + [Lang.Blocks.robotis_car_anim04, '31239'], + [Lang.Blocks.robotis_car_anim05, '31240'], + + [Lang.Blocks.robotis_car_anim06, '31241'], + [Lang.Blocks.robotis_car_anim07, '31242'], + [Lang.Blocks.robotis_car_anim08, '31243'], + [Lang.Blocks.robotis_car_anim09, '31244'], + [Lang.Blocks.robotis_car_anim10, '31245'], + + [Lang.Blocks.robotis_car_anim11, '31246'], + [Lang.Blocks.robotis_car_anim12, '31247'], + [Lang.Blocks.robotis_car_anim13, '31248'], + [Lang.Blocks.robotis_car_anim14, '31249'], + [Lang.Blocks.robotis_car_anim15, '31250'], + + [Lang.Blocks.robotis_car_anim16, '31251'], + [Lang.Blocks.robotis_car_anim17, '31252'], + [Lang.Blocks.robotis_car_anim18, '31253'], + [Lang.Blocks.robotis_car_anim19, '31254'], + ], + value: '31234', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotis_kkokdu_lite_kkokdu_anim_screen', + }, + paramsKeyMap: { + BACKGROUND: 0, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let screenValue = script.getNumberValue('BACKGROUND', script); + + let data_instruction = INST_WRITE; + let data_address = 163; + let data_length = 2; + let data_value = screenValue; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY //+ 1000 + ); + }, + syntax: { js: [], py: ['KkokduLite.kkokdu_animation_screen(%1)'] }, + }, + robotis_kkokdu_lite_text_screen: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_screen_text_font_small, '0'], + [Lang.Blocks.robotis_screen_text_font_big, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_red, '224'], + [Lang.Blocks.robotis_orange, '244'], + [Lang.Blocks.robotis_yellow, '252'], + [Lang.Blocks.robotis_green, '28'], + [Lang.Blocks.robotis_blue, '3'], + [Lang.Blocks.robotis_darkblue, '2'], + [Lang.Blocks.robotis_purple, '130'], + [Lang.Blocks.robotis_brown, '173'], + [Lang.Blocks.robotis_black, '0'], + [Lang.Blocks.robotis_white, '255'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + ' ', + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + null, + null, + ], + type: 'robotis_kkokdu_lite_text_screen', + }, + paramsKeyMap: { + TEXT: 0, + X: 1, + Y: 2, + FONT: 3, + COLOR: 4, + }, + class: 'robotis_kkokdu_lite_lcd', + isNotFor: ['RobotisKkokduLite'], + func(sprite, script) { + // instruction / address / length / value / default length + let text = script.getStringValue('TEXT', script); + let x = script.getNumberValue('X', script); + let y = script.getNumberValue('Y', script); + let font = script.getNumberValue('FONT', script); + let color = script.getNumberValue('COLOR', script); + let data_buf = []; + let i = 0; + + let data_instruction = INST_WRITE; + let data_address = 900; + let data_length = 2; + + if (x < -160) { + x = -160; + } else if (x > 160) { + x = 160; + } + + if (y < -120) { + y = -120; + } else if (y > 120) { + y = 120; + } + + let encoder = new TextEncoder('utf-8'); + let byteArray = encoder.encode(text); + + data_buf.push(x % 256); + data_buf.push(Math.floor(x / 256)); + data_buf.push(y % 256); + data_buf.push(Math.floor(y / 256)); + data_buf.push(font); + data_buf.push(0); + data_buf.push(0); + data_buf.push(color); + data_buf.push(byteArray.length); + for (i = 0; i < byteArray.length; i++) { + data_buf.push(byteArray[i]); + } + + data_length = 9 + byteArray.length; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_buf], + [INST_WRITE, 162, 1, 1], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + 200 + ); + }, + syntax: { + js: [], + py: ['KkokduLite.text_screen(%1,%2,%3,%4,%5)'], + }, + }, + robotis_kkokdu_lite_motion: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_stMotion1, '1'], + [Lang.Blocks.robotis_stMotion2, '25'], + [Lang.Blocks.robotis_stMotion3, '46'], + [Lang.Blocks.robotis_stMotion4, '47'], + [Lang.Blocks.robotis_stMotion5, '37'], //Lang.Blocks.robotis_common_green_color + [Lang.Blocks.robotis_stMotion6, '38'], + [Lang.Blocks.robotis_stMotion7, '39'], + [Lang.Blocks.robotis_stMotion8, '41'], + [Lang.Blocks.robotis_stMotion9, '40'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + ], + type: 'robotis_kkokdu_lite_motion', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_move', + isNotFor: ['RobotisKkokduLite'], + func: function (sprite, script) { + // instruction / address / length / value / default length + var data_instruction = Entry.Robotis_rb.INSTRUCTION.WRITE; + var data_address = 0; + var data_length = 0; + var data_value = 0; + var extraTime = 0; + + data_address = + Entry.Robotis_rb.CONTROL_TABLE.CM_MOTION[0]; + data_length = Entry.Robotis_rb.CONTROL_TABLE.CM_MOTION[1]; + data_value = script.getField('VALUE', script); + + + console.log("motion send"); + var data_sendqueue = [ + [data_instruction, data_address, data_length, 0], + [data_instruction, data_address, data_length, data_value] + ]; + + switch (data_value) { + case '1': + extraTime = 100; + break; + case '25': + case '46': + case '47': + extraTime = 3000; + break; + case '37': + extraTime = 3000; + break; + case '38': + extraTime = 1000; + break; + case '39': + extraTime = 1000; + break; + case '40': + extraTime = 2300; + break; + case '41': + extraTime = 2300; + break; + + + } + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + extraTime + 300 + ); + }, + syntax: { js: [], py: ['KkokduLite.run_motion(%1)'] }, + }, + robotis_kkokdu_lite_motion_other: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotis_spMotion1, '26'], + [Lang.Blocks.robotis_spMotion2, '27'], + [Lang.Blocks.robotis_spMotion3, '28'], + [Lang.Blocks.robotis_spMotion4, '29'], + [Lang.Blocks.robotis_spMotion5, '30'], //Lang.Blocks.robotis_common_green_color + [Lang.Blocks.robotis_spMotion6, '31'], + [Lang.Blocks.robotis_spMotion7, '32'], + [Lang.Blocks.robotis_spMotion8, '33'], + [Lang.Blocks.robotis_spMotion9, '48'], + [Lang.Blocks.robotis_spMotion10, '35'], + [Lang.Blocks.robotis_spMotion11, '36'], + [Lang.Blocks.robotis_spMotion12, '42'], + [Lang.Blocks.robotis_spMotion13, '43'], + [Lang.Blocks.robotis_spMotion14, '44'], + [Lang.Blocks.robotis_spMotion15, '45'], + ], + value: '26', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + ], + type: 'robotis_kkokdu_lite_motion_other', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_move', + isNotFor: ['RobotisKkokduLite'], + func: function (sprite, script) { + // instruction / address / length / value / default length + var data_instruction = Entry.Robotis_rb.INSTRUCTION.WRITE; + var data_address = 0; + var data_length = 0; + var data_value = 0; + var extraTime = 0; + + data_address = + Entry.Robotis_rb.CONTROL_TABLE.CM_MOTION[0]; + data_length = Entry.Robotis_rb.CONTROL_TABLE.CM_MOTION[1]; + data_value = script.getField('VALUE', script); + + + console.log("motion send"); + var data_sendqueue = [ + [data_instruction, data_address, data_length, 0], + [data_instruction, data_address, data_length, data_value] + ]; + + switch (data_value) { + case '26': + extraTime = 800; + break; + case '27': + extraTime = 1000; + break; + case '28': + extraTime = 800; + break; + case '29': + extraTime = 1000; + break; + case '30': + extraTime = 800; + break; + case '31': + extraTime = 1000; + break; + case '32': + extraTime = 5800; + break; + case '33': + extraTime = 3800; + break; + case '34': + extraTime = 8400; + break; + case '35': + extraTime = 4000; + break; + case '36': + extraTime = 300; + break; + case '42': + extraTime = 600; + break; + case '43': + extraTime = 800; + break; + case '44': + extraTime = 800; + break; + case '45': + extraTime = 1000; + break; + case '48': + extraTime = 12400; + break; + } + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + extraTime + 200 + ); + }, + syntax: { js: [], py: ['KkokduLite.run_motion_other(%1)'] }, + }, + + + robotis_kkokdu_lite_motion_custom: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['1'], + }, + null, + ], + type: 'robotis_kkokdu_lite_motion_custom', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'robotis_kkokdu_lite_move', + isNotFor: ['RobotisKkokduLite'], + func: function (sprite, script) { + // instruction / address / length / value / default length + var data_instruction = Entry.Robotis_rb.INSTRUCTION.WRITE; + var data_address = 0; + var data_length = 0; + var data_value = 0; + var extraTime = 0; + + data_address = + Entry.Robotis_rb.CONTROL_TABLE.CM_MOTION[0]; + data_length = Entry.Robotis_rb.CONTROL_TABLE.CM_MOTION[1]; + data_value = script.getNumberValue('VALUE', script); + + var data_sendqueue = [ + [data_instruction, data_address, data_length, 0], + [data_instruction, data_address, data_length, data_value] + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['KkokduLite.run_motion_custom(%1)'] }, + }, + robotis_kkokdu_lite_dxl_control: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['1'], + }, + ], + type: 'robotis_kkokdu_lite_dxl_control', + }, + + paramsKeyMap: { + ANGLE1: 0, + ANGLE2: 1, + ANGLE3: 2, + ANGLE4: 3, + + ANGLE5: 4, + ANGLE6: 5, + ANGLE7: 6, + ANGLE8: 7, + TIME: 8 + }, + class: 'robotis_kkokdu_lite_move', + isNotFor: ['RobotisKkokduLite'], + func(entity, script) { + let data_instruction = Entry.Robotis_rb.INSTRUCTION.WRITE; + let data_address = 19; + let data_length = 1; + let data_value = 1; + let move_time = script.getNumberValue('TIME', script) * 1000; + + let data_sendqueue = [ + [data_instruction, data_address, data_length, data_value], + [INST_DXL_REGWRITE, 64, 1, 1, [1]], + [INST_DXL_REGWRITE, 64, 1, 2, [1]], + [INST_DXL_REGWRITE, 64, 1, 3, [1]], + [INST_DXL_REGWRITE, 64, 1, 4, [1]], + [INST_DXL_REGWRITE, 64, 1, 5, [1]], + [INST_DXL_REGWRITE, 64, 1, 6, [1]], + [INST_DXL_REGWRITE, 64, 1, 7, [1]], + [INST_DXL_REGWRITE, 64, 1, 8, [1]], + [INST_DXL_ACTION, 0, 0, 0xFE], + ] + + let keyWord = 'ANGLE'; + for (let i = 1; i < 9; i++) { + keyWord = 'ANGLE' + i; + let value = script.getNumberValue('ANGLE' + i, script); + + let engValue = 2048; + engValue = Math.floor(2048 - Math.round(value * 4096) / 360); + + let velocity = 0; + + let data_buf = []; + + if (move_time == 0) { + velocity = 0; + } else { + velocity = Math.round(Math.floor(60 * Math.abs(value - Entry.RobotisKkokduLite.dxlPositions[i]) * 1000 / 4096 / move_time) / 0.229); + } + + Entry.RobotisKkokduLite.dxlPositions[i] = value; + + data_buf.push(Entry.RobotisKkokduLite.getLowByte(Entry.RobotisKkokduLite.getLowWord(velocity))); + data_buf.push(Entry.RobotisKkokduLite.getHighByte(Entry.RobotisKkokduLite.getLowWord(velocity))); + data_buf.push(Entry.RobotisKkokduLite.getLowByte(Entry.RobotisKkokduLite.getHighWord(velocity))); + data_buf.push(Entry.RobotisKkokduLite.getHighByte(Entry.RobotisKkokduLite.getHighWord(velocity))); + data_buf.push(Entry.RobotisKkokduLite.getLowByte(Entry.RobotisKkokduLite.getLowWord(engValue))); + data_buf.push(Entry.RobotisKkokduLite.getHighByte(Entry.RobotisKkokduLite.getLowWord(engValue))); + data_buf.push(Entry.RobotisKkokduLite.getLowByte(Entry.RobotisKkokduLite.getHighWord(engValue))); + data_buf.push(Entry.RobotisKkokduLite.getHighByte(Entry.RobotisKkokduLite.getHighWord(engValue))); + + data_sendqueue.push([INST_DXL_REGWRITE, 112, 8, i, data_buf]); + } + + data_sendqueue.push([INST_DXL_ACTION, 0, 0, 0xFE]); + + for (let j = 1; j < 9; j++) { + data_sendqueue.push([INST_DXL_REGWRITE, 112, 4, j, [0]]); + } + data_sendqueue.push([INST_DXL_ACTION, 0, 0, 0xFE]); + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + move_time + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['KkokduLite.dxl_control(%1, %2, %3, %4, %5, %6, %7, %8, %9)'] }, + }, + + robotis_kkokdu_lite_dxl_position_time: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ["1", '1'], + ["2", '2'], + ["3", '3'], + ["4", '4'], + ["5", '5'], + ["6", '6'], + ["7", '7'], + ["8", '8'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + 1, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['1'], + }, + ], + type: 'robotis_kkokdu_lite_dxl_position_time', + }, + + paramsKeyMap: { + DXLNUM: 0, + ANGLE: 1, + TIME: 2, + }, + class: 'robotis_kkokdu_lite_move', + isNotFor: ['RobotisKkokduLite'], + func(entity, script) { + let data_instruction = Entry.Robotis_rb.INSTRUCTION.BYPASS_WRITE; + let data_address = 0; + let data_length = 0; + + data_address = Entry.Robotis_rb.CONTROL_TABLE.DXL_PROFILE_VELOCITY[0]; + data_length = + Entry.Robotis_rb.CONTROL_TABLE.DXL_PROFILE_VELOCITY[1] + + Entry.Robotis_rb.CONTROL_TABLE.DXL_GOAL_POSITION[1]; + + let dxlID = script.getField('DXLNUM', script); + let angle = script.getNumberValue('ANGLE', script); + let time = script.getNumberValue('TIME', script) * 1000; + let data_buf = []; + + let engValue = 2048; + engValue = Math.floor(2048 - Math.round(angle * 4096) / 360); + let velocity = 0; + + if (time == 0) { + velocity = 0; + } else { + velocity = Math.round( + Math.floor( + (60 * + Math.abs( + engValue - Entry.RobotisKkokduLite.dxlPositions[dxlID] + ) * + 1000) / + 4096 / + time + ) / 0.229 + ); + } + + data_buf.push(velocity % 256); + data_buf.push(Math.floor(velocity / 256)); + data_buf.push(0); + data_buf.push(0); + + data_buf.push(engValue % 256); + data_buf.push(Math.floor(engValue / 256)); + data_buf.push(0); + data_buf.push(0); + + let data_sendqueue = [ + [data_instruction, data_address, data_length, dxlID, data_buf], + ]; + + return Entry.RobotisKkokduLite.postCallReturn( + script, + data_sendqueue, + time + DEFAULT_DELAY + ); + }, + syntax: { js: [], py: ['KkokduLite.dxl_each_control(%1, %2, %3)'] }, + }, + + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + }; + } + + requestLocalData() { + let packets = []; + while (this.robotisBuffer.length > 0) { + const data = this.robotisBuffer.shift(); + const instruction = data[0]; + const address = data[1]; + const length = data[2]; + const value = data[3]; + const dataBuffer = data[4]; + let id = 0; + let packet = null; + + switch (instruction) { + case INST_WRITE: + id = 200; + packet = this.writePacket(id, address, length, value); + break; + case INST_BYPASS_WRITE: + id = value; + packet = this.writePacket(id, address, length, dataBuffer); + break; + case INST_DXL_REGWRITE: + id = value; + packet = this.registWritePacket(id, address, length, dataBuffer); + break; + case INST_DXL_ACTION: + id = value; + packet = this.actionPacket(id); + break; + } + + if (packet !== null && Array.isArray(packet)) { + packets.push(...packet); + } + } + return packets; + } + + handleLocalData(data) { + let stuffLength = 0; + //console.log(`length: ${data.length}`); + for (let i = 0; i < data.length; i++) { + //this.receiveBuffer.push(data[i]); + const dataIn = data[i]; + + switch (this.packetReceiveState) { + case PACKET_STATE_IDLE: + if (this.headerCount >= 2) { + rxPacket.header[2] = dataIn; + + if ( + rxPacket.header[0] == 0xff && + rxPacket.header[1] == 0xff && + rxPacket.header[2] == 0xfd + ) { + this.headerCount = 0; + this.packetReceiveState = PACKET_STATE_RESERVED; + } else { + rxPacket.header[0] = rxPacket.header[1]; + rxPacket.header[1] = rxPacket.header[2]; + rxPacket.header[2] = 0; + } + } else { + rxPacket.header[this.headerCount] = dataIn; + this.headerCount++; + } + break; + + case PACKET_STATE_RESERVED: + if (dataIn == 0xfd) { + this.packetReceiveState = PACKET_STATE_IDLE; + } else { + rxPacket.reserved = dataIn; + this.packetReceiveState = PACKET_STATE_ID; + } + break; + + case PACKET_STATE_ID: + rxPacket.id = dataIn; + this.packetReceiveState = PACKET_STATE_LENGTH_L; + break; + + case PACKET_STATE_LENGTH_L: + rxPacket.packetLength = dataIn; + this.packetReceiveState = PACKET_STATE_LENGTH_H; + break; + + case PACKET_STATE_LENGTH_H: + rxPacket.packetLength |= dataIn << 8; + if (rxPacket.packetLength < 1000) { + this.packetReceiveState = PACKET_STATE_DATA; + } else { + this.packetReceiveState = PACKET_STATE_IDLE; + } + rxPacket.index = 0; + break; + + case PACKET_STATE_DATA: + rxPacket.data[rxPacket.index] = dataIn; + rxPacket.index++; + + if (rxPacket.index >= rxPacket.packetLength - 2) { + this.packetReceiveState = PACKET_STATE_CRC_L; + } + break; + + case PACKET_STATE_CRC_L: + rxPacket.crcReceived = dataIn; + this.packetReceiveState = PACKET_STATE_CRC_H; + break; + + case PACKET_STATE_CRC_H: + rxPacket.crcReceived |= dataIn << 8; + + stuffLength = this.removeStuffing(rxPacket.data, rxPacket.packetLength); + rxPacket.packetLength -= stuffLength; + + rxPacket.cmd = rxPacket.data[0]; + rxPacket.error = rxPacket.data[1]; + + if (rxPacket.cmd == INST_STATUS) { + //console.log(`rx length: ${rxPacket.packetLength}`); + if (rxPacket.packetLength >= 147) { + let tempValue = 0; + for (let i = 0; i < addrMap.length; i++) { + switch (addrMap[i][1]) { + case 1: + this.dataBuffer[addrMap[i][2]] = + rxPacket.data[2 + addrMap[i][0]]; + break; + + case 2: + tempValue = + rxPacket.data[2 + addrMap[i][0]] + + (rxPacket.data[2 + addrMap[i][0] + 1] << 8); + if (tempValue >= 32768) { + tempValue = tempValue - 65536; + } + this.dataBuffer[addrMap[i][2]] = tempValue; + break; + + case 4: + this.dataBuffer[addrMap[i][2]] = + rxPacket.data[2 + addrMap[i][0]] + + (rxPacket.data[2 + addrMap[i][0] + 1] << 8) + + (rxPacket.data[2 + addrMap[i][0] + 2] << 16) + + (rxPacket.data[2 + addrMap[i][0] + 3] << 24); + break; + } + } + + const dxlPositionStartAddr = + addrMap[addrMap.length - 1][0] + addrMap[addrMap.length - 1][1]; + + // DXL Position + for (let i = 0; i < 20; i++) { + const currentId = + rxPacket.data[2 + dxlPositionStartAddr + 3 * i]; + const currentPos = + rxPacket.data[2 + dxlPositionStartAddr + 3 * i + 1] + + (rxPacket.data[2 + dxlPositionStartAddr + 3 * i + 2] << 8); + if (currentId != 0xff && currentPos != 0xffff) { + this.dxlPositions[currentId] = currentPos; + } + } + + const lineCategoryStartAddr = dxlPositionStartAddr + 3 * 20; + // line category + this.dataBuffer[5201] = rxPacket.data[2 + lineCategoryStartAddr]; + + const sensorStartAddr = lineCategoryStartAddr + 1; + + // 온습도+조도+동작감지센서값 + this.pirPir[0] = rxPacket.data[2 + sensorStartAddr]; + this.pirTemperature[0] = rxPacket.data[2 + sensorStartAddr + 1]; + this.pirHumidity[0] = rxPacket.data[2 + sensorStartAddr + 2]; + this.pirBrightness[0] = rxPacket.data[2 + sensorStartAddr + 3]; + + // 거리+버튼+조도센서값 + this.distanceDistance[0] = + rxPacket.data[2 + sensorStartAddr + 4] + + (rxPacket.data[2 + sensorStartAddr + 5] << 8); + this.distanceButton[0] = rxPacket.data[2 + sensorStartAddr + 6]; + this.distanceBrightness[0] = rxPacket.data[2 + sensorStartAddr + 7]; + + for (let i = 0; i < addrMap2.length; i++) { + switch (addrMap2[i][1]) { + case 1: + this.dataBuffer[addrMap2[i][2]] = + rxPacket.data[2 + addrMap2[i][0]]; + break; + + case 2: + tempValue = + rxPacket.data[2 + addrMap2[i][0]] + + (rxPacket.data[2 + addrMap2[i][0] + 1] << 8); + if (tempValue >= 32768) { + tempValue = tempValue - 65536; + } + this.dataBuffer[addrMap2[i][2]] = tempValue; + break; + + case 4: + this.dataBuffer[addrMap2[i][2]] = + rxPacket.data[2 + addrMap2[i][0]] + + (rxPacket.data[2 + addrMap2[i][0] + 1] << 8) + + (rxPacket.data[2 + addrMap2[i][0] + 2] << 16) + + (rxPacket.data[2 + addrMap2[i][0] + 3] << 24); + break; + } + } + } + } + + this.packetReceiveState = PACKET_STATE_IDLE; + break; + + default: + // code block + } + } + } + + requestInitialData() { + this.robotisBuffer = []; + this.robotisBuffer.push([INST_WRITE, 21, 2, 20]); + this.robotisBuffer.push([INST_WRITE, 19, 1, 1]); // bypass 모드 켜기 + this.robotisBuffer.push([INST_WRITE, 20, 1, 0]); // bypass port를 BLE로 설정 + this.robotisBuffer.push([INST_WRITE, 23, 1, 1]); // auto report 기능 켜기 + this.robotisBuffer.push([INST_WRITE, 4250, 1, 1]); // ai_camera 텍스트 지우기 + this.robotisBuffer.push([INST_WRITE, 722, 1, 0]); // dxl 토크 끄기 + //this.robotisBuffer.push([INST_WRITE, 63, 1, 1]); // 부저음 시간 설정 + //this.robotisBuffer.push([INST_WRITE, 60, 1, 70]); // 부저음 발생 + this.robotisBuffer.push([INST_WRITE, 113, 2, 1040]); // "띵" 효과음 발생 + /* + //const ping = [0xff, 0xff, 0xfd, 0x00, 0xc8, 0x03, 0x00, 0x01, 0x3b, 0xfa]; + // run entry mode + const packet = [ + 0xff, 0xff, 0xfd, 0x00, 0xc8, 0x07, 0x00, 0x03, 0x15, 0x00, 0x14, 0x00, 0xc1, 0xb3, + ]; + return packet; + */ + } + + async initialHandshake() { + const status = true; + let sendBuffer = null; + this.requestInitialData(); + while (this.robotisBuffer.length) { + const data = this.robotisBuffer.shift(); + const instruction = data[0]; + const address = data[1]; + const length = data[2]; + const value = data[3]; + const dataBuffer = data[4]; + let id = 0; + + switch (instruction) { + case INST_WRITE: + id = 200; + sendBuffer = this.writePacket(id, address, length, value); + break; + case INST_BYPASS_WRITE: + id = value; + sendBuffer = this.writePacket(id, address, length, dataBuffer); + break; + } + Entry.hwLite.serial.sendAsciiAsBuffer(sendBuffer); + if (instruction == INST_WRITE && address == 2100 && length == 1 && value == 1) { + this.robotisBuffer = []; + } + } + return status; + } + })(); +})(); + +module.exports = Entry.RobotisKkokduLite; diff --git a/src/playground/blocks/hardwareLite/metadata_robotis_kkokdu_lite.json b/src/playground/blocks/hardwareLite/metadata_robotis_kkokdu_lite.json new file mode 100644 index 0000000000..163f6d3c40 --- /dev/null +++ b/src/playground/blocks/hardwareLite/metadata_robotis_kkokdu_lite.json @@ -0,0 +1,9 @@ +{ + "name": "RobotisKkokduLite", + "version": "1.0.0", + "type": "hardware", + "title": "로보티즈 꼭두", + "description": "로보티즈", + "imageName": "robotis_kkokdu_lite", + "moduleId": "070701" +}