阅读视图

发现新文章,点击刷新页面。
🔲 ☆

[AGV] OpenTCS 模組架構解析 | OpenTCS Modular Architecture Overview

本篇文章會說明 OpenTCS 各模組的職責,以及從派車、車輛移動到任務完成的完整流程說明,幫助讀者快速理解整體系統的運作方式。
This article explains the responsibilities of OpenTCS modules and how they work together throughout the workflow, from order dispatching and vehicle movement to order completion.

同時拆解每個模組的運作機制和如何替換,協助需要了解底層和客製化特定功能的讀者,快速定位關鍵模組與擴充切入點。
It also highlights internal mechanisms and module interactions, helping readers identify where to apply customizations when extending the system.

  1. 中文內容
    1. Model Layer
      1. plant model
      2. Transportorder model
      3. VehicleProcessModel
    2. Core Module
      1. Dispatcher
      2. Router
      3. VehicleController
      4. Scheduler
    3. Adapter
      1. Communication Adapter (Vehicle Driver)
      2. Peripheral Communication Adapter (Peripheral Driver)
    4. 運作流程
    5. 核心模組存取協定屬性的設計建議
    6. 補充說明
  2. English Version
    1. Model Layer
      1. Plant Model
      2. Transport Order Model
      3. Vehicle Process Model
    2. Core Modules
      1. Dispatcher
      2. Router
      3. Vehicle Controller
      4. Scheduler
    3. Adapters
      1. Vehicle Communication Adapter (Vehicle Driver)
      2. Peripheral Communication Adapter (Peripheral Driver)
    4. Execution Flow
    5. Design Recommendations for Accessing Protocol Properties in Core Modules
    6. Additional Observations from Integration Experience
  3. Reference

中文內容

Model Layer

主要是 OpenTCS 定義的相關資料格式,包含地圖、任務、車子本身的資料結構和屬性

plant model

地圖的資料格式,包含地圖上定義的所有資訊,除了基礎的 Point, Path, Location, Block 等,每個物件都支援自定義屬性,這些屬性都可以在任何地方被讀取,例如 VDA5050 的 Vehicle Driver 就自定義了許多屬性,讓地圖上可以定義 action,當發送 Command 時,會在依照地圖上的屬性將 action 放入 order 內,達到地圖自定義屬性可以影響車子行爲的效果

對應原始碼 PlantModel.java

Transportorder model

任務的資料格式,包含了任務上定義的所有屬性,像是基礎的名稱、狀態、orderType、指定車輛、目的地等,進階的則是路徑資訊、目前路徑進度以及自定義屬性,這個屬性同樣可以讓 Vehicle Driver 讀取,用來定義行爲,例如 VDA5050 就定義了特定屬性名稱,讓上位在API派車時,可以直接指定目的地要執行的action,TCS 本身也有定義了一個屬性,可以讓上位決定要繞過不走的 Point 或 Path 名稱

針對這些屬性的變化,都可以藉由繼承 eventHandler 來接收到變化的 event,非常方便,不需要一直輪詢屬性

對應原始碼 TransportOrder.java,eventHandler對應原始碼 StatisticsEventLogger.java

VehicleProcessModel

車子本身的屬性,像是狀態、Vehicle Driver 連線狀態、當前運行的任務、是否有載東西、當前的位置角度等,Vehicle Driver收到車子的狀態後,就會更新到此model,Vehicle Driver 可以繼承既有的 Class 擴充自身協定特有的屬性,像是VDA5050定義的各個 topic,接收到會存一份在這個 model 內

與 TransposrOrder 同理,這個 model 的屬性變化也可以用來接收相對應的 event,要對車子任何屬性做監控都非常的方便

對應原始碼 VehicleProcessModel.java,VDA5050 擴充部分對應原始碼 ProcessModelImpl.java

Core Module

這邊會說明 TSC 內建的幾個重要模組的作用,TCS 的抽象化做的很徹底,雖然一開始接觸時覺得模組數量衆多,琳琅滿目不知從何下手,但摸熟大概的架構後,每個模組都可以自行客製,輕鬆替換掉原生的模組,修改的程式碼都非常的少,每次修改完一個功能後,都會令筆者驚嘆,居然只要改這樣就可以了。

Dispatcher

功能如其名,負責指派任務給車子,這個模組會定時執行,預設的時間是10秒一次,這邊有個坑,筆者一開始不熟設定時,發現打API建立任務後,都會不定時 delay 幾秒才派給車子,就是這個原因,當初還以爲是 bug,後來 Member 找出設定後,才發現原來是我們不熟悉導致的誤會

指派任務的策略非常的多元,可以從 config 修改參照條件的順序,例如依照路徑 Cost 最小優先,或是任務設定的 deadline 等等,其他參數建議自行參照說明文件

同時若有開啓自動回停車區或充電功能,Dispatcher也會負責檢查可用的站點,建立任務將符合條件的車子派出,Dispatcher 所負責的每個功能,分成不同的 Phase 定義各自的邏輯,若需要調整,只需要找出對應的Phase修改或替換客製版本即可

對應原始碼 DefaultDispatcher.javaPhase位置

Router

主要用來計算路徑,除了常見的最短路徑,也會計算每條 Path 的 Cost,Cost 算法也非常彈性,可以直接從 config 設定,像是距離、時間等,並且可以多選,但需注意預設會將多種 Cost 結果相加,若單位不同就不太有意義,同時有些選項主要是用來卡控哪些路或是哪些情況不能走,像是 bounding box 選項,若車子體積大於 Point 上設定的可通過體積,Cost 會被視爲無限大,該路段就會被捨棄

在 Dispatcher 比較車子較符合哪個待命區或充電站時會使用到,或者在評估哪個任務和哪台車最適合時,也會使用到,同時會參考 TransportOrder 中定義的 tcs:resourcesToAvoid 屬性,算出符合需求的最小 Cost 路徑

對應程式碼 DefaultRouter.java

VehicleController

主要處理車子接收到任務後的流程,會依照任務內的路徑藉由 Scheduler 對 Point、Path、Location 進行佔用,會等待到佔用完成後,發送 Command 給 Vehicle Driver,並且在Vehicle Driver 回報已經過 Point 和 Path 後,再藉由 Scheduler 進行釋放,直到路徑走完爲止

當Path上有週邊設備的設定時,會在佔用 Path 路權後,觸發對應 Peripheral Driver,等到回報週邊設備可通行時,再接續發送 Command 給 Vehicle Driver

當路徑有變更時,VehicleController 也會收到通知,會把尚未發給 Vehicle Driver 的 Command 取消,並取消路權,再重新依照新路徑接續佔用

對應原始碼 DefaultVehicleController.java ,可以自己開發一個客製的 VehicleController class,在這邊修改即可套用

Scheduler

主要負責資源的佔用,包含Point、Path、Location,邏輯是先佔先贏,每次佔用都會開一個 thread,若搶不到會把該次的資源加入一個清單,後續再接續 trigger 佔用一次,如此不斷重複,並且每個查看、佔用和釋放路權的地方,都會使用lock,確保每個資源一次都只被一台車佔用

