V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Vincross
V2EX  ›  分享创造

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

  •  
  •   Vincross · 2017-05-12 19:06:59 +08:00 · 3094 次点击
    这是一个创建于 2744 天前的主题,其中的信息可能已经有所发展或是发生改变。

    摘要

    这次 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 * 100)
            }
            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 条回复    2017-05-15 16:36:26 +08:00
    Vincross
        1
    Vincross  
    OP
       2017-05-12 19:17:28 +08:00
    谢谢 @Livid 置顶,偷偷说翻译这篇时真的想吐血。
    wjm2038
        2
    wjm2038  
       2017-05-12 19:27:44 +08:00 via Android
    不会翻车么
    o00o
        3
    o00o  
       2017-05-12 19:48:26 +08:00
    要不然来个视频
    glume
        4
    glume  
       2017-05-12 21:55:28 +08:00
    持续关注中。。。。
    另外,蜘蛛会跳的,这个能跳么?
    Livid
        5
    Livid  
    MOD
       2017-05-13 14:11:32 +08:00
    补充个视频吧,你们有 Vimeo 频道么?
    Vincross
        6
    Vincross  
    OP
       2017-05-14 16:01:13 +08:00
    @Livid 下周一我们团队自己拍一个~
    Vincross
        7
    Vincross  
    OP
       2017-05-15 16:36:26 +08:00
    新鲜出炉的视频

    <a href="
    " target="_blank"><img src=" "
    alt="IMAGE ALT TEXT HERE" width="240" height="180" border="10" /></a>
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2936 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 07:23 · PVG 15:23 · LAX 23:23 · JFK 02:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.