設定自動調度管理工具

協調器是本機 SDV 代理程式,會在每個虛擬機器 (VM) 上執行,並提供機制來控管服務套件的建立、啟動、停止或毀損時間。這是透過自動化調度管理設定完成,您可以在其中定義一組規則,決定何時以及如何對服務套件執行個體執行動作。這些規則會根據車輛、電源和自訂模式而定。

您可以在設定 APEX 中設定 Orchestrator,也可以透過每個 VM 的設定進行設定。這個分散式設定系統可讓您透過服務套件登錄檔,獨立更新每個服務套件的部分內容,如圖所示。

協調器分散式設定圖

圖 1. Orchestrator 設定圖。

與車輛無關的設定不會因 OEM 或車輛而異。每個原始設備製造商 (OEM) 的所有車輛都採用相同的設定。不同 OEM 的車輛可能會有不同的車輛專屬設定,但特定 OEM 製造的所有車輛可能會有相同的設定。

設定 APEX

在執行階段,自動調度管理工具會前往服務套件註冊資料庫,擷取每個服務套件的 SDV 自動化調度管理,並載入及剖析每個設定。詳情請參閱「協調流程中繼資料」。

每個 VM 的設定

Orchestrator 啟動時,會載入並剖析 VM 設定 (如有)。這個設定檔的絕對路徑是透過系統屬性 persist.sdv.orchestrator_config_pathro.boot.sdv.orchestrator_config_path 指定。

系統會在啟動時,根據下列階層決定 VM 設定檔路徑:

  1. 系統會檢查 persist.sdv.orchestrator_config_path 屬性。如果該變數有值,系統會使用該路徑。這個值會在重新啟動時保留,或在執行階段設定。

  2. 如果 persist.sdv.orchestrator_config_path 為空白,系統會檢查 ro.boot.sdv.orchestrator_config_path 屬性。如果 ro.boot.sdv 屬性有值,該路徑會複製到持續性屬性,並用於目前的開機和所有日後的開機 (除非遭到覆寫)。

persist.sdv.orchestrator_config_path

SDV Orchestrator 代理程式會使用 persist.sdv.orchestrator_config_path 這個主要屬性,取得設定檔的路徑。這是持續性屬性,也就是說,即使裝置重新啟動,其值也會儲存。您可以在執行階段變更值,這對於測試或特定情境 (例如端對端測試) 很有幫助。

您可以使用 setprop 指令在執行階段設定值,並在建構時間使用 makefile (副檔名為 .mk) 或資源指令碼檔案 (副檔名為 .rc) 設定值。

在執行階段設定屬性

在執行階段設定屬性有助於測試或進行暫時性變更,因為系統會在重新啟動時儲存該值:

adb root
adb shell setprop persist.sdv.orchestrator_config_path {$path_to_file}.textproto

在建構時間設定屬性

如要將這項屬性設為裝置建構設定的一部分,請在產品或主機板的 Makefile 中新增一行。非常適合為新的裝置圖片設定預設值。

# Add this line to a product's or device's .mk file
PRODUCT_PROPERTY_OVERRIDES += persist.sdv.orchestrator_config_path={$path_to_file}.textproto

您也可以在資源指令碼檔案中設定這項屬性:

# Add this line to an .rc file
on {$property}
    setprop persist.sdv.orchestrator_config_path {$path_to_file}.textproto

ro.boot.sdv.orchestrator_config_path

ro.boot.sdv.orchestrator_config_path 是開機時的唯讀屬性,用於提供 persist.sdv.orchestrator_config_path 屬性的初始值。如果系統啟動時 persist.sdv.orchestrator_config_path 為空白,系統會將 ro.boot.sdv.orchestrator_config_path 的值複製到 persist.sdv.orchestrator_config_path。設定 persist.sdv.orchestrator_config_path 後,後續啟動時不會覆寫這個屬性。

您可以使用 bootconfig 或核心指令列設定 ro.boot.sdv.orchestrator_config_path

檔案格式

.textproto 格式定義協調設定 (例如結構化文字),以便在執行階段載入新設定。

設定語法

本節說明設定語法。

服務套裝組合

每個服務套件都必須使用服務套件設定定義,這項設定會識別 Orchestrator 中的套件,並用於處理套件例項的生命週期。服務組合設定會定義:

  • InstanceToGroupMapping 可讓您在群組中加入服務套件的執行個體,在相同服務套件的執行個體之間建立依附元件。

  • InstancesStates 定義服務套裝組合例項的不同狀態。

  • InstancesStateConfiguration 定義服務套裝組合執行個體必須設為的狀態 (來自 InstancesStates),條件評估結果為 true 時。

  • ServiceBundleConfig 包含特定服務套裝組合及其例項的相關資訊。其中包含套件的相應 InstanceToGroupMappingInstancesStateConfiguration

  • CustomModes 定義一組自訂模式,允許套件發布這些模式。CustomModes 可防止未經授權的套件修改自訂模式的值。這個欄位為選填,因為服務套裝組合可能不會發布至任何自訂模式。詳情請參閱「自訂模式」。

必要套裝組合設定

至少,套裝組合設定會提供下列屬性:

service_bundle_config {
    package_name: "package_name"
    service_bundle_name: "service_bundle_name"

    instance: "instance_1"
    instance: "instance_n"
}

