当前位置:   article > 正文

【聆思CSK6视觉AI开发套件试用测评】使用CSK6手势识别操控Unity3D游戏及待优化问题探讨

csk6

本篇文章来自极术社区与聆思科技组织的CSK6 视觉AI开发套件活动,更多开发板试用活动请关注极术社区网站。作者:李方文

非常幸运能被聆思科技选中,获得测评CSK6的机会,感谢官方大大和超级nice的客服小姐姐(笔芯_)。一拿到芯片的第一反应就是想做一个手势操控的Unity3D小游戏,应该会蛮好玩的(童心未泯_),经过一番折腾,终于搞定了,但也有一些待优化的方面感觉可以讨论。由于最近一直比较忙,文章现在才发出来。

拆箱组装好后如图所示:

1、烧录

按照官方文档烧录了hello_world,测试了串口工具,比较容易,一切OK。

2、体验手势识别

然后按照官方AI头肩检测实例项目的开发指引下载、配置prj.conf、编译并烧录了相应源代码,一路顺利过关。

按照PC 查看工具指引下载查看工具,并一路安装测试OK。

(原谅我单手手机拍照技术太菜,但必须得说手势识别效果真是666)

3、源码研究

接下来就是花了些时间好好看了下[app_algo_hsd_sample_for_csk6]的项目源码,找到非WEBUSB情况下的串口数据输出代码 :

LOG_INF("gesture result id: %d,state: %d", result->id, result->gesture_state);
  • 1

考虑到我的Unity3D项目中要使用串口而非webusb,所以将prj.conf文件中的CONFIG_WEBUSB设置为n,编译对应项目代码(添加-p将编译产物文件夹恢复原始状态来进行编译),并将代码通过lisa zep flash烧录进芯片。

4、创建Unity3D游戏场景(略过一万字…)

5、编写Unity3D代码

这里我先是直接把数据线插到了CSK USB口,导致在使用如下代码查找串口连接时总是找不到,最后是将数据线连接到DAPLink USB上时才找到串口连接的(期待官方如果能_出一个对各种常用语言的串口搜寻和连接示例代码_)。

string[] portList = SerialPort.GetPortNames()
  • 1

我的串口是COM3,这里直接连接它,全部代码如下:

//连接对应串口,并开启数据监听函数
sPort = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
        sPort.ReadTimeout = 10;
        try {
            if(!sPort.IsOpen) {
                sPort.Open();
                Debug.Log("sPort Open.");
                StartCoroutine(DataReceiveFunc());
            }
        }catch (Exception ex ) {
            Debug.Log(ex.Message);
        }

        StartCoroutine(CountdownThenCloseUsbRoutine00());
        
        
        //数据监听函数
        
    IEnumerator DataReceiveFunc() {
        while(true) {
            // Debug.Log("sport.isopen: " + sPort.IsOpen.ToString());
            if(sPort != null && sPort.IsOpen) {
                try {
                    processDataFunc();
                }catch (Exception ex) {
                    Debug.LogError(ex);
                }
            }
            yield return new WaitForSeconds(Time.deltaTime);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

然后是数据转换函数,供参考。

//数据转换函数
    
    private static string byteToHexStr(byte[] bytes) {
        string str = "";
        if(bytes != null) {
            for(int i=0; i < bytes.Length; i++) {
                str += bytes[i].ToString("x2");
                str += "_";
            }
        }
        return str;
    }

    private static string hexStrToStr(string hexstr) {
        string[] hexvalsplit = hexstr.Split("_");
        string end = string.Empty;
        foreach(string hex in hexvalsplit) {
            try {
                int val = Convert.ToInt32(hex, 16);
                string strVal = char.ConvertFromUtf32(val);
                char charVal = (char)val;
                end += charVal;
            }catch(Exception ex) {
                break;
            }
        }
        return end;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

重点的手势识别结果解析及游戏动作控制部分代码如下:

string msg = "";
    private void processDataFunc() {
        int n = sPort.BytesToRead;
        byte[] buf = new byte[n];
        sPort.Read(buf, 0, n);
        bufList.AddRange(buf);
        string hexStr = byteToHexStr(buf);
        if(hexStr != "") {
            string str = hexStrToStr(hexStr);
            // Debug.Log("str : " + str);
            int i0 = str.IndexOf("<inf> main: gesture result id: ");
            if(i0>=0) {
                msg= "";
            }
            msg += str;
            int i1 = msg.IndexOf("state: ");
            if(i0>=0 && i1>=0 && i1>i0+30) {
                Debug.Log("msg: "+msg);
                int action = Convert.ToInt32(msg.Substring(i1+8,1));
                if(action > 0) {
                    Debug.Log("action:"+action);
                    bool go = true;
                    float turnAngle = 0;
                    if(action == 1) {
                        //LIKE 
                    }else if(action == 2) {
                        //OK
                        go = true;
                    } else if(action == 3) {
                        //STOP
                        go = false;
                    } else if(action == 4) {
                        //YES
                        turnAngle = 10; //turn right
                    } else if (action == 5) {
                        //SIX
                        turnAngle = -10; //turn left
                    } else {
                        //OTHER
                        //经常会错判为OTHER手势,为保证游戏连续性,我们不管它。
                    }
                    
                    // Input.Accelerate = go;
                    // Input.Brake = !go;
                    // Input.TurnInput = turnAngle;
                }
                msg = "";
            }
        }
        
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

最终展示结果如下:

通过手势识别结果我们成功控制Unity3D场景中的赛车按照我们的逻辑进行运动。经测试,站在摄像头前半米左右时反应速度还算灵敏,误判率相对较低。

6、其他尝试

本游戏还有很多不完善的地方,同时在尝试优化的过程中发现有可以提升的地方,比如最开始我是想 通过LIKE手势向左指表示左转,向右指表示右转 ,但是通过对官方文档的阅读和对webusb输出信息进行调试发现,输出的手势坐标并不含对应的角度或方向信息。

7、测评反馈及与官方大大探讨

总体上,通过一段时间的试玩,本款芯片的头肩和手势识别效果还是非常棒的,非常期待其后续更多模块的更新和推出。

7.1 建议官方可以优化增加手势的方向数据指标,这样我们的游戏控制项目应该可以做到更好玩。
7.2 另外,建议官方大大可以_出一个对各种常用语言的串口搜寻和连接的示例代码_ 方便不同应用方向的更好实现。

后续我准备做一些跟元宇宙旅游相关的小demo项目,探讨该芯片可能的应用空间和相关可玩性。 再次感谢官方给与这次测评的机会!

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号