51

开发实录:如何做一个可实时视频的智能小车

 5 years ago
source link: https://mp.weixin.qq.com/s/MNT8QGB0RqejX8p7OC15cw?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文的三位作者正阳、海洋、阿力,是来自不同公司的工程师,将 Agora SDK 与智能小车结合,开发了一款通过智能小车来实时视频远程看房的创新项目。本文将从方案设计到具体实现,详实分享他们的开发经验。三人也凭借该项目,在7月1日结束的 Agora RTC Hack 上海站编程马拉松获得大奖。

创意与构思

此前听到多很多次“黑客马拉松”这样的活动,一群来自不同地方的人聚在一起,组队、构思、开发,在48小时内做出产品雏形。我们三人抱着去听听别人的创意,重在参与的想法参加了这次比赛。对于想要做的东西,在比赛前也只是有一个大概的方向:

  1. 构思的方向依据我们擅长的部分来组合拼接,这就得说到我的两位给力队友海洋、阿力;海洋是嵌入式软件工程师,汽车电子方向,写个驱动做个小车手到擒来。阿力是后端工程师,具备处理服务器端和前端页面的能力。

  2. 于是队伍有了嵌入式和云端两部分的能力,技术构思的方向是云端为嵌入式赋能。希望有一个小车,小车可以传递回视频图像,视频图像可以实时传给多个用户,用户在得到授权之后,实现远程对小车的操控。

方案设计与分工

U7r6fu2.jpg!web

出于这样的构思,实现架构如上图所示。现在有了一个基本架构,也清楚了我们要实现的功能,接下来就是分工了。考虑到我们各有所长,分工如下:

fyY7naA.jpg!web

E7Zr2qB.png!web

从硬件开发开始

小车采用了是4轮伺服电机驱动,搭配有视频采集模块、伺服电机驱动模块、STM32控制模块和摄像头云台模块,安装后整体效果图如下:

vUnU73E.jpg!web

图:效果图

用户在远程操控小车各种动作之前,需要小车通过wifi连接到互联网。用户可以通过上位机(Android App 或网页前端)控制小车前后左右移动或控制云台调整摄像头方向。

视频采集模块包含有 Wi-Fi 模块,可以连接到wifi热点为视频传输提供网络基础。也提供 HDMI 接口与显示器连接,方便用户调试。摄像头通过 USB 的方式与视频采集模块连接,我们采用免驱动的天敏6602型号摄像头,分辨率可以达到640*480,并能够自动调焦。

STM32 控制模块采用 Arduino 接口与伺服电机驱动模块连接, STM32 模块负责控制电机、云台信号的产生,并由伺服电机驱动模块直接驱动电机工作。伺服电机输入电压为6~12V,直流驱动。

工作原理

小车上的视频采集模块采用了定制的 Android 系统,提供网络连接、指令转发和视频流采集、传输功能。当上位机通过远程服务连接到小车后,上位机可以请求到当前小车摄像头上的视频信息;同时,视频采集模块也将上位机上传来的控制信号解析为指定格式和功能的协议数据,并通过串口发送到 STM32控制模块。

小车上的 STM32 控制模块在接收到相关控制信号后,调整输出脉冲信号的占空比,由驱动板转换输出电平后直接控制伺服电机或云台模块做出相应的动作,从而完成上位机用户想要的操控功能。

控制信号协议

对于只需要实现简单的小车控制的话,我们只需要实现通过串口向  STM32 控制模块发送控制信号即可,简单的控制信号协议如下:

eMrQBbv.jpg!web

Android SDK 的定制

开发工具

为了实现我们想要的实时视频与小车的远程控制功能,我们需要采用声网的视频通话  SDK ,并运行在 Android 开发板上。开发板,我们选用了 FireflyRK3128 平台,采用 Cortex-A7 架构四核1.3GHz 处理器、 Mali-400MP2 GPU ,板载千兆以太网口、 2.4GHz Wi-Fi 和蓝牙4.0,支持 AndroidUbuntu 双系统。

q2MNVnr.jpg!web

定制串口驱动

为了实现 RK3128 对小车的控制,我们需要实现 RK3128 通过 USB 转串口模块与 STM32 控制模块通信。因此我们首先要重新配置 RK3128 内核,使得  RK3128  支持 USB 转串口驱动程序。

首先下载完 RK3128 Android SDK 并先验证文件 MD5值: 

md5sum /path/to/fireprime_android5.1_git_20180510.tar.gz
fce0e6d65549939167923260142b2c1e fireprime_android5.1_git_20180510.tar.gz

确认无误后解压:  

mkdir -p ~/proj/fireprime
cd ~/proj/fireprime
tar xvf /path/to/fireprime_android5.1_git_20180510.tar.gz
git reset --hard
git remote add bitbucket https://bitbucket.org/T-Firefly/firenow-lollipop.git
git pull bitbucket fireprime:fireprime