這項宣告會定義 n 服務套件執行個體,並提供相應的 FQIN:

vm_name.package_name.service_bundle_name.instance_1

vm_name.package_name.service_bundle_name.instance_n

設定中未明確宣告 VM 名稱。由於設定是針對每個 VM 定義,因此 VM 名稱一律是設定檔部署的 VM 名稱,且編排代理程式已知道該名稱。

設定執行個體

宣告服務套件執行個體不會有任何作用。執行個體必須經過設定,才能由 Orchestrator 執行。舉例來說,Orchestrator 必須瞭解執行個體應在哪些條件 (或 VM/車輛狀態) 下執行。如要設定執行個體,請透過下列方式定義設定狀態:

  • condition 是指應評估的 VM 或車輛狀態運算式。

  • instances_states 是每個執行個體的一組狀態,如果條件評估結果為 true,就應套用這些狀態。

詳情請參閱「條件」。

service_bundle_config {
    package_name: "oem.package"
    service_bundle_name: "OemApplication"

    instance: "adaptive_light"
    instance: "reserve_light"

    state {
        condition {
            power_state: "ON"
        }

        instances_states {
            started: "adaptive_light"
            created: "reserve_light"
        }
    }
}

執行個體對應至群組

您也可以將服務執行個體納入服務群組,藉此設定服務執行個體。在服務套裝組合設定層級,您可以將執行個體新增至群組。然後在 VM 設定層級設定群組。詳情請參閱下一節和「服務組合」。

service_bundle_config {
    package_name: "oem.package"
    service_bundle_name: "OemApplication"

    instance: "fog_front_light"
    instance: "fog_rear_light"
    instance: "turn_signal_light"
    instance: "light_flasher_display"

    # Declare that fog_light contains fog_front_light and fog_rear_light.
    group_mapping {
        group: "fog_light"
        instance: "fog_front_light"
        instance: "fog_rear_light"
    }

    # Declare that flasher_light contains turn_signal_light and light_flasher_display.
    group_mapping {
        group: "flasher_light"
        instance: "turn_signal_light"
        instance: "light_flasher_display"
    }
}

Proto 結構定義

以下是 proto 結構定義範例:

// Service bundle configuration.
//
// Defines service bundle data, its instances and configuration for instances
// states depending on the state of the system
message ServiceBundleConfig {
  // Required. Name of the service bundle.
  string service_bundle_name = 1;

  // Required. Package name of the service bundle.
  string package_name = 2;

  // Required. Service instances.
  repeated string instance = 3;

  // Configuration for instances states depending on the state of the system.
  repeated InstancesStateConfiguration state = 4;

  // Mapping of groups to their member service instances.
  repeated InstanceToGroupMapping group_mapping = 5;

  // Custom modes that this service bundle is allowed to set.
  repeated string custom_mode = 6;

  // Defines the retry policies for specific instances.
  // If multiple mappings target the same instance, the one with the highest `max_retries`
  // value takes precedence. This applies across all configuration files.
  repeated InstanceToRetryMapping retry_mapping = 7;
}

// Mapping of instances to their retry configuration.
message InstanceToRetryMapping {
  // Required.
  //
  // Name of the instances for which the given retry configuration is applied.
  repeated string instance = 1;

  // Required.
  //
  // The configuration that defines the restart and retry strategy for the instances.
  RetryConfiguration retry_config = 2;

  // Configuration for retry and restart.
  // This configuration is applied after a failure on a transition or after the bundle instance
  // has crashed. Upon a successful operation, the retry counter are reset to max_retries. This
  // configuration can be applied to any service bundle, not only the monitored ones. If the
  // configuration is not provided or none of the optional fields are filled, the default behavior
  // stated is applied (the value from `ro.boot.sdv.orchestrator.recovery.max_retries`
  // or zero if not set).
  message RetryConfiguration {
    // The number of times a retry/restart operation can be performed.
    // Defines the number of times the Orchestrator retries a transition
    // after a transient failure or after a bundle crash notification.
    // This applies to creating, starting and destroying operations.
    // The retry count resets to max_retries after a successful operation.
    // If not set, the default configured value in the
    // `ro.boot.sdv.orchestrator.recovery.max_retries` is used, or-if not set-
    // it fallbacks to zero.
    optional uint32 max_retries = 1;
  }
}

// Mapping of groups to their member service instances.
message InstanceToGroupMapping {
  // Required. Names of groups to which members are added.
  //
  // Group behavior is defined in VM configuration.
  repeated string group = 1;

  // Required. Names of instances to be included in the groups.
  //
  // Can reference only instance defined in the same config file.
  repeated string instance = 2;
}

// Describes the state the service instances should be in after the state is executed.
//
// If there is no valid configuration for the instance in the specific system state, such instance is transitioned to the "destroyed" state.
//
// For the GroupsStates definition to be useful, at least one item should be present in any of the fields.
message InstancesStates {
  // Names of the instances that must be in a "created" state.
  repeated string created = 1;

  // Names of the instances that must be in a "started" state, overrides "created" state.
  repeated string started = 2;

  // Names of the instances that must not run, overrides all other states.
  repeated string destroyed = 3;
}

// Configuration for instances states depending on the state of the system.
message InstancesStateConfiguration {
  // Condition for the system state under which the related instances states should be executed by Orchestrator.
  //
  // If omitted, the related instances states are always executed.
  Condition condition = 1;

  // Required. States of service bundle instances to be executed by Orchestrator if the condition is true.
  InstancesStates instances_states = 2;
}

