Package: maintsim
maintsimmaintsimcan be used to model a discrete manufacturing system where components degrade over time and receive maintenance. Users can define the configuration and parameters of the system, as well as the maintenance policy to be carried out. It is built on theSimPydiscrete-event simulation package.Installing maintsimpip install maintsimUsing this packageRequirementsmaintsim relies on the following packages in addition to Python 3.6+:SimPyversion 3.0.11pandasversion >= 0.23.4SciPyversion >= 1.1.0 (if specifying random repair times)Setting up a manufacturing systemThe workflow begins by creating aSystemobject that is defined by the following parameters:Configuration parametersprocess_times- a list of process times for each machine in a serial line.interarrival_time- the time between part arrivals to the first machine in the system. The default is 1, which ensures the first machine is never starved.buffer_sizes- a list of buffer sizes for each machine, or an integer value for the buffer size of all machines. Default is 1. For n machines there are n-1 buffers.Failure parametersfailure_mode- currently either'degradation'orNone. Each machine is subject to the same mode of degradation. By default machines do not degrade.'degradation'- machine degradation occurs according to a discrete-state Markovian process. Currently only Markovian degradation is supported. Requires specification offailure_params, described in the following subsection.planned_failures- a list of planned failures to occur during the simulation time. Each of the form(location, time, duration). Planned failures do not adhere to maintenance capacity constraints and have not been thoroughly tested in tandem with random failures.Markovian degradation parametersThere are several options for specifying the mode of degradation using thefailure_paramsargument which should be passed as a dictionary.Constant degradation rate - passed as the value of thedegradation ratekey either as a single float or list of floats for each machine. The value is the probability of degrading by one unit at each time step and so should be between 0 and 1. Creates an upper bidiangonal degradation transition matrix.Failed state - if the degradation rate is specified, the maximum health (failed) state for each machine can be passed as the value of thefailed statekey. The default failed state is 10.Complete degradation transition matrix - can be specified as a singlenumpyarray (in which case each machine will be subject to the same degradation profile) or a list of arrays for each machine as the value of thedegradation transitionkey.Iffailure_mode = 'degradation'is passed to aSystemobject, either thedegradation rateordegradation transitionmust be defined. Degradation profiles beyond a constant degradation rate have not yet been thoroughly tested.Maintenance parametersmaintenance_policy- currently either'CM'or'CBM'.'CM'- "corrective maintenance", the default policy, machines will only be repaired upon complete failure, as determined by the mode of degradation.'CBM'- "condition-based maintenance", preventive maintenance is performed once a machine's condition reached a prescribed threshold.maintenance_params- the parameters that define the specified maintenance policy. ForCBM, a list of thresholds at which to schedule maintenance.Currently each machine has 11 health states, with 0 being perfect health and 10 being the failed state. The maintenance threshold should be in this range.repair_params- a dictionary ofscipy.statsfrozen discrete distributions of time to repair based on repair type.For example,repair_params = {'CM': stats.randint(10, 20), 'CBM': stats.randint(20, 40)}.maintenance_capacity- the maximum number of maintenance jobs that can be executed simultaneously. Currently if the number of simultaneously scheduled maintenance jobs exceeds the capacity they will be handled in a first in, first out (FIFO) manner.maintenance_costs- a dictionary of the cost of each type of maintenance job by type.System state parametersThese parameters can be set to initialize the system state before simulation. By default the system begins with empty buffers and machines in perfect health.initial_remaining_process- a list of remaining processing times for each machine. By default this is equal to the machine's total processing time when it does not have a part.initial_buffer- a list of initial levels for each buffer.initial_health- a list of initial health states for each machine.
Valid settings for the initial system state are not currently verified automatically.Creating a custom maintenance schedulerTheSystemobject can take an additionalschedulerobject that will determine how maintenance jobs are scheduled when the number of machines due for maintenance exceeds the maintenance capacity. By default a system will use a FIFO scheduler as defined by theSchedulerclass. A custom scheduler can also be created that inherits from themaintsim.Schedulerclass. This new class should include achoose_nextmethod that accepts the current maintenance queue as an argument. This method should then return a list of machine objects that are to be assigned maintenance. Thechoose_nextmethod is executed each time a maintenance resource is release from a job.An example of a custom scheduler that uses Monte Carlo tree search (as implemented by theMCTSpackage) is shown below:importmaintsimimportmctsclassMCTSScheduler(maintsim.Scheduler):'''Resolves maintenance scheduling conflicts using Monte Carlo tree search.'''def__init__(self,time_limit=None,iteration_limit=None,**kwds):'''Must specify either a time limit (in seconds) or iteration limit for theMCTS.'''super().__init__(**kwds)self.limit={}iftime_limitanditeration_limit:print('Error: cannot specify time and iteration limit.')eliftime_limit:self.limit['timeLimit']=time_limit*1000else:self.limit['iterationLimit']=iteration_limitdefchoose_next(self,queue):# formulate and solve MCTSmcts_schedule=mcts.mcts(**self.limit)best_action=mcts_schedule.search(initialState=MaintenanceState(self.system))next_machine=[self.system.machines[best_action-1]]returnnext_machineSimulating the systemWhen the system is instantiated, it will initialize by creating the necessary objects including the SimPyEnvironment, the maintenance resource, machines, and buffers. The simulation can be run by calling thesimulatemethod of theSystemobject with the following parameters:title- the tile of the simulation, used for naming any files that are saved.warmup_time- the time that the simulation will run before collecting data. Useful for ensuring the system is in steady state before observation.sim_time- the duration of time that simulation will run once the warmup is completed. Metrics will be determined based on the system performance during this time.seed- random seed for the simulation. A given seed should always produce the same results.verbose- boolean.Truewill print out a summary of the simulation run.Falsewill suppress all printed output, which may be preferred if many replications are being run.Simulation dataSeveral data frames are created to record data of a simulation run and stored as attributes of theSystemobject.state_data- remaining processing time of each machine and buffer levels at each time step.production_data- production volume (in units) and throughput (in units/time) of each machine at every time step.machine_data- status of each machine at every time step, including if machines are function and blocked or starved.queue_data- the number of machines waiting for maintenance at each time step.maintenance_data- the log of maintenance activities including the time at which the activity occurred, the type of activity (corrective, preventive, etc.), what the activity was (failure or repair), and the duration or time to failure.Iterating the simulationA system can be simulated several times using theSystem.iterate_simulationmethod. The arguments for this method are:replications- number of times to run the simulation.warmup_time- the time that the simulation will run before collecting data. Performance statistics are only collected after this time has elapsed.sim_time- the duration of time each replication will be simulated.objective- the objective values that will be returned once all replications are complete. Options include:production- the production volume in units of the system.ppl- the permanent production loss of the system over the specified simulation time.availability- the overall availability of machines in the system as a percentage.verbose-TrueorFalse, determines whether or not summary statistics will be displayed once all replications are completed.A simple exampleHere is a minimum example for implmenting a CBM policy:>>>importmaintsim>>>fromscipyimportstats>>>>>>system=maintsim.System(process_times=[3,5,4],...buffer_sizes=5,...failure_mode='degradation',...failure_params={'degradation rate':[0.25,0.1,0.2]},...maintenance_policy='CBM',...maintenance_params={'CBM threshold':[8,6,7]},...repair_params={'CM':stats.randint(20,30),...'CBM':stats.randint(10,20)},...maintenance_capacity=1)>>>system.simulate(warmup_time=100,sim_time=500)Simulationcompletein0.89sUnitsproduced:31Systemavailability:68.93%Planned featuresKey planned features includeParallelization of simulation iterationsImproved efficiency for iterating a simulationExporting system model for reuse