佔用的同時,還會經過一系列的 Module 的檢查,像是 SingleVehicleBlock 的邏輯,會確保這個資源若在的 SingleVehicleBlock 內,此時整個 Block 內其他資源沒有被其他車佔用,若有的話這個 module 會回報無法佔用,只要任意 Module 回報無法佔用,最終Scheduler就不會佔用這個資源,所有想要客製的佔用規則,可以自行建立 Module,再這邊加入引用即可,需注意此方法會被頻繁呼叫,盡量不要實作費時操作或邏輯,會影響整體效能

對應程式碼 DefaultScheduler.javaModule 位置

Adapter

Communication Adapter (Vehicle Driver)

主要負責實作車子的協定,會繼承固定的 interface 並實作,包含

  • 管理車子的連線、斷線狀態
  • 發送 Command 的方法,並轉成實際的車子控制命令給車子
  • 管理 Command 的 queue 和發送狀態
  • 接收車子即時狀態,設定初始位置,以及更新到 Model 中
  • 判斷當下狀態是否可以執行任務

理論上你知道車子的控制協定後,就可以寫一個 Adapter 讓 TCS 來控制它,一些針對這類型的客製邏輯也都可以實作在這裡,像是讀到地圖中車輛或 Point 的自定義屬性,要執行特定方法等,來達成一些預設行為

對應程式碼 內建模擬車VDA5050 Adapter

Peripheral Communication Adapter (Peripheral Driver)

主要負責檢查自定義邏輯是否通過判斷,是的話就允許 VehicleController 發送 Command 給 Adapter,通常用在自動門或電梯等被動式的簡單週邊設備,因為邏輯是自訂的,你可以用來判斷任意條件,不一定要跟設備掛鉤,例如要有載貨才能通過,在人員放東西上去車子回報後,就會放行了

對應程式碼 內建模擬週邊設備

運作流程

從API呼叫建立任務後,一直到車子移動,完成任務的整個完整流程,筆者憑藉着自己的經驗畫出了這個 流程圖,整理這個流程圖費了不少心力,畢竟模組非常多且流程也不短,雖然無法包含所有完整的細節,但還是希望能讓人清楚的了解整體流程,不會覺得很多地方是黑盒子,無法下手

流程圖使用 mermaid 格式,方便讀者自行修改,也方便 AI 讀取跟調整,若覺得有不清楚或可以加強的地方,歡迎不吝指教

Workflow (Mermaid)
flowchart TB

%% ========= API =========
subgraph API
    A["接收到任務"]
end

%% ========= Dispatcher =========
subgraph Dispatcher

    subgraph cycle["cycle"]
        D_confirm["確認新進任務<br/>找出最適合車輛"]
        D_charge["符合充電門檻<br/>指派 charging 任務"]
        D_park["閒置車輛<br/>指派 parking 任務"]
        D_cycle_end(("cycle end"))

        D_confirm --> D_charge
        D_charge --> D_park
        D_park --> D_cycle_end
    end

    subgraph Router
        R_calc["計算路徑與 cost"]
    end

    D_write["將路徑寫入 transportOrder"]
end

%% ========= VehicleController =========
subgraph VehicleController

    V_route["依路徑逐 step 申請路權"]
    V_reserved["佔用成功事件"]
    V_hasPeripheral{"需要週邊設備?"}
    V_toCommand["Step → Command"]
    V_release["完成後釋放路權"]
    V_last{"最後一個 Command?"}
    V_done["TransportOrder 完成"]

    %% ----- Scheduler -----
    subgraph Scheduler
        S_check["確認資源是否可用"]
        S_ok["佔用成功"]
        S_fail["佔用失敗<br/>重試"]

        subgraph BlockModule
            B_rule{"符合 BlockModule 規則?"}
        end
    end

    %% ----- Vehicle Driver -----
    subgraph VehicleDriver
        VD_send["Command → 車輛協定"]
        VD_report["回報 Command 完成"]
    end

    %% ----- Peripheral Driver -----
    subgraph PeripheralDriver
        P_send["發送設備命令"]
        P_done["設備完成回報"]
    end
end

%% ========= Main Flow =========
A --> D_confirm
D_cycle_end --> R_calc
R_calc --> D_write
D_write --> V_route

V_route --> S_check
S_check --> B_rule
B_rule -- 是 --> S_ok
B_rule -- 否 --> S_fail
S_fail --> S_check

S_ok --> V_reserved
V_reserved --> V_hasPeripheral

V_hasPeripheral -- 是 --> P_send
P_send --> P_done
P_done --> V_toCommand

V_hasPeripheral -- 否 --> V_toCommand

V_toCommand --> VD_send
VD_send --> VD_report
VD_report --> V_release
V_release --> V_last

V_last -- 否 --> V_toCommand
V_last -- 是 --> V_done

核心模組存取協定屬性的設計建議

在開發時,經常會遇到一些客製化流程的需求,希望 TCS 的核心模組(例如 VehicleController)能依據特定協定 Adapter 所定義的屬性,觸發不同的行為或流程,但 TCS 核心模組中卻無法直接取得 adapter 內部自行定義的屬性,因為 TCS 的專案架構將模組和 adapter 分離在不同的專案內,模組和 adapter 專案都會引用 opentcs-api-base 專案內的 interface。

實務上在模組的專案內直接 import apdater 專案,會出現編譯錯誤,並且也不該這麼做,會導致核心模組直接和協定耦合,未來擴充其他協定時,或是協定有異動時,都需要再變更核心模組的程式,並且未來在升級時也會出現更多的衝突影響可維護性。

因此建議做法是在 opentcs-api-base 的專案內進行擴充,建立新的 interface,並讓 adapter 繼承,讓 adapter 進行實作,未來有其他 adapter 也可以比照辦理,核心模組只需使用 instanceof 判斷 adapter 物件是否有繼承新的 interface 來決定是否轉型並呼叫 interface 內的方法即可。

補充說明

這邊補充幾個深入修改後發現的幾件事

  1. 雖然許多操作都會另開執行緒運行,但其實背後 thread pool 的數量只有1而已,並且搭配的 lock 也是 global 設計,所有的模組都共用一個鎖,我想這樣設計的原因是想要最大化降低 race condition 的風險,畢竟這類型的bug非常難解
  2. 可以自定義的地方真的太多,大大小小的模組,甚至包含 UI 的部分,只是我這邊主要聚焦在功能面,UI 就不著墨了

English Version

Model Layer

The model layer defines the core data structures used throughout OpenTCS.
It is the foundation for map definition, task execution, and vehicle state tracking, and is heavily used by both internal modules and custom extensions.

Plant Model

The plant model represents the map and all spatial elements defined within it, including points, paths, locations, and blocks.
Beyond the basic topology, each element supports custom properties that can be freely defined and accessed by other components at runtime.

This extensibility is critical in real-world integrations. For example, vehicle drivers such as VDA 5050 rely on custom map properties to define actions.
When a command is generated, these properties are translated into protocol-specific actions and embedded into transport orders, allowing map configuration to directly influence vehicle behavior without hard-coding logic.

Source: PlantModel.java

Transport Order Model

The transport order model defines all task-related information, including name, state, order type, assigned vehicle, destinations, routing data, and execution progress.
In addition to standard fields, transport orders support custom properties that can be interpreted by vehicle drivers at runtime.

This mechanism enables advanced behaviors, such as:

  • Defining actions to be executed at specific destinations
  • Specifying points or paths to be avoided using predefined attributes (e.g. tcs:resourcesToAvoid)

All changes to transport orders are published as events. By subscribing to these events, components can react immediately to state changes without polling, which greatly simplifies monitoring and integration logic.