VM 層級設定

VM 設定可定義群組對應和群組設定。這項功能可用於建立 VM 層級的服務套件相依性模型,因此可彈性地同時修改多個服務套件的狀態。群組的所有執行個體都會進入指定狀態。

Orchestrator 無法保證狀態變更的執行順序。Orchestrator 會將每個執行個體升級至指定狀態。

在任何設定部分使用 group 名稱,即可隱含宣告群組。例如執行個體對應群組、群組對應群組,以及群組設定狀態。

群組對群組對應

群組可以包含其他群組。宣告 group_1 包含 subgroup_2 後,我們實際上會將 subgroup_2 中的所有服務執行個體新增至 group_1

例如:

# Declare that body contains fog_light and flasher_light.
group_mapping {
    group: "body"
    subgroup: "fog_light"
    subgroup: "flasher_light"
}

設定群組

宣告群組不會產生任何影響。如要由自動化調度管理工具執行,必須先設定群組。舉例來說,Orchestrator 必須知道群組應在 VM 或車輛的哪些條件或狀態下執行。

您可以透過設定狀態,以類似於服務執行個體的方式設定群組。唯一的差別是語法中使用了 groups_states,而非 instances_states

state {
    condition {
        power_state: "ON"
    }

    groups_states {
        started: "Body"
        started: "Adas"
    }
}

Proto 結構定義

以下是 proto 結構定義範例:

// VM configuration.
//
// Defines group-to-group mappings and configuration for groups
// states depending on the state of the system.
//
// Configurations of service bundles can also be defined in VM configuration (as well as in a separate configuration file).
message VmConfig {
  // Group to member groups mapping.
  repeated GroupToGroupMapping group_mapping = 1;

  // Configuration of group states.
  repeated GroupsStateConfiguration state = 2;

  // Required. We also allow to configure individual service bundles in the VM config, to simplify development and migration from the monolithic configuration.
  repeated ServiceBundleConfig service_bundle_config = 3;
}

// Mapping of groups to their member groups.
message GroupToGroupMapping {
  // Required. Names of groups to which members are added.
  repeated string group = 1;

  // Required. Names of member groups to be included in the groups.
  repeated string subgroup = 2;
}

// Describes the state the service instance groups should be in after the state is executed.
//
// If group configuration is valid in a specific system state, the configured state is applied to
// all group members. After that, the normal service instance configuration rules still apply:
// - "destroyed" > "started" > "created" precedence
// - not configured means the instance should be moved to the default state
//
// For the GroupsStates definition to be useful, at least one item should be present in any of the fields.
message GroupsStates {
  // Names of the groups that must be in a "created" state.
  repeated string created = 1;

  // Names of the groups that must be in a "started" state, overrides "created" state.
  repeated string started = 2;

  // Names of the groups that must not run, overrides all other states.
  repeated string destroyed = 3;
}

// Configuration for group states depending on the state of the system.
message GroupsStateConfiguration {
  // Condition for the system state under which the related group states should be executed by  Orchestrator.
  //
  // If omitted, the related groups states are always executed.
  Condition condition = 1;

  // Required. States of service bundle groups to be executed by Orchestrator if the condition  is true.
  GroupsStates groups_states = 2;
}

設定狀態

設定狀態 (狀態) 會定義服務執行個體或群組的啟動、停止或毀損時間,並包含 conditionsinstances_states (套件組合設定) 和 groups_states (VM 設定)。

條件

條件可讓模型在布林值條件下,評估為 true 時套用定義的執行個體狀態。條件具有下列特徵:

  • 根據支援的信號 (例如電源、車輛和自訂模式) 形成的任意複雜布林運算式 (以 andnot 運算式組成)。

  • (選用) 沒有條件的設定狀態一律為有效狀態,也就是說,系統會評估為 true

執行個體狀態和群組狀態

instances_statesgroups_states 具有這些特徵。

  • 根據狀態為 active,指揮代理程式需要哪些狀態,才能套用至指定執行個體或群組。

  • 將狀態套用至群組時,該狀態會套用至群組中的每個服務套裝組合執行個體。執行個體進入該狀態的順序不一定。

支援的州包括:

  • 呼叫 Service::on_start 後的 started

  • created

    • 呼叫 Service::new 後,但在呼叫 Service::on_start 前。

    • 呼叫 Service::on_stop 後,但在呼叫 Service::drop 前。

  • 呼叫 Service::drop 後的 destroyed

規則集

視條件而定,設定狀態可以是「有效」或「無效」。你可以隨時啟用多個狀態。當編排代理程式收到信號更新時,系統會評估所有設定狀態,然後再修改服務套件的生命週期。系統會根據下列規則評估服務執行個體狀態:

  • 如果沒有任何有效狀態適用於服務執行個體,系統就會將其終止。

  • 如果適用一或多個有效狀態,則適用下列優先順序:

    1. destroyed 的優先順序最高。
    2. started優先於 created

Proto 結構定義

以下是 proto 結構定義範例:

