一步步开发AI运动小程序九姿态辅助调试桌面工具折使用

Posted Alphaair

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一步步开发AI运动小程序九姿态辅助调试桌面工具折使用相关的知识,希望对你有一定的参考价值。

随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让云上运动会、线上运动会、健身打卡、AI体育指导等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从零开始开发一个AI运动小程序,本系列文章将使用“云智AI运动识别小程序插件”,请先行在微信服务市场官网了解详情。

一、工具介绍

受限于微信小程序IDE,无法在IDE上直接调试camera组件及相关API,联机调试时console输出大数据时可能导致卡死的问题,为了弥补此项不足,我们为各位开发者准备了一个姿态调试的辅助桌面工具,帮助开发者更高效的进行姿态调试。

二、使用安装

请先按照集成文档,安装好工具的运行时。

三、启动服务器

点击【启动】按钮,启动调试工具回传服务器,准备接收回传数据,工具默认情况下是监听所有IP的20231端口,请关闭调试机器的防火墙,查看并记住本机的内网IP

四、小程序回传帧

小程序端是由BodyDebugClient对象,负责向工具进行回传人体识别数据的。

const AiSport = requirePlugin("aiSport");
const humanDetection = AiSport.humanDetection;
const BodyDebugClient = AiSport.BodyDebugClient;

//新建客户端
const client = new BodyDebugClient("http://192.168.5.87:20231"); //假设您运行工具的机器IP是192.168.5.87,实际使用替换相应的IP即可
client.connect();

//抽帧
const context = wx.createCameraContext();
const listener = context.onCameraFrame((frame) => 
	const iamge = 
		width: Number(frame.width),
		height: Number(frame.height),
		rawData: frame.data
	;
	
	//人体识别
	humanDetection.detectionAsync(image).then(human=>
		client.enqueue(frame, human);//回传暂存
	);
);
listener.start();

//切记先停止抽帧和识别,再进行执行同步,否则可能会导致UI卡死
listener.stop();

uni.showLoading(
	title: \'同步帧数据...\'
);
client.syncing((idx, total) => 

	uni.hideLoading();
	if (idx >= total)
		return;

	uni.showLoading(
		title: `同步进度$idx/$total`
	);

);

下篇将为您介绍姿态相似度比较功能,敬请期待...

开发中的辅助工具

        今天我们来看一看开发中的辅助工具,那么什么是开发环境呢?在我们的印象中,开发环境就指的是编写代码的环境。其实不然,开发环境包括三大部分:构建环境、调试环境以及测试环境。构建环境便指得是代码编写、程序编译以及版本控制等;调试环境则指的是用于定位问题的辅助工具集;测试环境指的是用于验证目标程序是否满足用户的显性需求和隐形需求。显性需求指的是客户的要求,而隐形需求则指的是一些用户没有要求到的但是必须具备的要求。比如一个应用程序在 win7 系统上可以运行起来,在 win10 系统上也要能运行起来。

        在嵌入式的开发中,我们在整个项目中的代码编写及目标构建上一般只花费 20% 的时间,剩下的 80% 的时间适用于测试、调试以及 bug 修复的。那么我们该如何提高开发效率呢?工欲善其事必先利其器,我们可以借助于一些工具,从而提高开发的效率。GNU 为 GCC 编译器提供了配套的辅助工具集(Binutils),网址是 http://www.gnu.org/software/binutils/ ;其中的一些工具介绍如下

工具名     
功能简介                                    
add2line 
将代码地址转换为对应的程序引导
strip        
提出可执行程序中的调试信息      
ar            
将目标文件打包成为静态库         
nm          
列出目标文件中的符号及对应地址
objdump
查看程序段信息及反汇编             
size         
查看目标文件中的段大小             
strings    
查看目标文件中的字符串             

        下来我们来一一的介绍下这几个工具。

        1、addr2line : 将制定复制转换为对应的文件名和行号,常用于分析和定位内存访问错误的问题。来个示例代码进行分析说明


func.c 源码

#include <stdio.h>

int* g_pointer;

int main()
{
    *g_pointer = (int)"D.T.Software";
    
    return 0;
}


test.c 源码

#include <stdio.h>

int g_global = 0;
int g_test = 1;

extern int* g_pointer;
extern void func();

