Esempio n. 1
0
    def testWindModel(self):
        overrides_in = {
            'sim': {
                'phys_sim': {
                    'wind_model': sim_types.kWindModelDrydenTurbulence,
                },
            },
        }
        overrides_out = overrides_util.PreprocessOverrides(overrides_in)
        self.assertEqual(sim_types.kWindModelDrydenTurbulence,
                         overrides_out['sim']['phys_sim']['wind_model'])

        overrides_in = {
            'sim': {
                'phys_sim': {
                    'wind_model': 'DrydenTurbulence',
                },
            },
        }
        overrides_out = overrides_util.PreprocessOverrides(overrides_in)
        self.assertEqual(sim_types.kWindModelDrydenTurbulence,
                         overrides_out['sim']['phys_sim']['wind_model'])

        overrides_in = {
            'sim': {
                'phys_sim': {
                    'wind_model': 'NotAWindModel',
                },
            },
        }
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(overrides_in)
Esempio n. 2
0
    def testFaultsSimError(self):
        overrides_in = {
            'sim': {
                'faults_sim': [{
                    't_start': 100.0,
                    'component': 'Pitot/actual_P_dyn',
                    'type': 'kSimFaultMeasurementRescale',
                }] * (1 + sim_types.MAX_FAULT_EVENTS)
            }
        }
        with self.assertRaises(overrides_util.InvalidArrayLength):
            overrides_util.PreprocessOverrides(overrides_in)

        overrides_in = {
            'sim': {
                'faults_sim': [{
                    't_start':
                    100.0,
                    'component':
                    'Pitot/actual_P_dyn',
                    'type':
                    'kSimFaultMeasurementRescale',
                    'parameters':
                    [0.0] * (1 + sim_types.MAX_FAULT_EVENT_PARAMETERS)
                }]
            }
        }
        with self.assertRaises(overrides_util.InvalidArrayLength):
            overrides_util.PreprocessOverrides(overrides_in)
Esempio n. 3
0
    def testWindSpeedUpdates(self):
        updates_in = [{
            't_update': 20.0,
            'offset': -5.0
        }, {
            't_update': 40.0,
            'offset': 10.0
        }]

        overrides_struct = {
            'sim': {
                'phys_sim': {
                    'wind_speed_update': updates_in
                }
            }
        }
        overrides = overrides_util.PreprocessOverrides(overrides_struct)

        self.assertTrue(
            'num_updates' in overrides['sim']['phys_sim']['wind_speed_update']
            and 'offsets' in overrides['sim']['phys_sim']['wind_speed_update'])
        self.assertEqual(
            2,
            overrides['sim']['phys_sim']['wind_speed_update']['num_updates'])
        self.assertEqual(
            sim_types.MAX_WIND_SPEED_UPDATES,
            len(overrides['sim']['phys_sim']['wind_speed_update']['offsets']))
Esempio n. 4
0
 def testSimOpt(self):
     overrides_struct = {'sim': {'sim_opt': ['kSimOptImperfectSensors', 1]}}
     overrides = overrides_util.PreprocessOverrides(overrides_struct)
     self.assertIn('sim', overrides)
     self.assertIn('sim_opt', overrides['sim'])
     self.assertEqual(1 | sim_types.kSimOptImperfectSensors,
                      overrides['sim']['sim_opt'])
Esempio n. 5
0
 def testJoystickSimError(self):
     overrides_in = {
         'sim': {
             'joystick_sim': {
                 'updates': [{
                     't_update': 100.0,
                     'type': 'kSimJoystickUpdateSwitchMiddle'
                 }] * (1 + sim_types.MAX_JOYSTICK_UPDATES)
             }
         }
     }
     with self.assertRaises(overrides_util.InvalidArrayLength):
         overrides_util.PreprocessOverrides(overrides_in)
Esempio n. 6
0
    def testJoystickSimJoystickType(self):
        overrides_struct = {
            'sim': {
                'joystick_sim': {
                    'joystick_type': 'Hardware'
                }
            }
        }
        overrides = overrides_util.PreprocessOverrides(overrides_struct)

        self.assertTrue(
            'sim' in overrides and 'joystick_sim' in overrides['sim']
            and 'joystick_type' in overrides['sim']['joystick_sim'])
        self.assertEqual(sim_types.kSimJoystickTypeHardware,
                         overrides['sim']['joystick_sim']['joystick_type'])
Esempio n. 7
0
    def testFaultsSim(self):
        faults_in = [{
            't_start': 100.0,
            't_end': 200.0,
            'component': 'Pitot/actual_P_dyn',
            'type': 'kSimFaultMeasurementRescale',
            'parameters': [1.0, 2.0, 3.0],
        }, {
            't_start': 100.0,
            'component': 'Pitot/actual_P_dyn',
            'type': 'kSimFaultMeasurementRescale',
        }]

        overrides_struct = {'sim': {'faults_sim': faults_in}}
        overrides = overrides_util.PreprocessOverrides(overrides_struct)

        # Check the overall structure of the created fields.
        self.assertTrue(
            'sim' in overrides and 'faults_sim' in overrides['sim']
            and 'num_fault_events' in overrides['sim']['faults_sim']
            and 'fault_events' in overrides['sim']['faults_sim'])
        self.assertEqual(2, overrides['sim']['faults_sim']['num_fault_events'])

        faults_out = overrides['sim']['faults_sim']['fault_events']
        self.assertEqual(sim_types.MAX_FAULT_EVENTS, len(faults_out))

        # Check the fault events that we specified.
        for (fault_in, fault_out) in zip(faults_in,
                                         faults_out[:len(faults_in)]):
            self.assertEqual(fault_in['component'], fault_out['component'])
            self.assertEqual(sim_types.kSimFaultMeasurementRescale,
                             fault_out['type'])

            if 'parameters' in fault_in:
                params_in = fault_in['parameters']
                params_out = fault_out['parameters']
                self.assertEqual(sim_types.MAX_FAULT_EVENT_PARAMETERS,
                                 len(params_out))
                self.assertEqual(params_in, params_out[:len(params_in)])
            else:
                self.assertEqual([0.0] * sim_types.MAX_FAULT_EVENT_PARAMETERS,
                                 fault_out['parameters'])

        # Check basic reasonableness of the unused faults.
        for fault in faults_out[len(faults_in):]:
            self.assertEqual(sim_types.kSimFaultNoFault, fault['type'])
            self.assertEqual(sim_types.MAX_FAULT_EVENT_PARAMETERS,
                             len(fault['parameters']))