// A root boolean condition.
message Condition {
  // Required.
  oneof root {
    // VPM power state condition.
    string power_state = 1;
    // VPM vehicle state condition.
    string vehicle_state = 2;
    // Custom mode state condition.
    CustomState custom_state = 3;
    // Negation of a nested condition.
    Condition not = 4;
    // Logical 'and' between conditions grouped in expression.
    Expression and = 5;
    // Logical 'or' between conditions grouped in expression.
    Expression or = 6;
  }
}

// Representation of Custom state condition.
//
// Custom mode(s) are defined by the OEM and are not standardized by the platform, in contrast with
// VPM modes (i.e. power and vehicle mode).
message CustomState {
  // Custom mode being checked.
  string mode = 1;
  // State of the custom mode.
  string state = 2;
}

// A set of conditions united under an 'and' or 'or' expression.
//
// Evaluation type ('and' or 'or') depends on the field in [Condition]/[Expression], where the
// expression is being used.
//
// At least one value in at least one of the fields is required.
message Expression {
  // VPM power state condition.
  repeated string power_state = 1;
  // VPM vehicle state condition.
  repeated string vehicle_state = 2;
  // Custom mode state condition.
  repeated CustomState custom_state = 3;
  // Negation of a nested condition.
  repeated Condition not = 4;
  // Logical 'and' between conditions grouped in expression.
  repeated Expression and = 5;
  // Logical 'or' between conditions grouped in expression.
  repeated Expression or = 6;
}

當機復原和重新啟動策略

Orchestrator 提供完善的機制,可處理服務套件當機和生命週期轉換失敗的問題。由於 Orchestrator 可全面掌握服務狀態並管理模式轉換,因此最適合執行重新啟動和重試策略。生命週期管理工具 (LM) 會透過繫結器終止通知,向 Orchestrator 回報服務套件當機情形。為避免對 LM 進行不必要的繫結器呼叫,Orchestrator 會快取每個套件的最後一個狀態 (無論是否成功),如果最後一個已知狀態與新要求狀態相同,就不會重新套用轉換。

重試設定

您可以使用 retry_mapping,在 Orchestrator 設定中定義每個執行個體的重新啟動和重試策略。如果未在設定中設定 max_retries,系統會從 ro.boot.sdv.orchestrator.recovery.max_retries 系統屬性取得預設值。如未設定這項屬性,值會回溯為 0。

  • max_retries:定義自動化調度管理工具在發生暫時性失敗或收到套件當機通知後,重試轉換的次數。作業成功或處理新模式後,重試計數器會重設為 max_retries 的值。如果多個對應項目指定相同執行個體,系統會優先採用 max_retries 最高的項目。

設定範例

service_bundle_config {
  package_name: "oem.package"
  service_bundle_name: "OemApplication"
  instance: "fog_front_light"
  instance: "fog_rear_light"

  # Defines the restart configuration mapping for specific instances.
  retry_mapping {
    instance: "fog_front_light"
    instance: "fog_rear_light"
    retry_config {
      max_retries: 3
    }
  }
}

復原行為

Orchestrator 的重新啟動和重試邏輯可順利管理多種失敗情況:

  • 正常運作時發生當機:如果服務套件在執行時當機,Orchestrator 會套用重新啟動策略,並根據剩餘的重試次數,嘗試將套件恢復至上次要求的狀態。
  • 模式轉換期間發生當機:如果強制執行新模式時發生當機,系統會將重新啟動要求加入佇列,稍後再處理。要求處理完畢後,Orchestrator 會檢查執行個體的最後狀態,且只有在執行個體並非處於最後要求狀態 (來自最後模式轉換) 時,才會套用重新啟動。
  • 復原期間的新模式:如果 Orchestrator 在重新啟動套件時收到轉換至新模式的要求 (或在要重新啟動的執行個體佇列中),就會取消進行中的復原作業。新的模式轉換會接管作業,並重設重試計數器,以便對新目標狀態進行一組新的嘗試。

Orchestrator 會區分 Lifecycle Manager 傳回的不同錯誤類型,以判斷重試策略:

  • 暫時性錯誤 (SERVICE_NOT_FOUNDOPERATION_FAILEDINTERNAL_ERROR):Orchestrator 會重試作業,不會採取任何特殊清除動作。
  • 持續性錯誤 (VALUE_CORRUPTEDINVALID_ARGUMENT):Orchestrator 會假設服務套件可能處於損毀狀態,並嘗試終止服務例項,然後重試作業,確保重新啟動時不會有任何問題。
  • 永久錯誤 (PERMISSION_DENIED):系統不會重試作業,且會將套件視為處於無法復原的狀態。

如果生命週期管理員當機,所有服務套件程序都會遺失。由於實際狀態不明,Orchestrator 會使每個執行個體失效,並套用剩餘重試次數的重新啟動策略,將每個執行個體帶到上次要求的狀態。

為避免套件重複當機或失敗,導致無限循環復原,只有在生命週期作業成功,或要求新的模式轉換時,重試計數器才會重設為 max_retries。如果一連串的失敗導致套件耗盡重試次數 (例如轉換失敗後發生當機),系統會等到重試計數器重設後,才會重新啟動套件。

向健康監測器回報狀態

Orchestrator 會公開內部繫結器介面,健康狀態監控器 (HM) 會向該介面註冊,以便持續接收所有服務套件的狀態更新。透過這個介面,自動化調度管理工具會主動回報下列兩項資訊:

  • 生命週期狀態:根據目前的設定和有效模式 (例如已啟動、已建立或已毀損),執行個體的預期狀態。
  • 復原狀態:達到預期生命週期狀態的狀態,指出執行個體是否可運作、目前是否在失敗後重試,或是在重試次數用盡後復原失敗。