配置并编译内核:  

cd ~/proj/fireprime/kernel
make rk3128-fireprime_defconfig
make menuconfig
make -j8 rk3128-fireprime.img

其中  make menuconfig  这一步需要勾选上  Device Drivers —> USB support —> USB Serial Converyer support —> USB Serial Console device support / USB Generic Serial Driver, 并勾选上 CP210x / CH341 / FTDI / PL2303 等常用串口工具设备

2iEfUjU.jpg!web

编译 Android 系统: 

cd ~/proj/fireprime
. build.sh
make -j8
./mkimage.sh

最后编译完成后烧录分区镜像,并插入  USB  转串口工具查看系统  dmesg  是否出现以下  log  信息: 

[ 2213.003173] usb 1-1.3: new full-speed USB device number 6 using rockchip_ehct
[ 2213.113759] usb 1-1.3: New USB device found, idVendor=10c4, idProduct=ea60
[ 2213.113839] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumbe3
[ 2213.113883] usb 1-1.3: Product: CP2102 USB to UART Bridge Controller
[ 2213.113921] usb 1-1.3: Manufacturer: Silicon Labs
[ 2213.113956] usb 1-1.3: SerialNumber: 0001
[ 2213.120813] cp210x 1-1.3:1.0: cp210x converter detected
[ 2213.209852] usb 1-1.3: reset full-speed USB device number 6 using rockchip_et
[ 2213.320161] usb 1-1.3: cp210x converter now attached to ttyUSB0

出现串口设备附着到 ttyUSBx ,即说明定制串口驱动成功。

以上为全编译  Android SDK  的方法,需要编译 Android 系统,相较于仅编译内核而言比较费时。我们可以在上述  make menuconfig  时将需要的串口驱动程序勾选为 M,通过  make modules  的方法,将驱动编译成 .ko 文件,然后在 Android  系统开机时自动加载驱动程序:

首先将 .ko 驱动程序文件复制到 Android 文件系统内  

adb shell
su
mount -o remount ,rw /
mkdir /modules
chmod 777 /modules
chown -R nobody:nobody /modules
exit
exit
adb push ./xxxx.ko /modules

编写启动运行脚本   /data/serial.sh  

#!/system/bin/sh
insmod /modules/xxxx.ko
mknod /dev/ttyUSB c 240 0

修改 init.rc  并添加运行自己的脚本 

service serial /system/bin/sh /data/serial.sh
user root
oneshot

在 App 端实现视频传输

视频传输和信令传输的部分,我们通过声网 Agora SDK 来实现。由于涉及到与嵌入式开发板的结合,我们主要参考的是声网在 Github 提供的各种案例中的抓娃娃机 demo 。示例代码中的结构图如下:

示例代码有视频传输的部分,控制信令需要参考声网信令文档自己完成。

FZZB3yr.png!web

声网 SDK 的集成

1. 首先申请 AppID

ZRziaay.jpg!web

Android APP 中在 res/values/strings_config.xml  加入如下内容,将  agora_app_id  进行配置 

<resources>
<string name="agora_app_id">1a486ee31a30xxxxxxxxxx</string>
</resources>

2. 将. jar  文件拷贝到libs/中

因为用到信令和视频传输两部分,需要两个. jar 文件分别为 agora-rtc-sdk.jar agora-sig-sdk.jar

3. 在 src/main/jniLibs 加入 armeabi-v7a 与其中的.so文件

6FbYvqQ.jpg!web

并在 build.gradle 中确定拥有如下描述: 

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'

}

就此,使用示例代码可以顺利开启视频传输功能。

用信令让 App 控制小车

信令的实现

信令的具体使用方法见声网官网文档中心的参考,这里就不进行详尽描述了。主要使用的函数如下: 

// 初始化信令 SDK
m_agoraAPI = AgoraAPIOnlySignal.getInstance(context, appID);

// 登录 Agora 信令系统
m_agoraAPI.login2(appId, account, token, uid, deviceID, retry_time_in_s, retry_count)

//////////////点对点测试/////////////
// 发送点对点消息
m_agoraAPI.messageInstantSend(account, uid, msg, msgID)

// 设置对端收到消息回调(
m_agoraAPI.onMessageInstantReceive(account, uid, msg){
//code there
}
/////////////频道测试///////////////
// 加入频道
m_agoraAPI.channelJoin(channelName)

// 发送频道消息
m_agoraAPI.messageChannelSend(channelName, msg, msgID)

// 设置对端接收到频道消息回调
m_agoraAPI.onMessageChannelReceive(channelID, account, uid, msg) {
// code there
}
//////////////////////////////////
// 退出 Agora 信令系统
m_agoraAPI.logout()