int main(int argc, char *argv[])
{
    printf("&g_global = %p
", &g_global);
    printf("&g_test = %p
", &g_test);
    printf("&g_pointer = %p
", &g_pointer);
    printf("g_pointer = %p
", g_pointer);
    printf("&func = %p
", &func);
    printf("&main = %p
", &main);
    
    func();
    
    return 0;
}

        我们先来分析下这份代码。我们在前面直接定义 int 类型的指针,但是并没有将其指为 NULL。那么此时 g_pointer 已经指向了内存的 0 地址处,在 main 函数中操作 0 地址处,这肯定会引起段错误。我们来看看编译运行结果

技术分享图片

        我们看到 g_pointer 是个空指针,后面就直接发生段错误,如果这是个很大的项目,几十万行的代码,相信我们定位问题就很困难了。那么此时我们该如何定位问题呢?addr2line 工具便出场了。使用的步骤如下:1、开启 core dump 选项:ulimit -c unlimited;2、运行程序,并生产崩溃时的 core 文件,执行导致程序崩溃的测试用例;3、读取 core 文件,获取 IP 寄存器的值:dmesg core;4、使用 add2line 定位代码行:addr2line 地址 -f -e test.out。如下

技术分享图片

        我们看到此时已经生成了 core 文件,我们来 dmesg core 看看 IP 寄存器的值是什么

技术分享图片

        我们看到 IP 寄存器的值是 0x080484b8,然后利用 addr2line 工具就可以直接定位到问题的所在了。

        2、strip:用于剔除程序文件中的调试信息,减少目标程序的大小。一般在程序发布前都需要将调试信息剔除,过多的调试信息可能影响程序的执行效率。我们来看看它的用法,strip test.out

技术分享图片

        我们看到在经过剔除之后,它的文件大小几乎减少了一半。使用它的注意事项:1、几乎所有的调试工具都依赖于目标文件中的调试信息,调试信息的运用能够快速定位问题;2、使用 gcc 编译程序时使用 -g 选项生成调试信息,发布程序时再考虑是否使用 strip 剔除调试信息。那么这时如果想要利用 core 文件定位问题就不可以了,因为 core 文件只能定位出调试版本的信息

技术分享图片

        我们看到它是定位不出问题的所在的。

        3、ar : 打包目标文件,ar crs libname.a x.o y.o;解压目标文件,ar x libname.a。下来看看是如何使用的

技术分享图片

        我们利用打包和解压命令从而就可以直接给别人发第三方库文件。如果我们只有第三方的库文件而想使用其中的一个 .o 文件,那么就可以使用解压命令来进行使用其中的一个文件。

        4、nm:用于列出目标文件中的标识符(变量名、函数名),输出结果由三部分组成{地址、段以及标识符}。示例如下

技术分享图片

        段标识说明如下

技术分享图片

        我们来看看 func.o 和 test.o 文件中的标识符

技术分享图片

        我们看到在 func.o 文件中 func 是位于代码段的,它的偏移量为0。在这没有经过链接,所以显示的都是相对地址。g_pointer 属于未定义的标识符,相对偏移量为 4。下来我们看看链接后的地址

技术分享图片

        我们看到经过链接后的地址是绝对地址。

        5、objdump : 反汇编目标问阿金,查看汇编到源码的映射。objdump -d func.o 或者 objdump -S func.o。查看目标文件中的详细段信息,objdump -h test.out。

        objdump -h 的输出说明如下

技术分享图片

        使用输出信息如下

技术分享图片

        我们再来看看链接后的 test.out 的详细信息。

技术分享图片

        我们看到它的 VMA 和 LMA 是一样的,也就是说,虚存地址和加载地址是一样的。在进行运行程序的时候,首先是为可执行文件分配虚存,接着通过 file off 获取到相对位置,通过复制段信息过去,加载目标地址到虚存上。最后是执行程序。

        6、size 用来获取目标文件中的所有段大小,size test.outstrings 用来获取目标文件中的所有字符串常量。如下

技术分享图片

        那么我们获取它们的大小和字符串有什么意义呢?在嵌入式的开发中,资源往往是非常受限的,因此我们就必须得严格控制目标文件的大小,以防止超出其界限造成不可预料的错误;我们如果想要获取某些特定的字符串时就不必去看代码了,直接用 strings 就可以看到全部的字符串了,以提高开发效率。

以上是关于一步步开发AI运动小程序九姿态辅助调试桌面工具折使用的主要内容,如果未能解决你的问题,请参考以下文章

一步步开发AI运动小程序一准备工作

一步步开发AI运动小程序七进行运动计时计数

一步步开发AI运动小程序三运动识别处理流程

一步步开发AI运动小程序六人体骨骼图绘制

一步步开发AI运动小程序五帧图像人体识别

利用“姿态相似度比较”功能,对运动(动作)识别检测“秒”适配