怎样写一个类似ROS的易用的android机器人框架(3)

怎样写一个类似ROS的易用的android机器人框架(3)

怎样写一个类似ROS的易用的android机器人框架(2)

参考项目源码

我们实现了类似ROS系统的节点注册和消息转发机制,在这个机制中,节点自定义的消息封装在Bundle对象中,这样每个节点的 publish()都统一了,但是也有不好的,用起来就没那么方便,我们更希望定义自己的消息类,将一些复杂的数据填入这个类对象中,然后发布,如机器人马达的数据,可以定义:

data class MsgMotor(@JvmField var L: Int = 0, @JvmField var R: Int = 0)

转换成Bundle就得这么写

Bundle().apply {
	putInt("L", xxx.L)
	putInt("R",xxx.R)
}

其他节点接收到这个消息时又得反向解析一遍,很麻烦 能否简单解决呢?

利用 apt 自动生成转换类的代码

apt可以扫描源码中特定的注解,并根据注解生成特定的代码,因此我们开发apt工具库,然后在让编译脚本调用这个工具库帮我们生成这些转换代码。源码目录下

  • easyAptApi : 包含源码和apt工具库需要识别的注解的定义
  • easyAptProcessor: 是实现这个代码处理过程的实现

gradle脚本中指定 **kapt **(apt的Kotlin实现)processor的设置和依赖

dependencies {
	compile project(":easyAptApi")
	//指定 apt
	kapt project(":easyAptProcessor")
}

需要转换的类添加注解

@MessageType("")
data class MsgMotor(@JvmField var L: Int = 0, @JvmField var R: Int = 0)

然后编译 kapt 自动在 generated 目录下生成转换类的源码

public final class ConvertMsgMotor {
  public static Bundle toBundle(MsgMotor msgmotor) {
    Bundle b = new Bundle();
    try {
      b.putInt("L", msgmotor.L);
      b.putInt("R", msgmotor.R);
    } catch (Exception e) {
       e.printStackTrace();
    }
    return b;
  }

  public static MsgMotor toMsg(Bundle b) {
    MsgMotor r = new MsgMotor();
    try {
      r.L = b.getInt("L");
      r.R = b.getInt("R");
    } catch (Exception e) {
       e.printStackTrace();
    }
    return r;
  }
}

使用这个ConvertMsgMotor即可实现MsgMotor与Bundle之间的相互转换了。

kapt processor 的实现过程

gradle脚本添加

dependencies {
    compile project(':easyAptApi')
    compile 'com.google.auto.service:auto-service:1.0-rc2'
    compile 'com.squareup:javapoet:1.9.0'
}

定义主类

processor的主类需要实现 AbstractProcessor接口,并添加注解 @AutoService(Processor::class) ,这是com.google.auto.service中的注解,用来生成apt插件库

需要定义 resource 目录下的 META-INF/services/javax.annotation.processing.Processor文件,填写主类的完整包名和类名,否则编译脚本将无法搜索到这个插件类

实现 AbstractProcessor的所有方法

  1. override fun init(processingEnv: ProcessingEnvironment) :插件初始化时调用
  2. override fun getSupportedAnnotationTypes(): Set<String> : 必须返回所有需要处理的注解的完整包名类名的集合,否则将忽略不处理
  3. override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean : 真正的处理函数,可在此调用 com.squareup:javapoet 库生成 java文件

通过Java Peot库生成java源代码文件

这样,一个根据注解自动生成代码的apt插件库机完成了

怎样写一个类似ROS的易用的android机器人框架(4)

猜你喜欢

转载自my.oschina.net/u/181909/blog/1813843