Source: TransportOrder.java, event handling via StatisticsEventLogger.java

Vehicle Process Model

The vehicle process model represents the real-time state of a vehicle, including operational state, driver connection status, current order, load condition, position, and orientation.
Vehicle drivers continuously update this model based on feedback from the physical vehicle.

Drivers may also extend this model with protocol-specific data.
For example, the VDA 5050 implementation stores received topic data directly in the process model, making it accessible to other modules.

Like transport orders, changes in vehicle state are exposed via events, allowing fine-grained monitoring of any vehicle attribute with minimal effort.

Source: VehicleProcessModel.java, VDA 5050 extensions in ProcessModelImpl.java

Core Modules

OpenTCS follows a strongly modular architecture.
Although the number of modules can be intimidating at first, each module is highly focused and can be customized or replaced independently.
In practice, even non-trivial behavior changes often require only minimal code modifications once the overall structure is understood.

Dispatcher

The dispatcher is responsible for assigning transport orders to vehicles.
It runs periodically (10 seconds by default), which can introduce a short delay between order creation and assignment if not properly configured—an issue that is often mistaken for a system bug by new users.

Assignment strategies are highly configurable and may prioritize factors such as:

  • Route cost
  • Order deadlines
  • Charging or parking behavior

Dispatcher logic is divided into multiple phases. Each phase encapsulates a specific responsibility, allowing targeted customization by replacing or extending only the relevant phase.

Source: DefaultDispatcher.java, Phase

Router

The router calculates feasible routes and their associated costs.
Cost calculation is flexible and configurable, supporting metrics such as distance, time, and various constraints. Multiple cost factors can be combined, though care must be taken when mixing different units.

The router also enforces constraints, such as bounding box limitations.
If a vehicle exceeds the allowed size of a point or path, the corresponding route is treated as infeasible.

Routing is used extensively during:

  • Vehicle selection
  • Evaluation of parking or charging assignments
  • Order feasibility checks, including resources defined to be avoided

Source: DefaultRouter.java

Vehicle Controller

The vehicle controller manages the execution lifecycle after a transport order is assigned.
It coordinates with the scheduler to allocate points, paths, and locations, then issues commands to the vehicle driver once resources are secured.

As the vehicle reports progress, resources are released incrementally.
If peripheral devices are involved (e.g. doors or elevators), the controller triggers the corresponding peripheral drivers and waits for clearance before continuing.

When a route changes, the vehicle controller cancels pending commands, releases allocated resources, and re-executes the allocation process based on the updated route.

Source: DefaultVehicleController.java, Module config

Scheduler

The scheduler is responsible for exclusive resource allocation of points, paths, and locations.
Each allocation attempt runs in its own thread and follows a first-come-first-served strategy, with retries handled internally.

All resource access is synchronized using locks to guarantee that a resource is never occupied by more than one vehicle at a time.

Before allocation is finalized, requests pass through a chain of scheduling modules, such as the single-vehicle block check.
Any module may reject an allocation, in which case the scheduler aborts the attempt.

Custom scheduling rules can be implemented as additional modules, but they must be lightweight, as scheduling logic is executed frequently and directly impacts system performance.

Source: DefaultScheduler.java, Module

Adapters

Vehicle Communication Adapter (Vehicle Driver)

Vehicle drivers implement protocol-specific communication with vehicles.
Their responsibilities include:

  • Managing connection and disconnection states
  • Translating commands into vehicle-specific instructions
  • Handling command queues and execution states
  • Receiving real-time vehicle feedback and updating the process model
  • Determining whether a vehicle is currently capable of executing a task

Most integration-specific logic is implemented here, including behavior driven by custom map or order properties.

Source: Built-In Simulated Vehicle AdapterVDA5050 Adapter

Peripheral Communication Adapter (Peripheral Driver)

Peripheral drivers control access to passive or logical resources such as doors, elevators, or custom conditions.
They determine whether a vehicle may proceed, based on user-defined logic that does not necessarily correspond to a physical device.

Source: Built-In Simulated Peripheral Adapter

This flexibility allows peripheral drivers to enforce arbitrary conditions, such as requiring a vehicle to be loaded before entering a specific area.

Execution Flow

From task creation via the API to vehicle movement and task completion, OpenTCS involves a long chain of interacting modules.
A workflow diagram is provided using Mermaid syntax to make the process explicit, modifiable, and easy to reason about.

Workflow (Mermaid)
flowchart TB

%% ========= API =========
subgraph API
    A["Task received"]
end

%% ========= Dispatcher =========
subgraph Dispatcher

    subgraph cycle["cycle"]
        D_confirm["Validate new task<br/>Select suitable vehicle"]
        D_charge["Meets charging threshold<br/>Assign charging task"]
        D_park["Idle vehicle<br/>Assign parking task"]
        D_cycle_end(("cycle end"))

        D_confirm --> D_charge
        D_charge --> D_park
        D_park --> D_cycle_end
    end

    subgraph Router
        R_calc["Calculate route and cost"]
    end

    D_write["Write route into TransportOrder"]
end

%% ========= VehicleController =========
subgraph VehicleController

    V_route["Request resource allocation step by step<br/>based on route"]
    V_reserved["Resource reserved event"]
    V_hasPeripheral{"Peripheral required?"}
    V_toCommand["Step → Command"]
    V_release["Release resources after completion"]
    V_last{"Last command?"}
    V_done["TransportOrder completed"]

    %% ----- Scheduler -----
    subgraph Scheduler
        S_check["Check resource availability"]
        S_ok["Reservation successful"]
        S_fail["Reservation failed<br/>Retry"]

        subgraph BlockModule
            B_rule{"Satisfies BlockModule rules?"}
        end
    end

    %% ----- Vehicle Driver -----
    subgraph VehicleDriver
        VD_send["Command → Vehicle protocol"]
        VD_report["Report command completion"]
    end

    %% ----- Peripheral Driver -----
    subgraph PeripheralDriver
        P_send["Send peripheral command"]
        P_done["Peripheral completion report"]
    end
end

%% ========= Main Flow =========
A --> D_confirm
D_cycle_end --> R_calc
R_calc --> D_write
D_write --> V_route

V_route --> S_check
S_check --> B_rule
B_rule -- Yes --> S_ok
B_rule -- No --> S_fail
S_fail --> S_check

S_ok --> V_reserved
V_reserved --> V_hasPeripheral

V_hasPeripheral -- Yes --> P_send
P_send --> P_done
P_done --> V_toCommand

V_hasPeripheral -- No --> V_toCommand

V_toCommand --> VD_send
VD_send --> VD_report
VD_report --> V_release
V_release --> V_last

V_last -- No --> V_toCommand
V_last -- Yes --> V_done

Design Recommendations for Accessing Protocol Properties in Core Modules

During development, it is common to encounter customized workflow requirements where TCS core modules (such as VehicleController) need to trigger different behaviors or processing logic based on properties defined by a specific protocol adapter. However, core modules in TCS cannot directly access adapter-defined custom properties.

This limitation is intentional and stems from the TCS project architecture: core modules and adapters are separated into different projects, and both depend only on the interfaces defined in the opentcs-api-base project.

