ISISComputingGroup / IBEX

Top level repository for IBEX stories
5 stars 2 forks source link

IOC: Little blue cryostat #5546

Closed John-Holt-Tessella closed 4 years ago

John-Holt-Tessella commented 4 years ago

As a POLREF scientist I want to control the little blue cryostat. It is run from a Mercury controller but has extra logic on top which change the needle value. This logic is in C:\LabVIEW Modules\Drivers\Oxford Instruments\MERCURY\Mercury - Cryostat.llb\Mercury - Cryostat + Level - Front Panel 1.vi

I think it is a PID controller for pressure set based on required temperature but could do with some guidance.

Acceptance Criteria

Notes

Although this comes from labview this is now documented below and we no longer need labview expertise.

KathrynBaker commented 4 years ago

Within the VI listed above I can find no information about a needle valve, and nothing that performs any calculations, there is a subtlety missing in the ticket

kjwoodsISIS commented 4 years ago

Is it possible that POLREF has a locally modified VI that has not found its way back to the SourceSafe repository?

John-Holt-Tessella commented 4 years ago

Maybe I have sent this to the instrument scienitist

I am not sure I can find the code for the mercury changes for the little blue cryostat. You mentioned that they had been done by someone, can you let me know who that was and if you known where the changes are?

John-Holt-Tessella commented 4 years ago

Answer:

The little blue cryostat on POLREF can be found in one of the sub-configurations in the SECI configuration files. The algorithm is done by the LabVIEW code. The details of the driver are : C:\LabVIEW Modules\Drivers\Oxford Instruments\MERCURY\Mercury - Cryostat.llb\Mercury - Cryostat - Setup Dialog.vi C:\LabVIEW Modules\Drivers\Oxford Instruments\MERCURY\Mercury - Cryostat.llb\Mercury - Cryostat - Front Panel 1.vi C:\LabVIEW Modules\Drivers\Oxford Instruments\MERCURY\Mercury - Cryostat.llb\Mercury - Cryostat + Level - Front Panel 1.vi (same thing but showing cryo levels) These are the details I have on my machine as of when I left instrumentation. I would expect them to be roughly correct. Hope it help. Can offer advice if needed.

Looking through the setup I can see the Gain parameter (I was looking at the one on POLREF it may or may not be in the generic one)

image

following this I see:

image

Which shows the PID (just P?) behaviour. I suspect we don't have this in the IBEX Mercury controller @Tom-Willemsen can you confirm.

kjwoodsISIS commented 4 years ago

Questions:

  1. Is this response from Gareth?
  2. Are there differences between the version stored in SourceSafe (and, presumably, on DEMO) the ones on POLREF and Gareth's(?) machines?
KathrynBaker commented 4 years ago

So the reason I couldn't find this - it is actually specific to that top level VI, it is used by both versions of the VI, with levels or without, which isn't what was implied.

If this isn't already implemented then there is something missing from the existing Mercury as well potentially, but I can look through that code and give a better idea of what it is doing, now that I know where to look, and yes, it is in source safe and I can see it on my copy.

Tom-Willemsen commented 4 years ago

@John-Holt-Tessella the EPICS mercury driver does not have any software-defined PID in it. It just sends PID parameters to the box.

I think this is the difference between the "Mercury" vis and the "Mercury cryostat" vis, the latter are only used in very few places I believe. I think gareth may have started an EPICS implementation of this at https://github.com/ISISComputingGroup/IBEX/issues/3683 but I don't know how far it got (clearly, not far enough to get into review).

KathrynBaker commented 4 years ago

I'm struggling to decide if this is a simple PID or not at the moment. #3683 was a DCOM implementation, so not applicable in any helpful form to implementing this in a native fashion. There's different behaviour based on whether or not Temperature - Temperature Setpoint - Temperature Deadband is greater than 0 or not, and the Ramp VI is one we can't look at the code of, so to get an idea of what it is doing may require some black box reverse engineering. I'm not going to have time to complete that today - but I will try and explain everything except that value (the magic ramp value below, as the rest of it looks more straightforward.

The pressure set point calc is called in the timeout state, so is called quite frequently

Values that the device knows about () Temperature Details.Temperature Signals.Temperature Temperature Details.Control Loop.Set Point

From the Cryostat Setup (so set as macros): Setup.Gain Setup.Temperature Deadband Setup.Minimum Pressure Setup.Maximum Pressure Setup.Offset Setup.Offset Duration Setup.Pressure Controls (Temperature (K) v Control Pressure (mbar) lookup table)

Final Target Pressure = Control Pressure value from lookup table (up to Temperature in table use associated control pressure)

As values are reused I've broken the equations down and I am using letters to represent things is a pseudocode type fashion

A = Temperature Details.Temperature Signals.Temperature - Temperature Details.Control Loop.Set Point B = A - Setup.Temperature Deadband C = |B| x Setup.Gain D = C to the power of 2 + Final Target Pressure E = B < (Setup.Temperature Deadband x -3) F = |A| > Setup.Temperature Deadband If E is True: G = Setup.Minimum Pressure Else: G = Final Target Pressure Endif If E is True OR F is True: H = 0 Else: H = magic ramp value Endif If B > 0: Pressure Setpoint = D + magic ramp value Else: Pressure Setpoint = G + H Endif The Pressure Set Point is coerced to the maximum/minimum pressures in the setup as the last step before writing it to the controller (not on demand, but whenever the information is read from the device or a clear is requested)

John-Holt-Tessella commented 4 years ago

Magic ramp internals:

image

and

image

John-Holt-Tessella commented 4 years ago

As python


temp = 1
sp = 1
deadband = 0.1

if abs(temp - sp) > deadband:
    start_ramp = current_time

if temp - sp <= deadband:
    low_temp_set
else:
    normal_temp_set()

def low_temp_set():
    if temp - sp <= -2*deadband:  # temperature is much lower than sp
        return minimum_pressure
    else:
        base_pressure = final_pressure(sp)

    if abs(temp - sp) > deadband: # temperature is outside the deadband
        ramp_pressure = 0
    else:
        ramp_pressure = ramp()

    return base_pressure + ramp_pressure

def final_pressure(temp):
    """find largest temp in list which is smaller than temp and use pressure from that"""
    pass

def normal_temp_set():
    """temp is  within the deadband or above it"""
    final_target_pressure = final_pressure(temp)
    base_pressure = (abs(temp - sp - deadband) * Gain) **2 + final_target_pressure

    if base_pressure > max_pressure:
        base_pressure = max_pressure
    elif base_pressure < final_target_pressure:
        base_pressure = final_target_pressure

    return base_pressure + ramp()

def ramp():
    # ramp_rate is in minutes
    ramp_rate=
    pressure = (current_time - start_ramp) * ramp_rate/60 * sign(offset)

    retruenmin(max(0, pressure), final_pressure(temp))
John-Holt-Tessella commented 4 years ago

Pull requests (includes fix to convert record):

John-Holt-Tessella commented 4 years ago

STFC person to review please.