一、OpenTCS4.12 創建一個新的通信驅動

很多人研究這個平臺,都會卡在第一步,如何創建一個新的通信驅動,
官方文檔也沒怎麼寫清楚
今天寫這個博客,是爲了幫助大家創建一個新的驅動(具體的通信,我這兒就不講解)

一、首先在官網下載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切換到操作模式
在這裏插入圖片描述

在這裏插入圖片描述

看到以上畫面,我們就成功創建了一個驅動,具體怎麼通信,我們下次再講解

發佈了8 篇原創文章 · 獲贊 33 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章