所有執行個體都會回報這項資訊,包括未註冊要接受心跳監控的執行個體。HM 會使用這項資訊實作其 API,以回報 VM 的狀態。詳情請參閱「Health monitoring」。

範例

本節提供範例,說明如何設定具有條件的狀態。

基本服務範例
  • 沒有條件,因此一律處於啟用狀態。
  • 啟動單一服務執行個體。
state {
  # Note: This state has no condition, hence its actions are valid throughout the lifetime of the program
  instances_states { started: "ServiceBundleName" }
}
空調應用程式範例
  • 條件:在 custom_state != occupancy.OCCUPANCY_EMPTY || custom_state == preheat.PREHEAT_ON 時啟用。

  • 將多個與空調相關的服務例項宣告為 started

state {
  condition {
    or {
      # I.e. when the vehicle is occupied (for example, by _DRIVER / _NON_DRIVER / _PET)
      not {
        custom_state {
          mode: "occupancy"
          state: "OCCUPANCY_EMPTY"
        }
      }
      custom_state {
        mode: "preheat"
        state: "PREHEAT_ON"
      }
    }
  }

  # HVAC-related services
  instances_states {
    started: "HvacTemperatureCommand"
    started: "TempSensorDriverZone"
    started: "TempSensorPassengerZone"
    started: "RefrigerantLoop"
  }
}
省電範例
  • 條件:在 custom_state == system_power.SYSTEM_POWER_LOW && custom_state == range_ext.RANGE_EXT_ON 時啟用。

    這種狀態可視為省電狀態。

  • 將一個與 HVAC 相關的服務執行個體宣告為 destroyed

  • 在本範例中,當 SYSTEM_POWER_LOWRANGE_EXT_ON 模式處於啟用狀態時,HVAC 應用程式會執行,但不會使用 RefrigerantLoop 服務執行個體:

    state {
      condition {
        and {
          custom_state {
            mode: "system_power"
            state: "SYSTEM_POWER_LOW"
          }
          custom_state {
            mode: "range_ext"
            state: "RANGE_EXT_ON"
          }
        }
      }
    
      # Disable services with high power consumption
      instances_states { destroyed: "RefrigerantLoop" }
    }
    
機上生活範例
  • 條件:如果 power_state == ON && vehicle_state == LIFE_ON_BOARD,則為有效。

    這種狀態可視為車內有人且車輛已啟動

  • 宣告溫度感應器正在運作。

  • 車內有人時,系統會監控溫度等項目,確保安全。

state {
  condition {
    and {
      power_state: "ON"
      vehicle_state: "LIFE_ON_BOARD"
    }
  }

  # Temperature monitoring services
  instances_states {
    started: "TempSensorDriverZone"
    started: "TempSensorPassengerZone"
  }
}

範例

本節提供完整範例,包含:

  • 服務套裝組合層級的 Proto 設定,其中包含兩個執行個體的服務套裝組合,每個執行個體都是群組的一部分

  • VM 層級的 proto 設定,可根據模式導入與群組互動的邏輯

服務套裝組合層級設定

# proto-file: //system/software_defined_vehicle/orchestration/distributed_config/src/protos/service_bundle_config.proto
# proto-message: ServiceBundleConfig

package_name: "oem.package"
service_bundle_name: "OemApplication"
instance: "fog_front_light"
instance: "fog_rear_light"
instance: "turn_signal_light"
custom_mode: "FOG"
custom_mode: "TURN"

group_mapping {
    group: "fog_light"
    instance: "fog_front_light"
    instance: "fog_rear_light"
}

group_mapping {
    group: "flasher_light"
    instance: "turn_signal_light"
}

state {
    condition {
        power_state: "ON"
    }

    instances_states {
        created: "turn_signal_light"
        destroyed: "fog_front_light"
        destroyed: "fog_rear_light"
    }
}

VM 層級設定

# proto-file: //system/software_defined_vehicle/orchestration/distributed_config/src/protos/vm_config.proto
# proto-message: VmConfig

group_mapping {
    group: "lights"
    subgroup: "fog_light"
    subgroup: "flasher_light"
}

state {
    condition {
        custom_state {
            mode: "FOG"
            state: "ON"
        }
    }
    groups_states {
        started: "fog_light"
    }
}

state {
    condition {
        custom_state {
            mode: "TURN"
            state: "RIGHT"
        }
    }
    groups_states {
        started: "flasher_light"
    }
}

state {
    condition {
        vehicle_state: "SUSPEND_TO_RAM_ENTER"
    }
    groups_states {
        created: "lights"
    }
}

設定套裝組合管理平行處理

ro.boot.sdv.max_bundles_management_threads 系統屬性是重要的調整參數,可控制服務套件生命週期作業期間的效能和資源耗用量。這項設定會定義服務套裝組合交易的平行處理數量上限,並直接影響兩項核心服務:

  1. 協調引擎:這項服務會讀取屬性,判斷協調器可對生命週期管理員發出的並行呼叫次數 (例如 startServicestopService)。如果許多套件可能會同時變更狀態,這對於啟動和模式轉換期間的效能至關重要。

  2. 生命週期管理工具:這項服務會使用屬性的值來計算 Binder 執行緒集區的大小,負責處理所有傳入的要求。這可確保 LM 有足夠的執行緒來處理 Orchestrator 的並行要求。

