OpenTCS打造移动机器人交通管制系统(三)

本章主要介绍下如何开发一个新的VehicleAdapter模块(车辆驱动适配对象)。

OpenTCS是一个开放的系统,从内核到模块组件全部是挂载式设计,这得益于Java语言的反射机制(JAVA从语言级就支持反射)。

在介绍驱动开发之前有必要说明下IOC和DI。即所谓的依赖注入和控制反转,网络上有很多关于这两个技术的介绍,其实这是一种设计模式。(个人觉得IOC时DI的一种实现)。OpenTCS使用了Google的Guice来实现依赖注入。Guice是一个非常优秀的依赖注入框架,很小很好用。

开发OpenTCS的驱动程序可以参考Developer’s Guide(5.3.3)。这里简要总结一下步骤:

1、创建一个类,继承自VehicleCommAdapter类。当然VehicleCommAdapter这个类是顶层的接口,不建议直接继承这个类,我们应该继承BasicVehicleCommAdapter 类,该类是一个抽象类,继承体系如下:

OpenTCS打造移动机器人交通管制系统(三)_第1张图片

2、第一步我们事先了驱动的类,但是如何被创建呢?即如何创建一个Adapter的实例?OpenTCS应用了工厂模式,那就需要再创建一个工厂类了,我们需要从VehicleCommAdapterFactory类继承,类图如下所示:

OpenTCS打造移动机器人交通管制系统(三)_第2张图片

3、这一步可选。如果需要在控制面板里面常见一个Panel,那么还需要VehicleCommAdapterPanel 类继承创建一个MyVehicleCommAdapterPanel 类。这样才能注册一个Adapter的图形化界面。

创建一个Adapter必须的步骤就是1、2步骤。所以这一章主要讲这两个步骤的代码实现(MyVehicleCommAdapter和MyVehicleCommAdapterFactory这两个类),为了方便起见,我们直接在openTCS-CommAdapter-Loopback工程里面添加相关代码(实际工程建议另起一个工程)。

以下的代码片段只是为了简化说明问题,代码不做任何逻辑处理,同时会对关键接口追加注释。

代码MyVehicleCommAdapter 代码如下:

/**
 * Authors:白色冰激凌
 * Website:https://blog.csdn.net/xlh145
 */
package org.opentcs.myvehicle;

import java.util.List;

import org.opentcs.drivers.vehicle.BasicVehicleCommAdapter;
import org.opentcs.drivers.vehicle.MovementCommand;
import org.opentcs.drivers.vehicle.VehicleProcessModel;
import org.opentcs.util.ExplainedBoolean;

public class MyCommAdapter extends BasicVehicleCommAdapter {

  private boolean isConnected;

  public MyCommAdapter(VehicleProcessModel vehicleModel) {
    super(vehicleModel, 2, 2, "charge");
  }

  @Override
  public ExplainedBoolean canProcess(List operations) {
    //默认可以处理所有操作,实际操作是否支持需要根据项目的情况来判断
    return new ExplainedBoolean(true,"");
  }

  @Override
  public void processMessage(Object message) {
    //这里为了简化不处理任何消息
  }

  @Override
  public void sendCommand(MovementCommand cmd) throws IllegalArgumentException {
    //这里处理实际的运动指令,运动指令被包装到了MovementCommand这个类中。你需要提取Path然后做响应的处理。
  }

  @Override
  protected void connectVehicle() {
    //这里需要连接具体的Vehicle。如果你的Vehicle是TCP接口的那就这里进行Socket连接。
    //如果是其他接口的也在这里进行网络连接
    
    isConnected = true;
  }

  @Override
  protected void disconnectVehicle() {
    //这里需要断开具体的Vehicle连接。如果你的Vehicle是TCP接口的那就这里断开Socket连接。
    //如果是其他接口的也在这里断开连接
    isConnected = false;
  }

  @Override
  protected boolean isVehicleConnected() {
    // 设备是否已连接
    return isConnected;
  }
}

代码MyVehicleCommAdapterFactory 代码如下::

/**
 * Authors:白色冰激凌
 * Website:https://blog.csdn.net/xlh145
 */
package org.opentcs.myvehicle;

import org.opentcs.data.model.Vehicle;
import org.opentcs.drivers.vehicle.VehicleCommAdapter;
import org.opentcs.drivers.vehicle.VehicleCommAdapterFactory;
import org.opentcs.drivers.vehicle.VehicleProcessModel;


public class MyCommAdapterFactory implements VehicleCommAdapterFactory {
 
  public MyCommAdapterFactory() {
    
  }

  @Override
  public void initialize() {
    
  }

  @Override
  public boolean isInitialized() {
    return true;
  }

  @Override
  public void terminate() {
 
  }

  @Override
  public boolean providesAdapterFor(Vehicle vehicle) {
    return true;
  }

  @Override
  public VehicleCommAdapter getAdapterFor(Vehicle vehicle) {
    //这里返回一个Adapter实例
    return new MyCommAdapter(new VehicleProcessModel(vehicle));
  }

  @Override
  public VehicleCommAdapterDescription getDescription() {
    //这里返回一个Adapter描述对象,这里其实是得到一个字符串用于标识你的Adapter名称
    return new VehicleCommAdapterDescription(){
      @Override
      public String getDescription() {
        return "MyVehicle";
      }
    };
  }
}

最后还要在Guice中注册以下工厂类,在configure函数内追加一行代码:

vehicleCommAdaptersBinder().addBinding().to(MyCommAdapterFactory.class);

通过上面简单的几步,其实一个驱动就开发完了(当然实际项目一个Adapter没有上面那么简单,上面代码只是为了说明问题)。

下一章分析OpenTCS中的一些策略和算法,同时拓展Service。

你可能感兴趣的:(机器人相关,OpenTCS,opentcs,移动机器人,调度系统,AGV)