In practice, directly importing an adapter project into a core module project will result in compilation errors due to circular dependencies. More importantly, it is fundamentally a bad design choice. Doing so tightly couples core modules to a specific protocol implementation, meaning that any future protocol changes or the addition of new protocols would require modifications to the core module itself. This significantly reduces maintainability and increases the risk of conflicts during future upgrades.

To address this properly, the recommended approach is to extend the opentcs-api-base project by defining a new interface that represents the required capability or behavior. The adapter can then implement this interface and provide the corresponding logic. If additional adapters are introduced in the future, they can follow the same pattern.

The core module only needs to check whether a given object implements the interface (for example, using instanceof). If so, it can safely cast the object and invoke the interface methods. This approach allows core modules to react to protocol-specific capabilities without being directly coupled to any particular protocol implementation.

Additional Observations from Integration Experience

  • Although many operations appear asynchronous, OpenTCS relies on a very limited thread pool combined with global locking to minimize race conditions.
  • Extension points are abundant across backend modules and even the UI, though this article focuses on functional components.

Reference

🔲 ☆

[AGV] 初探 OpenTCS 開源車隊管理系統 | Exploring OpenTCS

This article briefly introduces OpenTCS as an open-source fleet management system and focuses on its positioning and suitable use cases, based on practical integration experience, to help engineers assess whether it fits their needs.

車隊管理系統 (Fleet Management System) 是調度多台AGV(AMR)時所需的必要系統,其功能主要包括整合上位系統、任務管理、交通管理、充電策略等等,目的是讓車輛的運行順暢和符合上位系統(MES or WCS)的期待,這篇文章將介紹筆者接觸到的開源解決方案 OpenTCS 是一個什麼樣的車隊系統,又適合哪些用戶來使用,協助工程師評估導入的可行性,不會包含詳細的功能說明和操作步驟。

目錄

  1. 中文內容
    1. OpenTCS 簡介
    2. 重點功能介紹
      1. 地圖
      2. 任務管理
      3. 路徑搜尋與成本
      4. 交通管理
      5. 待命區
      6. 充電策略
      7. 模擬車
      8. 整合性
    3. 使用心得
      1. 各功能評估
      2. 期望與落差
      3. 適用客群
  2. English Version
    1. Introduction to OpenTCS
    2. Key Features Overview
      1. Map
      2. Task Management
      3. Path Finding and Cost Calculation
      4. Traffic Management
      5. Parking Areas
      6. Charging Strategy
      7. Simulated Vehicles
      8. Integration Capabilities
    3. Practical Evaluation
      1. Feature Assessment
      2. Expectations vs Reality
      3. Target Users
  3. Reference

中文內容

OpenTCS 簡介

OpenTCS 是由德國公司 Fraunhofer IML 維護的開源專案,採用寬鬆友善的 MIT 授權,該車隊系統的Scope包含了一般對車隊系統的認知的功能,因爲供應商中立的特性,可以自行整合任意協定的車輛,這也意味着官方沒有爲了特定廠商開發協定的Adapter,需要自己動手開發對應的Adapter,唯一支援的協定,也是開源的AGV控制協定 VDA5050,github上有專門的 Repo 維護 VDA5050 Adapter,對於電梯或自動門等設備的整合,也可以開發週邊設備的Adapter自行整合,可以做到確保設備回到成功才讓車子拿到路徑資源允許通過。

其使用的程式語言爲 java,支援跨平臺使用,官方提供了 3 個桌面程式和1個控制台程式,分別是

  • Model Editor : 地圖編輯器,用來編輯地圖layout以及車輛資訊
  • Operations Desk : 觀看車輛、任務、路徑資源的即時狀態,可以進行派車、設定車輛可用性等
  • Kernel Control Center : 車輛和週邊設備的控制管理,可以設定車輛的 Adapter 類型、停用啓用、週邊設備控制,可以看一些 Kernel Watchdog 的訊息
  • Kernel : 車隊的主程式,沒有任何 UI,會將運行狀況以文字顯示在控制台界面上,前三者操作時,都是對 Kernel 進行連線後才能動作

整體而言,應用程式的 UI 非常工程師,算是堪用狀態,一些簡單的操作也需要做很多動作,屬於簡單直接沒有 UX 的 UI,更新方面,目前 OpenTCS 算是活躍的專案,約1-2個月就會發佈更新,持續修復問題和提供新功能,爲了方便描述,以下會將 OpenTCS 簡稱爲 TCS。

重點功能介紹

地圖

TCS的地圖屬於拓撲式,由點和線組成,比較特別的是兩點之間來回會算成2條線,而不是1條線,地圖上可以定義的元素如下

  • Point:定義坐標、角度、類型
  • Path:定義路線,包含開始與結束的Point、最高速度、是否鎖定
  • Location Type:站點類型,供站點參照,定義可執行的”操作“,像是對接、充電等,也可以定義可執行的設備”操作“,像是開門”關門等
  • Location:站點,關聯到特定的Point,作爲派車的目的地,也可以是設備的觸發點,會跟Path關聯,像是走到這條路就觸發開門,開門完成後才會把命令發給車子
  • Block:資源的集合,所謂的資源指的是前面的Point、Path、Location,不同類型有不同作用,像是僅允許一臺車或是僅允許相同入口,不符合條件時,車輛會在外面等待,直到可以爲止
  • Vehicle:定義車輛屬性,有名稱、最高速度、電量門檻、尺寸、允許接受的任務類型(一對多)、整合度,其中整合度可以決定車子是否占用資源、允許接收任務

爲了可以整合各種車輛和客製化邏輯,以上各元素都支援自定義屬性,這算是TCS的特色,TCS自己的屬性會用 tcs: 為前綴,整合 VDA5050 時,adapter 也會讀取 vda5050: 開頭的屬性,保留最大的彈性

任務管理

TCS 的搬運任務稱爲 TransportOrder,是上位派車時的最小單位,可包含多個目的地,每個目的地就像一個子任務,稱爲DriveOrder,TransportOrder 可以指定

  • 類型:對應 vehicle 的任務類型,可以做到不同類型的車接收各自類型的任務
  • 期限時間:用來當成排序得參考
  • 指定車輛:是否指定特定車輛執行
  • 自動取消:主要用於回待命區或充電的 Order,可自動取消並接受新的 Order 節省時間
  • 依賴:可設定A和B任務都完成後才執行此任務,TCS 會依照依賴順序執行 Order
  • 客製化屬性:這邊定義的屬性都可以在 Adapter 內被讀取到,用來實現客製化的功能,以 VDA5050 Adapter 爲例,可以定義在目的地要執行的 action

任務的排序和每個任務挑選車子的條件可在config中動態設定各條件的優先順序,可以做到回頭車、Order期限快到時優先執行等較複雜的任務管理

路徑搜尋與成本

TCS內建 Dijkstra 算法找尋成本最低的路徑,成本則可以在 config 中多選,像是距離、Point數量、時間、群組、尺寸,其中群組是可以在 Path 和 Vehicle 定義屬性,讓相同群組的車使用對應的成本值,可以做到特定路讓特定車優先,尺寸則是在 Point 限定允許通過的大小,若 Vehicle 定義的大小超過則成本無限大,不允許通過,路徑一旦算出來後,就不會再改變了,基本上Path的鎖定沒有變更的話,算幾次都是一樣的結果

交通管理