如未設定這項屬性,這兩項服務的預設值都是 12

設定方法

如要在裝置的 BoardConfig.mk 檔案中設定屬性,請將屬性新增至 BOARD_BOOTCONFIG 變數。這樣可確保每次裝置啟動時都會套用該值。

BOARD_BOOTCONFIG += \
    androidboot.sdv.max_bundles_management_threads=8

如要變更裝置的值,請在適當的 BoardConfig.mk 檔案中修改這一行,然後重新建構。

啟動時間最佳化

ro.sdv.orchestrator.state.readywrite-once 布林值屬性,屬於開機時效能最佳化策略。這表示 Orchestration 代理程式已完成初始化,準備開始管理服務套件的生命週期。主要用途是控管其他 SDV 代理程式的啟動順序,優先啟動 Orchestrator 及其代管服務套件。

  • 設定者:自動化調度管理代理程式。
  • 時間:開機程序期間一次。
  • 用途:初始化系統會使用這項屬性,控管大多數 SDV 代理程式 (更新管理員、VSIDL 提供者、健康監控器、服務探索、資料通道、RPC、VPM 和遙測) 的啟動順序。提早啟動 Orchestrator 並讓其他代理等待這項屬性,可確保 Orchestrator 能開始啟動服務套件的重要工作,而不必爭用系統資源。

效能

在系統啟動期間,同時啟動所有代理程式可能會導致資源爭用,進而拖慢整體啟動程序。為緩解這個問題,系統會使用系統屬性強制執行依序啟動順序:

  1. 服務套裝組合登錄:首先載入所有服務套裝組合中繼資料。
  2. 生命週期管理員和協調器:這些核心代理程式會在登錄檔準備就緒後立即啟動。提早啟動至關重要,因為這可讓 Orchestrator 開始評估設定,並準備立即啟動服務套裝組合。
  3. 其他 SDV 代理:只有在自動調度管理工具準備就緒後,才能啟動。

這個受控序列可確保 Orchestrator 優先使用系統資源,盡早啟動服務套件,進而加快系統啟動速度、提高確定性及效率。

自動化調度管理工具使用的模式

自動調度管理代理程式會主動訂閱 VPM 傳輸的車輛和電源模式。Orchestrator 與車輛和電源管理 (VPM) 系統建立初始連線後,Orchestrator 會將下列布林系統屬性設為 true

  • sdv.orchestrator.bootup.power_mode.ready

  • sdv.orchestrator.bootup.vehicle_mode.ready

以設定檔為參照,協調代理程式會根據收到的模式目前值,動態計算應處於執行狀態的服務套件組合。然後,Orchestrator 會與生命週期管理員通訊,發出不同指令,使服務套件的實際狀態與計算出的目標狀態一致。

車輛和電源狀態

車輛模式和電源管理 (VPM) 代理程式可讓 SDV 元件瞭解車輛的目前狀態,例如運作模式 (例如停車或行車) 和電源狀態 (例如開啟和暫停)。Orchestrator 會評估這些值,根據 Orchestrator 設定定義應執行的服務組合。詳情請參閱「車輛和電源管理」。

自訂模式

由於車輛模式眾多,我們無法為所有模式建立模型。每家 OEM 的需求不同,標準化車輛模式無法滿足所有 OEM 用途。因此,我們支援 OEM 專屬模式,也就是自訂模式。這些模式不會擴充現有的車輛和電源模式。而是提供定義新模式的方法。

功能:

  • 全域範圍:自訂模式為全域模式,適用於 Orchestrator 管理的所有 VM。

  • 組成:每個自訂模式變更都包含兩個元素:

    • 名稱:OEM 選取的專屬 ID,代表自訂模式。

    • 值:自訂模式的目前狀態,如果未設定任何值,則為 UNDEFINED

  • 調度員角色:調度員會被動接收自訂模式值。

  • 服務套裝組合角色:每個服務套裝組合可擁有多個自訂模式,並可將新值發布至任何模式。多個服務套裝組合可以擁有相同的自訂模式,也就是說,自訂模式可以從不同來源接收新值。

  • 驗證責任:OEM 必須確保狀態轉換有效。Orchestrator 會接受任何新值。

預估特徵:

  • 預估計數:電源和車輛模式會管理大多數服務套件的生命週期,自訂模式則扮演輔助角色。我們預期自訂模式的量級為數十個,而非數百個。

  • 預估時間:模式不會定期傳送。模式是由事件觸發,例如開門、啟動停車程序、開始充電週期,以及其他 OEM 定義的重要事件。

自訂模式設計可彈性定義及管理特定模式,同時讓 Orchestrator 保持與基礎狀態機邏輯無關。

支援的模式

為確保服務套件只會發布至所擁有的自訂模式,每個服務套件都必須在 Orchestrator 設定中明確宣告所擁有的自訂模式清單,這份清單位於本機 VM,並與服務套件登錄檔一起提供。系統會捨棄嘗試發布至未宣告自訂模式的內容。

如要宣告服務套件可發布 (因此擁有) 的自訂模式,請使用下列項目擴充 service_bundle_config proto 結構定義:

