本章主要介紹下如何開發一個新的VehicleAdapter子產品(車輛驅動适配對象)。
OpenTCS是一個開放的系統,從核心到子產品元件全部是挂載式設計,這得益于Java語言的反射機制(JAVA從語言級就支援反射)。
在介紹驅動開發之前有必要說明下IOC和DI。即所謂的依賴注入和控制反轉,網絡上有很多關于這兩個技術的介紹,其實這是一種設計模式。(個人覺得IOC時DI的一種實作)。OpenTCS使用了Google的Guice來實作依賴注入。Guice是一個非常優秀的依賴注入架構,很小很好用。
開發OpenTCS的驅動程式可以參考Developer’s Guide(5.3.3)。這裡簡要總結一下步驟:
1、建立一個類,繼承自
VehicleCommAdapter
類。當然
VehicleCommAdapter這
個類是頂層的接口,不建議直接繼承這個類,我們應該繼承
BasicVehicleCommAdapter
類,該類是一個抽象類,繼承體系如下:
2、第一步我們事先了驅動的類,但是如何被建立呢?即如何建立一個Adapter的執行個體?OpenTCS應用了工廠模式,那就需要再建立一個工廠類了,我們需要從
VehicleCommAdapterFactory
類繼承,類圖如下所示:
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。