Esempio n. 8
0
    def testJoystickSimUpdates(self):
        updates_in = [{
            't_update': 100.0,
            'type': 'kSimJoystickUpdateSwitchMiddle'
        }, {
            't_update': 100.0,
            'type': 'kSimJoystickUpdateThrottle',
            'enum_value': 'kSimJoystickThrottleManual',
            'value': 22.0
        }, {
            't_update': 200.0,
            'type': 'kSimJoystickUpdateThrottle',
            'enum_value': 'kSimJoystickThrottleCrosswindNormal'
        }, {
            't_update': 200.0,
            'type': 'kSimJoystickUpdateThrottle',
            'enum_value': 'kSimJoystickThrottleCrosswindNormal',
            'value': -1.0
        }, {
            't_update': 200.0,
            'type': 'kSimJoystickUpdateSwitchMiddle',
            'enum_value': 0
        }]

        overrides_struct = {'sim': {'joystick_sim': {'updates': updates_in}}}
        overrides = overrides_util.PreprocessOverrides(overrides_struct)

        self.assertTrue('sim' in overrides
                        and 'joystick_sim' in overrides['sim']
                        and 'num_updates' in overrides['sim']['joystick_sim']
                        and 'updates' in overrides['sim']['joystick_sim'])
        self.assertEqual(5, overrides['sim']['joystick_sim']['num_updates'])
        self.assertEqual(sim_types.MAX_JOYSTICK_UPDATES,
                         len(overrides['sim']['joystick_sim']['updates']))

        self.assertEqual(
            0.0, overrides['sim']['joystick_sim']['updates'][0]['value'])

        for update in overrides['sim']['joystick_sim']['updates'][
                len(updates_in):]:
            self.assertEqual(sim_types.kSimJoystickUpdateNone, update['type'])
Esempio n. 9
0
            assert False, '--input_file must be specified for --type=monitor.'
        elif FLAGS.type == 'sim':
            assert False, '--input_file must be specified for --type=sim.'
        elif FLAGS.type == 'system':
            assert False, '--input_file must be specified for --type=system.'
        else:
            assert False, '--type was not properly validated.'

    # Convert a configuration filename to the equivalent module name by
    # remove the beginning "config/" and the trailing ".py", and then
    # replacing "/" with ".".
    module_str = FLAGS.input_file[7:-3].replace('/', '.')

    # Parse overrides command line option.
    if FLAGS.overrides:
        overrides = overrides_util.PreprocessOverrides(
            json.loads(FLAGS.overrides))
    else:
        overrides = {}

    # Make a parameters dict from the configuration files.
    params = mconfig.MakeParams(module_str,
                                overrides=overrides,
                                override_method='derived')

    # Write parameters to the output_file or to stdout.
    if FLAGS.output_file is None:
        print params
    else:
        if FLAGS.type == 'json':
            WriteJsonParams(params, FLAGS.output_file)
        elif FLAGS.type == 'control':