// Service bundle configuration.
//
// Defines service bundle metadata, its instances, and configuration for instances
// lifecycle states depending on the state of the vehicle.
message ServiceBundleConfig {
      [...]

    // The list of custom modes that this service bundle publishes.
    repeated string custom_mode = 5;
}

根據模式設定組合

現有的 Orchestrator Proto 設定 (Condition 元件) 支援根據自訂模式操控服務組合:

message Condition {
  oneof root {
    string power_state = 1;
    string vehicle_state = 2;
    CustomState custom_state = 3;
    Condition not = 4;
    Expression and = 5;
    Expression or = 6;
  }
}

message CustomState {
  // Custom mode being checked.
  string mode = 1;
  // State of the custom mode.
  string state = 2;
}

Proto 範例

以下範例說明如何設定服務套件的執行個體,根據 TURNFOG 狀態啟動:

service_bundle_config {
package_name: "oem.package"
service_bundle_name: "OemApplication"
instance: "flasher_light"
// Service bundle is allowed to set values for the TURN mode
custom_mode: "TURN"
// Service bundle is allowed to set values for the FOG mode
custom_mode: "FOG"

state {
    condition {
        custom_state {
            mode: "TURN"
            state: "LEFT"
        }
    }
    instances_states {
        started: "flasher_light"
    }
}

state {
    condition {
        custom_state {
            mode: "FOG"
            state: "ON"
        }
    }
    // Group assumed to be defined containing all FOG lights instances.
    groups_states {
        started: "fog_lights"
    }
}

}

設定新的自訂模式

設定新自訂模式值的程序會從服務套件開始,該套件會將所需值傳達給在同一部 VM 上執行的本機 Orchestrator。然後,Orchestrator 會參照 .textproto 中定義的設定,驗證服務套件是否具備發布至指定自訂模式所需的權限,以判斷是否應將值傳播至其他 VM。傳播完成後,每個 Orchestrator 都會檢查自己的設定,找出應變更狀態的服務套裝組合清單。

RPC

每個 VM 上執行的 Orchestrator 都會建立 RPC 伺服器,監聽新的自訂模式值。如要更新自訂模式,每個服務套件都必須建立伺服器的 RPC 用戶端。系統會強制執行存取控制清單,防止未經授權的套件連線至伺服器。

透過 RPC 設定新值的 proto 定義如下例所示:

syntax = "proto3";

import "google/protobuf/timestamp.proto";

package com.sdv.google.Orchestrator;

// Representation of the request used by service bundles to update a custom mode.
// Service bundles are permitted to update only the custom modes specifically designated
// for them within the Orchestrator configuration.
message SetCustomStateRequest {
  // Required.
  // The name of the custom mode.
  // The mode string can not be longer than 56 characters and can only contain
  // letters, numbers, dashes, dots and underscores: [a-zA-Z0-9_-.].
  // No other special character nor spaces should be present in the mode.
  string mode = 1;

  // Required.
  // The new value for the custom mode.
  // The value string can not be longer than 56 characters and can only contain
  // letters, numbers, dashes, dots and underscores: [a-zA-Z0-9_-.].
  // No other special character nor spaces should be present in the value.
  string value = 2;

  // Required.
  // The timestamp in which the new custom mode value was set. This is used to
  // prevent race conditions whenever different service bundles in different
  // VMs want to set a new value for the same custom mode.
  // We use this timestamp to order the requests and we promise eventual
  // consistency: while temporary inconsistencies may occur, the system will
  // eventually converges to the correct state.
  .google.protobuf.Timestamp timestamp = 3;
}

// Representation of the set custom state response.
message SetCustomStateResponse {}

// Orchestrator interface for service bundles that update the value of a
// custom mode.
// When a new value is received, it is propagated to Orchestrators running on
// other VMs.
service CustomStateService {
  // Updates the value for the custom mode.
  // Returns the error:
  // - PermissionDenied: the service is not authorized to update the custom mode.
  // - InvalidArgument: the provided mode and/or value are not valid.
  rpc SetCustomState(SetCustomStateRequest) returns (SetCustomStateResponse) {};
}

取消電源轉換

Orchestrator 可透過 SHUTDOWN_CANCELLED 電源模式 (由 VPM 傳送至 Orchestrator) 取消進行中的電源轉換。

以下列 Orchestrator 設定為例:

state {
    condition {
        power_state: "SUSPEND_TO_RAM_ENTER"
    }
    instances_states {
        started: "instance-1"
        started: "instance-2"
        started: "instance-3"
    }
}

收到 SHUTDOWN_CANCELLED 模式時,有兩種主要情況會決定 Orchestrator 的行為。在這兩種情況下,SHUTDOWN_CANCELLED 電源模式都會附加到佇列結尾。然後在佇列元素用盡後執行 SHUTDOWN_CANCELLED

情境 1:目前進行中的模式是省電模式

如果自動化調度管理工具正在執行電源模式更新,系統會要求取消進行中的模式。雖然生命週期管理工具本身不支援取消進行中的轉換作業,但 Orchestrator 會驗證是否未啟動任何新的服務套件要求。

舉例來說,如果收到 SHUTDOWN_CANCELLED 模式時,上一個範例中的設定 instance-1 正在啟動,instance-1 就會完成啟動程序。不過,instance-2instance-3 不會轉換為已啟動狀態。