有資源管理的概念,每個資源同時只能被一台車持有,正常狀況下,每台車會持有所在的 Point,有任務路徑時,會持有後續 N 段 Path 和 Point,如果路徑有交錯,先拿先贏,其他車只能等待釋出後再取得。

有些時候兩台車算出來的路徑會有衝突,例如都在同一條雙向道上,兩台車都各拿1個點,就會造成黑羊白羊過橋問題卡住,這時候可以設定 Block 來限定特定區域只能一台車來避免問題,但 Block 是把雙面刃,過度設置也會造成交通癱瘓

另外針對設備的部分,可以在走到特定路線時,對特定的設備 Adapter 發起 Open 的命令,等到設備確實回報成功,才會將行走的命令發給車子,並且繼續往後占有路權

待命區

Point 的類型可以選擇待命區,然後 config 檔設定閒置時自動回待命區,還可以設置待命區的優先順序,或是特定車輛停在特定待命區,更進階的還可以設定當優先權高的待命區空出時,重新把低優先權的車派過去停。

充電策略

每台車可以設定幾個門檻

  • 低 critical energy level 於門檻時,不接任務且前往充電
  • 低 good energy level 於門檻時,閒置時會去充電,但一有任務就會中斷去執行任務
  • 高 full (sufficiently) recharged energy level 於門檻時,停止充電,回到待命區

也可以設定每輛車優先或特定的充電站,但僅此而已

模擬車

TCS 有提供模擬車輛,可以接收任務模擬行走,但是真實度有限,行走部分並不會參考速度,而是一個點一個點跳躍,可以用來測試地圖的可運行性,另外有支援耗電跟充電功能,可以測試充電策略

整合性

針對外部系統整合部分,有提供Restful Web API,跟 Swagger 可以了解格式,但是沒有 event trigger 的方法,只能不斷輪詢,頂多有一個 long polling 的API可以接收所有類型的 event,使用過後還是直接輪詢特定資訊的 API 比較方便

對於車子的部分,需要自行開發Adapter,這部分可以參考模擬車的專案進行修改,將 TCS 這邊定義的 command 發給車子,並把車子回傳的狀態,對應到TCS的車輛狀態,像是電量、是否有貨、閒置還是執行中等等,就可以控制車子

對於設備的部分,也是有開放Adapter的開發彈性,看你是要整合電梯還是自動門等,有明確的協定就可以完成

使用心得

各功能評估

以下對針對各功能評估對於一般使用情境是否足夠,尚缺哪些必要機制

✅:滿足所需
🆖:堪用但不足
❌:不滿足需求

功能名稱評價評論
工具軟體🆖Model Editor 操作有大量待優化空間,尤其是地圖設定自定義屬性的操作步驟過多,且沒有檢查機制,很容易漏東漏西

Operations Desk 可派簡易的循環任務,但不支援派含有自定義屬性的任務,只能自己打 API,另外可以看每台車的路權,不過想要看交互關係(A車卡B車、B車卡C車)就只能自己分析了

Kernel Control Center 操作部分較少,算是堪用,但要看問題,內建的 watchdog 資訊還是太少

以上工具還有一個缺點,就是一定要執行程式,沒有提供網頁界面快速瀏覽,也沒有提供權限功能,一定程度上很難給非維護單位使用,需要自行開發好用的 UI

Kernel 有些機制不方便,會影響維運,像是上傳地圖會中斷並清空所有任務,重啓也不會記憶先前的任務,也沒有歷史資訊可供查詢,所以要上傳地圖或是升版的話,就必須取消所有任務,事後再重派
地圖✅基礎屬性已涵蓋大部份功能,且支援自定義屬性,有高度擴充性
任務管理✅有支援優先權概念和距離概念,也可以設定車子對應不同任務類型的優先權,算是非常完整足夠

針對一連串任務有 sequence 功能支援綁定同一台車,避免車輛在任務中間空檔接收其他任務
路徑搜尋與成本🆖有基礎的功能可用,但成本沒辦法考慮旋轉次數,會以純距離或是時間來看,有些人覺得很繞的路在TCS看來成本是一樣的,需要再自行擴充需要的功能

如果現場想要特別繞遠路,原生雖有支援,但設定方式非常繁瑣和不好維護
交通管理❌這部分是真的不夠用,除非你的場域非常足夠,可以每條路都兩線道,只有簡單十字路口要交管,就可以勉強應付

Block 的維護很看人的經驗,尤其是考慮避障後,像是要轉彎的地方或是十字路口,或是兩條路某一段太接近,爲了避免兩車太近觸發避障,就要廣設 Block,漏設就等着現場反映問題

另外雖支援大車不能走小路,但沒有動態切換功能,像是有些路空車可以走,載貨體積變大不能走,目前是做不到的

不支援動態路徑,看起來會覺得很不聰明,只能等待後通過
待命區✅蠻完整的,可設定優先權甚至重新停到高優先權,可以依照不同情境設定
充電策略🆖只有門檻機制過於簡單,多車共用充電站時,沒辦法交換充電,除非一直有任務進來,才會剛好離開空出充電站,但還是沒辦法避免多車同時沒電的問題
模擬車🆖僅能驗證地圖和交管機制,缺乏速度模擬跟對接等待時間,沒辦法用來算精確的時間
整合性✅WebAPI速度算快,幾十ms就會回傳,即使輪詢也足以負荷

如果想要 event 機制,就需要自行擴充,內部可以接收 event 再看要用什麼機制發出

期望與落差

雖然更新頻繁,但是看到新的功能時,不要太過興奮跟腦補,往往都只是提供最陽春的功能而已,舉個例子,某一版開始可以設定車子和點的長寬高,讓大車不能走小路,但僅此而已,占用路權時並不會用這個條件考慮,讓車身彼此不重疊,所以新功能務必試過後才能確定運作機制

適用客群

TCS 需要二次開發,沒辦法開箱即用,即使使用 VDA5050 協定的 Adapter,多多少少還是有一些邏輯需要客製修改,bug 也還是有,筆者本身也提報過一些 bug 給官方修改,所以適合原本已有做車子的廠商,或者是一開始就鎖定發展車隊系統的廠商

比起平地造山,還是可以省掉不少工,但就是要花點心思看懂TCS內部程式架構,TCS的架構算是設計的不錯,雖然功能較多切分的class非常多,抽象化得很徹底,但一旦釐清後,修改或替換的工相對少,日後也不難維護

English Version

Introduction to OpenTCS

OpenTCS is an open-source project maintained by Fraunhofer IML in Germany and released under the permissive MIT license.
The scope of OpenTCS covers the common functionality expected from a fleet management system. Due to its vendor-neutral design, it allows integration with vehicles using arbitrary protocols. However, this also means that OpenTCS does not provide protocol adapters tailored to specific vendors out of the box; users are expected to implement the required adapters themselves.

The only officially supported vehicle protocol is the open-source AGV control protocol VDA 5050. A dedicated GitHub repository is maintained for the VDA 5050 adapter.
For integrating equipment such as elevators or automatic doors, OpenTCS supports peripheral device adapters, which can be implemented to coordinate vehicle movement with external devices—for example, ensuring that a vehicle is granted path resources only after the device operation has completed successfully.

