大家好,我是 小富。
你们想过用手柄,控制自己的表情吗?有位“狼人”做到了:
昨晚看到视频的我,直接惊呆了,他可太秀了。
按下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;
void Cb( const 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);
void setup()
{
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);
}
void loop()
{
nh.spinOnce();
delayMicroseconds(5);
}
这不是还挺简单的?学废了吗?
大多数时候把它往皮肤上一贴,不一定会有预期效果——关键得找准电击穴位,这就得靠自己对着人体肌肉模型一一摸索了。
以及适配手柄除了手里的这个罗技,Switch、PS4也可以,还包括键盘。
最后,依照同样的原理,他还整了个控制手指的活儿:
这东西还可以用来反向操作,玩游戏,比如老头环里打女武神。
或者这样的玩法也不是不行:
去年火过的视频,通过控制肌肉来打鼓。
这个项目已开源,开兴趣的可以看一看:
项目地址: https://github.com/maHidaka/ros_face
当然,作者也在项目中表明了:
代码自取,风险自负。
我反正是有了一些大胆的想法。
在看、点赞、转发,是对我最大的鼓励。