Esempio n. 10
0
    def __init__(self, **kwargs):
        base_params = mconfig.MakeParams('common.all_params',
                                         overrides=None,
                                         override_method='simple')

        # Time [s] to end simulation.
        if FLAGS.flight_plan == 'TurnKey':
            end_time = 1500.0
        elif FLAGS.flight_plan == 'HighHover':
            end_time = 1000.0
        else:
            assert False, 'Unsupported flight plan: %s' % FLAGS.flight_plan

        flight_plan = 'kFlightPlan' + FLAGS.flight_plan

        # Build the list of tables.

        raw_base_overrides = {
            'system': {
                'flight_plan': flight_plan
            },
            'sim': {
                'phys_sim': {
                    'wind_model': ('kWindModelDatabase' if FLAGS.turbsim_folder
                                   else FLAGS.wind_model)
                },
                'telemetry_sample_period':
                0.0,
                'sim_opt': [
                    'kSimOptExitOnCrash', 'kSimOptFaults',
                    'kSimOptGroundContact', 'kSimOptImperfectSensors',
                    'kSimOptPerch', 'kSimOptPerchContact',
                    'kSimOptStackedPowerSystem'
                ],
                'sim_time':
                end_time
            }
        }

        # Only use sensor imperfections in Monte Carlo simulations.
        if FLAGS.monte_carlo:
            raw_base_overrides['sim']['sim_opt'] += ['kSimOptImperfectSensors']

        if FLAGS.offshore:
            raw_base_overrides['system']['test_site'] = 'kTestSiteNorway'
        else:
            raw_base_overrides['system']['test_site'] = 'kTestSiteParkerRanch'

        # Update raw_base_overrides with flag base_overrides.
        raw_base_overrides = dict_util.UpdateNestedDict(
            raw_base_overrides, json.loads(FLAGS.base_overrides))

        if ('system' in raw_base_overrides
                and 'wing_serial' in raw_base_overrides['system']):
            assert False, (
                'Cannot override wing_serial; '
                'it is set implicitly by flight plan and wing_model.')

        y_ranges = []

        if FLAGS.turbsim_folder:
            # Initialize object for selecting appropriate wind databases for each run.
            turbsim_database_selector = turbsim_util.TurbSimDatabaseSelector(
                FLAGS.turbsim_folder, base_params)

            # TODO: Rather than hardcode the shear reference height,
            # pull from a database/file with properties of each database set.
            # Also think about overriding this value in the base_params.
            x_range = parameter_tables.WindSpeedParameterRange(
                FLAGS.wind_speeds, wind_shear_ref_height_agl=21.0)

            if FLAGS.monte_carlo:
                # TODO: Pull the range of options for these from a
                # database/file with properties of each database set. Would need to be
                # able to query a sheet w/ these parameters; maybe make a descriptive
                # csv or json file in each database folder.
                y_ranges += [
                    parameter_tables.WindDatabaseInitialTimeParameterRange(
                        [30.0, 270.0],
                        distribution={
                            'lower_bound': 30.0,
                            'upper_bound': 270.0,
                            'type': 'uniform'
                        }),
                    parameter_tables.WindDatabaseYOffsetParameterRange(
                        [-100.0, 100.0],
                        distribution={
                            'lower_bound': -100.0,
                            'upper_bound': 100.0,
                            'type': 'uniform'
                        }),
                ]

        else:
            turbsim_database_selector = None

            # Sweep wind speeds.
            # If times for wind speed updates are specified (a 3-by-1 list of time
            # values in seconds), then saturate the mean wind speed to
            # FLAGS.max_hover_mean_wind_speed before the second time entry and after
            # the third time entry.
            # NOTE:
            # - This flag will not affect simulations which use a TurbSim database.
            # - Here, the second value in t_updates corresponds to the approximate
            #   time when the kite enters crosswind, and the third value is the time
            #   when the joystick throttle is updated to
            #   kSimJoystickThrottleReturnToPerch.
            x_range = parameter_tables.WindSpeedParameterRange(
                FLAGS.wind_speeds,
                wind_shear_ref_height_agl=base_params['sim']['phys_sim']
                ['wind_shear_ref_height_agl'],
                t_updates=[0.0, 460.0, 820.0],
                max_wind_speed=FLAGS.max_hover_mean_wind_speed)

            # Sweep environmental properties.
            # Original source for WindElevation is unknown.
            # TODO: Update WindElevation distribution based on Parker Ranch
            # wind measurements.
            # Wind veer range is based on Parker Ranch wind measurements as discussed
            # in http://b/117942530.
            y_ranges += [
                parameter_tables.WindElevationDegParameterRange([-6.0, 6.0],
                                                                distribution={
                                                                    'mean':
                                                                    0.0,
                                                                    'sigma':
                                                                    3.0,
                                                                    'bound':
                                                                    2.0,
                                                                    'type':
                                                                    'normal'
                                                                }),
                parameter_tables.WindVeerDegParameterRange(
                    [-45.0, -21.0, 21.0, 45.0],
                    distribution={
                        'mean': 13.5,
                        'sigma': 7.5,
                        'bound': 3.0,
                        'type': 'normal'
                    }),
            ]

        shear_parameter_range = parameter_tables.WindShearExponentParameterRange(
            FLAGS.wind_shears)
        # Add shear exponents as a sweep if this is not a Monte Carlo run.
        if not FLAGS.monte_carlo:
            y_ranges.append(shear_parameter_range)

        # Sweep mass properties.
        y_ranges += [
            # Center of mass location: maximum 0.05 m error in each dimension for
            # Monte Carlo sweeps, and 0.05 m variation in crosswind parameters
            # sweeps.
            parameter_tables.CenterOfMassOffsetParameterRange(
                0, [-0.05, 0.05],
                distribution={
                    'mean': 0.0,
                    'sigma': 0.025,
                    'bound': 2.0,
                    'type': 'normal'
                },
                body='wing_sim',
                body_name='Wing'),
            parameter_tables.CenterOfMassOffsetParameterRange(
                1, [-0.05, 0.05],
                distribution={
                    'mean': 0.0,
                    'sigma': 0.025,
                    'bound': 2.0,
                    'type': 'normal'
                },
                body='wing_sim',
                body_name='Wing'),
            parameter_tables.CenterOfMassOffsetParameterRange(
                2, [-0.05, 0.05],
                distribution={
                    'mean': 0.0,
                    'sigma': 0.025,
                    'bound': 2.0,
                    'type': 'normal'
                },
                body='wing_sim',
                body_name='Wing'),
            # Mass scaling: 1.4% error for both Monte Carlo and crosswind sweeps.
            parameter_tables.MassScaleParameterRange([0.986, 1.014],
                                                     distribution={
                                                         'mean': 1.0,
                                                         'sigma': 0.014,
                                                         'bound': 2.0,
                                                         'type': 'normal'
                                                     },
                                                     body='wing_sim',
                                                     body_name='Wing'),
            # Inertia scaling: maximum errors for Monte Carlo sweeps of 5% for Ixx,
            # 2% for Iyy and 4.4% for Izz. 10% variation in crosswind sweeps.
            parameter_tables.InertiaScaleParameterRange(0, [0.90, 1.1],
                                                        distribution={
                                                            'mean': 1.0,
                                                            'sigma': 0.025,
                                                            'bound': 2.0,
                                                            'type': 'normal'
                                                        },
                                                        body='wing_sim',
                                                        body_name='Wing'),
            parameter_tables.InertiaScaleParameterRange(1, [0.90, 1.1],
                                                        distribution={
                                                            'mean': 1.0,
                                                            'sigma': 0.01,
                                                            'bound': 2.0,
                                                            'type': 'normal'
                                                        },
                                                        body='wing_sim',
                                                        body_name='Wing'),
            parameter_tables.InertiaScaleParameterRange(2, [0.90, 1.1],
                                                        distribution={
                                                            'mean': 1.0,
                                                            'sigma': 0.022,
                                                            'bound': 2.0,
                                                            'type': 'normal'
                                                        },
                                                        body='wing_sim',
                                                        body_name='Wing'),
        ]

        # Sweep aerodynamics parameters.
        # The following parameters override existing aerodynamic offsets in our
        # config files.
        if FLAGS.wing_model == 'm600':
            y_ranges += [
                # CD offset: maximum 0.050 error.
                # Known offset in CD from RPX-07 glide data analysis is 0.075.
                # Use 0.075 as mean for Monte Carlo sweeps.
                # This is chosen since this will override existing offsets.
                # [0.075 - 0.050, 0.075 + 0.050] variation in crosswind sweeps.
                parameter_tables.AeroSimOffsetParameterRange(
                    'CD', [0.025, 0.125],
                    distribution={
                        'mean': 0.075,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    }),
                # CL offset: maximum 0.3 error for Monte Carlo sweeps,
                # 0.2 variation in crosswind sweeps.
                # Flight data and aero database comparison shows CL is over predicted,
                # thus setting the mean at -0.125 from Monte Carlo sweeps.
                parameter_tables.AeroSimOffsetParameterRange(
                    'CL', [-0.2, 0.2],
                    distribution={
                        'mean': -0.125,
                        'sigma': 0.15,
                        'bound': 2.0,
                        'type': 'normal'
                    }),
            ] + parameter_sweeps.GetAeroDerivativeParameterRanges()
        elif FLAGS.wing_model == 'oktoberkite':
            y_ranges += [
                parameter_tables.AeroSimOffsetParameterRange(
                    'CD', [-0.011, 0.033],
                    distribution={
                        'mean': 0.011,
                        'sigma': 0.011,
                        'bound': 2.0,
                        'type': 'normal'
                    }),
                parameter_tables.AeroSimOffsetParameterRange(
                    'CL', [-0.275, 0.275],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.15,
                        'bound': 2.0,
                        'type': 'normal'
                    }),
            ] + parameter_sweeps.GetAeroDerivativeParameterRanges()
        else:
            assert False, '{} wing_model is not supported.'.format(
                FLAGS.wing_model)

        # Sweep Pitot parameters.
        y_ranges += [
            # Pitot angles offsets: maximum 1 deg offset for Monte Carlo and
            # crosswind sweeps.
            # Pitot Cp offset: maximum 0.01 offset for Monte Carlo and
            # 0.02 variation in crosswind sweeps.
            parameter_tables.PitotPitchDegParameterRange([-1.0, 1.0],
                                                         distribution={
                                                             'mean': 0.0,
                                                             'sigma': 0.5,
                                                             'bound': 2.0,
                                                             'type': 'normal'
                                                         }),
            parameter_tables.PitotYawDegParameterRange([-1.0, 1.0],
                                                       distribution={
                                                           'mean': 0.0,
                                                           'sigma': 0.5,
                                                           'bound': 2.0,
                                                           'type': 'normal'
                                                       }),
            parameter_tables.PitotCpOffsetParameterRange([-0.02, 0.02],
                                                         distribution={
                                                             'mean': 0.0,
                                                             'sigma': 0.01,
                                                             'bound': 2.0,
                                                             'type': 'normal'
                                                         }),
        ]

        # Sweep actuator parameters.
        y_ranges += parameter_sweeps.GetFlapOffsetParameterRanges()

        # Sweep offshore parameters.
        if FLAGS.offshore:
            # Current uncertainties:
            #   - 5% on mass properties.
            #   - 5% on hydrodynamic model parameters.
            #   - 5% on mooring line model parameters.
            #   - 5 deg on yaw equilibrium heading.
            #   - 50 cm on axial mooring line attachment point model.
            #   - 20 cm on orthogonal mooring line attachment point model.
            # TODO: Refine the parameter variations once we have measured
            # data and knowledge of sensitivity.
            # TODO: Add a deterministic offshore crosswind sweep to the
            # nightly (b/137648033).
            y_ranges += [
                # Center of mass offset.
                parameter_tables.CenterOfMassOffsetParameterRange(
                    0, [-0.2, 0.2],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.1,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    body='buoy_sim',
                    body_name='Buoy'),
                parameter_tables.CenterOfMassOffsetParameterRange(
                    1, [-0.2, 0.2],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.1,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    body='buoy_sim',
                    body_name='Buoy'),
                parameter_tables.CenterOfMassOffsetParameterRange(
                    2, [-1.0, 1.0],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.39,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    body='buoy_sim',
                    body_name='Buoy'),

                # Mass scaling.
                parameter_tables.MassScaleParameterRange([0.9, 1.1],
                                                         distribution={
                                                             'mean': 1.0,
                                                             'sigma': 0.025,
                                                             'bound': 2.0,
                                                             'type': 'normal'
                                                         },
                                                         body='buoy_sim',
                                                         body_name='Buoy'),

                # Inertia scaling.
                parameter_tables.InertiaScaleParameterRange(0, [0.9, 1.1],
                                                            distribution={
                                                                'mean': 1.0,
                                                                'sigma': 0.025,
                                                                'bound': 2.0,
                                                                'type':
                                                                'normal'
                                                            },
                                                            body='buoy_sim',
                                                            body_name='Buoy'),
                parameter_tables.InertiaScaleParameterRange(1, [0.9, 1.1],
                                                            distribution={
                                                                'mean': 1.0,
                                                                'sigma': 0.025,
                                                                'bound': 2.0,
                                                                'type':
                                                                'normal'
                                                            },
                                                            body='buoy_sim',
                                                            body_name='Buoy'),
                parameter_tables.InertiaScaleParameterRange(2, [0.9, 1.1],
                                                            distribution={
                                                                'mean': 1.0,
                                                                'sigma': 0.025,
                                                                'bound': 2.0,
                                                                'type':
                                                                'normal'
                                                            },
                                                            body='buoy_sim',
                                                            body_name='Buoy'),

                # Hydrodynamic model uncertainties.
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Torsional Damping X Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='torsional_damping_x_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Torsional Damping Y Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='torsional_damping_y_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Torsional Damping Z Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='torsional_damping_z_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Buoyancy Damping Coeff. Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='buoyancy_damping_coeff_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Added Mass Coeff. Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='Ca_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Effective Heave Diameter Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='Dh_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Added Inertia Coeff. Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='hydrodynamics',
                    variable='ki_scale'),

                # Mooring line model uncertainties.
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Equilibrium Yaw Angle Delta [deg]',
                    np.arange(-180., 180., 30.),
                    distribution={
                        'mean': 0.0,
                        'sigma': 2.5,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='yaw_equilibrium_heading_delta'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Yaw Torsional Stiffness Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='torsional_stiffness_z_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Effective Mooring Line X Attachment Delta [m]',
                    [-0.2, 0.2],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.1,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='mooring_attach_pos_x_delta'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Effective Mooring Line Y Attachment Delta [m]',
                    [-0.2, 0.2],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.1,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='mooring_attach_pos_y_delta'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Effective Mooring Line Z Attachment Delta [m]',
                    [-0.5, 0.5],
                    distribution={
                        'mean': 0.0,
                        'sigma': 0.25,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='mooring_attach_pos_z_delta'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Mooring Line Linear Spring Coeff. Scale [#]',
                    [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='kt0_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Mooring Line Quadratic Spring Coeff. Scale [#]',
                    [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='kt1_scale'),
                parameter_tables.BuoyModelParameterRange(
                    'Buoy Mooring Line Damping Coeff. Scale [#]', [0.9, 1.1],
                    distribution={
                        'mean': 1.0,
                        'sigma': 0.025,
                        'bound': 2.0,
                        'type': 'normal'
                    },
                    category='mooring_lines',
                    variable='ct_scale'),
            ]

            # Sweep environmental properties.
            # Air density at Stavanger test site is 1.220 kg/m^3.
            # Use this as mean value and maximum 5% error
            # in density measurement for Monte Carlo sweeps. For crosswind sweeps,
            # high limit is at sea-level density and low limit is at roughly 2500 m
            # density altitude.
            # NOTE: Ideally, we would like to point the mean value of
            # the air density parameter range to the air_density in the config
            # structure. However, it is a parameter that is derived from the test_site
            # param, which is also overridden at the current level.
            y_ranges += [
                parameter_tables.AirDensityParameterRange([0.976, 1.225],
                                                          distribution={
                                                              'mean': 1.220,
                                                              'sigma': 0.025,
                                                              'bound': 2.0,
                                                              'type': 'normal'
                                                          })
            ]

            # Parameters used to define the 'WaveParameterSelector' class used in
            # Monte Carlo analyses and define the distribution in the
            # parameter_tables. See the WaveParameterSelector and ParameterRange class
            # definitions in parameter_tables.py for more description.
            # Note, for example, that the 'mean' used in a lognormal distribution is
            # the mean of the underlying normal distribution, and can therefore be
            # outside the upper/lower_bounds.
            # Generated from Colab notebook: b/130682761#comment15
            # Source: 'NORA10_5922N_0509E.txt'
            # Data filtered for Jun to Sep, between hours of 6 and 20, and when
            # wind speed at 10 m is between 5 and 15 m/s.'
            # Overwriting the upper_bound of the significant wave height to 3.0 m
            # to account for wave envelope due to max significant wave height for
            # personnel transfers at sea: b/130682761#comment18
            wave_variation_params = {
                'peak_period': {
                    'correlation_fit': {
                        'coefficient': 1.186394,
                        'description': 'TP = coefficient * HS + intercept'
                        ' + (lognorm(mean, sigma) + loc)',
                        'intercept': 5.822409,
                        'lower_bound': 3.923101,
                        'upper_bound': 13.687049,
                    },
                    'description':
                    'Peak wave period of the total sea state, based on total sea '
                    'significant wave height.',
                    'distribution': {
                        'loc': -4.342332,
                        'lower_bound': -2.478684,
                        'mean': 1.384812,
                        'sigma': 0.405295,
                        'type': 'lognormal',
                        'upper_bound': 4.217562,
                    },
                    'label':
                    'Peak wave period variation [s]',
                    'values': [-2.478684, 4.217562],
                },
                'significant_height': {
                    'correlation_fit': {
                        'coefficient':
                        0.012127,
                        'description':
                        'HS = coefficient * speed^2 + intercept + (lognorm(mean, '
                        'sigma) + loc). Note the distribution is closer to '
                        'exponnorm, but lognorm should be close enough and keeps '
                        'things simpler.',
                        'intercept':
                        0.653568,
                        'lower_bound':
                        0.427477,
                        'upper_bound':
                        3.0,
                    },
                    'description':
                    'Significant wave height of the total sea state, '
                    'based on wind speed at 10 m.',
                    'distribution': {
                        'loc': -2.647313,
                        'lower_bound': -0.854369,
                        'mean': 0.953525,
                        'sigma': 0.196548,
                        'type': 'lognormal',
                        'upper_bound': 1.108073,
                    },
                    'label':
                    'Significant wave height variation [m]',
                    'values': [-0.854369, 1.108073],
                },
                'wave_wind_alignment': {
                    'description':
                    'Alignment [deg] of total sea peak wave direction minus wind '
                    'direction at 10 m. Corrected for use of wave heading '
                    'as wave-direction-of-travel.',
                    'distribution': {
                        'bound': 2.000000,
                        'mean': 191.708319,
                        'sigma': 51.891563,
                        'type': 'normal',
                    },
                    'label':
                    'Wave alignment [deg] relative to wind',
                    'values': [87.925192, 295.491445],
                },
                'wind_direction': {
                    'description': 'Measured at 10 m.',
                    'distribution': {
                        'distributions': [{
                            'mean': 170.364074,
                            'sigma': 29.122998,
                            'type': 'vonmises',
                            'units': 'deg',
                        }, {
                            'mean': 335.172882,
                            'sigma': 14.044122,
                            'type': 'vonmises',
                            'units': 'deg',
                        }],
                        'type':
                        'multimodal',
                        'weights': [0.510851, 0.489149],
                    },
                    'label': 'Wind direction [deg]',
                    'values': [170.364074, 335.172882],
                },
            }

            y_ranges += [
                parameter_tables.WindDirectionDegParameterRange(
                    wave_variation_params['wind_direction']['values'],
                    distribution=wave_variation_params['wind_direction']
                    ['distribution'])
            ]
            if FLAGS.randomize_waves:
                del wave_variation_params['wind_direction']
                for param in wave_variation_params:
                    y_ranges += [
                        parameter_tables.CustomParameterRange(
                            wave_variation_params[param]['label'],
                            ['sim', 'sea_sim', 'waves', param],
                            wave_variation_params[param]['values'],
                            wave_variation_params[param]['distribution'])
                    ]
                wave_parameter_selector = parameter_tables.WaveParameterSelector(
                    wave_variation_params)
            else:
                wave_parameter_selector = None
        else:
            wave_parameter_selector = None

            # Sweep environmental properties.
            # Air density at Parker Ranch test site is 1.026 kg/m^3. This is roughly
            # 1800 m density altitude. Use this as mean value and maximum 5% error
            # in density measurement for Monte Carlo sweeps. For crosswind sweeps,
            # high limit is at sea-level density and low limit is at roughly 2500 m
            # density altitude.
            y_ranges += [
                parameter_tables.AirDensityParameterRange([0.976, 1.225],
                                                          distribution={
                                                              'mean': 1.026,
                                                              'sigma': 0.025,
                                                              'bound': 2.0,
                                                              'type': 'normal'
                                                          })
            ]

            # Wind at Parker Ranch test site is nominally from the NorthEast.
            # From the initial analysis of our 2018 Aug-Oct Lidar data at the test
            # site, the mean is roughly at 55 degrees azimuth.
            # From the analysis presented in go/makani-cw09-wind-envelope, the
            # operational envelope for the wind direction was set to [0 - 75] degrees.
            # The normal distribution is clipped 5 degrees past these limits.
            # NOTE: Wind direction is an epistemic random variable that
            # we treat as an aleatory random variable to simplify the Monte Carlo
            # analysis.
            y_ranges += [
                parameter_tables.WindDirectionDegParameterRange(
                    [30, 80],
                    distribution={
                        'mean': 55.0,
                        'sigma': 15.0,
                        'lower_bound': -5.0,
                        'upper_bound': 80.0,
                        'type': 'normal'
                    })
            ]

        base_overrides = overrides_util.PreprocessOverrides(raw_base_overrides)

        # Wipe out existing y_range if only_custom_sweep flag is passed.
        if FLAGS.only_custom_sweep:
            y_ranges = []

        # Parse the custom_sweep flag.
        custom_sweep_entries = json.loads(FLAGS.custom_sweep)

        # Add custom sweep entries to y_ranges.
        for entry in custom_sweep_entries:
            y_ranges += [
                parameter_tables.CustomParameterRange(
                    entry['name'],
                    entry['path'],
                    # Values can be unspecified for monte-carlo usage.
                    entry.get('values', None),
                    # Distribution can be unspecifed for deterministic sweep usage.
                    entry.get('distribution', None))
            ]

        tables = []
        if FLAGS.monte_carlo:
            num_cols = len(x_range.values)

            for shear_exponent in shear_parameter_range.values:
                for value in x_range.values:
                    table_base_overrides = dict_util.MergeNestedDicts(
                        base_overrides, x_range.GetOverrides(value))
                    table_base_overrides = dict_util.MergeNestedDicts(
                        table_base_overrides,
                        shear_parameter_range.GetOverrides(shear_exponent))
                    tables.append(
                        parameter_tables.ParameterRangeMonteCarloTable(
                            'Monte Carlo %s = %g, shear exponent = %g' %
                            (x_range.label, x_range.GetDisplayValue(value),
                             shear_exponent),
                            [FLAGS.monte_carlo_cols, FLAGS.monte_carlo_rows],
                            y_ranges,
                            base_overrides=table_base_overrides,
                            turbsim_database_selector=turbsim_database_selector,
                            wave_parameter_selector=wave_parameter_selector))
            title = FLAGS.flight_plan + ' Monte Carlo'
        else:
            num_cols = 4
            for y_range in y_ranges:
                tables.append(
                    parameter_tables.ParameterRangeTable(
                        y_range.label,
                        x_range,
                        y_range,
                        base_overrides=base_overrides,
                        turbsim_database_selector=turbsim_database_selector))
            title = FLAGS.flight_plan + ' Parameter Sweeps'

        wing_model = wing_flag.FlagToWingModelName(FLAGS.wing_model)
        params = batch_sim_params.CrosswindSweepsParameters(
            flight_plan=flight_plan,
            wing_model=wing_model,
            offshore=FLAGS.offshore)
        super(CrosswindSweepsSimClient,
              self).__init__(FLAGS.output_dir,
                             tables,
                             params.scoring_functions,
                             title=title,
                             columns=num_cols,
                             **kwargs)
Esempio n. 11
0
    def __init__(self, **kwargs):
        # The scale of the disturbances were calculated based on the following.
        #
        # m = 1499  # Mass of the wing [kg].
        # g = 9.81  # Gravitational acceleration [m/s^2]
        # num_rotors = 8  # Number [#] of rotors.
        # V = 15  # Wind speed [m/s].
        # y_motor = 3.6  # Distance [m] to the COM from the outboard motors.
        # z_motor = 1.6  # Distance [m] to the COM from the bottom row motors.
        # Vgust = 4  # Increased wind speed [m/s] due to a gust.
        # Cd = 1.2  # Flat plate drag coefficient [#].
        # rho = 1.225  # Air density [kg / m^3].
        # c = 1.28  # Wing chord [m].
        # b = 26  # Wing span [m].
        # A_ele = 4  # Elevator area [m^2].
        # A_rud = 4  # Rudder area [m^2].
        # r_tail = 7  # Distance of tail from COM [m].
        #
        #
        # For roll we consider a gust on the tip of the wing:
        #
        # roll_disturbance = 0.5 * rho * Cd * c * (
        #     (V+Vgust)**2.0 * 0.5 * ((b/2.0)**2.0 - (0.75 * b/2.0)**2.0)
        #     - V**2.0 * 0.5 * ((b/2.0)**2.0 - (0.75 * b/2.0)**2.0))
        #
        # For pitch we consider the elevator suddenly shifting to be 90
        # deg to the wind or a bottom row motor suddenly being unable to
        # provide thrust.
        #
        # pitch_disturbance = [0.5 * rho * Cd * A_ele * V**2 * r_tail,
        #                      z_motor * m * g / num_rotors]
        #
        # For yaw we consider a sudden 45 deg. shift in wind conditions
        # hitting the rudder or an outboard propellor suddenly being
        # unable to provide thrust.
        #
        # yaw_disturbance = [(0.5 * rho * Cd * A_rud *
        #                     (numpy.cos(numpy.pi / 4.0) * V)**2.0 * r_tail),
        #                    y_motor * m * g / num_rotors]
        #
        # We then increase these numbers by 50 percent.

        # Different disturbance directions.
        # NOTE: The way that FaultParameterRange uses numpy.min and
        #              numpy.max downstream of disturbances_data restricts these
        #              arrays to have only a single component in a 0, 1, or 2
        #              direction. This makes the min/max for a parameter sweep on
        #              a batch sim result page for a single sweep look a little odd
        #              as well, but it remains functional. Eventually someone may
        #              want multi-axis disturbances and this will have to be fixed.
        disturbances_data = [
            ('Pos. Roll', ([1500.0, 0.0, 0.0], [7500.0, 0.0, 0.0])),
            ('Pos. Pitch', ([0.0, 1500.0, 0.0], [0.0, 7500.0, 0.0])),
            ('Pos. Yaw', ([0.0, 0.0, 1500.0], [0.0, 0.0, 10500.0])),
            ('Neg. Roll', ([-7500, 0.0, 0.0], [-1500.0, 0.0, 0.0])),
            ('Neg. Pitch', ([0.0, -7500.0, 0.0], [0.0, -1500.0, 0.0])),
            ('Neg. Yaw', ([0.0, 0.0, -10500.0], [0.0, 0.0, -7500.0]))
        ]

        params = batch_sim_params.HoverDisturbancesParameters()
        t_start = params.setup_time
        t_end = params.setup_time + params.impulse_duration

        disturbances = []
        for (disturbance_name, parameters) in disturbances_data:
            name = '%g second %s Torque Step' % (t_end - t_start,
                                                 disturbance_name)
            disturbances += [(name,
                              TorqueStepAmplitudeRange(name, t_start, t_end,
                                                       parameters[0],
                                                       parameters[1]))]

        wind_speeds = parameter_tables.WindSpeedParameterRange(
            FLAGS.wind_speeds)

        base_overrides = overrides_util.PreprocessOverrides({
            'system': {
                'flight_plan': 'kFlightPlanStartDownwind'
            },
            'control': {
                'hover': {
                    'inject': {
                        'use_signal_injection': False
                    }
                }
            },
            'sim': {
                'sim_opt': [
                    'Faults', 'GroundContact', 'ImperfectSensors', 'Perch',
                    'PerchContact', 'StackedPowerSystem'
                ],
                'telemetry_sample_period':
                0.0,
                'sim_time': (params.setup_time + params.impulse_duration +
                             params.settle_time),
            }
        })

        super(HoverDisturbancesSimClient,
              self).__init__(FLAGS.output_dir,
                             base_overrides,
                             wind_speeds,
                             disturbances,
                             params.scoring_functions,
                             title='Hover Disturbances',
                             **kwargs)
Esempio n. 12
0
    def BuildConfig(self, case_name):
        """Build a config for a specific IEC case.

    Args:
      case_name: Name of the case.

    Returns:
      A config suitable for running a simulation corresponding to the provided
          case.

    Raises:
      ValueError: `case_name` does not correspond to a known case.
    """

        overrides = {
            'sim': {
                'iec_sim': {},
                'phys_sim': {
                    'wind_model': sim_types.kWindModelIec,
                    'wind_shear_exponent': 0.2,
                },
                'sim_opt': (sim_types.kSimOptFaults
                            | sim_types.kSimOptPerch
                            | sim_types.kSimOptStackedPowerSystem
                            | sim_types.kSimOptGroundContact
                            | sim_types.kSimOptImperfectSensors),
                'sim_time':
                150.0,
            },
            'system': {
                'flight_plan': sim_types.kFlightPlanStartDownwind
            }
        }
        iec_sim = overrides['sim']['iec_sim']
        phys_sim = overrides['sim']['phys_sim']

        # Power production
        # DLC 1.1: NTM V_in < V_hub < V_out, Ultimate
        # DLC 1.2: NTM V_in < V_hub < V_out, Fatigue
        if case_name in ('1.1', '1.2'):
            iec_sim['load_case'] = sim_types.kIecCaseNormalTurbulenceModel
            phys_sim['wind_speed'] = self._v_hub

        # DLC 1.3: ETM V_in < V_hub < V_out, Ultimate
        elif case_name == '1.3':
            iec_sim['load_case'] = sim_types.kIecCaseExtremeTurbulenceModel

        # DLC 1.4: ECD V_hub = V_r - 2, V_r, V_r + 2, Ultimate
        elif case_name.startswith('1.4'):
            iec_sim['event_t_start'] = 60.0
            iec_sim['load_case'] = (
                sim_types.kIecCaseExtremeCoherentGustWithDirectionChange)
            if case_name == '1.4b':
                phys_sim['wind_speed'] = self._v_hub_m2_sensed
            elif case_name == '1.4c':
                phys_sim['wind_speed'] = self._v_hub_p2_sensed

        # DLC 1.5: EWS V_in < V_hub < V_out, Ultimate
        elif case_name == '1.5a':
            iec_sim['event_t_start'] = 20.0
            iec_sim['load_case'] = (
                sim_types.kIecCaseExtremeWindShearHorizontal)
        elif case_name == '1.5b':
            iec_sim['event_t_start'] = 20.0
            iec_sim['load_case'] = (sim_types.kIecCaseExtremeWindShearVertical)

        # Power production plus occurrence of fault.
        #
        # I'm not sure how the different types of IEC faults should be interpreted,
        # so I'm assuming rotor-out, servo-out, GSG fails faults.
        #
        # DLC 2.1: NTM V_in < V_hub < V_out, Control system fault, Ultimate
        elif case_name == '2.1':
            iec_sim['load_case'] = sim_types.kIecCaseNormalTurbulenceModel
            phys_sim['wind_speed'] = self._v_hub
            overrides['sim']['faults_sim'] = [self._fault_power_sys_zero]

        # DLC 2.2: NTM V_in < V_hub < V_out, Protection system fault, Ultimate
        elif case_name == '2.2':
            iec_sim['load_case'] = sim_types.kIecCaseNormalTurbulenceModel
            phys_sim['wind_speed'] = self._v_hub
            overrides['sim']['faults_sim'] = [{
                't_start': 20.0,
                't_end': 25.0,
                'component': 'GSG/elevation[0]',
                'type': sim_types.kSimFaultMeasurementRescale,
                'parameters': [0.0]
            }, {
                't_start': 20.0,
                't_end': 25.0,
                'component': 'GSG/elevation[1]',
                'type': sim_types.kSimFaultMeasurementRescale,
                'parameters': [0.0]
            }]

        # DLC 2.3: EOG V_hub = V_r-2, V_r+2, V_out, Electrical fault, Ultimate
        elif case_name.startswith('2.3'):
            iec_sim['event_t_start'] = 20.0
            iec_sim['load_case'] = sim_types.kIecCaseExtremeOperatingGust
            overrides['sim']['faults_sim'] = [self._fault_power_sys_zero]
            if case_name == '2.3b':
                phys_sim['wind_speed'] = self._v_hub_sensed - 2.0
            elif case_name == '2.3c':
                phys_sim['wind_speed'] = self._v_hub_sensed + 2.0

        # DLC 2.4: NTM V_in < V_hub < V_out, Fault, Fatigue
        elif case_name == '2.4':
            iec_sim['load_case'] = sim_types.kIecCaseNormalTurbulenceModel
            phys_sim['wind_speed'] = self._v_hub
            overrides['sim']['faults_sim'] = [{
                't_start':
                150.0,
                't_end':
                170.0,
                'component':
                'Servo[1]',
                'type':
                sim_types.kSimFaultActuatorZero,
            }]

        # Start up
        # DLC 3.1: NWP V_in < V_hub < V_out, Fatigue
        elif case_name == '3.1':
            iec_sim['load_case'] = sim_types.kIecCaseNormalWindProfile

        # DLC 3.2: EOG V_hub = V_in, V_r-2, V_r+2, V_out, Ultimate
        elif case_name.startswith('3.2'):
            iec_sim['event_t_start'] = 10.0
            iec_sim['load_case'] = sim_types.kIecCaseExtremeOperatingGust
            phys_sim['wind_speed'] = self._v_in_sensed
            if case_name == '3.2b':
                phys_sim['wind_speed'] = self._v_hub_m2_sensed
            elif case_name == '3.2c':
                phys_sim['wind_speed'] = self._v_hub_p2_sensed
            elif case_name == '3.2d':
                phys_sim['wind_speed'] = self._v_out_sensed

        # DLC 3.3: EDC V_hub = V_in, V_r-2, V_r+2, V_out, Ultimate
        elif case_name.startswith('3.3'):
            iec_sim['event_t_start'] = 10.0
            iec_sim['load_case'] = sim_types.kIecCaseExtremeDirectionChange
            phys_sim['wind_speed'] = self._v_in_sensed
            if case_name == '3.3b':
                phys_sim['wind_speed'] = self._v_hub_m2_sensed
            elif case_name == '3.3c':
                phys_sim['wind_speed'] = self._v_hub_p2_sensed
            elif case_name == '3.3d':
                phys_sim['wind_speed'] = self._v_out_sensed

        # Normal shut down
        # DLC 4.1: NWP V_in < V_hub < V_out, Fatigue
        elif case_name == '4.1':
            iec_sim['load_case'] = sim_types.kIecCaseNormalWindProfile

        # DLC 4.2: EOG V_hub = V_r-2, V_r+2, V_out, Ultimate
        elif case_name.startswith('4.2'):
            iec_sim['event_t_start'] = 50.0
            iec_sim['load_case'] = sim_types.kIecCaseExtremeOperatingGust
            if case_name == '4.2a':
                phys_sim['wind_speed'] = self._v_hub_m2_sensed
            elif case_name == '4.2b':
                phys_sim['wind_speed'] = self._v_hub_p2_sensed
            elif case_name == '4.2c':
                phys_sim['wind_speed'] = self._v_out_sensed

        else:
            raise ValueError('Unknown IEC Case: ' + case_name)

        # Missing cases:
        #  - Emergency shut down.
        #  - Parked (standing still or idling).
        #  - Parked and fault conditions.
        #  - Transport assembly, maintenance, and repair.

        return mconfig.MakeParams(
            'common.all_params',
            overrides_util.PreprocessOverrides(overrides),
            override_method='derived')
Esempio n. 13
0
    def testWingSimXg0(self):
        # Test Cartesian coordinates.
        with self.assertRaises(overrides_util.InvalidArgument):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'wing_sim': {
                        'Xg_0': [22.0, 22.0]
                    }
                }})

        with self.assertRaises(overrides_util.InvalidArgument):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'wing_sim': {
                        'Xg_0': [22.0, 22.0, 22.0, 22.0]
                    }
                }})

        overrides = overrides_util.PreprocessOverrides(
            {'sim': {
                'wing_sim': {
                    'Xg_0': [22.0, 22.0, 22.0]
                }
            }})
        self.assertTrue('sim' in overrides and 'wing_sim' in overrides['sim']
                        and 'Xg_0' in overrides['sim']['wing_sim'])
        self.assertEqual([22.0, 22.0, 22.0],
                         overrides['sim']['wing_sim']['Xg_0'])

        # Test spherical coordinates.
        with self.assertRaises(overrides_util.InvalidArgument):
            overrides_util.PreprocessOverrides({
                'sim': {
                    'wing_sim': {
                        'Xg_0': {
                            'ele': 22.0,
                            'azi': 0.0,
                            'r': 0.0,
                            'bad': 0.0
                        }
                    }
                }
            })

        with self.assertRaises(overrides_util.InvalidArgument):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'wing_sim': {
                        'Xg_0': {
                            'ele': 22.0,
                            'azi': 0.0
                        }
                    }
                }})

        overrides = overrides_util.PreprocessOverrides({
            'sim': {
                'wing_sim': {
                    'Xg_0': {
                        'ele': numpy.pi / 3,
                        'azi': 0.0,
                        'r': 1.0
                    }
                }
            }
        })
        self.assertTrue('sim' in overrides and 'wing_sim' in overrides['sim']
                        and 'Xg_0' in overrides['sim']['wing_sim'])
        expected = [-0.5, 0.0, -numpy.sqrt(3.0) / 2.0]
        for i in range(3):
            self.assertAlmostEqual(expected[i],
                                   overrides['sim']['wing_sim']['Xg_0'][i])
