From 69dab192124a26919e911b4156005d8aef7b53c3 Mon Sep 17 00:00:00 2001 From: gmegh Date: Mon, 22 Jul 2024 11:34:01 -0700 Subject: [PATCH] Update to use ts_ofc v3.2.0 --- bin.src/img_closed_loop.py | 1 + doc/versionHistory.rst | 6 ++++ policy/config/controllers/oic_controller.yaml | 30 +++++++++++++++++++ policy/config/controllers/pid_controller.yaml | 28 +++++++++++++++++ python/lsst/ts/imsim/closed_loop_task.py | 28 +++++++++++++---- tests/test_closed_loop_task.py | 3 +- 6 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 policy/config/controllers/oic_controller.yaml create mode 100644 policy/config/controllers/pid_controller.yaml diff --git a/bin.src/img_closed_loop.py b/bin.src/img_closed_loop.py index 93461a9..88f9e75 100644 --- a/bin.src/img_closed_loop.py +++ b/bin.src/img_closed_loop.py @@ -56,6 +56,7 @@ args.iter_num, args.pipeline_file, args.config_pointer_file, + args.controller_config_file, args.turn_off_sky_background, args.turn_off_atmosphere, args.turn_off_wavefront_estimates, diff --git a/doc/versionHistory.rst b/doc/versionHistory.rst index 50e874d..c3a9f9b 100644 --- a/doc/versionHistory.rst +++ b/doc/versionHistory.rst @@ -5,6 +5,12 @@ ################## Version History ################## +------------- +1.6.0 +------------- + +* Update to use ts_ofc version 3.2.0. + ------------- 1.5.6 ------------- diff --git a/policy/config/controllers/oic_controller.yaml b/policy/config/controllers/oic_controller.yaml new file mode 100644 index 0000000..e1a82a6 --- /dev/null +++ b/policy/config/controllers/oic_controller.yaml @@ -0,0 +1,30 @@ +# Description: Optimal Integral Controller (OIC) configuration file +# +# Name: OIC +# xref is the reference to the controller, it can be ['x0', 'x00', '0'] +# kp is the proportional gain +# ki is the integral gain defined as ki = kp*T/T_i +# kd is the derivative gain defined as kd = kp*T_d/T +# derivative_filter_coeff is the coefficient of the derivative filter +# setpoint is the setpoint for each degree of freedom (array of 50 elements) + +description: Optimal Integral Controller (OIC) + +name: OIC +xref: x00 +kp: -1.0 +ki: 0 +kd: 0 +derivative_filter_coeff: 1.0 +setpoint: [ + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0 +] diff --git a/policy/config/controllers/pid_controller.yaml b/policy/config/controllers/pid_controller.yaml new file mode 100644 index 0000000..0171b70 --- /dev/null +++ b/policy/config/controllers/pid_controller.yaml @@ -0,0 +1,28 @@ +# Description: Proportional-Integral-Derivative Controller (PID) configuration file +# +# Name: PID +# kp is the proportional gain +# ki is the integral gain defined as ki = kp*T/T_i +# kd is the derivative gain defined as kd = kp*T_d/T +# derivative_filter_coeff is the coefficient of the derivative filter +# setpoint is the setpoint for each degree of freedom (array of 50 elements) + +description: Proportional-Integral-Derivative Controller + +name: PID +kp: 0.9 +ki: 0.0 +kd: 0.0 +derivative_filter_coeff: 1.0 +setpoint: [ + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0 +] diff --git a/python/lsst/ts/imsim/closed_loop_task.py b/python/lsst/ts/imsim/closed_loop_task.py index b026c3c..cfa3982 100644 --- a/python/lsst/ts/imsim/closed_loop_task.py +++ b/python/lsst/ts/imsim/closed_loop_task.py @@ -27,6 +27,7 @@ from argparse import ArgumentParser from copy import deepcopy from glob import glob +from pathlib import Path import astropy import numpy as np @@ -186,7 +187,7 @@ def _set_sky_sim_based_on_opd_field_pos( ) star_id += 1 - def config_ofc_calc(self, cam_type: CamType) -> None: + def config_ofc_calc(self, cam_type: CamType, controller_config_file: str) -> None: """Configure the OFC calculator. OFC: Optical feedback calculator. @@ -195,9 +196,15 @@ def config_ofc_calc(self, cam_type: CamType) -> None: ---------- cam_type : lsst.ts.imsim.utils.CamType Camera type. + controller_config_file : str + Controller configuration file. """ - self.ofc_calc = OFC(OFCData(cam_type.value)) + ofc_data = OFCData(cam_type.value) + ofc_data.controller_filename = ( + Path(get_config_dir()) / "controllers" / controller_config_file + ) + self.ofc_calc = OFC(ofc_data) self.ofc_calc.ofc_data.znmin = 4 self.ofc_calc.ofc_data.zn_selected = np.arange( self.ofc_calc.ofc_data.znmin, self.max_noll_index + 1 @@ -387,7 +394,7 @@ def _run_sim( code will just default to sending it to stdout. (The default is "".) """ - state_0 = self.ofc_calc.ofc_controller.aggregated_state + state_0 = self.ofc_calc.controller.aggregated_state self.imsim_cmpt.dof_in_um = state_0 # If using wavefront sensors we measure one per pair @@ -541,12 +548,11 @@ def _run_sim( wfe=wfe, sensor_names=sensor_names, filter_name=obs_metadata.band.upper(), - gain=-1, rotation_angle=obs_metadata.rotator_angle, ) # Set the new aggregated DOF to phosimCmpt - dof_in_um = self.ofc_calc.ofc_controller.aggregated_state + dof_in_um = self.ofc_calc.controller.aggregated_state self.imsim_cmpt.dof_in_um = dof_in_um # Save the DOF file @@ -1015,6 +1021,7 @@ def run_img( iter_num: int, pipeline_file: str, imsim_config_pointer_file: str, + controller_config_file: str, turn_off_sky_background: bool, turn_off_atmosphere: bool, turn_off_wavefront_estimates: bool, @@ -1059,6 +1066,8 @@ def run_img( Path to pointer file with locations of yaml configuration files for imsim submodules. If empty string then the code will use the default in policy/config for the given inst. + controller_config_file : str + Path to the controller configuration file. turn_off_sky_background : bool If set to True then the closed loop will simulate images without sky background. @@ -1108,7 +1117,7 @@ def run_img( self.config_sky_sim( cam_type, obs_metadata, path_sky_file=path_sky_file, star_mag=star_mag ) - self.config_ofc_calc(cam_type) + self.config_ofc_calc(cam_type, controller_config_file) self.imsim_cmpt = ImsimCmpt( num_of_zk=self.max_noll_index - self.ofc_calc.ofc_data.znmin + 1 ) @@ -1332,6 +1341,13 @@ def set_default_parser(parser: ArgumentParser) -> ArgumentParser: help="Imsim Configuration Pointer File.", ) + parser.add_argument( + "--controller_config_file", + type=str, + default="oic_controller.yaml", + help="Path to the controller configuration file.", + ) + parser.add_argument( "--sky_seed", type=int, diff --git a/tests/test_closed_loop_task.py b/tests/test_closed_loop_task.py index a3eda20..e34ee3e 100644 --- a/tests/test_closed_loop_task.py +++ b/tests/test_closed_loop_task.py @@ -70,7 +70,7 @@ def test_config_sky_sim_with_sky_file(self): def test_config_ofc_calc(self): cam_type = CamType.LsstCam self.closed_loop_task.max_noll_index = 28 - self.closed_loop_task.config_ofc_calc(cam_type) + self.closed_loop_task.config_ofc_calc(cam_type, "oic_controller.yaml") ofc_calc = self.closed_loop_task.ofc_calc self.assertEqual(ofc_calc.ofc_data.name, "lsst") @@ -131,6 +131,7 @@ def test_set_default_parser(self): self.assertEqual(args.output, "") self.assertFalse(args.clobber) self.assertEqual(args.config_pointer_file, "") + self.assertEqual(args.controller_config_file, "oic_controller.yaml") self.assertEqual(args.pipeline_file, "") self.assertEqual(args.sky_seed, 42) self.assertEqual(args.pert_seed, 11)