大家好,我是 Jack。
你们想过用手柄,控制自己的表情吗?有位“狼人”做到了:
转自:量子位 鱼羊 | 编辑:Jack Cui
昨晚看到视频的我,直接惊呆了,他可太秀了。
按下LB键眨左眼,按下RB键眨右眼,还可以左右左右走一套连击。(画面为镜像
摇动右摇杆控制嘴巴,歪嘴战神。
而通过左摇杆,对于普通人类而言难度颇高的单边挑眉表情,也能瞬间拿下。
但要注意尽量别一通乱按,否则就会...
痛苦面具。
这是一个最近火爆的开源项目,作者叫handaru,自称热衷于一些“没啥用的工作”。
而他这个最新“没啥用”作品一传上网,直接把网友们都给看呆了,推文点赞已经将近7万。
那反过来,是不是可以通过面部动作,玩游戏了?
作者表示,这个电击,有点疼。

项目原理

这么一个看上去有点“自虐”的系统,原理其实很简单,大家打眼一看就明白,就是靠电刺激。
我们都知道,肌肉在受到一定的电刺激后就会收缩。
具体来说就是,如果给的电压能使肌细胞初始去极化程度到达阈电位,进而产生动作电位的话,肌肉收缩。
动作电位的峰电位持续时间为2ms,最高可由-80mV上升到60mV。
而大多数肌肉在受到刺激时会以20ms的周期收缩一次。
这和伺服电机的信号周期非常相似,于是作者就用它来供电,保证最后输出的电压为150mV。
不过伺服电机的控制电压,也就是给电路板的供电电压为5V,就需要设计电路图进行处理:
主要的控制器是一块Arduino Uno (Arduino最新版):用它一头连手柄,一头连我们的肌肉。
作者一共做了10个触头,为了增加导电率,每个触头上的电极都用盐水浸泡过的纱布覆盖,然后直接粘贴到皮肤上。
用下面这样的网格基板+凝胶导电贴也可以实现,但作者发现都没有直接让电极接触皮肤的效果好。
最后就是编写程序了,这里用Arduino的一个现成库Servo来控制伺服电机,记得把电机的ON时间设置为2ms就行。
Servo可以很方便地添加通道,后续还可以做更复杂的控制,更扭曲的表情。
然后在将手柄连接到Arduino板的接口之前,用一个叫做ROSSerial的框架设定一下哪个键对应哪个触头,一切就全部搞定了。
#include<ros.h>
#include<ros_face_msgs/FaceCmd.h>
#include<ros_face_msgs/Ch.h>


#include<Arduino.h>
#include<Servo.h>


#define pulse_width 2400

#define pin1 2
#define pin2 3
#define pin3 4
#define pin4 5
#define pin5 6
#define pin6 7
#define pin7 8
#define pin8 9
#define pin9 10
#define pin10 11
ros::NodeHandle  nh;

Servo channel_1;

Servo channel_2;

Servo channel_3;

Servo channel_4;

Servo channel_5;

Servo channel_6;

Servo channel_7;

Servo channel_8;

Servo channel_9;

Servo channel_10;



voidCbconst ros_face_msgs::FaceCmd& data)
{

if
(data.ch1.state){

        channel_1.writeMicroseconds(pulse_width);

    }
else
{

        channel_1.writeMicroseconds(
0
);

    }


if
(data.ch2.state){

        channel_2.writeMicroseconds(pulse_width);

    }
else
{

        channel_2.writeMicroseconds(
0
);

    }


if
(data.ch3.state){

        channel_3.writeMicroseconds(pulse_width);

    }
else
{

        channel_3.writeMicroseconds(
0
);

    }


if
(data.ch4.state){

        channel_4.writeMicroseconds(pulse_width);

    }
else
{

        channel_4.writeMicroseconds(
0
);

    }


if
(data.ch5.state){

        channel_5.writeMicroseconds(pulse_width);

    }
else
{

        channel_5.writeMicroseconds(
0
);

    }


if
(data.ch6.state){

        channel_6.writeMicroseconds(pulse_width);

    }
else
{

        channel_6.writeMicroseconds(
0
);

    }


if
(data.ch7.state){

        channel_7.writeMicroseconds(pulse_width);

    }
else
{

        channel_7.writeMicroseconds(
0
);

    }


if
(data.ch8.state){

        channel_8.writeMicroseconds(pulse_width);

    }
else
{

        channel_8.writeMicroseconds(
0
);

    }


if
(data.ch9.state){

        channel_9.writeMicroseconds(pulse_width);

    }
else
{

        channel_9.writeMicroseconds(
0
);

    }


if
(data.ch10.state){

        channel_10.writeMicroseconds(pulse_width);

    }
else
{

        channel_10.writeMicroseconds(
0
);

    }


    delay(
20
);

}


ros::Subscriber<ros_face_msgs::FaceCmd> sub("face_cmd", Cb)
;



voidsetup()
{

    pinMode(
13
, OUTPUT);

    nh.getHardware()->setBaud(
115200
);

    nh.initNode();

    nh.subscribe(sub);

    channel_1.attach(pin1,
40
,
2400
);

    channel_2.attach(pin2,
40
,
2400
);

    channel_3.attach(pin3,
40
,
2400
);

    channel_4.attach(pin4,
40
,
2400
);

    channel_5.attach(pin5,
40
,
2400
);

    channel_6.attach(pin6,
40
,
2400
);

    channel_7.attach(pin7,
40
,
2400
);

    channel_8.attach(pin8,
40
,
2400
);

    channel_9.attach(pin9,
40
,
2400
);

    channel_10.attach(pin10,
40
,
2400
);

}


voidloop()
{

    nh.spinOnce();

    delayMicroseconds(
5
);

}

这不是还挺简单的?学废了吗?
大多数时候把它往皮肤上一贴,不一定会有预期效果——关键得找准电击穴位,这就得靠自己对着人体肌肉模型一一摸索了。
以及适配手柄除了手里的这个罗技,Switch、PS4也可以,还包括键盘。
最后,依照同样的原理,他还整了个控制手指的活儿:
这东西还可以用来反向操作,玩游戏,比如老头环里打女武神。
或者这样的玩法也不是不行:
去年火过的视频,通过控制肌肉来打鼓。
这个项目已开源,开兴趣的可以看一看:
项目地址:
https://github.com/maHidaka/ros_face
当然,作者也在项目中表明了:
代码自取,风险自负。
我反正是有了一些大胆的想法。
·················END·················
继续阅读
阅读原文