Esempio n. 14
0
    def testBadEnumValues(self):
        # Test overriding the flight_plan.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(
                {'system': {
                    'flight_plan': 'kFlightPlanEit'
                }})

        # Test a name that doesn't start with FLIGHT_PLAN.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(
                {'system': {
                    'flight_plan': 'kSimOptPerch'
                }})

        # Test a name that doesn't exist.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'sim_opt': ['kSimOptEit']
                }})

        # Test a name that doesn't start with SIM_OPT.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'sim_opt': ['kFlightPlanTurnKey']
                }})

        # Test a name that doesn't exist.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'faults_sim': [{
                        'type': 'kSimFaultUpdateEit'
                    }]
                }})

        # Test a name that doesn't start with SIM_FAULT.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides(
                {'sim': {
                    'faults_sim': [{
                        'type': 'kSimOptPerch'
                    }]
                }})

        # Test a name that doesn't exist.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides({
                'sim': {
                    'joystick_sim': {
                        'updates': [{
                            'type': 'kSimJoystickUpdateEit'
                        }]
                    }
                }
            })

        # Test a name that doesn't start with SIM_JOYSTICK_UPDATE.
        with self.assertRaises(c_helpers.EnumError):
            overrides_util.PreprocessOverrides({
                'sim': {
                    'joystick_sim': {
                        'updates': [{
                            'type': 'kSimJoystickTypeProgrammed'
                        }]
                    }
                }
            })