Skip to content

Commit 7501ee6

Browse files
authored
feat: enable config overlays for instances (#976)
* feat: enable config overlays for instances This allow to set unique config variation per instances of your robots in a swarm * fmt * Port cu_instance_overrides_demo to app builder
1 parent 52e94cf commit 7501ee6

12 files changed

Lines changed: 883 additions & 13 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ members = [
7676
"examples/cu_config_variation",
7777
"examples/cu_dorabench",
7878
"examples/cu_image_aligner",
79+
"examples/cu_instance_overrides_demo",
7980
"examples/cu_iceoryx2_bridge_demo",
8081
"examples/cu_logging_size",
8182
"examples/cu_logviz_demo",

core/cu29_derive/src/lib.rs

Lines changed: 104 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3140,6 +3140,7 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
31403140
let prepare_config_sig = if std {
31413141
quote! {
31423142
fn prepare_config(
3143+
instance_id: u32,
31433144
config_override: Option<CuConfig>,
31443145
) -> CuResult<(CuConfig, RuntimeLifecycleConfigSource)>
31453146
}
@@ -3150,21 +3151,59 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
31503151
};
31513152

31523153
let prepare_config_call = if std {
3153-
quote! { Self::prepare_config(config_override)? }
3154+
quote! { Self::prepare_config(instance_id, config_override)? }
31543155
} else {
31553156
quote! { Self::prepare_config()? }
31563157
};
31573158

31583159
let prepare_resources_sig = if std {
31593160
quote! {
3160-
pub fn prepare_resources(config_override: Option<CuConfig>) -> CuResult<AppResources>
3161+
pub fn prepare_resources_for_instance(
3162+
instance_id: u32,
3163+
config_override: Option<CuConfig>,
3164+
) -> CuResult<AppResources>
31613165
}
31623166
} else {
31633167
quote! {
31643168
pub fn prepare_resources() -> CuResult<AppResources>
31653169
}
31663170
};
31673171

3172+
let prepare_resources_compat_fn = if std {
3173+
Some(quote! {
3174+
pub fn prepare_resources(
3175+
config_override: Option<CuConfig>,
3176+
) -> CuResult<AppResources> {
3177+
Self::prepare_resources_for_instance(0, config_override)
3178+
}
3179+
})
3180+
} else {
3181+
None
3182+
};
3183+
3184+
let init_resources_compat_fn = if std {
3185+
Some(quote! {
3186+
pub fn init_resources_for_instance(
3187+
instance_id: u32,
3188+
config_override: Option<CuConfig>,
3189+
) -> CuResult<AppResources> {
3190+
Self::prepare_resources_for_instance(instance_id, config_override)
3191+
}
3192+
3193+
pub fn init_resources(
3194+
config_override: Option<CuConfig>,
3195+
) -> CuResult<AppResources> {
3196+
Self::prepare_resources(config_override)
3197+
}
3198+
})
3199+
} else {
3200+
Some(quote! {
3201+
pub fn init_resources() -> CuResult<AppResources> {
3202+
Self::prepare_resources()
3203+
}
3204+
})
3205+
};
3206+
31683207
let build_with_resources_sig = if sim_mode {
31693208
quote! {
31703209
fn build_with_resources<S: SectionStorage + 'static, L: UnifiedLogWrite<S> + 'static>(
@@ -3834,6 +3873,37 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
38343873
}
38353874
};
38363875

3876+
let new_with_resources_compat_fn = if sim_mode {
3877+
quote! {
3878+
pub fn new_with_resources<S: SectionStorage + 'static, L: UnifiedLogWrite<S> + 'static>(
3879+
clock: RobotClock,
3880+
unified_logger: Arc<Mutex<L>>,
3881+
app_resources: AppResources,
3882+
instance_id: u32,
3883+
sim_callback: &mut impl FnMut(SimStep) -> SimOverride,
3884+
) -> CuResult<Self> {
3885+
Self::build_with_resources(
3886+
clock,
3887+
unified_logger,
3888+
app_resources,
3889+
instance_id,
3890+
sim_callback,
3891+
)
3892+
}
3893+
}
3894+
} else {
3895+
quote! {
3896+
pub fn new_with_resources<S: SectionStorage + 'static, L: UnifiedLogWrite<S> + 'static>(
3897+
clock: RobotClock,
3898+
unified_logger: Arc<Mutex<L>>,
3899+
app_resources: AppResources,
3900+
instance_id: u32,
3901+
) -> CuResult<Self> {
3902+
Self::build_with_resources(clock, unified_logger, app_resources, instance_id)
3903+
}
3904+
}
3905+
};
3906+
38373907
let build_with_resources_fn = quote! {
38383908
#build_with_resources_sig {
38393909
let AppResources {
@@ -4002,9 +4072,10 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
40024072
}
40034073

40044074
#prepare_config_fn
4005-
4075+
#prepare_resources_compat_fn
40064076
#prepare_resources_fn
4007-
4077+
#init_resources_compat_fn
4078+
#new_with_resources_compat_fn
40084079
#build_with_resources_fn
40094080

40104081
/// Mutable access to the underlying runtime (used by tools such as deterministic re-sim).
@@ -4149,7 +4220,7 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
41494220
};
41504221

41514222
let builder_prepare_config_call = if std {
4152-
quote! { #application_name::prepare_config(self.config_override)? }
4223+
quote! { #application_name::prepare_config(self.instance_id, self.config_override)? }
41534224
} else {
41544225
quote! {{
41554226
let _ = self.config_override;
@@ -4337,6 +4408,20 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
43374408
None
43384409
};
43394410

4411+
let builder_with_unified_logger_method = if std {
4412+
Some(quote! {
4413+
#[allow(dead_code)]
4414+
pub fn with_unified_logger(
4415+
self,
4416+
unified_logger: Arc<Mutex<UnifiedLoggerWrite>>,
4417+
) -> #builder_name<#builder_log_path_generics> {
4418+
self.with_logger::<MmapSectionStorage, UnifiedLoggerWrite>(unified_logger)
4419+
}
4420+
})
4421+
} else {
4422+
None
4423+
};
4424+
43404425
// backward compat on std non-parameterized impl.
43414426
let std_application_impl = if sim_mode {
43424427
// sim mode
@@ -4422,6 +4507,8 @@ pub fn copper_runtime(args: TokenStream, input: TokenStream) -> TokenStream {
44224507
}
44234508
}
44244509

4510+
#builder_with_unified_logger_method
4511+
44254512
#[allow(dead_code)]
44264513
pub fn with_instance_id(mut self, instance_id: u32) -> Self {
44274514
self.instance_id = instance_id;
@@ -4827,20 +4914,23 @@ fn build_config_load_stmt(
48274914
subsystem_id
48284915
);
48294916
let multi_config = cu29::config::read_multi_configuration(config_filename)?;
4830-
let subsystem = multi_config.subsystem(subsystem_id).ok_or_else(|| {
4831-
CuError::from(format!(
4832-
"Multi-Copper configuration '{}' does not define subsystem '{}'.",
4833-
config_filename,
4834-
subsystem_id
4835-
))
4836-
})?;
4837-
(subsystem.config.clone(), RuntimeLifecycleConfigSource::ExternalFile)
4917+
(
4918+
multi_config.resolve_subsystem_config_for_instance(subsystem_id, instance_id)?,
4919+
RuntimeLifecycleConfigSource::ExternalFile,
4920+
)
48384921
} else {
48394922
let original_config = Self::original_config();
48404923
debug!(
48414924
"CuConfig: Using the bundled subsystem configuration compiled into the binary (subsystem={}).",
48424925
#subsystem_id
48434926
);
4927+
if instance_id != 0 {
4928+
debug!(
4929+
"CuConfig: runtime file '{}' is missing, so instance-specific overrides for instance_id={} cannot be resolved; using bundled subsystem defaults.",
4930+
config_filename,
4931+
instance_id
4932+
);
4933+
}
48444934
(
48454935
cu29::config::read_configuration_str(original_config, None)?,
48464936
RuntimeLifecycleConfigSource::BundledDefault,
@@ -4849,6 +4939,7 @@ fn build_config_load_stmt(
48494939
}
48504940
} else {
48514941
quote! {
4942+
let _ = instance_id;
48524943
let (config, config_source) = if let Some(overridden_config) = config_override {
48534944
debug!("CuConfig: Overridden programmatically.");
48544945
(overridden_config, RuntimeLifecycleConfigSource::ProgrammaticOverride)

0 commit comments

Comments
 (0)