OpenTCS is implemented in Java and supports cross-platform usage. The official distribution includes three desktop applications and one console application:

  • Model Editor:
    A map editor used to define the layout, plant model, and vehicle information.
  • Operations Desk:
    Provides real-time visibility into vehicle states, transport orders, and path resources. It also allows manual dispatching and configuration of vehicle availability.
  • Kernel Control Center:
    Used for managing vehicles and peripheral devices, including adapter configuration, enabling or disabling components, and monitoring Kernel watchdog messages.
  • Kernel:
    The core fleet management service. It has no graphical user interface and outputs runtime information as text in a console. All three desktop applications must connect to the Kernel in order to operate.

Overall, the user interface of OpenTCS is highly engineering-oriented and functional but minimal. Even simple operations often require multiple steps, reflecting a straightforward design with little emphasis on user experience.
In terms of maintenance and development activity, OpenTCS is an active project, with releases approximately every one to two months, continuously addressing issues and introducing new features.

For convenience, OpenTCS will be referred to as TCS in the following sections.Introduction to OpenTCS

OpenTCS is an open-source project maintained by Fraunhofer IML in Germany and released under the permissive MIT license.
The scope of OpenTCS covers the common functionality expected from a fleet management system. Due to its vendor-neutral design, it allows integration with vehicles using arbitrary protocols. However, this also means that OpenTCS does not provide protocol adapters tailored to specific vendors out of the box; users are expected to implement the required adapters themselves.

The only officially supported vehicle protocol is the open-source AGV control protocol VDA 5050. A dedicated GitHub repository is maintained for the VDA 5050 adapter.
For integrating equipment such as elevators or automatic doors, OpenTCS supports peripheral device adapters, which can be implemented to coordinate vehicle movement with external devices—for example, ensuring that a vehicle is granted path resources only after the device operation has completed successfully.

OpenTCS is implemented in Java and supports cross-platform usage. The official distribution includes three desktop applications and one console application:

  • Model Editor:
    A map editor used to define the layout, plant model, and vehicle information.
  • Operations Desk:
    Provides real-time visibility into vehicle states, transport orders, and path resources. It also allows manual dispatching and configuration of vehicle availability.
  • Kernel Control Center:
    Used for managing vehicles and peripheral devices, including adapter configuration, enabling or disabling components, and monitoring Kernel watchdog messages.
  • Kernel:
    The core fleet management service. It has no graphical user interface and outputs runtime information as text in a console. All three desktop applications must connect to the Kernel in order to operate.

Overall, the user interface of OpenTCS is highly engineering-oriented and functional but minimal. Even simple operations often require multiple steps, reflecting a straightforward design with little emphasis on user experience.
In terms of maintenance and development activity, OpenTCS is an active project, with releases approximately every one to two months, continuously addressing issues and introducing new features.

For convenience, OpenTCS will be referred to as TCS in the following sections.

Key Features Overview

Map

The map model in TCS is topological, composed of points and paths. One notable characteristic is that bidirectional movement between two points is represented as two separate paths, rather than a single bidirectional path.

The following elements can be defined in the map:

  • Point: Defines a coordinate, orientation, and point type.
  • Path: Defines a route between two points, including the source and destination points, maximum allowed speed, and whether the path is locked.
  • Location Type: Defines the type of a location and the set of executable operations associated with it, such as docking or charging. It can also define executable device operations, such as opening or closing a door.
  • Location: Represents a destination associated with a specific point. Locations can be used as dispatch targets for transport orders or as trigger points for peripheral devices. Locations can be associated with paths—for example, reaching a specific path may trigger a door-opening operation, and only after the operation is completed will the command be sent to the vehicle.
  • Block: Represents a collection of resources. Resources refer to points, paths, and locations. Different block types enforce different constraints, such as allowing only one vehicle at a time or restricting access to vehicles entering from the same direction. If the constraints are not satisfied, vehicles will wait outside the block until access is granted.
  • Vehicle: Defines vehicle properties such as name, maximum speed, battery thresholds, physical dimensions, accepted transport order types (one-to-many), and integration level. The integration level determines whether the vehicle is allowed to allocate resources and receive transport orders.

To support integration with various vehicle types and custom logic, all of the above elements support custom properties, which is a key design feature of TCS.
Built-in OpenTCS properties use the tcs: prefix, while adapters—such as the VDA 5050 adapter—can read properties prefixed with vda5050:, preserving maximum flexibility for extensions and integrations.

Task Management

In TCS, a transport task is called a TransportOrder, which is the smallest unit submitted by higher-level systems for dispatching.
A TransportOrder may contain multiple destinations, where each destination acts as a sub-task referred to as a DriveOrder.

A TransportOrder can be configured with the following attributes:

  • Type:
    Corresponds to the task types supported by vehicles, allowing different vehicle types to accept only their respective task categories.
  • Deadline:
    Used as a reference for task prioritization and sorting.
  • Intended Vehicle:
    Specifies whether a particular vehicle is assigned to execute the order.
  • Dispensable:
    Primarily used for orders such as returning to a parking area or charging.
    These orders can be automatically canceled when a new order becomes available, reducing idle time.
  • Dependencies:
    Allows defining prerequisite orders. For example, an order may only be executed after both Order A and Order B are completed.
    TCS schedules and executes transport orders according to the defined dependency chain.
  • Custom Properties:
    Properties defined here can be read by the vehicle adapter to implement custom behaviors.
    For example, in the VDA 5050 adapter, actions to be executed at a destination can be defined via these properties.

Task prioritization and vehicle selection criteria are configurable via configuration files, where the priority of different factors can be adjusted.
This enables more advanced task management strategies, such as prioritizing return trips, or executing orders with approaching deadlines ahead of others.

Path Finding and Cost Calculation

TCS uses the built-in Dijkstra algorithm to find the lowest-cost path.
The cost function is configurable and can be composed of multiple factors, such as distance, number of points, travel time, group, and size.

The group factor can be defined as a property on both paths and vehicles, allowing vehicles within the same group to apply specific cost values. This makes it possible to prioritize certain routes for specific vehicles.

The size constraint is defined on points to restrict the maximum allowed vehicle size. If a vehicle’s defined size exceeds the allowed limit, the cost is treated as infinite, and the path becomes non-traversable.

Once a route is calculated, it remains unchanged. As long as path locks do not change, repeated calculations will yield the same result.

Traffic Management

TCS adopts a resource management model in which each resource can be held by only one vehicle at a time.
Under normal conditions, a vehicle holds the point it is currently occupying. When executing a transport order, it additionally reserves the next N segments of paths and points along its planned route.

When multiple routes intersect, resource allocation follows a first-come, first-served principle. Other vehicles must wait until the resources are released before proceeding.

In some cases, route conflicts may still occur. For example, when two vehicles plan routes along the same bidirectional path and each holds one point, a classic deadlock situation—similar to the “bridge crossing” problem—can arise.

To mitigate this, Blocks can be configured to restrict a specific area to a single vehicle at a time. However, blocks are a double-edged sword: excessive or overly coarse block definitions can significantly reduce throughput and even lead to traffic congestion.

For peripheral device integration, TCS allows issuing open or control commands to a specific device adapter when a vehicle reaches a designated path.
Only after the device reports successful completion will the movement command be sent to the vehicle, and the vehicle will continue reserving subsequent route resources.

Parking Areas

Points can be configured with a parking position type.
Through configuration files, vehicles can be set to automatically return to a parking position when they become idle.

Parking positions can be assigned priorities, or specific vehicles can be restricted to park at designated parking positions.
More advanced configurations allow vehicles parked at lower-priority positions to be reassigned and moved when a higher-priority parking position becomes available.

