斗牛太危险,来斗机器人吧 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
爱意满满的作品展示区。
Vincross

斗牛太危险,来斗机器人吧

  •  
  •   Vincross May 12, 2017 3922 views
    This topic created in 3274 days ago, the information mentioned may be changed or developed.

    摘要

    这次 HEXA 不是尬舞或逗宠物那么简单了,而是学会追逐眼前的一抹红了。(孩子大了,不省心呐)。开发者利用拍照功能确认红色,并发起千里追凶。现在这个功能已经成功上架到 Vincross Skill Store,工作人员亲测任何在 HEXA 距离 1 米以内的红色物体都会引起它的亲密追逐。


    我教会了 HEXA 如何斗牛

    by @Heinegan 第一次看到这个小家伙的时候,就被这个六只脚的小家伙萌翻了。开箱照?实在太激动,忘拍了。现在有点后悔没记录下那一刻。 我很快下载了 App,并且玩了一会儿。它的动作太逗了,天知道我摆弄了多久。但光是玩儿还不过瘾,我觉得它还可以更好玩一些!

    大概想了一刻钟我都没想出还能怎么玩。于是我改变了想法也许我不该执着于 HEXA 能干嘛,而应该专注于我能让它干什么。 由于我之前做过一些关于计算机视觉的工作,所以我决定帮 HEXA 醒醒目。另外,我喜欢西班牙的斗牛表演,我是 coder 外表斗牛士的心,不过真要自己去尝试我这个体格肯定不行。但我们是技术派嘛,HEXA 可以当我的公牛!我可以看着它追逐红布但不会伤到我。

    于是我去官网查了文档和 SDK 和文档,必须说 Vincross 干得不错。在找到了我需要的信息后,我就很快去投入创作了。

    为了让 HEXA 变成公牛,我必须:

    • 教 HEXA 的图像识别系统可以识别和找到红色。

    • 让 HEXA 一旦发现红色,就勇猛地冲过去。

    Pseudo-code 如下:

    • 转动 HEXA 的头部,每转动一定角度,HEXA 就拍一张照片
    • 判断照片里面是否有红色
    • 如果有红色,HEXA 停止转动头部,并向红色跑去
    • 如果没有红色,则继续转动头部搜索
    • 跑动过程中继续拍照,如果还有红色则继续前进
    • 跑动过程中如果没有红色里则停下寻找红色

    我用了 3 个 go routinue 分别控制头部转动、向前走以及监测红色。转动头部时,头部移动以及红色的检测在同一个 routinue 里面实现了。然后我将这些 go routinue 映射到几个状态。作为一个 hacking demo,这儿实现得不怎么优雅。这里建议大家看下官网给出的几个简单的示例,对快速上手 HEXA 的开发很有帮助。 https://github.com/vincross/hexa-example-skills

    以下是具体的开发过程,欢迎分享你的意见。

    1. 转动头部

    HEXA 身体控制接口由 hexabody package 提供,注意在使用前需要调用 Start()函数,结束后调用 Stop()。Start 调用后就可以愉快地调用其他接口控制 HEXA 了。MoveHead 可以控制头部的移动,参数 degree 控制移动的角度,duration 控制移动的时间。这里吐槽下,接口文档说的是将头部移动到指定的角度,但实际上是以当前角度为参考,顺时钟移动值为‘ degree ’的角度。duration 表示需要多长时间做完这个动作,也就是决定移动的速度,但我在文档中找了一会没有找到 HEXA 转动头部的最大值.

    func (skill *ScanRed) searchRed() { for skill.status { if skill.round { direction := hexabody.Direction() direction += 30 hexabody.MoveHead(direction, 200) skill.checkRedLightDistrict() time.Sleep(time.Millisecond * 10) } time.Sleep(time.Millisecond * 200) } } 

    2. 检测红色

    多媒体接口由 Media 接口提供,同 hexabody 一样,需要调用 Start 和 Stop。我们需要用到的是 SnapshotRGBA 这个接口,它返回一张 RGBA Image。我太想看到最终的效果是怎样的,所以用了一种最简单的方式判断这张图片是否有红色。先从图片中取出中间那一部分,然后判断里面有多少个像素,大于一个阈值则认为是红色,这种方法比较笨,效率也不高,但可用。对了,这里用到了 goalng 的 image package。这部分代码如下:

     newImg := m.SubImage(subBounds) width := newImg.Bounds().Size().X height := newImg.Bounds().Size().Y for w := 0; w < width; w++ { for h := 0; h < height; h++ { r, g, b, _ := newImg.At(w, h).RGBA() r = r >> 8 g = g >> 8 b = b >> 8 c := (int(r) - int(g)) + (int(r) - int(b)) if c > thresHold { subRed++ } } } log.Info.Printf("%d %d", subRed, width*height) if subRed > (width*height)/200 { return true } return false } 

    3. 往前走

    当 HEXA 检测到前方有红色时,HEXA 会停止转动头部,并且朝红色方向走去。这儿调用了 heaxbody 的 Walk 函数,很明显这个函数的方向是需要你定义的。接着吐槽下,文档里有 Moving forward one frame,但里面没有说明一步 frame 有多远.

    func (skill *ScanRed) goToRed() { for skill.status { if skill.run { log.Info.Printf("RUN...") hexabody.Walk(hexabody.Direction(), 100) } else { time.Sleep(time.Millisecond * 200) } } } 

    我大概花了一天的时间来做这个 skill,时间主要花在熟悉文档以及判断红色的算法上面。虽然上面有吐槽,但总的来说文档结构已经内容都还是非常清晰明了,非常容易看懂。

    现在我的 HEXA 已经变身勇猛的“公牛”了。额,其实也许并不很猛,说它萌还差不多。接下来我会继续更新这个帖子的。但也许我还想先试试为 HEXA 发展出其他功能。


    这个帖子的内容来自 Vincross (也就是我们自己)的开发者论坛。原贴是英文的,我们觉得很有意思,所以把帖子翻译成中文。 开发使用的是 Golang 语言。

    文中提到的 frame 缺乏说明和示例问题,Documentation 里已经改正了~

    特别说明:Vincross 拥有使用这个帖子的转载和宣传的权力。

    7 replies    2017-05-15 16:36:26 +08:00
    Vincross
        1
    Vincross  
    OP
       May 12, 2017
    谢谢 @Livid 置顶,偷偷说翻译这篇时真的想吐血。
    wjm2038
        2
    wjm2038  
       May 12, 2017 via Android
    不会翻车么
    o00o
        3
    o00o  
       May 12, 2017
    要不然来个视频
    glume
        4
    glume  
       May 12, 2017
    持续关注中。。。。
    另外,蜘蛛会跳的,这个能跳么?
    Livid
        5
    Livid  
    MOD
    PRO
       May 13, 2017
    补充个视频吧,你们有 Vimeo 频道么?
    Vincross
        6
    Vincross  
    OP
       May 14, 2017
    @Livid 下周一我们团队自己拍一个~
    Vincross
        7
    Vincross  
    OP
       May 15, 2017
    新鲜出炉的视频

    <a href="
    " target="_blank"><img src=" "
    alt="IMAGE ALT TEXT HERE" width="240" height="180" border="10" /></a>
    About     Help     Advertise     Blog     API     FAQ     Solana     1178 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 43ms UTC 17:50 PVG 01:50 LAX 10:50 JFK 13:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86