天天看點

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打造移動機器人交通管制系統(三)

2、第一步我們事先了驅動的類,但是如何被建立呢?即如何建立一個Adapter的執行個體?OpenTCS應用了工廠模式,那就需要再建立一個工廠類了,我們需要從

VehicleCommAdapterFactory

類繼承,類圖如下所示:

OpenTCS打造移動機器人交通管制系統(三)

3、這一步可選。如果需要在控制台裡面常見一個Panel,那麼還需要

VehicleCommAdapterPanel

 類繼承建立一個My

VehicleCommAdapterPanel

 類。這樣才能注冊一個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<String> 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。

繼續閱讀