Hashimoto.Koji
2021年05月16日作成 (2021年05月16日更新)
製作品 2794
obniz 2個使いでロボットアームを遠隔制御してみた
はじめに
遠隔医療などのデモ用にグローブに搭載された加速度センサーを利用して、ロボットアームを制御するシステムを構築しました。
説明資料
デモ動画
ソースコード
ロボットアーム制御(2つのobnizでコード共有)
<!-- HTML Example -->
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script
src="https://unpkg.com/obniz@3.7.1/obniz.js"
crossorigin="anonymous"
></script>
</head>
<body>
<div id="obniz-debug"></div>
<h3>ハンド操作
<button id="hand_close" style="width: 80px; height: 30px;float: right;">とじる</button>
<button id="hand_open" style="width: 80px; height: 30px;float: right;">ひらく</button>
</h3>
<h3>アーム1操作
<button id="arm1_close" style="width: 80px; height: 30px; float: right;">した</button>
<button id="arm1_open" style="width: 80px; height: 30px; float: right;">うえ</button>
</h3>
<h3>アーム2操作
<button id="arm2_close" style="width: 80px; height: 30px; float: right;">した</button>
<button id="arm2_open" style="width: 80px; height: 30px; float: right;">うえ</button>
</h3>
<h3>アーム3操作
<button id="arm3_close" style="width: 80px; height: 30px; float: right;">した</button>
<button id="arm3_open" style="width: 80px; height: 30px; float: right;">うえ</button>
</h3>
<h3>土台操作
<button id="base_right" style="width: 80px; height: 30px; float: right;">右まわり</button>
<button id="base_left" style="width: 80px; height: 30px; float: right;">左まわり</button>
</h3>
<script>
var obniz = new Obniz("3047-9097");
document.body.style.webkitUserSelect = 'none';
obniz.onconnect = async function () {
var obniz2 = new Obniz("3363-3232");
/*var pwm = obniz.getFreePwm();
pwm.start({io:10});
pwm.freq(10000); // 10k hz
pwm.duty(99) // 50%*/
// 初期値設定
obniz.io0.output(true); // 開く
obniz.io1.output(true); // 閉じる
obniz.io2.output(true); // アーム1を上げる
obniz.io3.output(true); // アーム1を下げる
obniz.io4.output(true); // アーム2を下げる
obniz.io5.output(true); // アーム2を上げる
obniz.io6.output(true); // アーム3を上げる
obniz.io7.output(true); // アーム3を下げる
obniz.io8.output(true); // 右に回る
obniz.io9.output(true); // 左に回る
obniz.io10.output(false); // LED
obniz2.onconnect = async function () {
// 3軸加速度センサー
var sensor = obniz2.wired("KXR94-2050", { vcc:0, gnd:1, x:3, y:4, z:5, enable:7, self_test:8 });
var status = { none: { value : 0, string : '真っすぐ'},
front_front: { value : 1, string : '表で前'},
front_back: { value : 2, string : '表で後ろ'},
front_left: { value : 3, string : '表で左'},
front_right: { value : 4, string : '表で右'},
back_front: { value : 5, string : '裏で前'},
back_back: { value : 6, string : '裏で後ろ'},
back_left: { value : 7, string : '裏で左'},
back_right: { value : 8, string : '裏で右'}
};
const status_strings = ['真っすぐ', '表で前', '表で後ろ', '表で左', '表で右', '裏で前', '裏で後ろ', '裏で左', '裏で右']
var prev_status = status.none.value, current_status = status.none.value, stable_status = status.none.value, count = 0;
sensor.onChange = function(values){
// console.log("status:" + current_status + "x:" + values.x + " y:" + values.y + " z:" +values.z);
// console.log(" z:" +values.z);
// 現在の状態を判定
// 上向き
if(values.z > 0.2) {
if(values.x > 0.2){
// console.log("表で前に傾いてる");
current_status = status.front_front.value;
}else if(values.x < -0.5){
// console.log("表で後ろに傾いてる");
current_status = status.front_back.value;
}else if(values.y > 0.2){
// console.log("表で左に傾いてる");
current_status = status.front_left.value;
}else if(values.y < -0.5){
// console.log("表で右に傾いてる");
current_status = status.front_right.value;
}else{
// console.log("表で真っすぐ");
current_status = status.none.value;
}
}else if(values.z < -0.5){ // 下向き
if(values.x > 0.2){
// console.log("裏で前に傾いてる");
current_status = status.back_front.value;
}else if(values.x < -0.5){
// console.log("裏で後ろに傾いてる");
current_status = status.back_back.value;
}else if(values.y > 0.2){
// console.log("裏で右に傾いてる");
current_status = status.back_right.value;
}else if(values.y < -0.5){
// console.log("裏で左に傾いてる");
current_status = status.back_left.value;
}else{
// console.log("裏で真っすぐ");
current_status = status.none.value;
}
}else{
// console.log("裏で真っすぐ");
current_status = status.none.value;
}
// 前の状態と比較
if(current_status == prev_status)
count++;
else
count = 0;
// 閾値を超えたら安定した状態とする
// 安定状態が変化したときだけ動かす
// if(count > 15 && stable_status != current_status)
if(((current_status == status.none.value && count > 2) || (current_status != status.none.value && count > 15) )
&& stable_status != current_status)
{
console.log(status_strings[current_status]);
stable_status = current_status;
switch (current_status) {
case status.none.value:
// 全部止める、trueで止まる,LEDはfalseで消える
obniz.io0.output(true); // 開く
obniz.io1.output(true); // 閉じる
obniz.io2.output(true); // アーム1を上げる
obniz.io3.output(true); // アーム1を下げる
obniz.io4.output(true); // アーム2を下げる
obniz.io5.output(true); // アーム2を上げる
obniz.io6.output(true); // アーム3を上げる
obniz.io7.output(true); // アーム3を下げる
obniz.io8.output(true); // 右に回る
obniz.io9.output(true); // 左に回る
obniz.io10.output(false); // LED
console.log("止まる");
break;
case status.front_front.value:
obniz.io4.output(false); // アーム2を下げる
console.log("アーム2を下げる");
break;
case status.front_back.value:
obniz.io5.output(false); // アーム2を上げる
console.log("アーム2を上げる");
break;
case status.front_left.value:
obniz.io0.output(false); // 開く
obniz.io10.output(true);
console.log("開く");
break;
case status.front_right.value:
obniz.io1.output(false); // 閉じる
obniz.io10.output(true);
console.log("閉じる");
break;
case status.back_front.value:
obniz.io3.output(false); // アーム1を下げる
console.log("アーム1を下げる");
break;
case status.back_back.value:
obniz.io2.output(false); // アーム1を上げる
console.log("アーム1を上げる");
break;
case status.back_left.value:
obniz.io9.output(false); // 左に回る
console.log("左に回る");
break;
case status.back_right.value:
obniz.io8.output(false); // 右に回る
console.log("右に回る");
break;
}
}
// 前回の状態を保存
prev_status = current_status;
}
$("#slider").on('input', async function() {
});
$("#hand_close").on('touchstart mousedown', function() {
obniz.io0.output(true);
obniz.io1.output(false);
// obniz.io10.output(true);
});
$("#hand_close").on('touchend mouseup', function() {
obniz.io0.output(true);
obniz.io1.output(true);
// obniz.io10.output(false);
});
$("#arm1_close").on('touchstart mousedown', function() {
obniz.io2.output(true);
obniz.io3.output(false);
});
$("#arm1_close").on('touchend mouseup', function() {
obniz.io2.output(true);
obniz.io3.output(true);
});
$("#arm2_close").on('touchstart mousedown', function() {
obniz.io4.output(false);
obniz.io5.output(true);
});
$("#arm2_close").on('touchend mouseup', function() {
obniz.io4.output(true);
obniz.io5.output(true);
});
$("#arm3_close").on('touchstart mousedown', function() {
obniz.io6.output(true);
obniz.io7.output(false);
});
$("#arm3_close").on('touchend mouseup', function() {
obniz.io6.output(true);
obniz.io7.output(true);
});
$("#base_left").on('touchstart mousedown', function() {
obniz.io8.output(true);
obniz.io9.output(false);
});
$("#base_left").on('touchend mouseup', function() {
obniz.io8.output(true);
obniz.io9.output(true);
});
$("#hand_open").on('touchstart mousedown', function() {
obniz.io0.output(false);
obniz.io1.output(true);
// obniz.io10.output(true);
});
$("#hand_open").on('touchend mouseup', function() {
obniz.io0.output(true);
obniz.io1.output(true);
// obniz.io10.output(false);
});
$("#arm1_open").on('touchstart mousedown', function() {
obniz.io2.output(false);
obniz.io3.output(true);
});
$("#arm1_open").on('touchend mouseup', function() {
obniz.io2.output(true);
obniz.io3.output(true);
});
$("#arm2_open").on('touchstart mousedown', function() {
obniz.io4.output(true);
obniz.io5.output(false);
});
$("#arm2_open").on('touchend mouseup', function() {
obniz.io4.output(true);
obniz.io5.output(true);
});
$("#arm3_open").on('touchstart mousedown', function() {
obniz.io6.output(false);
obniz.io7.output(true);
});
$("#arm3_open").on('touchend mouseup', function() {
obniz.io6.output(true);
obniz.io7.output(true);
});
$("#base_right").on('touchstart mousedown', function() {
obniz.io8.output(false);
obniz.io9.output(true);
});
$("#base_right").on('touchend mouseup', function() {
obniz.io8.output(true);
obniz.io9.output(true);
});
};
};
(function(console){
console.save = function(data, filename){
if(!data) {
console.error('Console.save: No data')
return;
}
if(!filename) filename = 'console.json'
if(typeof data === "object"){
data = JSON.stringify(data, undefined, 4)
}
var blob = new Blob([data], {type: 'text/json'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
}
})(console)
obniz.onclose = async function(){
$("#slider").off('input');
};
window.addEventListener("deviceorientation", event => {
const beta = event.beta;
const gamma = event.gamma;
const alpha = event.alpha;
console.log(beta);
console.log(gamma);
console.log(alpha);
});
window.addEventListener(
"devicemotion",
function (event1) {
let x = event1.accelerationIncludingGravity.x;
let y = event1.accelerationIncludingGravity.y;
document.write("<strong>Samurai</strong>");
},
true
);
</script>
</body>
</html>
-
Hashimoto.Koji
さんが
2021/05/16
に
編集
をしました。
(メッセージ: 初版)
-
Hashimoto.Koji
さんが
2021/05/16
に
編集
をしました。
ログインしてコメントを投稿する