很多人研究这个平台,都会卡在第一步,如何创建一个新的通信驱动,
官方文档也没怎么写清楚
今天写这个博客,是为了帮助大家创建一个新的驱动(具体的通信,我这儿就不讲解)
一、首先在官网下载4.12的源码
http://www.opentcs.org/en/download.html
二、安装IDE 我这儿使用的是NetBeans8.2(不会装的就别学JAVA了)
不要用Eclipse或者IntelliJ IDEA(会有问题的,不信你试试)
给NetBeans安装Gradle插件(自己百度怎么装,我不管,你不会研究也别学JAVA了)
三、打开项目,选择下载的源码(解压哦)
打开后等待会片刻就行(Gradle会自己添加依赖,要联网哟)
最后双击一下openTCS-CommAdapter-Loopback,openTCS-Kernel以及openTCS-PlatOverView(到时候运行要用到)
双击完在项目下后,关闭折叠,可以看到这三个项目
四、创建通信驱动
1.在openTCS-CommAdapter-Loopback下创建一个package(按实际情况来,我这儿比较随意)
按照官方文档步骤操作
2.创建一个驱动实现类VehicleCommAdapter(名字随意,我这边用TestCommAdapter)
a.之类为BasicVehicleCommAdapter
b.实现抽象方法
然后提示需要创建构造方法,那我们就写一个构造方法(参照LoopbackCommunicationAdapter,configuration可以不需要)
3.此时我们需要新建TestAdapterComponentsFactory和TestVehicleModel这两个东西(超找一下virtualvehicle可以写出来)
最后修改一下TestCommAdapter,我的代码如下:
package org.opentcs.testvehicle;
import com.google.inject.assistedinject.Assisted;
import java.util.List;
import static java.util.Objects.requireNonNull;
import javax.inject.Inject;
import org.opentcs.data.model.Vehicle;
import org.opentcs.data.order.Route.Step;
import org.opentcs.drivers.vehicle.BasicVehicleCommAdapter;
import org.opentcs.drivers.vehicle.MovementCommand;
import org.opentcs.util.CyclicTask;
import org.opentcs.util.ExplainedBoolean;
/**
*
* @author zjw
*/
public class TestCommAdapter extends BasicVehicleCommAdapter {
private TestAdapterComponentsFactory componentsFactory;
private Vehicle vehicle;
private boolean initialized;
private CyclicTask testTask;
@Inject
public TestCommAdapter(TestAdapterComponentsFactory componentsFactory, @Assisted Vehicle vehicle) {
super(new TestVehicleModel(vehicle), 2, 1, "CHARGE");
this.componentsFactory = componentsFactory;
this.vehicle = vehicle;
}
@Override
public void initialize() {
initialized = true;
//网络通信,获取当前位置,电量,等信息
//getProcessModel().setVehicleState(Vehicle.State.IDLE);
//getProcessModel().setVehiclePosition("Point-0001");
}
@Override
public synchronized void enable() {
if (isEnabled()) {
return;
}
//开启线程(略)
//testTask = new TestTask();
//Thread simThread = new Thread(testTask, getName() + "-Task");
//simThread.start();
super.enable();
}
@Override
public synchronized void disable() {
if (!isEnabled()) {
return;
}
//线程停止
//testTask.terminate();
//testTask = null;
super.disable();
}
@Override
public void sendCommand(MovementCommand cmd)
throws IllegalArgumentException {
requireNonNull(cmd, "cmd");
}
@Override
public ExplainedBoolean canProcess(List<String> operations) {
requireNonNull(operations, "operations");
final boolean canProcess = isEnabled();
final String reason = canProcess ? "" : "adapter not enabled";
return new ExplainedBoolean(canProcess, reason);
}
@Override
public void processMessage(Object message) {
}
@Override
protected void connectVehicle() {
}
@Override
protected void disconnectVehicle() {
}
@Override
protected boolean isVehicleConnected() {
return true;
}
/**
* 内部类,用于处理运行步骤
*/
private class TestTask
extends CyclicTask {
private TestTask() {
super(0);
}
//线程执行
@Override
protected void runActualTask() {
try {
//获取状态 位置 速度 反向
final MovementCommand curCommand;
synchronized (TestCommAdapter.this) {
curCommand = getSentQueue().peek();
}
final Step curStep = curCommand.getStep();
//运行Step,略
if (!curCommand.isWithoutOperation()) {
//运行操作(上料或者下料,略)
}
if (getSentQueue().size() <= 1 && getCommandQueue().isEmpty()) {
getProcessModel().setVehicleState(Vehicle.State.IDLE);
}
//更新UI
synchronized (TestCommAdapter.this) {
MovementCommand sentCmd = getSentQueue().poll();
if (sentCmd != null && sentCmd.equals(curCommand)) {
getProcessModel().commandExecuted(curCommand);
TestCommAdapter.this.notify();
}
}
}
catch (Exception ex) {
}
}
}
}
4.让Kernel加载该驱动
修改GuiceConfig
新增下面这两句
5.创建TestCommAdapterFactory类
实现抽象方法
具体代码如下:
package org.opentcs.testvehicle;
import static java.util.Objects.requireNonNull;
import javax.inject.Inject;
import org.opentcs.data.model.Vehicle;
import org.opentcs.drivers.vehicle.VehicleCommAdapter;
import org.opentcs.drivers.vehicle.VehicleCommAdapterFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author zjw
*/
public class TestCommAdapterFactory implements VehicleCommAdapterFactory {
private static final Logger LOG = LoggerFactory.getLogger(TestCommAdapterFactory.class);
private TestAdapterComponentsFactory componentsFactory;
private boolean initialized;
@Inject
public TestCommAdapterFactory(TestAdapterComponentsFactory componentsFactory) {
this.componentsFactory = requireNonNull(componentsFactory, "componentsFactory");
}
@Override
@Deprecated
public String getAdapterDescription() {
//这是Kernel中显示的驱动名称,中文会乱码,如果要使用中文,请使用配置文件
return "MyTestAdapter";
//return ResourceBundle.getBundle("org/opentcs/virtualvehicle/Bundle").getString("AdapterTestFactoryDescription");
}
@Override
public boolean providesAdapterFor(Vehicle vehicle) {
requireNonNull(vehicle, "vehicle");
return true;
}
@Override
public VehicleCommAdapter getAdapterFor(Vehicle vehicle) {
requireNonNull(vehicle, "vehicle");
return componentsFactory.createCommAdapter(vehicle);
}
@Override
public void initialize() {
if (initialized) {
LOG.debug("Already initialized.");
return;
}
initialized = true;
}
@Override
public boolean isInitialized() {
return initialized;
}
@Override
public void terminate() {
if (!initialized) {
LOG.debug("Not initialized.");
return;
}
initialized = false;
}
}
6.最后运行一下Kernel以及PlantOverview看一下有没有驱动显示出来
在PlantOverview下Load Model 选择Demo-01.xml
然后点击File -> Persist mode in the kernel
在点击File->Mode -> Operating mode切换到操作模式
看到以上画面,我们就成功创建了一个驱动,具体怎么通信,我们下次再讲解