Android App 操作串口

对于小车端的 Android App 得到信令之后需要串口发送数据。因此如何实现 Android App 操作串口。这里简述两种方案:

  1. 采用 Android 系统给出的架构进行处理, Android 带有串口 demo 代码,名称为 SerialPort 。这里注意两点,此处的代码依赖于 JNI 工具和 NDK ,如果没有完整安装在使用项目代码的时候会出现问题。另外,串口操作不方便使用 Android 模拟器进行测试,对于没有串口的设备,在开启串口的动作时,会报错并可能导致程序退出崩溃。

  2. 选择使用 Android 代码发送 shell 命令的方式,直接模拟 Linuxshell 控制代码,示例 echo ‘aa’ > /dev/ttyUSB0 将  aa  发送到串口 ttyUSB0 ,这样做的好处时代码本身简单,串口直接调用底层。

对于短时间实现功能来说,方案2是更容易实现的方法,这里需要非常注意的一点, 需要重新编译 Androidframework 层给 App 赋予 root 权限

当信令解析完成,串口调试通过,就可以实现远程控制小车的行进了。

最后:服务器端的部署

为了实现用户可以方便通过手机或者电脑在线实时看房,我们需要通过 W eb 端连接小车的 Android App 端,获取实时传输过来的视频内容。在我们的设想中,用户可以通过远程控制小车,这样可以方便用户了解房屋各个方面的情况。综上所述,我们需要实现如下两个功能:

  • 具有视频连接功能

  • 具有远程遥控功能

幸运的是,通过声网提供的服务,我们可以很便捷的搭建这两个服务。
在本项目中,我们使用声网的视频 SDK 实现网页端和小车 App 端的视频连接,通过信令 SDK 发送消息,去控制小车的前后左右行走和摄像头上下左右摆动。

罗列一下我们使用到的工具:

  • 声网视频通话 Web SDK 及文档,用来实现远程的视频交互功能;

  • 声网信令 SDK 及文档,用来实现远程遥控智能小车;

  • 服务器,用于部署静态页面;

实现视频连接和发送消息

先在页面上引入视频和信令的 SDK。然后我们先来实现视频连接。 

// 创建 AgoraRTC 实例并加入频道
const client = AgoraRTC.CreateClient({mode:"interop"})


client.init(appId, function () {
console.log("AgoraRTC client initialized");
client.join(channel_key, CHANNEL_NAME, null, function (uid) {
console.log("User " + uid + " join channel successfully")
console.log(new Date().toLocaleTimeString())

// do something
}
}

订阅远端的视频流并播放。 

let stream = AgoraRTC.creatStream(merge(defaultConfig.config))
localStream.init(() =>{
client.on('stream-added', function (evt) {
var stream = evt.stream;
console.log("New stream added: " + stream.getId());
console.log("Subscribe ", stream);
client.subscribe(stream, function (err) {
console.log("Subscribe stream failed", err);
});
});
client.on('stream-subscribed', function (evt) {
var stream = evt.stream;
console.log("Subscribe remote stream successfully: " + stream.getId());
if ($('div#video #agora_remote' + stream.getId()).length === 0) {
$('div#video').append('<div id="agora_remote' + stream.getId() + '" style=" width:810px;height:607px;"></div>');
}
stream.play('agora_remote' + stream.getId());
});

})

通过下述方法来实现发送信息。 

// 创建信令的对象
const signal = Signal(appId)

// 在实验条件下,不设置token
const token = '_no_need_token'
// 登录
const session = signal.login(account, token)

session.onLoginSuccess = (uid) => {
//发送消息给指定的账号
signal.sendMessage(reciveAcount, message)
}

完成上述的步骤之后,与小车端设置相同的  appId  和  token (如有必要),设定好对应的参数,我们就可以远程控制小车并获取视频了

y6beEbe.jpg!web

图:现场演示

Ev2IJrn.jpg!web

图:48小时改装的小车

EvymMjB.gif

Hacker 们用实际行动,说明了 RTC 技术不仅仅可应用于娱乐、社交、教育等领域,还可以迸发出更多新的创意。就在近期, Agora RTC Hack 还在全球其它城市火热进行中。有个人,也有来自创业公司的团队参赛并获奖。我们将邀请其中几支来自世界各地的获奖团队参加到9月7日 - 8日举行的 RTC 2018 实时互联网大会。现场不仅有 Google WebRTC 产品经理、华为多媒体实验室首席科学家、Twitch 首席研发工程师、AVS 标准工作组组长等技术大咖们带来的干货,还将有这些饱含创意与开发热情的小项目。想与他们聊一聊,交个朋友么?扫码报名,现场约起来吧!

Q3MBVzj.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK