开发OpenTCS的驱动程序可以参考Developer’s Guide(5.3.3)。这里简要总结一下步骤:
1、创建一个类,继承自VehicleCommAdapter类。当然VehicleCommAdapter这个类是顶层的接口,不建议直接实现这个类,我们应该继承BasicVehicleCommAdapter 类,该类是一个抽象类,继承体系如下:
2、第一步我们实现了驱动的类,但是如何被创建呢?即如何创建一个Adapter的实例?OpenTCS应用了工厂模式,那就需要再创建一个工厂类了,我们需要从VehicleCommAdapterFactory类继承,类图如下所示:
3、这一步可选。如果需要在控制面板里面常见一个Panel,那么还需要VehicleCommAdapterPanel 类继承创建一个MyVehicleCommAdapterPanel 类。这样才能注册一个Adapter的图形化界面。
创建一个Adapter必须的步骤就是1、2步骤。所以这一章主要讲这两个步骤的代码实现(MyVehicleCommAdapter和MyVehicleCommAdapterFactory这两个类),为了方便起见,我们直接在openTCS-CommAdapter-Loopback工程里面添加相关代码(实际工程建议另起一个工程)。
以下的代码片段只是为了简化说明问题,代码不做任何逻辑处理,同时会对关键接口追加注释。
代码MyVehicleCommAdapter 代码如下:
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 代码如下:
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没有上面那么简单,上面代码只是为了说明问题)。