Charging Strategy

Each vehicle can be configured with multiple battery thresholds:

  • Critical energy level: When the battery level falls below this threshold, the vehicle will stop accepting transport orders and proceed directly to charging.
  • Good energy level: When the battery level is below this threshold, the vehicle will go charging while idle, but will interrupt charging and execute a transport order as soon as a new order is assigned.
  • Full (sufficiently recharged) energy level: When the battery level reaches this threshold, charging stops and the vehicle returns to a parking position.

Vehicles can also be configured to prefer or restrict themselves to specific charging stations.
Beyond these options, the built-in charging strategy remains relatively simple.

Simulated Vehicles

TCS provides simulated vehicles that can receive orders and simulate movement. However, realism is limited: movement is discrete, point by point, without considering actual speed. It is mainly useful for testing map feasibility.

The simulation also supports battery consumption and charging, allowing you to test charging strategies in a controlled environment.

Integration Capabilities

For external system integration, OpenTCS provides a RESTful Web API, along with Swagger documentation for understanding request and response formats.
However, the API does not provide true event-based callbacks. Consumers must rely on continuous polling, with the only alternative being a long-polling API that delivers all event types in a single stream.

In practice, after experimenting with the long-polling approach, polling specific APIs for targeted information often turns out to be more practical and easier to manage.

For vehicle integration, a custom Communication Adapter must be implemented.
The built-in simulated vehicle adapter serves as a good reference and can be extended or modified. The adapter is responsible for translating OpenTCS commands into vehicle-specific control commands, and mapping vehicle feedback back into OpenTCS vehicle states, such as battery level, load status, idle or executing state, etc.
Once this mapping is in place, the vehicle can be fully controlled by TCS.

For peripheral devices, OpenTCS also provides flexible adapter extension points.
Whether integrating elevators, automatic doors, or other equipment, as long as a clear communication protocol exists, the integration can be implemented via a custom adapter.

Practical Evaluation

Feature Assessment

The following evaluates whether each major feature is sufficient for typical real-world use cases, and highlights areas where additional mechanisms are required:

  • ✅ Meets requirements
  • 🆖 Usable but insufficient
  • ❌ Does not meet requirements
評價評論
Tools & Software🆖Model Editor: The interface has significant room for optimization. Editing custom properties in maps requires too many steps and lacks validation, making it easy to miss configurations.

Operations Desk: Supports simple cyclical task dispatching, but does not support tasks with custom properties—these must be submitted via API. It allows viewing each vehicle’s reserved resources, but analyzing interactions (e.g., Vehicle A blocking B, Vehicle B blocking C) must be done manually.

Kernel Control Center: Limited functionality; usable but minimal. The built-in watchdog provides insufficient information for debugging.

General tools limitation: All tools require running the programs; there is no web-based interface for quick overview, nor role-based access control. This makes it difficult for non-maintenance personnel to use without developing a custom UI.

Kernel: Some mechanisms complicate operations and maintenance. Uploading a new map interrupts and clears all existing tasks, and restarting does not retain prior tasks. No historical data is available. Updating maps or upgrading versions requires canceling all tasks and redispatching afterward.
Map✅Basic properties cover most needs and support custom attributes, offering high extensibility.
Task Management✅Supports priority and distance concepts. Vehicle order type mapping for prioritization is available, making it very complete.

Supports sequencing to bind multiple orders to the same vehicle, preventing idle gaps during task execution.
Path Finding & Cost🆖Basic functionality is available, but cost calculation does not account for rotation counts; it considers only distance or time. Some routes that feel circuitous may appear equal in cost in TCS.

Additional functionality may require custom extension.
Native support exists for intentionally choosing longer routes, but configuration is cumbersome and difficult to maintain.
Traffic Management❌Limited for complex environments. Only works reasonably in spacious areas where paths can accommodate two lanes, and only simple intersections require traffic management.

Block maintenance is highly experience-dependent. Considering collision avoidance, corners, intersections, or closely spaced paths may require extensive Block setup; missing blocks can lead to on-site issues.

Supports restricting large vehicles from small paths, but no dynamic switching. For example, empty vehicles can use certain paths, but vehicles carrying cargo exceeding size limits cannot dynamically switch—this is not supported.

Dynamic rerouting is unsupported; vehicles must wait for resource release, which may appear unintelligent in practice.
Parking Areas✅Quite complete. Supports priorities and reassigning vehicles to higher-priority positions. Configurable for various scenarios.
Charging Strategy🆖Only uses a simple threshold mechanism. When multiple vehicles share a charging station, there is no active handover. Vehicles may free the station only if new tasks arrive, but cannot avoid situations where multiple vehicles simultaneously run out of battery.
Simulated Vehicles🆖Useful for validating maps and traffic management logic. Lacks speed simulation and docking wait time, so it cannot provide accurate timing estimates.
Integration✅Web API is fast (tens of milliseconds), and even polling can handle the load.

Event-driven mechanisms require custom development.
TCS can internally receive events, but you must implement your own mechanism to trigger them externally.

Expectations vs Reality

Although OpenTCS is updated frequently, new features should not be overhyped or assumed to be fully mature. Often, they provide only the most basic functionality.

For example, a recent version added the ability to define vehicle and point dimensions to prevent large vehicles from using small paths. However, this feature does not affect resource occupation calculations—vehicles may still overlap in space. Therefore, new features must always be tested in practice to understand their actual behavior and limitations.

Target Users

TCS requires custom development and cannot be used straight out of the box. Even when using a VDA5050-compliant adapter, some logic still needs to be customized, and bugs are still present—the author has personally reported several to the official maintainers.

TCS is most suitable for companies that already operate vehicles or those that are committed to developing a fleet management system from the start.

Compared to building everything from scratch, TCS can save considerable effort. However, it requires time and focus to understand the internal architecture. The system is well-designed: although there are many classes and extensive abstraction, once the architecture is understood, modifications or replacements require minimal effort, and maintenance is straightforward in the long term.

Reference

🔲 ⭐

你理想的混合现实MR世界是什么样的呢

当前的元宇宙似乎更多金融属性,好像每个人都有自己的一个理解,暂且抛弃不谈这些镜中水月,而是简单聊聊AR、MR和VR,甚至不过多的谈VR,因为上篇文章已经聊过了,而是谈谈出现过那些AR和MR设备现状怎么样了,以及我们想要的混合现实MR世界是什么样的呢?

AR、MR和VR

1、VR(virtual reality,虚拟现实)
可以让用户沉浸其中的由计算机生成的三维虚拟环境,并与现实环境相隔绝。最大场景是游戏给人以沉浸感。

2、AR(augmented reality,增强现实)
在真实环境中增添或者移除由计算机实时生成的可以交互的虚拟物体或信息。常见场景有三个,一是基于标记的增强现实比如扫福。二是基于地理位置LBS的增强现实比如街道名称,商家名称评价,实景导航。三是基于投影的增强现实,手机拨号键投到手上,隔空打电话等。

3、MR(mixed reality,混合现实)
通过全息图,将现实环境与虚拟环境相互混合,也可以看成是VR与AR的混合。几个比较合适场景,比如装修设计,教育培训,医学工业等等

如果还不好理解AR和MR,可以简单这样思考AR构建的虚拟景象是永远在你眼睛前方的,而MR构建的虚拟景象可以固定在特定位置,如建筑物的某一个墙面上~

