在机器人开发过程中可能会出现非正常行为,在沟通的过程中需要反馈一些数据Log,以便思岚进行数据分析。本文将通过GetLogInfo介绍如何使用Android SDK来获取底盘的Log信息,以便分析之用。
本页内容
运行环境准备
软件平台
- Android Studio 3.1.3
- Slamware Android SDK: slamware_sdk_android.2.6.0_dev.20180917.tar.gz
- RoboStudio(用于显示地图):Robostudio installer
RoboStudio 插件:peer log / action stack / diagnosis,其中插件的激活码需要申请,由思岚工程师提供
Sample Code: SampleCode.java
注意
Slamware 的固件和SDK在2018年9月14日才添加用户获取Log的功能和接口,如有获取Log的需求,请更新至2018年9月14日的版本。
使用不同版本的Android Studio可能会带来编译异常,请自行下载相关库和修改build.gradle配置文件,本例程基于Slamware Android SDK 2.6.0 进行开发,若想尝试更高的SDK版本,请直接替换工程中的 slamware_sdk_android.jar 和 librpsdk.so 文件。
硬件平台
(以下任选其一)
- Slamware SDP mini
- Slamware SDP
- Slamware 套装 (基于Slamware导航方案的用户机器人系统)
- Zeus/Apollo等底盘系统
编译运行
- 打开GetLogInfo工程,检查libs路径下是否有 slamware_sdk_android.jar 文件,以及jinLibs路径下是否有 librpsdk.so 文件,若想尝试其他版本的SDK,请直接将这两个文件替换。
到 Project Structure --> app --> Dependencies 检查Slamware SDK是否添加到工程中。
将以下代码段的"10.0.130.71"修改为底盘的IP地址,默认情况下为192.168.11.1,当WIFI处于Station模式下请将PC与底盘使用Ethenet连接后查看。方法说明:AbstractSlamwarePlatform connect(String host, int port),其中host为底盘IP,port为网络端口号,返回值为底盘的实例对象。
// connect to the robot. String ip = "10.0.130.71"; int port = 1445; Log.i("MyCorePlatform", "start to connect."); com.slamtec.slamware.AbstractSlamwarePlatform corePltfm = com.slamtec.slamware.discovery.DeviceManager.connect(ip, port);
Android设备连接底盘发射出的WIFI或连入底盘的同一网络,按下shift + F10 运行,可以在AS Logcat中看到通过SDK获取到的Log信息,如下图所示。
本例程仅仅用作最简单SDK类和方法的演示,故没有设计Android界面
- Robostudio peer log插件显示的Log如下图所示,使用Robostudio 获取查看底盘Log信息的方法请参考 KBSW180156 如何使用robostudio采集分析问题所用数据。
- Log数据的相关格式请参考Log Samples Of Customer Log.pdf,Android SDK的Log相关的接口说明请参考Slamware-log-customer文档.pdf。
代码描述
- 获取Log信息
try { // connect to the robot. String ip = "10.0.130.71"; int port = 1445; Log.i("MyCorePlatform", "start to connect."); com.slamtec.slamware.AbstractSlamwarePlatform corePltfm = com.slamtec.slamware.discovery.DeviceManager.connect(ip, port); if (null == corePltfm) { Log.e("MyCorePlatform", "Failed to connect."); return; } Log.i("MyCorePlatform", "Connected"); // Create Customer Log Receiver for receiving logs; // If the connection is lost, the old log receiver will not work, a new one should be created. com.slamtec.slamware.log.customer.ICustomerLogReceiver logReceiver = corePltfm.createCustomerLogReceiver(); if (null == logReceiver) { Log.e("MyLogReceiver", "Failed to create."); return; } Log.i("MyLogReceiver", "Created"); com.slamtec.slamware.log.customer.CustomerLogReceiverInitArg initArg = null; // if you want to resume the last receive status, load the saved status data like the following codes: /* { initArg = new com.slamtec.slamware.log.customer.CustomerLogReceiverInitArg(); initArg.setLastRecvStatus(lastRecvStatus); // lastRecvStatus is the last receive status data you saved before } */ com.slamtec.slamware.log.customer.ResultCode resCode = logReceiver.init(initArg); if (com.slamtec.slamware.log.customer.ResultCode.Ok != resCode) { Log.e("MyLogReceiver", "Failed to init, resCode: " + resCode.name()); return; } boolean isWorking = true; while (isWorking) { // some other operations of your application int maxCntToRead = 0; // set to zero to use the default value of the robot. com.slamtec.slamware.utils.StdPair<com.slamtec.slamware.log.customer.ResultCode, com.slamtec.slamware.log.customer.ReadResult> pairRes = logReceiver.recvLogs(maxCntToRead); if (com.slamtec.slamware.log.customer.ResultCode.Ok == pairRes.getFirst()) { showMyLogsResult_(pairRes.getSecond()); } else { Log.e("MyLogs", ("ResultCode: " + pairRes.getFirst().name())); } // some other operations of your application Thread.sleep(100); } // you may save it for the next time to continue to receive logs if you want. /* { com.slamtec.slamware.log.customer.CustomerLogReceiverLastRecvStatus lastRecvStatus = logReceiver.getLastRecvStatus(); // now you can save lastRecvStatus somewhere for the next time } */ } catch (Exception e) { Log.e("MyException", e.toString()); }
private void showMyLogsResult_(com.slamtec.slamware.log.customer.ReadResult tRes) { java.util.ArrayList<com.slamtec.slamware.log.LogData> logsList = tRes.getLogs(); int iLogsCnt = (null != logsList ? logsList.size() : 0); Log.i("MyLogs", ("LogsCnt: " + iLogsCnt)); if (iLogsCnt < 1) return; for (int i = 0; i < iLogsCnt; ++i) { Log.i("MyLogs", ("logs[" + i + "]")); com.slamtec.slamware.log.LogData logDat = logsList.get(i); if (null == logDat) { // it should not be null here, there may be some problems. Log.e("MyLogs", "null log data."); continue; } boolean bIsJsonLog = logDat.getIsJsonLog(); if (bIsJsonLog) { // if it is json Log, you can parse the string of log to a JSON object. // ALL customer logs are json log. } String strMsg = ("LogSource: " + logDat.getLogSource() + "\n"); strMsg += ("LogLevel: " + logDat.getLogLevel().name() + "\n"); strMsg += ("IsJsonLog: " + bIsJsonLog + "\n"); strMsg += ("StringOfLog: " + logDat.getStringOfLog() + "\n"); Log.i("MyLogs", strMsg); } }