/***
* KMMotorCommandKMOne.js
* Created by Harada Hiroshi on 2017/12/07.
*
* Copyright (c) 2017 Keigan Inc. https://keigan-motor.com/
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
'use strict';
const EventEmitter = require("events").EventEmitter;
const KMUtl = require('./KMUtl');
const KMComWebBLE = require('./KMComWebBLE');
const KMStructures=require('./KMStructures');
/**
* @classdesc KM1コマンド送信クラス
*/
class KMMotorCommandKMOne extends EventEmitter{
/********************************************
* 定数
********************************************/
/**
* 接続方式定数
* @readonly
* @enum {number}
* @property {number} WEBBLE - 1:WEBBLE
* @property {number} BLE - 2:BLE
* @property {number} SERIAL - 3:SERIAL
*/
static get KM_CONNECT_TYPE(){
return {"WEBBLE":1,"BLE":2,"SERIAL":3};
}
/**
* cmdPreparePlaybackMotionの開始位置オプション定数
* @readonly
* @enum {number}
* @property {number} START_POSITION_ABS - 0:記憶された開始位置(絶対座標)からスタート
* @property {number} START_POSITION_CURRENT - 1:現在の位置を開始位置としてスタート
*/
static get cmdPreparePlaybackMotion_START_POSITION(){
return{
'START_POSITION_ABS':0,
'START_POSITION_CURRENT':1
};
}
/**
* cmdLedのLEDの点灯状態オプション定数
* @readonly
* @enum {number}
* @property {number} LED_STATE_OFF - 0:消灯
* @property {number} LED_STATE_ON_SOLID - 1:LED点灯(点灯しっぱなし)
* @property {number} LED_STATE_ON_FLASH - 2:LED点滅(一定間隔で点滅)
* @property {number} LED_STATE_ON_DIM - :3LEDがゆっくり明滅する
*/
static get cmdLed_LED_STATE(){
return{
'LED_STATE_OFF':0,
'LED_STATE_ON_SOLID':1,
'LED_STATE_ON_FLASH':2,
'LED_STATE_ON_DIM':3
};
}
/**
* cmdCurveTypeの加減速カーブオプション定数
* @readonly
* @enum {number}
* @property {number} CURVE_TYPE_NONE - 0:モーションコントロール OFF
* @property {number} CURVE_TYPE_TRAPEZOID - 1:モーションコントロール ON (台形加減速)
*/
static get cmdCurveType_CURVE_TYPE(){
return{
'CURVE_TYPE_NONE': 0,
'CURVE_TYPE_TRAPEZOID':1
};
}
/**
* cmdMotorMeasurementIntervalのモーター測定値の取得間隔定数
* @readonly
* @enum {number}
* @property {number} MOTOR_MEAS_INTERVAL_5MS - 0:5MS
* @property {number} MOTOR_MEAS_INTERVAL_10MS - 1:10MS
* @property {number} MOTOR_MEAS_INTERVAL_20MS - 2:20MS
* @property {number} MOTOR_MEAS_INTERVAL_50MS - 3:50MS
* @property {number} MOTOR_MEAS_INTERVAL_100MS - 4:100MS
* @property {number} MOTOR_MEAS_INTERVAL_200MS - 5:200MS
* @property {number} MOTOR_MEAS_INTERVAL_500MS - 6:500MS
* @property {number} MOTOR_MEAS_INTERVAL_1000MS - 7:1000MS
*/
static get cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL(){
return{
'MOTOR_MEAS_INTERVAL_5MS': 0,
'MOTOR_MEAS_INTERVAL_10MS':1,
'MOTOR_MEAS_INTERVAL_20MS':2,
'MOTOR_MEAS_INTERVAL_50MS':3,
'MOTOR_MEAS_INTERVAL_100MS':4,
'MOTOR_MEAS_INTERVAL_200MS':5,
'MOTOR_MEAS_INTERVAL_500MS':6,
'MOTOR_MEAS_INTERVAL_1000MS':7
};
}
/**
* cmdIMUMeasurementIntervalの加速度・ジャイロ測定値の取得間隔定数
* @readonly
* @enum {number}
* @property {number} MOTOR_MEAS_INTERVAL_5MS - 0:5MS
* @property {number} MOTOR_MEAS_INTERVAL_10MS - 1:10MS
* @property {number} MOTOR_MEAS_INTERVAL_20MS - 2:20MS
* @property {number} MOTOR_MEAS_INTERVAL_50MS - 3:50MS
* @property {number} MOTOR_MEAS_INTERVAL_100MS - 4:100MS
* @property {number} MOTOR_MEAS_INTERVAL_200MS - 5:200MS
* @property {number} MOTOR_MEAS_INTERVAL_500MS - 6:500MS
* @property {number} MOTOR_MEAS_INTERVAL_1000MS - 7:1000MS
*/
static get cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL(){
return{
'IMU_MEAS_INTERVAL_5MS': 0,
'IMU_MEAS_INTERVAL_10MS':1,
'IMU_MEAS_INTERVAL_20MS':2,
'IMU_MEAS_INTERVAL_50MS':3,
'IMU_MEAS_INTERVAL_100MS':4,
'IMU_MEAS_INTERVAL_200MS':5,
'IMU_MEAS_INTERVAL_500MS':6,
'IMU_MEAS_INTERVAL_1000MS':7
};
}
/*
* ReadRegisterで取得する時用のコマンド引数定数
* @readonly
* @enum {number}
* @property {number} maxSpeed - 2:最大速さ
* @property {number} minSpeed - 3:最小速さ
* @property {number} curveType - 5:加減速曲線
* @property {number} acc - 7:加速度
* @property {number} dec - 8:減速度
* @property {number} maxTorque - 14:最大トルク
* @property {number} qCurrentP - 24:q軸電流PIDゲイン(P)
* @property {number} qCurrentI - 25:q軸電流PIDゲイン(I)
* @property {number} qCurrentD - 26:q軸電流PIDゲイン(D)
* @property {number} speedP - 27:速度PIDゲイン(P)
* @property {number} speedI - 28:速度PIDゲイン(I)
* @property {number} speedD - 29:速度PIDゲイン(D)
* @property {number} positionP - 30:位置PIDゲイン(P)
* @property {number} positionI - 31:位置PIDゲイン(I)
* @property {number} positionD - 32:位置PIDゲイン(D)
* @property {number} posControlThreshold - 33:モーターの位置制御時、ID制御を有効にする偏差の絶対値
* @property {number} interface - 46:モーター通信経路
* @property {number} response - 48:コマンドを受信したときに通知するか
* @property {number} ownColor - 58:デバイスLEDの固有色
* @property {number} deviceName - 70:
* @property {number} deviceInfo - 71:
*/
static get cmdReadRegister_COMMAND(){
return{
"maxSpeed":0x02,//
"minSpeed":0x03,//
"curveType":0x05,//
"acc":0x07,//
"dec":0x08,//
"maxTorque":0x0E,//
"teachingInterval":0x16,//
"playbackInterval":0x17,//
"qCurrentP":0x18,//
"qCurrentI":0x19,//
"qCurrentD":0x1A,//
"speedP":0x1B,//
"speedI":0x1C,//
"speedD":0x1D,//
"positionP":0x1E,//
"positionI":0x1F,//
"positionD":0x20,//
"posControlThreshold":0x21,//
//"notifyPosArrival":0x2B,
"motorMeasurementInterval":0x2C,//
"motorMeasurementByDefault":0x2D,//
"interface":0x2E,//
//"response":0x30,//todo::値が取得出来ない 2.24
"ownColor":0x3A,//
"iMUMeasurementInterval":0x3C,//
"iMUMeasurementByDefault":0x3D,//
"deviceName":0x46,//
"deviceInfo":0x47,//
"speed":0x58,//
"positionOffset":0x5B,//
"moveTo":0x66,//
"hold":0x72,//
"status":0x9A,//
"i2CSlaveAddress":0xC0,//
"uartBaudRate":0xC3,
"led":0xE0,//
"enableCheckSum":0xF3//
};
}
/*
* モーター制御手段(インターフェイス)の経路指定用定数
* @readonly
* @enum {number}
* @property {number} BLE - 0x1:BLE
* @property {number} USB - 0x1000:USB
* @property {number} I2C - 0x10000:I2C
* @property {number} HDDBTN - 0x10000000:物理ボタン
*/
static get cmdInterface_INTERFACE_TYPE(){
return{
"BLE":0b1,
"USB":0b1000,
"I2C":0b10000,
"HDDBTN":0b10000000
};
}
/**
* constructor
* @param {KMMotorCommandKMOne.KM_CONNECT_TYPE} connect_type 接続方式
* @param {object} kmcom 通信オブジェクト {@link KMComBLE} {@link KMComWebBLE}
* @private
*/
constructor(connect_type,kmcom){
super();
/**
* イベントタイプ定数
* @readonly
* @enum {string}
*/
this.EVENT_TYPE={
/** 初期化完了時<br>return:function({KMDeviceInfo}) */ init:"init",
/** 接続時<br>return:function({KMDeviceInfo}) */ connect:"connect",
/** 切断時<br>return:function({KMDeviceInfo}) */ disconnect:"disconnect",
/** 接続に失敗時<br>return:function({KMDeviceInfo},{msg}) */ connectFailure:"connectFailure",
/** モーター回転情報受信時<br>return:function({@link KMRotState}) */ motorMeasurement:"motorMeasurement",
/** モーターIMU情報受信時<br>return:function({@link KMImuState}) */ imuMeasurement:"imuMeasurement",
/** モーターログ情報受信時<br>return:function({cmdName},{errorlogObject}) */ motorLog:"motorLog",
};
Object.freeze(this.EVENT_TYPE);//info::後からフリーズしないとjsdocが生成されない。
/**
* モーターの全コマンド
* @readonly
* @enum {number}
* @private
* @ignore
*/
this._MOTOR_COMMAND={
/** 最大速さを設定する */ maxSpeed:0x02,
/** 最小速さを設定する */ minSpeed:0x03,
/** 加減速曲線を設定する */ curveType:0x05,
/** 加速度を設定する */ acc:0x07,
/** 減速度を設定する */ dec:0x08,
/** 最大トルクを設定する */ maxTorque:0x0E,
/** ティーチング間隔 */ teachingInterval:0x16,
/** プレイバック間隔 */ playbackInterval:0x17,
/** q軸電流PIDゲイン(P)を設定する */ qCurrentP:0x18,
/** q軸電流PIDゲイン(I)を設定する */ qCurrentI:0x19,
/** q軸電流PIDゲイン(D)を設定する */ qCurrentD:0x1A,
/** 速度PIDゲイン(P)を設定する */ speedP:0x1B,
/** 速度PIDゲイン(I)を設定する */ speedI:0x1C,
/** 速度PIDゲイン(D)を設定する */ speedD:0x1D,
/** 位置PIDゲイン(P)を設定する */ positionP:0x1E,
/** 位置PIDゲイン(I)を設定する */ positionI:0x1F,
/** 位置PIDゲイン(D)を設定する */ positionD:0x20,
/** モーターの位置制御時、ID制御を有効にする偏差の絶対値を指定する */ posControlThreshold:0x21,
/** PIDゲインをリセットする */ resetPID:0x22,
/** 位置制御時、目標位置に到達時、判定条件を満たした場合通知を行う*/ notifyPosArrival:0x2B,
/** モーター測定値の取得間隔(USB,I2Cのみ) */ motorMeasurementInterval:0x2C,
/** モーター測定値の取得設定 */ motorMeasurementByDefault:0x2D,
/** モーター制御手段(インターフェイス)の設定 */ interface:0x2E,
/** コマンドを受信したときに成功通知(errorCode = 0)をするかどうか */ response:0x30,
/** デバイスLEDの固有色を設定する */ ownColor:0x3A,
/** IMU測定値通知間隔(有線のみ) */ iMUMeasurementInterval:0x3C,
/** デフォルトでのIMU測定値通知ON/OFF */ iMUMeasurementByDefault:0x3D,
/** 指定の設定値を取得する */ readRegister:0x40,
/** 全ての設定値をフラッシュに保存する */ saveAllRegisters:0x41,
/** デバイスネームの取得 */ readDeviceName:0x46,
/** デバイス情報の取得 */ readDeviceInfo:0x47,
/** 指定の設定値をリセットする */ resetRegister:0x4E,
/** 全設定値をリセットする */ resetAllRegisters:0x4F,
/** モーターの動作を不許可とする */ disable:0x50,
/** モーター動作を許可する */ enable:0x51,
/** 速度の大きさを設定する */ speed:0x58,
/** 位置のプリセットを行う(原点設定) */ presetPosition:0x5A,
/** 位置のプリセットに関するOFFSET量 */ readPositionOffset:0x5B,
/** 正回転する(反時計回り) */ runForward:0x60,
/** 逆回転する(時計回り) */ runReverse:0x61,
/** モーターを指定速度で回転させる */ run:0x62,
/** 絶対位置に移動する(速度あり) */ moveToPositionSpeed:0x65,
/** 絶対位置に移動する */ moveToPosition:0x66,
/** 相対位置に移動する(速度あり) */ moveByDistanceSpeed:0x67,
/** 相対位置に移動する */ moveByDistance:0x68,
/** モーターの励磁を停止する */ free:0x6C,
/** 速度ゼロまで減速し停止する */ stop:0x6D,
/** トルク制御を行う */ holdTorque:0x72,
/** タスクセットを実行する */ startDoingTaskset:0x81,
/** タスクセットを停止 */ stopDoingTaskset:0x82,
/** モーションを再生(準備なし) */ startPlaybackMotion:0x85,
/** モーション再生を停止する */ stopPlaybackMotion:0x88,
/** キューを停止する */ pauseQueue:0x90,
/** キューを再開する */ resumeQueue:0x91,
/** キューを指定時間停止し再開する */ waitQueue:0x92,
/** キューをリセットする */ resetQueue:0x95,
/** モーターの状態 */ readStatus:0x9A,
/** タスクセットの記録を開始する */ startRecordingTaskset:0xA0,
/** タスクセットの記録を停止する */ stopRecordingTaskset:0xA2,
/** 指定のタスクセットを削除する */ eraseTaskset:0xA3,
/** タスクセットを全削除する */ eraseAllTaskset:0xA4,
/** タスクセットの記録名設定 */ setTasksetName:0xA5,
/** タスクセット内容把握 */ readTasksetInfo:0xA6,
/** タスクセット使用状況把握 */ readTasksetUsage:0xA7,
/** ダイレクトティーチング開始(準備なし) */ startTeachingMotion:0xA9,
/** ティーチングを停止する */ stopTeachingMotion:0xAC,
/** ティーチングで覚えた動作を削除する */ eraseMotion:0xAD,
/** ティーチングで覚えた全動作を削除する */ eraseAllMotion:0xAE,
/** I2Cスレーブアドレス */ setI2CSlaveAddress:0xC0,
/** LEDの点灯状態をセットする */ led:0xE0,
/** モーターの測定値取得(通知)を開始 */ enableMotorMeasurement:0xE6,
/** モーターの測定値取得(通知)を開始 */ disableMotorMeasurement:0xE7,
/** IMUの値取得(通知)を開始する */ enableIMUMeasurement:0xEA,
/** IMUの値取得(通知)を停止する */ disableIMUMeasurement:0xEB,
/** システムを再起動する */ reboot:0xF0,
/** チェックサム(CRC16) 有効化 */ enableCheckSum:0xF3,
/** ファームウェアアップデートモードに入る */ enterDeviceFirmwareUpdate:0xFD
};
Object.freeze(this._MOTOR_COMMAND);//info::後からフリーズしないとjsdocが生成されない。
//モーターの全コマンド(逆引用)
this._REV_MOTOR_COMMAND={};
Object.keys(this._MOTOR_COMMAND).forEach((k)=>{this._REV_MOTOR_COMMAND[this._MOTOR_COMMAND[k]]=k;});
//SendNotifyPromisのリスト
this._notifyPromisList=[];
this.cmdPreparePlaybackMotion_START_POSITION=this.constructor.cmdPreparePlaybackMotion_START_POSITION;
this.cmdLed_LED_STATE=this.constructor.cmdLed_LED_STATE;
this.cmdCurveType_CURVE_TYPE=this.constructor.cmdCurveType_CURVE_TYPE;
this.cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL=this.constructor.cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL;
this.cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL=this.constructor.cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL;
this.cmdInterface_INTERFACE_TYPE=this.constructor.cmdInterface_INTERFACE_TYPE;
this._PositionArrivalNotification=null;//KM_SUCCESS_ARRIVAL監視用
this._PositionArrivalNotificationTimeOutId=0;
//--------------------------
// section::entry point
//--------------------------
this._connectType=connect_type;
this._KMCom=kmcom;
//内部イベントバインド
this._KMCom.onInit=(connector)=>{
this.emit(this.EVENT_TYPE.init,connector.deviceInfo);//デバイス情報を返す
};
/**
* モーター初期化時イベント
* @event KMMotorCommandKMOne#init
* @type {KMDeviceInfo}
* @property {object} KMDeviceInfo {@link KMDeviceInfo}
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.init,function(kMDeviceInfo){
* console.log(kMDeviceInfo.GetValObj());
* });
* });
*/
this._KMCom.onConnect=(connector)=>{
this.emit(this.EVENT_TYPE.connect,connector.deviceInfo);
};
/**
* モーター接続時イベント
* @event KMMotorCommandKMOne#connect
* @type {KMDeviceInfo}
* @property {object} KMDeviceInfo {@link KMDeviceInfo}
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.connect,function(kMDeviceInfo){
* console.log(kMDeviceInfo.GetValObj());
* });
* });
*/
this._KMCom.onDisconnect=(connector)=>{
this.emit(this.EVENT_TYPE.disconnect,connector.deviceInfo);
};
/**
* モーター切断時イベント
* @event KMMotorCommandKMOne#disconnect
* @type {KMDeviceInfo}
* @property {object} KMDeviceInfo {@link KMDeviceInfo}
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.disconnect,function(kMDeviceInfo){
* console.log(kMDeviceInfo.GetValObj());
* });
* });
*/
this._KMCom.onConnectFailure=(connector, err)=>{
this.emit(this.EVENT_TYPE.connectFailure,connector.deviceInfo,err);
};
/**
* モーター接続失敗時イベント
* @event KMMotorCommandKMOne#connectFailure
* @type {KMDeviceInfo}
* @property {object} KMDeviceInfo {@link KMDeviceInfo}
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.connectFailure,function(kMDeviceInfo){
* console.log(kMDeviceInfo.GetValObj());
* });
* });
*/
/**
* モーター回転情報受信
* @param {KMRotState} rotState
* @private
*/
this._KMCom.onMotorMeasurement=(rotState)=>{
//let rotState=new KMStructures.KMRotState(res.position,res.velocity,res.torque);
this.emit(this.EVENT_TYPE.motorMeasurement,rotState);
};
/**
* モーター回転情報受信時イベント
* @event KMMotorCommandKMOne#motorMeasurement
* @type {KMRotState}
* @property {object} KMRotState {@link KMRotState}
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.motorMeasurement,function(kMRotState){
* console.log(name,kMRotState.GetValObj());
* });
* });
*/
/**
* モーターIMU情報受信
* @param {KMImuState} imuState
* @private
*/
this._KMCom.onImuMeasurement=(imuState)=>{
this.emit(this.EVENT_TYPE.imuMeasurement,imuState);
};
/**
* モーターIMU情報受信時イベント
* @event KMMotorCommandKMOne#imuMeasurement
* @type {KMImuState}
* @property {object} KMImuState {@link KMImuState}
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.imuMeasurement,function(kMImuState){
* console.log(name,kMImuState.GetValObj());
* });
* });
*/
/**
* モーターログ情報取得
* @param {number} cmdID
* @param {KMMotorLog} motorLog
* @private
*/
this._KMCom.onMotorLog=(motorLog)=>{
//コマンドIDからコマンド名を取得追加
let cmdName=this._REV_MOTOR_COMMAND[motorLog.cmdID]?this._REV_MOTOR_COMMAND[motorLog.cmdID]:motorLog.cmdID;
motorLog.cmdName=cmdName;
this.emit(this.EVENT_TYPE.motorLog,motorLog);
//info::位置制御時、目標位置に到達時、判定条件を満たした場合通知を行う
if(motorLog.errID===100){//KM_SUCCESS_ARRIVAL
if(this._PositionArrivalNotification){
if(this._PositionArrivalNotification.tagName===motorLog.id){
this._PositionArrivalNotification.callResolve({id:this._PositionArrivalNotification.tagName,msg:'Position Arrival Notification',info:motorLog.info});
}
else{
// this._PositionArrivalNotification.callReject({id:this._PositionArrivalNotification.tagName,msg:'Instruction override:' +cmdName,overrideId:motorLog.id});
}
}
}
};
/**
* モーターログ情報受信時イベント
* @event KMMotorCommandKMOne#motorLog
* @type {KMMotorLog}
* @property {object} KMMotorLog {@link KMMotorLog}
*
* @example
* KMMotorOneUSBSerial.on(KMMotorOneUSBSerial.EVENT_TYPE.discoverNewMotor,function(kMMotorOne){
* kMMotorOne.on(kMMotorOne.EVENT_TYPE.motorLog,function(kMMotorLog){
* console.log(name,kMMotorLog.GetValObj());
* });
* });
*/
/**
* モーター設定情報取得
* @param {number} registerCmd
* @param {number} res
* @private
*/
this._KMCom.onMotorSetting=(registerCmd, res)=>{
_KMNotifyPromis.sendGroupNotifyResolve(this._notifyPromisList,registerCmd,res);
};
}
/********************************************
* プロパティ
********************************************/
/**
* モーターとの接続が有効か
* @readonly
* @type {boolean}
*/
get isConnect(){
return this._KMCom.deviceInfo.isConnect;
}
/**
* 接続方式
* @readonly
* @type {KMMotorCommandKMOne.KM_CONNECT_TYPE}
*/
get connectType(){
return this._connectType;
}
/**
* デバイス情報
* @readonly
* @type {KMDeviceInfo}
*/
get deviceInfo(){
return this._KMCom.deviceInfo;
}
/**
* モーター名
* @readonly
* @type {string}
*/
get name(){
return this._KMCom.deviceInfo?this._KMCom.deviceInfo.name:null;
}
/**
* 接続コネクター
* @private
* @type {KMComBase}
* @ignore
*/
get connector(){
return this._KMCom;
}
/********************************************
* section::モーターコマンド https://document.keigan-motor.com/motor-control-command/motor_action.html
********************************************/
/**
* @summary モーター動作を不許可とする(上位命令)
* @desc 安全用:この命令を入れるとモーターは動作しない<br>
* コマンドはタスクセットに記録することは不可
*/
cmdDisable(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.disable);
}
/**
* @summary モーター動作を許可する(上位命令)
* @desc 安全用:この命令を入れるとモーターは動作可能となる<br>
* モーター起動時は disable 状態のため、本コマンドで動作を許可する必要があり<br>
* コマンドはタスクセットに記録することは不可
*
*/
cmdEnable(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.enable);
}
/**
* @summary 速度の大きさをセットする(単位系:RPM)
* @param {number} speed_rpm float [0-X rpm] (正の数)
*/
cmdSpeed_rpm(speed_rpm = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(speed_rpm*0.10471975511965977,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.speed,buffer);
}
/**
* @summary 速度の大きさをセットする(単位系:ラジアン)
* @param {number} speed float 速度の大きさ 単位:角度(ラジアン)/秒 [0-X rps] (正の数)
*/
cmdSpeed(speed = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(speed,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.speed,buffer);
}
/**
* @summary 位置のプリセットを行う(原点設定)(単位系:ラジアン)
* @param {number} position float 絶対角度:radians
*/
cmdPresetPosition(position = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(KMUtl.toNumber(position),10));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.presetPosition,buffer);
}
/**
* @summary 位置のプリセットに関するOFFSET量
* @desc 位置のオフセット量(presetPositionで設定した値に対応)を読み取る
* @returns {Promise<int|Array>}
*/
cmdReadPositionOffset(){
return this.cmdReadRegister(this._MOTOR_COMMAND.readPositionOffset);
}
/**
* @summary 正回転する(反時計回り)
* @desc cmdSpeed で保存された速度で、正回転
*/
cmdRunForward(){
let cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.runForward);
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary 逆回転する(時計回り)
* @desc cmdSpeed で保存された速度で、逆回転
*/
cmdRunReverse(){
let cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.runReverse);
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary モーターを指定速度で回転させる
* @param {number} speed float 速度の大きさ 単位:角度(ラジアン)/秒 [±X rps]
*/
cmdRun(speed = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(speed,10)));
let cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.run,buffer);
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary モーターを指定速度で回転させる
* @param {number} speed_rpm float [±X rpm]
*/
cmdRun_rpm(speed_rpm = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(speed_rpm*0.10471975511965977,10));
let cid= this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.run,buffer);
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary 絶対位置に移動する
* @desc speedの指定がnullの場合、直近の速度が引き継がれる
* @param {number} position float 角度:radians
* @param {number} speed float 速度の大きさ 単位:角度(ラジアン)/秒 [0-X rps]
*/
cmdMoveToPosition(position,speed=null){
if(position=== undefined){return;}
let cid=null;
if(speed!==null){
let buffer = new ArrayBuffer(8);
new DataView(buffer).setFloat32(0,parseFloat(position,10));
new DataView(buffer).setFloat32(4,parseFloat(speed,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveToPositionSpeed,buffer);
}else{
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(position,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveToPosition,buffer);
}
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary 絶対位置に移動し、移動の成否を通知する (MotorFarm Ver >= 2.23)
* @desc speedの指定がnullの場合、直近の速度が引き継がれる
* <ul>
* <li>このコマンド実行中に別の移動系のコマンドを実行すると'Instruction override'としてrejectされる</li>
* </ul>
* @example
* Promise.resolve().then((resolve) =>{
* kMMotorOne.cmdNotifyPosArrival(1,KMUtl.degreeToRadian(0.5));//到達と判定する目標座標の範囲 +-0.5度
* //原点移動 30rpm タイムアウト 5s
* return kMMotorOne.cmdMoveToPositionSync(0,KMConnector.KMUtl.rpmToRadianSec(30),5000);
* }).then((resolve) =>{
* //position Arrived
* }).catch((e)=>{
* console.log(e);//'Instruction override' or Timeout
* });
* @param {number} position float 角度:radians
* @param {number} speed float 速度の大きさ 単位:角度(ラジアン)/秒 [0-X rps]
* @param {number} timeout int [0 - x ms] デフォルト 0:タイムアウト無し
* @returns {Promise<any>}
*/
cmdMoveToPositionSync(position,speed=null,timeout=0){
if(position=== undefined){return;}
let self=this;
let cid=null;
if(speed!==null){
let buffer = new ArrayBuffer(8);
new DataView(buffer).setFloat32(0,parseFloat(position,10));
new DataView(buffer).setFloat32(4,parseFloat(speed,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveToPositionSpeed,buffer);
}else{
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(position,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveToPosition,buffer);
}
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
//成否の捕捉
return new Promise(function(resolve, reject) {
let tm= Math.abs(parseInt(timeout));
self._PositionArrivalNotification=new _KMNotifyPromis(cid,"cmdMoveToPositionSync",null,resolve,reject,tm);//notify経由のKM_SUCCESS_ARRIVALをPromisと紐付け
if(tm){
self._PositionArrivalNotification.startRejectTimeOutCount();
}
});
}
/**
* @summary 相対位置に移動する
* @desc speedの指定がnullの場合、直近の速度が引き継がれる
* <ul>
* <li>cmdMoveByDistance実行中にcmdMoveByDistance複数回実行すると、積算したdistanceの座標に移動する</li>
* </ul>
* @param {number} distance float 角度:radians[左:+radians 右:-radians]
* @param {number} speed float 速度の大きさ 単位:角度(ラジアン)/秒 [0-X rps] (正の数)
*/
cmdMoveByDistance(distance = 0,speed=null){
let cid=null;
if(speed!==null){
let buffer = new ArrayBuffer(8);
new DataView(buffer).setFloat32(0,parseFloat(distance,10));
new DataView(buffer).setFloat32(4,parseFloat(speed,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveByDistanceSpeed,buffer);
}else{
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(distance,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveByDistance,buffer);
}
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary 相対位置に移動し、移動の成否を通知する (MotorFarm Ver >= 2.23)
* @desc speedの指定がnullの場合、直近の速度が引き継がれる
* <ul>
* <li>このコマンド実行中に別の移動系のコマンドを実行すると'Instruction override'としてrejectされる</li>
* </ul>
* @example
* Promise.resolve().then((resolve) =>{
* kMMotorOne.cmdNotifyPosArrival(1,KMUtl.degreeToRadian(0.5));//到達と判定する目標座標の範囲 +-0.5度
* //360度相対移動 30rpm タイムアウト無し
* return kMMotorOne.cmdMoveByDistanceSync(KMConnector.KMUtl.degreeToRadian(360),KMConnector.KMUtl.rpmToRadianSec(30));
* }).then((resolve) =>{
* //position Arrived
* }).catch((e)=>{
* console.log(e);//'Instruction override' or Timeout
* });
* @param {number} distance float 角度:radians[左:+radians 右:-radians]
* @param {number} speed float 速度の大きさ 単位:角度(ラジアン)/秒 [0-X rps] (正の数)
* @param {number} timeout int [0 - x ms] デフォルト 0:タイムアウト無し
* @returns {Promise<any>}
*/
cmdMoveByDistanceSync(distance = 0,speed=null,timeout=0){
let self=this;
let cid=null;
if(speed!==null){
let buffer = new ArrayBuffer(8);
new DataView(buffer).setFloat32(0,parseFloat(distance,10));
new DataView(buffer).setFloat32(4,parseFloat(speed,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveByDistanceSpeed,buffer);
}else{
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(distance,10));
cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.moveByDistance,buffer);
}
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
//成否の捕捉
return new Promise(function(resolve, reject) {
let tm= Math.abs(parseInt(timeout));
self._PositionArrivalNotification=new _KMNotifyPromis(cid,"cmdMoveByDistanceSync",null,resolve,reject,tm);
if(tm){
self._PositionArrivalNotification.startRejectTimeOutCount();
}
});
}
/**
* @summary モーターの励磁を停止する(感触は残ります)
* @desc 完全フリー状態を再現する場合は、 cmdFree().cmdDisable() として下さい。
*/
cmdFree(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.free);
}
/**
* @summary モーターを速度ゼロまで減速し停止する
* @desc rpm = 0 となる。
*/
cmdStop(){
let cid=this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.stop);
this._moveSyncInstructionOverrideReject(cid);//移動系のSyncコマンド実行時のCBのReject
}
/**
* @summary トルク制御を行う
* @param {number} torque float トルク 単位:N・m [-X ~ + X Nm] 推奨値 0.3-0.05
* @desc 速度や位置を同時に制御する場合は、モーター設定の 0x0E: maxTorque と 0x60: runForward 等を併用して下さい。
*
*/
cmdHoldTorque(torque){
if(torque===undefined){return;}
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,parseFloat(torque,10));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.holdTorque,buffer);
}
/**
* @summary 記憶したタスク(命令)のセットを実行する
* @param {number} index int タスクセット番号(0~65535)
* @param {number} repeating int 繰り返し回数 0は無制限
*
* @desc KM-1 は index: 0~49 まで。(50個のメモリバンク 各8128 Byte まで制限あり)<br>
* タスクセットの記録は、コマンド(タスクセット)を参照下さい。 https://document.keigan-motor.com/motor-control-command/taskset.html
*/
cmdStartDoingTaskset(index = 0,repeating = 1){
let buffer = new ArrayBuffer(6);
new DataView(buffer).setUint16(0,Math.abs(parseInt(index)));
new DataView(buffer).setUint32(2,Math.abs(parseInt(repeating)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.startDoingTaskset,buffer);
};
/**
* @summary タスクセットを停止
* @desc タスクセットの再生を停止する
*/
cmdStopDoingTaskset(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.stopDoingTaskset);
}
/**
* @summary モーションを再生(準備なし)
* @desc モーションのプレイバックを(準備なしで)プレイバック開始する
* @param {number} index int モーション番号(0~65535)
* @param {number} repeating int 繰り返し回数 0は無制限
* @param {KMMotorCommandKMOne.cmdPreparePlaybackMotion_START_POSITION} start_position int スタート位置の設定<br>
* START_POSITION_ABS:記憶された開始位置(絶対座標)からスタート<br>
* START_POSITION_CURRENT:現在の位置を開始位置としてスタート
*/
cmdStartPlaybackMotion(index = 0,repeating = 0,start_position = 0){
let buffer = new ArrayBuffer(7);
new DataView(buffer).setUint16(0,Math.abs(parseInt(index)));
new DataView(buffer).setUint32(2,Math.abs(parseInt(repeating)));
new DataView(buffer).setUint8(6,Math.abs(parseInt(start_position)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.startPlaybackMotion,buffer);
}
/**
* @summary モーション再生を停止する
* @ignore
*/
cmdStopPlaybackMotion(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.stopPlaybackMotion);
}
//---------------------//
// section::キュー操作
//---------------------//
/**
* @summary キューを一時停止する
*/
cmdPauseQueue(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.pauseQueue);
}
/**
* @summary キューを再開する(蓄積されたタスクを再開)
*/
cmdResumeQueue(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.resumeQueue);
}
/**
* @summary キューを指定時間停止し再開する
* @desc cmdPause(キュー停止)を実行し、指定時間(ミリ秒)経過後、自動的に cmdResume(キュー再開) を行います。
* @param {number} time 停止時間[msec]
*/
cmdWaitQueue(time = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setUint32(0,Math.abs(parseInt(time)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.waitQueue,buffer);
}
/**
* @summary キューをリセットする
*/
cmdResetQueue(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.resetQueue);
}
/**
* @summary モーターの状態を読み取る (read専用)
* @returns {Promise<int|Array>}
*/
cmdReadStatus(){
return this.cmdReadRegister(this._MOTOR_COMMAND.readStatus);
}
//---------------------//
// section::タスクセット
//---------------------//
/**
* @summary タスク(命令)のセットの記録を開始する
* @desc 記憶するインデックスのメモリはコマンド:eraseTaskset により予め消去されている必要があり
* @param {number} index int インデックス KM-1 の場合、インデックスの値は 0~49 (計50個記録)
*/
cmdStartRecordingTaskSet(index = 0){
let buffer = new ArrayBuffer(2);
new DataView(buffer).setUint16(0,Math.abs(parseInt(index)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.startRecordingTaskset,buffer);
}
/**
* @summary タスクセットの記録を停止する
*/
cmdStopRecordingTaskset(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.stopRecordingTaskset);
}
/**
* @summary 指定のインデックスのタスクセットを消去する
* @param {number} index int インデックス
*/
cmdEraseTaskset(index = 0){
let buffer = new ArrayBuffer(2);
new DataView(buffer).setUint16(0,Math.abs(parseInt(index)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.eraseTaskset,buffer);
}
/**
* @summary 全てのタスクセットを消去する
*/
cmdEraseAllTaskset(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.eraseAllTaskset);
}
/**
* @summary タスクセットの記録名設定
* @desc タスクセットの記録名を設定する。(これから記録するものに対して)
*/
cmdSetTasksetName(name){
let buffer= (new Uint8Array([].map.call(name, function(c) {
return c.charCodeAt(0);
}))).buffer;
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.setTasksetName,buffer);
}
//---------------------//
// section::ティーチング
//---------------------//
/**
* @summary ダイレクトティーチング開始(準備なし)
* @desc KM-1 の場合、インデックスの値は 0~19 (計20個記録)となる。記録時間は 65408 [msec] を超えることはできない
* 記憶するインデックスのメモリはbleEraseMotion により予め消去されている必要がある
*
* @param {number} index int インデックス [0-19]
* @param {number} time int 記録時間 [msec 0-65408]
*/
cmdStartTeachingMotion(index = 0,lengthRecordingTime = 0){
let buffer = new ArrayBuffer(6);
new DataView(buffer).setUint16(0,Math.abs(parseInt(index)));
new DataView(buffer).setUint32(2,Math.abs(parseInt(lengthRecordingTime)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.startTeachingMotion,buffer);
}
/**
* @summary 実行中のティーチングを停止する
*/
cmdStopTeachingMotion(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.stopTeachingMotion);
}
/**
* @summary 指定したインデックスのモーションを消去する
* @param {number} index int インデックス
*
* @desc KM-1 の場合、インデックスの値は 0~19 (計20個記録)となる
*
*/
cmdEraseMotion(index = 0){
let buffer = new ArrayBuffer(2);
new DataView(buffer).setUint16(0,Math.abs(parseInt(index)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.eraseMotion,buffer);
}
/**
* @summary 全てのモーションを消去する
*/
cmdEraseAllMotion(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.eraseAllMotion);
}
//---------------------//
// section::LED
//---------------------//
/**
* @summary LEDの点灯状態をセットする
* @param {KMMotorCommandKMOne.cmdLed_LED_STATE} cmdLed_LED_STATE int 点灯状態<br>
* LED_STATE_OFF:LED消灯<br>
* LED_STATE_ON_SOLID:LED点灯<br>
* LED_STATE_ON_FLASH:LED点滅(一定間隔で点滅)<br>
* LED_STATE_ON_DIM:LEDがゆっくり明滅する
* @param {number} red int 0-255
* @param {number} green int 0-255
* @param {number} blue int 0-255
*/
cmdLed(cmdLed_LED_STATE,red,green,blue){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setUint8(0,Math.abs(parseInt(cmdLed_LED_STATE)));
new DataView(buffer).setUint8(1,Math.abs(parseInt(red)));
new DataView(buffer).setUint8(2,Math.abs(parseInt(green)));
new DataView(buffer).setUint8(3,Math.abs(parseInt(blue)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.led,buffer);
}
//---------------------//
// IMU ジャイロ
//---------------------//
/**
* @summary IMU(ジャイロ)の値取得(通知)を開始する
* @desc 本コマンドを実行すると、IMUのデータはBLEのキャラクタリスティクスMOTOR_IMU_MEASUREMENTに通知される<br>
* MOTOR_IMU_MEASUREMENTのnotifyはイベントタイプ KMMotorCommandKMOne.EVENT_TYPE.imuMeasurement に通知
*/
cmdEnableIMUMeasurement(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.enableIMUMeasurement);
}
/**
* @summary IMU(ジャイロ)の値取得(通知)を停止する
*/
cmdDisableIMUMeasurement(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.disableIMUMeasurement);
}
//---------------------//
// IMU モーター
//---------------------//
/**
* @summary モーターの測定値(位置・速度・トルク)出力を開始する
* @desc デフォルトではモーター起動時on。 motorMeasurementByDefault() 参照
* @ignore
*/
cmdEnableMotorMeasurement(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.enableMotorMeasurement);
}
/**
* @summary モーターの測定値(位置・速度・トルク)出力を停止する
* @ignore
*/
cmdDisableMotorMeasurement(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.disableMotorMeasurement);
}
//---------------------//
// システム
//---------------------//
/**
* @summary システムを再起動する
* @desc BLEに接続していた場合、切断してから再起動
*/
cmdReboot(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.reboot);
}
/**
* @summary チェックサム(CRC16) 有効化
* @desc コマンド(タスク)のチェックサムを有効化する
* @param {number} isEnabled 0:Disbled, 1:Enabled
*/
cmdEnableCheckSum(isEnabled){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,isEnabled?1:0);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.enableCheckSum,buffer);
}
/**
* @summary ファームウェアアップデートモードに入る
* @desc ファームウェアをアップデートするためのブートローダーモードに入る。(システムは再起動される。)
*/
cmdEnterDeviceFirmwareUpdate(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.enterDeviceFirmwareUpdate);
}
//---------------------//
// モーター設定 MOTOR_SETTING
//---------------------//
/**
* @summary モーターの最大速さを設定する
* @param {number} maxSpeed float 最大速さ [radian / second](正の値)
*/
cmdMaxSpeed(maxSpeed){
if(maxSpeed===undefined){return;}
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(maxSpeed,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.maxSpeed,buffer);
}
/**
* @summary モーターの最小速さを設定する
* @param {number} maxSpeed float 最小速さ [radian / second](正の値)
* @desc minSpeed は、blePreparePlaybackMotion 実行の際、開始地点に移動する速さとして使用される。通常時運転では使用されない。
*/
cmdMinSpeed(minSpeed){
if(minSpeed===undefined){return;}
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(minSpeed,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.minSpeed,buffer);
}
/**
* @summary 加減速曲線を指定する(モーションコントロールの設定)
* @param {KMMotorCommandKMOne.cmdCurveType_CURVE_TYPE} cmdCurveType_CURVE_TYPE int 加減速カーブオプション<br>
* CURVE_TYPE_NONE:0 モーションコントロール OFF<br>
* CURVE_TYPE_TRAPEZOID:1 モーションコントロール ON (台形加減速)
*/
cmdCurveType(cmdCurveType_CURVE_TYPE = 0){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,Math.abs(parseInt(cmdCurveType_CURVE_TYPE)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.curveType,buffer);
}
/**
* @summary モーターの加速度を設定する
* @param {number} acc float 加速度 0-200 [radian / second^2](正の値)
* @desc acc は、モーションコントロール ON の場合、加速時に使用されます。(加速時の直線の傾き)
*/
cmdAcc(acc = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(acc,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.acc,buffer);
}
/**
* @summary モーターの減速度を設定する
* @param {number} dec float 減速度 0-200 [radian / second^2](正の値)
* @desc dec は、モーションコントロール ON の場合、減速時に使用されます。(減速時の直線の傾き)
*/
cmdDec(dec = 0){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(dec,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.dec,buffer);
}
/**
* @summary モーターの最大トルク(絶対値)を設定する
* @param {number} maxTorque float 最大トルク [N*m](正の値)
*
* @desc maxTorque を設定することにより、トルクの絶対値が maxTorque を超えないように運転します。<br>
* maxTorque = 0.1 [N*m] の後に runForward (正回転)を行った場合、0.1 N*m を超えないようにその速度をなるだけ維持する。<br>
* ただし、トルクの最大値制限により、システムによっては制御性(振動)が悪化する可能性がある。
*
*/
cmdMaxTorque(maxTorque){
if(maxTorque===undefined){return;}
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(maxTorque,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.maxTorque,buffer);
}
/**
* @summary ダイレクトティーチングのサンプリング間隔
* @desc ティーチング・プレイバックの実行間隔
* @param {number} interval ms(2-1000 0, 1msはエラーとなる)
*/
cmdTeachingInterval(interval){
if(interval===undefined){return;}
let _interval=Math.abs(parseInt(interval));
_interval=_interval<2?2:_interval;
_interval=_interval>1000?1000:_interval;
let buffer = new ArrayBuffer(4);
new DataView(buffer).setUint32(0,_interval);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.teachingInterval,buffer);
}
/**
* @summary 記憶再生時の再生間隔
* @desc 記憶再生時の再生間隔
* @param {number} interval ms(2-1000 0, 1msはエラーとなる)
*/
cmdPlaybackInterval(interval){
if(interval===undefined){return;}
let _interval=Math.abs(parseInt(interval));
_interval=_interval<2?2:_interval;
_interval=_interval>1000?1000:_interval;
let buffer = new ArrayBuffer(4);
new DataView(buffer).setUint32(0,_interval);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.playbackInterval,buffer);
}
/**
* @summary モーターのq軸電流制御Pパラメタを設定する
* @param {number} qCurrentP float q軸電流PIDコントローラの係数P [0.01 - 3.0] (default:0.2)
*/
cmdQCurrentP(qCurrentP){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(qCurrentP,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.qCurrentP,buffer);
}
/**
* @summary モーターのq軸電流制御Iパラメタを設定する
* @param {number} qCurrentI float q軸電流PIDコントローラの係数I [0.001 - 50.0] (default:20.0)
*/
cmdQCurrentI(qCurrentI){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(qCurrentI,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.qCurrentI,buffer);
}
/**
* @summary モーターのq軸電流制御Dパラメタを設定する
* @param {number} qCurrentD float q軸電流PIDコントローラの係数D [0.0 - 0.01] (default:0)
*/
cmdQCurrentD(qCurrentD){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(qCurrentD,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.qCurrentD,buffer);
}
/**
* @summary モーターの速度制御Pパラメタを設定する
* @param {number} speedP float 速度PIDコントローラの係数P [5.000 - 20.000] (default:14.000)
*/
cmdSpeedP(speedP){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(speedP,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.speedP,buffer);
}
/**
* @summary モーターの速度制御Iパラメタを設定する
* @param {number} speedI float 速度PIDコントローラの係数I [0.0001 - 0.01] (default:0.001)
*/
cmdSpeedI(speedI){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(speedI,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.speedI,buffer);
}
/**
* @summary モーターの速度制御Dパラメタを設定する
* @param {number} speedD float 速度PIDコントローラの係数D [0.0 - 0.01] (default:0.0)
*/
cmdSpeedD(speedD){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(speedD,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.speedD,buffer);
}
/**
* @summary モーターの位置制御Pパラメタを設定する
* @param {number} positionP float 位置PIDコントローラの係数P [1.0000 - 20.0000] (default 5.0)
*/
cmdPositionP(positionP){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(positionP,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.positionP,buffer);
}
/**
* @summary モーターの位置制御Iパラメタをセット
* @param {number} positionI float 位置PIDコントローラの係数I [1.0000 - 100.0000] (default 10.0)
*/
cmdPositionI(positionI){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(positionI,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.positionI,buffer);
}
/**
* @summary モーターの位置制御Dパラメタをセット
* @param {number} positionD float 位置PIDコントローラの係数D [0.0001 - 0.2] (default 0.01)
*/
cmdPositionD(positionD){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(positionD,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.positionD,buffer);
}
/**
* @summary モーターの位置制御時、ID制御を有効にする偏差の絶対値を指定する
* @param {number} threshold float ID制御を有効にする偏差の絶対値 [0.0 - n] (default 0.0139626f // 0.8deg)
*/
cmdPosControlThreshold(threshold){
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0,Math.abs(parseFloat(threshold,10)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.posControlThreshold,buffer);
}
/**
* @summary 位置制御時、目標位置に到達時、判定条件を満たした場合通知を行う。
* @desc 判定条件: tolerance 内に位置が入っている状態が、settleTime 連続で続くと、通知(KM_SUCCESS_ARRIVAL)が一回行われる。
* <ul>
* <li>tolerance内に位置が入っている状態が、settleTimeの間連続で続くと通知がトリガーされる。</li>
* <li>toleranceに一瞬でも入ってsettleTime未満で出ると通知トリガーは削除され、通知は行われない。</li>
* <li>toleranceに一度も入らない場合、通知トリガーは残り続ける。(トリガーの明示的な消去は cmdNotifyPosArrival(0,0,0) )</li>
* <li>再度notifyPosArrivalで設定を行うと、以前の通知トリガーは消える。</li>
* </ul>
* @param {number} isEnabled 0:Disbled, 1:Enabled
* @param {number} tolerance float [0.0 - n] 許容誤差 radian (デフォルト ≒ 0.1deg)
* @param {number} settleTime int [0 - n] 判定時間 ミリ秒 (デフォルト 200ms)
*
*/
cmdNotifyPosArrival(isEnabled=0,tolerance=0.00174533,settleTime=200){
let buffer = new ArrayBuffer(9);
new DataView(buffer).setUint8(0,isEnabled?1:0);
new DataView(buffer).setFloat32(1,Math.abs(parseFloat(tolerance,10)));
new DataView(buffer).setUint32(5,Math.abs(parseInt(settleTime)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.notifyPosArrival,buffer);
}
/**
* @summary 全てのPIDパラメータをリセットしてファームウェアの初期設定に戻す
* @desc qCurrentP, qCurrentI, qCurrentD, speedP, speedI, speedD, positionP をリセットします
*
*/
cmdResetPID(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.resetPID);
}
/**
* @summary モーター測定値の取得間隔設定
* @desc 有線(USB, I2C)のみ有効。BLEでは固定 100ms 間隔で通知される。<br>設定を反映するには、設定後にcmdEnableMotorMeasurement()を再実行する必要がある。
* @param {KMMotorCommandKMOne.cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL} cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL enum モーター測定値の取得間隔
*/
cmdMotorMeasurementInterval(cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL=4){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,parseInt(cmdMotorMeasurementInterval_MOTOR_MEAS_INTERVAL));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.motorMeasurementInterval,buffer);
}
/**
* @summary モーター測定値の取得設定
* @desc isEnabled = 1 の場合、(位置・速度・トルク)の通知を行う(起動後、interface の設定で優先される通信経路に、自動的に通知が開始される)
* @param {number} isEnabled 0:Disbled, 1:Enabled
*/
cmdMotorMeasurementByDefault(isEnabled){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,isEnabled?1:0);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.motorMeasurementByDefault,buffer);
}
/**
* @summary モーター制御手段(インターフェイス)の設定
* @desc uint8_t flags ビットにより、含まれるパラメータを指定する(1の場合含む・0の場合含まない)
* @param {number} bitFlg
* ---------------------------------------------------------------
* bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
* 物理 有線 有線 無線
* ボタン * * I2C USB * * BLE
* デフォルト デフォルト デフォルト デフォルト
* ---------------------------------------------------------------
*/
cmdInterface(bitFlg){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,parseInt(bitFlg));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.interface,buffer);
}
/**
* @summary コマンドを受信したときに成功通知(errorCode = 0)をするかどうか
* @param {number} isEnabled 0:通知しない, 1:通知する
*/
cmdResponse(isEnabled){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,isEnabled?1:0);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.response,buffer);
}
/**
* @summary モーターの起動時固有LEDカラーを設定する
* @param {number} red int 0-255
* @param {number} green int 0-255
* @param {number} blue int 0-255
*
* @desc ownColor はアイドル時の固有LEDカラー。<br>saveAllSettingsを実行し、再起動後に初めて反映される。<br>
* この設定値を変更した場合、BLEの Device Name の下3桁が変更される。
*/
cmdOwnColor(red,green,blue){
let buffer = new ArrayBuffer(3);
new DataView(buffer).setUint8(0,Math.abs(parseInt(red)));
new DataView(buffer).setUint8(1,Math.abs(parseInt(green)));
new DataView(buffer).setUint8(2,Math.abs(parseInt(blue)));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.ownColor,buffer);
}
/**
* @summary 6軸センサー(加速度・ジャイロ)測定値の取得間隔
* @desc 有線(USB, I2C)のみ有効。BLEでは固定 100ms 間隔で通知される。<br>設定を反映するには、設定後にcmdEnableIMUMeasurement()を再実行する必要がある。
* @param {KMMotorCommandKMOne.cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL} cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL enum 加速度・ジャイロ測定値の取得間隔
*/
cmdIMUMeasurementInterval(cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL=4){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,parseInt(cmdIMUMeasurementInterval_IMU_MEAS_INTERVAL));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.iMUMeasurementInterval,buffer);
}
/**
* @summary 6軸センサー(加速度・ジャイロ)の値の通知をデフォルトで開始する
* @desc isEnabled = true の場合、enableIMU() を送信しなくても起動時に自動で通知が開始される
* @param {number} isEnabled 0:Disbled, 1:Enabled
*/
cmdIMUMeasurementByDefault(isEnabled){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,parseInt(isEnabled));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.iMUMeasurementByDefault,buffer);
}
/**
* @summary 指定した設定値を取得
* @param {number | array} registers <int | []> 取得するプロパティのコマンド(レジスタ番号)値
* @returns {Promise.<int | array>} 取得した値 <br>registersがint=レジスタ値のプリミティブ値 <br>registersがArray=レジスタ値のオブジェクト
*
* @none 取得する値はコマンド実行後にBLEのキャラクタリスティクスMOTOR_SETTINGに通知される。<br>
* それを拾ってpromiseオブジェクトののresolveに返して処理を繋ぐ<br>
* MOTOR_SETTINGのnotifyは_onBleMotorSettingで取得
*/
cmdReadRegister(registers){
if(Array.isArray(registers)){
return new Promise((allresolve, allreject)=> {
let promiseList=[];
for(let i=0;i<registers.length;i++){
let register=parseInt(registers[i],10);
promiseList.push( new Promise((resolve, reject)=> {
let ccp=new _KMNotifyPromis(register,this._REV_MOTOR_COMMAND[register],this._notifyPromisList,resolve,reject,5000);//notify経由のresultをPromisと紐付け
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0, register);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.readRegister, buffer,ccp);
}));
}
Promise.all(promiseList).then((resar)=>{
let t=[{}].concat(resar);
let rtobj=Object.assign.apply(null,t);
allresolve(rtobj);
}).catch((msg)=>{
allreject(msg);
});
});
}else{
return new Promise((lastresolve, lastreject)=> {
let register=parseInt(registers);
new Promise((resolve, reject)=> {
let ccp=new _KMNotifyPromis(register,this._REV_MOTOR_COMMAND[register],this._notifyPromisList,resolve,reject,1000);//notify経由のresultをPromisと紐付け
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,register);
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.readRegister, buffer,ccp);
}).then((res)=>{
lastresolve(res[Object.keys(res)[0]]);
}).catch((msg)=>{
lastreject(msg);
});
});
}
}
/**
* モーターの全てのレジスタ値の取得 (廃止予定1.3.2〜)
* @returns {Promise.<array>}
*/
cmdReadAllRegister(){
//info::廃止予定1.3.2〜 MotorFarmのversionにより、取得出来ないレジスタが存在する為。
// (存在しないレジスタが1つでもあるとプロパティが揃わずtimeoutになる)
let cm= this.constructor.cmdReadRegister_COMMAND;
let allcmds=[];
Object.keys(cm).forEach((k)=>{allcmds.push(cm[k]);});
return this.cmdReadRegister(allcmds);
}
//////保存
/**
* @summary 全ての設定値をフラッシュメモリに保存する
* @desc 本コマンドを実行しない限り、設定値はモーターに永久的に保存されない(再起動で消える)
*/
cmdSaveAllRegisters(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.saveAllRegisters);
}
//////リセット
/**
* @summary 指定したレジスタをファームウェアの初期値にリセットする
* @param {KMMotorCommandKMOne.cmdReadRegister_COMMAND} register 初期値にリセットするコマンド(レジスタ)値
*/
cmdResetRegister(register){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,parseInt(register));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.resetRegister,buffer);
}
/**
* @summary 全てのレジスタをファームウェアの初期値にリセットする
* @desc bleSaveAllRegistersを実行しない限り、リセット値はモーターに永久的に保存されない(再起動で消える)
*/
cmdResetAllRegisters(){
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.resetAllRegisters);
}
/**
* @summary デバイスネームの取得
* @desc デバイスネームを読み取る
* @returns {Promise<int|Array>}
*/
cmdReadDeviceName(){
return this.cmdReadRegister(this._MOTOR_COMMAND.readDeviceName);
}
/**
* @summary デバイス情報の取得
* @desc デバイスインフォメーションを読み取る
* @returns {Promise<any>}
*/
cmdReadDeviceInfo(){
return this.cmdReadRegister(this._MOTOR_COMMAND.readDeviceInfo);
}
/**
* @summary I2Cスレーブアドレス
* @desc I2Cから制御する場合のスレーブアドレス(0x00-0xFF)を設定する
* @param {number} address アドレス
*/
cmdSetI2CSlaveAddress(address){
let buffer = new ArrayBuffer(1);
new DataView(buffer).setUint8(0,parseInt(address));
this._KMCom._sendMotorCommand('MOTOR_TX',this._MOTOR_COMMAND.setI2CSlaveAddress,buffer);
}
/********************************************
* 内部
********************************************/
_isInstancOfPromise(any){
return obj instanceof Promise || (obj && typeof obj.then === 'function');
}
/**
* 他の移動系のコマンドを実行時、既に移動系のSyncコマンドが実行されている場合はそのCBをRejectする
* 移動系のSyncコマンド(cmdMoveByDistanceSync、cmdMoveToPositionSync)等
* @private
*/
_moveSyncInstructionOverrideReject(cid){
if(this._PositionArrivalNotification){
this._PositionArrivalNotification.callReject({id:this._PositionArrivalNotification.tagName,msg:'Instruction override',overrideId:cid});
this._PositionArrivalNotification=null;
}
}
//////class//
}
/**
* SendBleNotifyPromis
* cmdReadRegister等のBLE呼び出し後に
* コマンド結果がnotifyで通知されるコマンドをPromisと紐付ける為のクラス
* @private
*/
class _KMNotifyPromis{
//成功通知
static sendGroupNotifyResolve(groupArray,tagName,val){
if(!Array.isArray(groupArray)){return;}
//送信IDの通知 CallbackPromisで呼び出し元のメソッドのPromisに返す
for(let i=0; i<groupArray.length; i++){
if( groupArray[i].tagName===tagName ){
groupArray[i].callResolve(val);
}
}
}
/**
* const
* @param tagName
* @param groupArray
* @param promisResolveObj
* @param promisRejectObj
* @param rejectTimeOut
*/
constructor(tagName,tagInfo=null,groupArray=[],promisResolveObj, promisRejectObj,rejectTimeOut){
this.timeoutId=0;
this.tagName=tagName;
this.tagInfo=tagInfo;
this.groupArray=Array.isArray(groupArray)?groupArray:[];
this.groupArray.push(this);
this.promisResolveObj=promisResolveObj;
this.promisRejectObj=promisRejectObj;
this.rejectTimeOut=rejectTimeOut;
}
//カウントの開始 characteristics.writeValue呼び出し後に実行
startRejectTimeOutCount(){
this.timeoutId=setTimeout(()=>{
this._removeGroup();
this.promisRejectObj({msg:"timeout:",tagName:this.tagName,tagInfo:this.tagInfo});
}, this.rejectTimeOut);
}
callResolve(arg){
clearTimeout(this.timeoutId);
this._removeGroup();
this.promisResolveObj(arg);
}
callReject(msg){
clearTimeout(this.timeoutId);
this._removeGroup();
this.promisRejectObj({msg:msg});
}
_removeGroup(){
for(let i=0; i<this.groupArray.length; i++){
if( this.groupArray[i]===this){
this.groupArray.splice(i,1);
break;
}
}
}
}
module.exports =KMMotorCommandKMOne;