设备商现状

1、Google Glass
失败,伴随着最近一次更新,只剩下了打接电话,失败原因是多样的,一是隐私风波,二是规划描述的太美好根本实现不了

2、Microsoft Hololens
没有成功,全息投影效果基本没有实现,用一个特别难看的,而且空间构建经常出现五彩斑斓白效果,对象主要对研究人员和企业,不面向消费者。。。

3、Magic Leap
没有成功,大家对他最惊艳的莫过于体育馆一跃而起的鲸鱼视频,但是呢,实际实现效果一般,相对来讲比其他效果好一些,面向消费者,提供了多个应用,价格昂贵效果一般销量很低,仍然算不上成功

05a0a609f1444d1a86bb74f149efcf3f.gif

理想的混合现实MR世界

1、色彩
我们生活的世界大多数是黑白灰,这也是为什么我们非常喜欢游戏的原因之一吧。
我们很难去改变黑白灰现状,但是可以通过叠加虚拟,做很多节日色彩,做很多装饰色彩,比如下面长沙步行街的春节装扮

IMG_5536.GIF

2、生活
点餐可以为我们呈现虚拟的菜样,这样所见即所得。
超市为我们指引购物方向,提供更多购物建议。
街道提供更多方向指引基础设施。

IMG_5537.GIF

3、互动
好多时候面对真人反而会减少互动,真人呢,会担心犯错,也会疲惫,而虚拟形象反而可以提升锻炼人与人之间沟通,即解开心扉,又能加强沟通。

你的理想MR世界是什么样的呢?你希望什么场景有所改变呢?

资料1:【何同学】2021年了,AR眼镜可以做什么?
资料2:麦阿臻

The post 你理想的混合现实MR世界是什么样的呢 first appeared on 司马他.
🔲 ☆

[經驗]無人搬運車(AGV)廠商合作模式分享

筆者曾因工作需求,接觸過一些無人搬運車(AGV)廠商,商談合作細節,今天就來分享我遇過或周遭朋友遇過的產品特性和廠商合作模式,首先介紹一下使用的背景,公司已經有自己開發的完整MES系統,因此所有對內的整合都可以自己處理,不考慮外包給廠商,一方面考慮私有系統機密性,另一方面都已經有養人了,對自己系統也熟,做起來一定比廠商還要快。

接著介紹產品特性和合作模式,概略可分為這幾種方式,會一一說明,以下為筆者自身和周邊遇到的經驗,不代表整個業界~

  1. 成熟穩定的產品,使用說明詳細,卻不能客製功能
  2. 有基礎功能,想要更多,就專案合作
  3. 功能較陽春,願意配合修改
  4. 簡單易用,但無法擴充

成熟穩定的產品,使用說明詳細,卻不能客製功能

這種類型通常都是國際大廠,因為產品已發展相當成熟,容易上手使用,設定上相當開放,即使是專業的設定,也開放給客戶自行調整,不管你想的到或想不到的功能,都一併提供,並在說明手冊上詳細說明,提供教育訓練和技術諮詢。用日常例子的話,就像買汽車,交車時示範一次給你看,後續你自己回家研究,真的有問題可以打去車行問一下,但不可能手把手完全帶你。

以筆者的經驗,使用的是SLAM導航,除了第一次原廠人員來示範一些常用操作以外,後續就讓客戶自己處理了,從掃描地圖、設站點和到站行為、設定地圖規則(行走速度、規定路線、單行道等),甚至是安全距離這種專業參數都可以讓客戶調整,設定多達1~2百項。當然遇到一些不瞭解或是不知道怎麼解的問題,原廠除了提供諮詢,也願意前來幫忙,但是不可能隨叫隨到,都是要提前預約時間。

優點:

  1. 軟體設計得很完整成熟,客戶掌握度高,不需要凡事麻煩原廠處理
  2. 客戶最了解自己的需求,掌握車子功能後,可以自行調整最合適的流程
  3. 適用大多數使用場景,無須等待開發時程,到貨即可使用

缺點:

  1. 需要花時間熟悉,並且細部調整都需要自己來,建地圖容易,但如果場地有一些限制,需要調到順暢使用就很花時間,這也是廠商打的如意算盤吧,把這個功給客戶做,自己可以專心賣產品,服務相對少很多
  2. 功能雖多,但也就是這樣了,有些特定作法只能用原廠提供的方式迂迴實現,如果需要客製化功能,就要看你的單若夠不夠大量,基本上都很難說服原廠幫您加入

有基礎功能,想要更多,就專案合作

這一類跟上一個案例對比,就是兩個極端,從頭到尾都需要原廠的人來介入,提供使用的軟體非常基礎,甚至有工程版的錯覺,就是那種工程師自己會用,介面完全沒有針對外觀和UX優化過的,身為工程師的我,一眼就看的出來了XD。並且詢問一些相對基礎的功能時,軟體也沒有提供,都只能透過原廠工程師設定,隨便舉幾個例子:

  1. 我想要可以自己設定車子上的Wifi,但沒有提供任何有線連入方式修改 (當然工程師自己一定可以,只是沒有另外寫程式把這個功能開放出來)
  2. 我想要設定車子行走時的音樂,同樣沒有開放這個功能
  3. 我想要調整車子的速度,只能依照原廠設置的速度機制,寬敞時快,狹窄時慢,但是在我方場地實在是過慢…

針對以上功能,原廠都說可以專案合作,但會收相對費用,就看客戶能不能接受這種做法了,很不巧筆者因為有使用過成熟的產品,並且是以系統整合的角度去看,所以覺得由奢入儉難XD,不過還是要平衡一下,至少有客製這個選項,對於有特殊流程,或者公司沒有養工程師,想要連系統整合都外包的客戶,就非常適合。

優點:

  1. 對於無資訊背景之客戶,可以全部包到好
  2. 有客製化選項,你有特殊需求可以專案處理

缺點:

  1. 採購後還需要開發時程,不適合有時程壓力的客戶
  2. 對於有工程師的客戶,無法完全掌握,凡事都需易透過原廠

功能較陽春,願意配合修改

這一類跟上一類有點類似,但是產品又更陽春一些,像是只有藍芽而沒有Wifi功能,所以不容易整合內部系統取得車輛運作資訊,或是沒有車隊系統,調度派車都是透過手動觸發,比較適合無須整合系統的客戶使用。

話雖如此,但廠商配合度高,如果你可以自己處理藍芽和Wifi之間的橋接,廠商是願意提供協定細節的,不會因為牽涉太底層就視為機密。可能因為產品發展時間還不夠久,或是他們的客層就是鎖定簡單用戶,也積極想要了解進階客戶需求,慢慢發展上去。

不過如果真的要整合起來,客戶這邊工會很重,有一種我做這個系統,只是為了完善廠商產品的感覺,說到底,具體還是要看需求,喜歡自己來的老闆可能會覺得賺到。

簡單易用,但無法擴充

這類型就沒什麼太多可以說的,主要都是以簡單應用為主,不具備任何整合功能,通常都是單機使用,價錢也相當親民,適合傳產這類的客戶使用。

以上就是筆者與接觸過的AGV廠商經驗分享,多少會帶有一些主觀想法,不能代表全部,廠商百百間,相信只要認真找,一定會有適合的廠商。

❌