情境 2:處理佇列中存在電源模式

如果 Orchestrator 正在處理非電源模式更新,且待執行的模式佇列中有電源要求,系統會從佇列中移除電源轉換。因此無法執行。

範例:使用上一個範例中的設定,如果 Orchestrator 正在處理非電源相關的更新 (例如車輛更新),且佇列中有 SUSPEND_TO_RAM_ENTER,則收到 SHUTDOWN_CANCELLED 時,系統不會啟動任何執行個體 (instance-1instance-2instance-3)。

導入範例

如果用戶端想使用中介軟體產生的程式碼建立 RPC 伺服器的用戶端,目錄可能如下所示:

# proto-file: //system/software_defined_vehicle/vsidl/language/src/protos/sdv/vsidl/v1/syntax.proto
# proto-message: VsidlEntry

package: "package_name"

service_bundle {
    name: "service_bundle_name"

    client {
        service: "com.android.sdv.orchestrator.CustomStateService"
    }
}

產生程式碼時,您必須將依附元件新增至 Orchestrator 目錄:

--dependency-catalog-path orchestration/engine/stable/vsidl/*

傳送新值的用戶端程式碼如下:

let fqin = ServiceFqin::builder()
        .sdv_vm_name("vm_name")
        .sdv_package_name("package_name")
        .service_bundle_name("service_bundle_name")
        .service_instance_name("instance_name")
        .build()
        .unwrap();
let context_ref = ContextRef::create(fqin);
let comms = Arc::new(SdvComms { context: context_ref });
// service_bundle_name is the bundle generated with middleware code that defines
// the RPC client to "com.android.sdv.orchestrator.CustomStateService".
let client = service_bundle_name::new(comms).await.unwrap();
let rpc_client = client
        .create_rpc_client::<Client>(
            UnitName::builder()
                .vm_name(comms.context.get_self_fqin().get_sdv_vm_name())
                .package_name("com.android.sdv.orchestrator")
                .bundle_name("OrchestratorServiceBundle")
                .service_unit_name(Client::DEFAULT_UNIT_NAME)
                .build()
                .unwrap(),
            ClientOptions::default(),
        )
        .await;
let client = Arc::new(rpc_client.unwrap());
let request = SetCustomStateRequest {
mode: custom_mode_name,
value: custom_mode_value,
timestamp: MessageField::some(Timestamp::now()),
..Default::default()
};
let result = client.SetCustomState(&request).await;
// Process result

偵錯工具

Orchestrator 代理程式支援 dumpsys 工具。如要叫用這項功能,請在執行中的 SDV 執行個體上執行下列指令:

adb shell dumpsys com.google.sdv.ISdvAgent/orch

使用這項工具偵錯,並深入瞭解 Orchestrator 代理程式的內部狀態。這麼做會顯示:

  • 目前模式狀態:查看目前啟用的車輛、電源和自訂模式。
  • 自訂模式發布商:找出可發布自訂模式的服務 (以及可發布的模式)。
  • 各服務的必要狀態:根據預先定義的條件和目前模式,瞭解各服務套裝組合的狀態。這有助於診斷服務未處於預期狀態的原因。
  • 模式強制執行狀態:清楚瞭解目前強制執行模式的進度,或上次強制執行的模式 (如果目前沒有強制執行模式)。
  • 模式強制執行佇列:查看等待強制執行的模式。

例如:

AGENT NAME: SDV Agent dump - Orchestrator
AGENT FQIN: instance1:com.android.sdv.orchestrator.OrchestratorServiceBundle/default
AGENT STATE: See orchestrator state below.
----------------
----------------
INTERNAL STATE REPORTERS:

*NAME: Configuration state
*REPORT:
Active modes:
MODE                          VALUE                         TIMESTAMP (scs, ns)
Power                         POWER_OFF_EXIT                -
Vehicle                       VEHICLE_ON                    -
Custom("CHARGING")            ON                            1750757590 (scs) 466507459 (ns)
Custom("TIRE_PRESSURE")       front-left                    1750757570 (scs) 554522995 (ns)

Modes allowed to publish by bundle (FQIN: modes):
com.android.sdv.sample.orchestration/CustomModeControlBundle: CHARGING, TIRE_PRESSURE

Requested state for instances:
STATE          FQIN
Started        com.android.sdv.sample.orchestration/CustomModeControlBundle/always-started-instance
Started        com.android.sdv.sample.orchestration/OrchestratedServiceBundle/my-instance
Started        com.sdv.oem.sample.diagnostics/DiagnosticsSampleWithDataItem/instance
Started        com.sdv.oem.sample.diagnostics/DiagnosticsSampleWithEvent/instance
Started        com.sdv.oem.user_preferences/UserPreferencesServiceBundle/default
----------------
*NAME: Engine state
*REPORT:
Last mode enforced was Custom("CHARGING") with value "ON"

Next modes to process: []
----------------

如要進一步瞭解 Orchestrator 管理的個別服務組合,請使用 Lifecycle Manager 的現有 dumpsys,方法如下:

dumpsys google.sdv.lifecycle.ILifecycleManager/default

這樣做可提供各項服務生命週期狀態的詳細資訊。將 Orchestrator dumpsys 輸出內容與 Lifecycle Manager 的輸出內容合併,即可完整瞭解 VM 中的服務套件生命週期。