package fcs

import org.lsst.ccs.subsystems.fcs.*
import org.lsst.ccs.subsystems.fcs.testbench.*
import org.lsst.ccs.subsystems.fcs.common.*
import org.lsst.ccs.subsystems.fcs.simulation.*
import org.lsst.ccs.subsystems.fcs.drivers.*
import org.lsst.ccs.monitor.Channel
import org.lsst.ccs.monitor.Device
import org.lsst.ccs.description.groovy.CCSBuilder
import org.lsst.ccs.drivers.canopenjni.*
import org.lsst.ccs.drivers.canopenjni.rmi.*


CCSBuilder builder = ["fcs"]
//********************************************************************************//
//Carousel variables
//********************************************************************************//
/* 
 * carousel positions when a socket is at STANDBY
 * example : socket 1 is at STANDBY when carousel position is -204200
 * */
def standbyPositionSocket = [-204200,-1075906,-1948470,-2821074,-3694258] as int[]

/* numOfAnalogInput on the CANopen device where we read the clamps sensors*/
def numOfAnalogInputFilterPresenceSensorXminus = [1, 2, 3, 4, 5] as int[]
def numOfAnalogInputLockSensorXminus = [6, 7, 8, 9, 10] as int[]
def numOfAnalogInputFilterPresenceSensorXplus = [11, 12, 13, 14, 15] as int[]
def numOfAnalogInputLockSensorXplus = [16, 17, 18, 19, 20] as int[]


//Carousel Can Open Devices (CAN-CBX-AI814)
def adcName = "ai814"

//Carousel CAN OPEN device to read carousel clamp sensors
def caTTC580Name = "hyttc580"

//Carousel clamps controllers name
def clampXminusControllerName = "clampXminusController" //controller to unlock clamp on the side Xminus
def clampXplusControllerName =  "clampXplusController" //controller to unlock clamp on the side Xplus
//********************************************************************************//

//********************************************************************************//
//Autochanger variables
//********************************************************************************//
def acPlutoGatewayName = "acSensorsGateway" // to monitor the autochanger sensors
//********************************************************************************//

//********************************************************************************//
//Loader variables
//********************************************************************************//
def bridgeToLoaderName = "loaderTcpProxy"
def loaderPlutoGatewayName = "loaderPlutoGateway" // to monitor the loader sensors
//********************************************************************************//

builder.
    main(org.lsst.ccs.subsystems.fcs.FcsMain,
    bridge:ref("tcpProxy"),   
    bridgeToLoader:ref("$bridgeToLoaderName"),
) { //begin description of Main subs
    
    //-------------------------
    // BEGIN Filter Manager description
    filterManager(FilterManager) {
        //begin description of filter manager's children
        filterU (Filter,filterID:29, weight:38)
        filterG (Filter,filterID:3, weight:33)
        filterR (Filter,filterID:60, weight:30)
        filterI (Filter,filterID:34, weight:28)
        filterZ (Filter,filterID:17, weight:28)
        filterY (Filter,filterID:15, weight:22.5)
        dummyFilter (Filter,filterID:46,weight:44.5)
    }//end description of filter manager's children
    // END Filter Manager description
    // ------------------------------
    
    //-------------------------
    // tcp Proxy
    tcpProxy (CanOpenProxy, hardwareBootTimeout:5000, busName:"0", baud:"125k") {
        
        canInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.158.155.193", "canbus0")) 
        
        //Carousel Hardware
        "$clampXminusControllerName" (CanOpenEPOSCarouselClamp,
            nodeID:0x1a, serialNB:"79003900",
            paramsForCurrent: [
                MotorType:11, 
                PositionSensorType:3,
                PolePairNumber:8,
                ContinuousCurrentLimit:2360,
                OutputCurrentLimit:4720,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:25],
            paramsForProfilePosition: [MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        
        "$clampXplusControllerName" (CanOpenEPOSCarouselClamp,
            nodeID:0x1b, serialNB:"79020968",
            paramsForCurrent: [
                MotorType:11, 
                PositionSensorType:3,
                PolePairNumber:8,
                ContinuousCurrentLimit:2360,
                OutputCurrentLimit:4720,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:25],
            paramsForProfilePosition: [MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        
        carouselController (CanOpenEPOSCarousel,
            nodeID:0xc, serialNB:"80003117",
            paramsForCurrent:[
                ContinuousCurrentLimit:9375,
                OutputCurrentLimit:12500,
                MaxSpeedInCurrentMode:5000,
                MotorType:11,PolePairNumber:12,
                PositionSensorType:8],
            paramsForProfilePosition: [
                MinPositionLimit:-2147483648,
                MaxPositionLimit:2147483647,
                MotionProfileType:1, /*0:trapezoidal, 1:sinusoidal*/
                ProfileAcceleration:2000,
                ProfileDeceleration:2000,
                MaxProfileVelocity:5371,
                QuickStopDeceleration:10000],
            paramsForHoming:[HomeOffset:0])
        
        // can open devices to read clamps sensors
        "$caTTC580Name" (CanOpenTTC580, nodeID:0x3, serialNB:"25008180")
        
        // can open devices to read brakes sensors and temperatures
        "$adcName" (CanCBXAI814, nodeID:0x1e, serialNB:"c7ca0645", transmissionType:1)
        
        // can open devices to read brakes sensors and temperatures
        pt100 (CanOpenDevice, nodeID:0x1f, serialNB:"c7c50149") 
        
        // autochanger can open devices
        //sensors gateway
        "$acPlutoGatewayName" (CanOpenPlutoGateway, nodeID:0x3a,serialNB:"3269")
             
        brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"2071")
        
        tempSensorsDevice (CanOpenSystecIO, nodeID: 0x20, serialNB:"4bb6b")
        
        proximitySensorsDevice (CanCBXAI420, nodeID: 0x22, serialNB:"c7c60331")
        
        onlineStrainGauge (CanOpenStrainGauge, nodeID: 0x21, serialNB:"0")
        
        // can open devices
        linearRailMasterController (CanOpenEPOSLinearRailTruck, 
            nodeID:0x2a,serialNB:"80001881",
            paramsForCurrent:[
                MotorType:10, PositionSensorType:260,PolePairNumber:1,
                ContinuousCurrentLimit:7200,OutputCurrentLimit:14400,
                ThermalTimeConstantWinding:187,
                MaxSpeedInCurrentMode:9140],
            paramsForProfilePosition:[
                ProfileAcceleration:310, ProfileDeceleration:310,
                MaxProfileVelocity:322, QuickStopDeceleration:310,
                MaxFollowingError:999999,//on verra plus tard
                ProfileVelocity:310,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
            encoderRibbonMinValue:8161299,
        )

        // can open devices
        linearRailSlaveController (CanOpenEPOSLinearRailTruck,
            nodeID:0x2c,serialNB:"80008572",
            paramsForCurrent:[
                MotorType:10, PositionSensorType:1,PolePairNumber:1,
                ContinuousCurrentLimit:7200,OutputCurrentLimit:14400,
                ThermalTimeConstantWinding:187,MaxSpeedInCurrentMode:9140],
            paramsForProfilePosition:[
                ProfileAcceleration:310,
                ProfileDeceleration:310,
                ProfileVelocity:310,
                QuickStopDeceleration:10000,
                MaxFollowingError:7000,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
            encoderRibbonMinValue:7449994,
        )     

        latchXminusController (CanOpenEPOS,  //CanOpenEPOS24-3
            nodeID:0xf,serialNB:"84004735",
            paramsForCurrent: [
                MotorType:1, PositionSensorType:0,PolePairNumber:2,
                ContinuousCurrentLimit:400,OutputCurrentLimit:400,
                ThermalTimeConstantWinding:40,
                MaxSpeedInCurrentMode:100],
            paramsForProfilePosition: [MotionProfileType:0],
            paramsForHoming:[HomeOffset:0]
        )

        // can open devices
        latchXplusController (CanOpenEPOS,  //CanOpenEPOS24-3
            nodeID:0xe, serialNB:"84004711",
            paramsForCurrent: [
                MotorType:1, PositionSensorType:0,PolePairNumber:2,
                ContinuousCurrentLimit:400,OutputCurrentLimit:400,
                ThermalTimeConstantWinding:40,
                MaxSpeedInCurrentMode:100],
            paramsForProfilePosition: [MotionProfileType:0],
            paramsForHoming:[HomeOffset:0]
        )

        // can open devices
        onlineClampXminusController (CanOpenEPOSOnlineClamp, 
            nodeID:0x31,serialNB:"79011618",
            paramsForCurrent: 
            [MotorType:1, PositionSensorType:0,PolePairNumber:1,
                ContinuousCurrentLimit:3200,OutputCurrentLimit:4000,
                ThermalTimeConstantWinding:419, //160?
                MaxSpeedInCurrentMode:25000],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
        )
        // can open devices
        onlineClampXplusController (CanOpenEPOSOnlineClamp, 
            nodeID:0x30, serialNB:"79011616",
            paramsForCurrent: 
            [MotorType:1, PositionSensorType:0,PolePairNumber:1,
                ContinuousCurrentLimit:5000,OutputCurrentLimit:4000,
                ThermalTimeConstantWinding:419, //160?
                MaxSpeedInCurrentMode:25000],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
        )
        // can open devices
        onlineClampYminusController (CanOpenEPOSOnlineClamp, 
            nodeID:0x32, serialNB:"79011243",
            paramsForCurrent: 
            [MotorType:1, PositionSensorType:0,PolePairNumber:1,
                ContinuousCurrentLimit:5000,OutputCurrentLimit:4000,
                ThermalTimeConstantWinding:419, //160?
                MaxSpeedInCurrentMode:25000],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
        )
    }//end description of bridgeToChanger's children
    //----------------------------------------------
    // END Bridge To CHANGER description
    //----------------------------------------------                
    //
    // tcp Proxy
    "$bridgeToLoaderName"(LoaderCanOpenProxy, hardwareBootTimeout:3000, busName:"1", baud:"125k") {
        //baie du loader
        loaderCanInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.158.155.194", "canbus1"))
        
        "$loaderPlutoGatewayName" (CanOpenPlutoGateway, 
            nodeID:5,serialNB:"22d6")
        
        // can open devices
        hooksController (CanOpenEPOS,
            nodeID:0x5b,serialNB:"79007141",
            paramsForCurrent:[
                ContinuousCurrentLimit:500,
                OutputCurrentLimit:6880,
                MaxSpeedInCurrentMode:750,
                MotorType:10,PolePairNumber:1,
                PositionSensorType:1],
            paramsForProfilePosition:[
                MinPositionLimit:-2147483648,
                MaxPositionLimit:537000,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0]) 
                        
        carrierController (CanOpenEPOS,nodeID:0x5a,serialNB:"80003184",
            paramsForCurrent:[
                ContinuousCurrentLimit:7290,
                OutputCurrentLimit:14580,
                MaxSpeedInCurrentMode:9840,
                MotorType:10,
                PositionSensorType:4,
                ThermalTimeConstantWinding:187,
                PolePairNumber:1],
            paramsForProfilePosition:[
                MinPositionLimit:-2147483648,
                MaxPositionLimit:1037800,
                MotionProfileType:1,
                MaxFollowingError:2000,
                MaxProfileVelocity:228, 
                ProfileVelocity:200,
                ProfileAcceleration:30,
                ProfileDeceleration:8,
                QuickStopDeceleration:1000],
            paramsForHoming:[
                HomeOffset:500,
                HomingAcceleration:200,
                CurrentThresholdHomingMode:500])
        
        /*
         * QuickStopDeceleration=10000 SpeedForSwitchSearch=10 SpeedForZeroSearch=10 HomingAcceleration=200 CurrentThresholdHomingMode=500 HomePosition=0
         * */
    }//end description of bridge's childrens
    //----------------------------------------------
    // END Bridge To LOADER description
    //----------------------------------------------
    
    
    // BEGIN Filter Identificator description
    filterIdentificator(FilterIdentificator)
    {//begin description of filter Identificator's children
        filterIDSensor0 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:0,byteNumero:4)
        
        filterIDSensor1 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:1,byteNumero:4)
        
        filterIDSensor2 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:2,byteNumero:4)
        
        filterIDSensor3 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:3,byteNumero:4)
        
        filterIDSensor4 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:4,byteNumero:4)
        
        filterIDSensor5 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:5,byteNumero:4)
    }//end description of filter identificator's children
    // END Filter Identificator description

    
    /**********************************************************************/
    /*                BEGIN OF CAROUSEL DESCRIPTION                       */
    /**********************************************************************/

    //----------------------------
    // BEGIN Carousel description
    carousel(Carousel)
    {//begin description of carousel's children
        /**********************************************************************/
        /*SOCKETi*/
        for (int i = 1; i<6;i++ ) {
            "socket${i}" ( CarouselSocket,
                id:i,
                clampXminus:ref("clampXminus${i}"),
                clampXplus:ref("clampXplus${i}"),
                standbyPosition: standbyPositionSocket[i-1],
                slaveModuleSensor:ref("slaveModuleSensor${i}")
            )
            {   
                "slaveModuleSensor${i}" (CarouselSensor, deviceName: caTTC580Name)
                //-------------------------
                // BEGIN clampXminus description
                "clampXminus${i}" (CarouselClamp,
                    filterPresenceSensor:ref("filterPresenceXminus${i}"),
                    lockSensor:ref("lockSensorXminus${i}"),
//                    thermometer:ref("thermometerXminus${i}")
                ) 
                {
                    "filterPresenceXminus${i}" (CarouselClampSensor, deviceName: caTTC580Name)
                    
                    "lockSensorXminus${i}" (CarouselClampSensor, deviceName: caTTC580Name) 
                    
//                    "thermometerXminus${i}" (Thermometer)
                }
                //-------------------------
                // END clampXminus description
                
                //-------------------------
                // BEGIN clampXplus description
                "clampXplus${i}" (CarouselClamp,
                    filterPresenceSensor:ref("filterPresenceXplus${i}"),
                    lockSensor:ref("lockSensorXplus${i}"),
//                    thermometer:ref("thermometerXplus${i}")
                )
                {
                    "filterPresenceXplus${i}" (CarouselClampSensor, deviceName:caTTC580Name)
                    "lockSensorXplus${i}" (CarouselClampSensor, deviceName:caTTC580Name)
//                    "thermometerXplus${i}" (Thermometer)
                }
                //-------------------------
                // END clampXplus description
            } // END carouselSocket /*SOCKETi*/ description
        } // END of loop of carouselSocket description.
        
//        acAF3 (ComplementarySensors,
//            sensor:ref("acAF3s"),
//            sensorC:ref("acAF3b"),
//        ) {
//            //TODO replace that by good values
//            acAF3s (DigitalSensor,
//                dioName:caTTC580Name, inputNumero:6, byteNumero:11)
//            acAF3b (DigitalSensor,
//                dioName:caTTC580Name, inputNumero:7, byteNumero:11)
//        }
    }//end description of carousel's children
    //END Carousel description
    // ------------------------    
    
    // ------ Monitoring 
    systec(SystecIO_X5, tempSensorsDevice:ref("tempSensorsDevice"))
    
    // Channels read as a group with getADCValues
    tempLinearRailMotorXplus(Channel, devcName:"systec", hwChan:1, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempLinearRailMotorXminus(Channel, devcName:"systec", hwChan:2, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempClampMotorXplus(Channel, devcName:"systec", hwChan:3, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempClampMotorYminus(Channel, devcName:"systec", hwChan:4, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempClampMotorXminus(Channel, devcName:"systec", hwChan:5, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempFrontBox(Channel, devcName:"systec", hwChan:6, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempRearBox(Channel, devcName:"systec", hwChan:7, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempCellXminus(Channel, devcName:"systec", hwChan:8, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)

    //**************************************************************************//
    //**************************************************************************//
    // autochanger
    //**************************************************************************//
    //**************************************************************************//
    autochanger(Autochanger, plutoGateway:ref("$acPlutoGatewayName")) {
        ////begin description of autochanger children
        loaderConnectedSensors (ComplementarySensors, // Loader_LPS
            sensor:ref("loaderConnectedSensor"),
            sensorC:ref("loaderConnectedSensorC")) {
            loaderConnectedSensor ( DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:4, byteNumero:2)		
            loaderConnectedSensorC ( DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:5, byteNumero:2)		
        }//end description of autochanger loaderConnectedSensors children

        //Carousel_CS
        carouselStoppedAtStandbySensors (ComplementarySensors, // Carousel_CS
            sensor:ref("carouselStoppedAtStandby"),
            sensorC:ref("carouselStoppedAtStandbyC")) {
                carouselStoppedAtStandby (DigitalSensor,
                    dioName:acPlutoGatewayName, inputNumero:0, byteNumero:3)		
                carouselStoppedAtStandbyC ( DigitalSensor ,		
                    dioName:acPlutoGatewayName, inputNumero:1, byteNumero:3)
        }//end description of autochanger carouselStoppedAtStandbySensors children
        
        carousel_CF0Sensors (ComplementarySensors, // Carousel_CF0
            sensor:ref("carousel_CF0"),
            sensorC:ref("carousel_CF0_C")) {
                carousel_CF0 (DigitalSensor,
                    dioName:acPlutoGatewayName, inputNumero:2, byteNumero:3)		
                carousel_CF0_C ( DigitalSensor ,		
                    dioName:acPlutoGatewayName, inputNumero:3, byteNumero:3)
        }//end description of autochanger carousel_CF0 children 
        
        carousel_CF1Sensors (ComplementarySensors, // Carousel_CF1
            sensor:ref("carousel_CF1"),
            sensorC:ref("carousel_CF1_C")) {
                carousel_CF1 (DigitalSensor,
                    dioName:acPlutoGatewayName, inputNumero:4, byteNumero:3)		
                carousel_CF1_C ( DigitalSensor ,		
                    dioName:acPlutoGatewayName, inputNumero:5, byteNumero:3)
        }//end description of autochanger carousel_CF1 children 
        
                
        // Local Protection Module status
        lpmLinearRailMasterStatus ( DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:6, byteNumero:4) 
            
        lpmLinearRailSlaveStatus ( DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:7, byteNumero:4)        
            
        lpmOnlineClampsStatus ( DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:0, byteNumero:5)
            
        lpmLatchesStatus ( DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:1, byteNumero:5)
            
        //Carousel_CFC signal read on AC pluto Gateway sent by carousel.
        carouselHoldingFilterSensors (ComplementarySensors,
            sensor:ref("carouselHoldingFilterSensor0"),
            sensorC:ref("carouselHoldingFilterSensor1")
        ){		
            carouselHoldingFilterSensor0(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:6,byteNumero:3)		
            carouselHoldingFilterSensor1(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:7,byteNumero:3)		
        }
            
        //Signals read on AC pluto gateway sent by loader
        // 
        loaderHoldingFilterSensors (ComplementarySensors, //Loader_LRH (ex LFL)
            sensor:ref("loaderHoldingFilterSensor0"),
            sensorC:ref("loaderHoldingFilterSensor1")) {		
            loaderHoldingFilterSensor0(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:6, byteNumero:2)		
            loaderHoldingFilterSensor1(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:7, byteNumero:2)    		
        }
        
        //**************************************************************************//
        // autochanger trucks description
        //**************************************************************************//
        autochangerTrucks (AutochangerTwoTrucks, 
            truckXminus:ref("acTruckXminus"), truckXplus:ref("acTruckXplus"),
            linearRailMasterController:ref("linearRailMasterController"),
            linearRailSlaveController:ref("linearRailSlaveController")) {
            //begin description of autochanger trucks children
            acTruckXminus (AutochangerTruck, 
                controller:ref("linearRailMasterController"),
                handoffPositionSensors:ref("handoffPositionSensorsXminus"),
                onlinePositionSensors:ref("onlinePositionSensorsXminus"),
                standbyPositionSensors:ref("standbyPositionSensorsXminus"),
            )
            {//begin description of autochanger truckXminus children
                handoffPositionSensorsXminus ( ComplementarySensors,
                    sensor: ref("handoffPositionSensorXminus"),
                    sensorC: ref("handoffPositionSensorBXminus"),
                )
                {
                    handoffPositionSensorXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:0, byteNumero:1)
                    
                    handoffPositionSensorBXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:1, byteNumero:1)
                }
                onlinePositionSensorsXminus ( ComplementarySensors,
                    sensor: ref("onlinePositionSensorXminus"),
                    sensorC: ref("onlinePositionSensorBXminus"),
                )
                {
                    onlinePositionSensorXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:2, byteNumero:1)
                    
                    onlinePositionSensorBXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName,inputNumero:3, byteNumero:1)
                }
                standbyPositionSensorsXminus ( ComplementarySensors,
                    sensor: ref("standbyPositionSensorXminus"),
                    sensorC: ref("standbyPositionSensorBXminus"),
                )
                {
                    standbyPositionSensorXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:6, byteNumero:0)
                    
                    standbyPositionSensorBXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:7, byteNumero:0)
                }
            }//end description of autochanger acTruckXminus children
            acTruckXplus (AutochangerTruck, 
                controller:ref("linearRailSlaveController"),
                handoffPositionSensors:ref("handoffPositionSensorsXplus"),
                onlinePositionSensors:ref("onlinePositionSensorsXplus"),
                standbyPositionSensors:ref("standbyPositionSensorsXplus"),
            )
            {//begin description of autochanger truckXplus children
                handoffPositionSensorsXplus (ComplementarySensors,
                     sensor: ref("handoffPositionSensorXplus"),
                     sensorC: ref("handoffPositionSensorBXplus"),
                 )
                 {
                     handoffPositionSensorXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero: 0, byteNumero:9)                                    
                     handoffPositionSensorBXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:1, byteNumero:9)
                 }
                 onlinePositionSensorsXplus (ComplementarySensors,
                     sensor: ref("onlinePositionSensorXplus"),
                     sensorC: ref("onlinePositionSensorBXplus"),
                 )
                 {
                     onlinePositionSensorXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:2, byteNumero:9)
                     onlinePositionSensorBXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:3, byteNumero:9)
                 }
                 standbyPositionSensorsXplus (ComplementarySensors,
                     sensor: ref("standbyPositionSensorXplus"),
                     sensorC: ref("standbyPositionSensorBXplus"),
                 )
                 {
                     standbyPositionSensorXplus( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:6, byteNumero:8)
                     standbyPositionSensorBXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:7, byteNumero:8)
                 }
            }//end description of autochanger acTruckXplus children
            
        }//end description of autochanger trucks children            
        //**************************************************************************//
        // end of autochanger trucks description
        //**************************************************************************//
        
        //**************************************************************************//
        // autochanger latches description
        //**************************************************************************//
        latches (AutochangerTwoLatches, latchXminus:ref("latchXminus"), latchXplus:ref("latchXplus"))
        {//begin description of autochanger latches children
            //*************************************//
            // autochanger latchXminus description
            //*************************************//
            latchXminus (AutochangerLatch,
                latchController:ref("latchXminusController"),
                closeSensors:ref("closeSensorsLatchXminus"),
                openSensors:ref("openSensorsLatchXminus"),
                filterEngagedSensors:ref("filterEngagedSensorsLatchXminus"),
            )
            {//begin description of autochanger latchXminus children
                closeSensorsLatchXminus ( ComplementarySensors,
                    sensor:ref("closeSensorLatchXminus"),
                    sensorC:ref("closeSensorBLatchXminus")
                )
                {//begin description of autochanger lockSensorslatchXminus children
                    closeSensorLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:0, byteNumero:0)
                    closeSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:1, byteNumero:0)
                }//end description of autochanger lockSensorslatchXminus children                
                
                openSensorsLatchXminus ( ComplementarySensors,
                    sensor:ref("openSensorLatchXminus"),
                    sensorC:ref("openSensorBLatchXminus")
                ) {//begin description of autochanger unlockSensorslatchXminus children
                    openSensorLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:2, byteNumero:0)
                    openSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:3, byteNumero:0)
                }//end description of autochanger unlockSensorslatchXminus children
                
                filterEngagedSensorsLatchXminus ( ComplementarySensors,
                    sensor:ref("filterEngagedSensorLatchXminus"),
                    sensorC:ref("filterEngagedSensorBLatchXminus")
                )
                {//begin description of autochanger filterEngagedSensorslatchXminus children
                    filterEngagedSensorLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:4, byteNumero:0)
                    filterEngagedSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:5, byteNumero:0)
                }//end description of autochanger filterEngagedSensorslatchXminus children
            }//end description of autochanger latchXminus children
            //**********************************************//
            // end of autochanger latchXminus description   //
            //**********************************************//
            //*************************************//
            // autochanger latchXplus description
            //*************************************//
            latchXplus (AutochangerLatch,
                latchController:ref("latchXplusController"),
                closeSensors:ref("closeSensorsLatchXplus"),
                openSensors:ref("openSensorsLatchXplus"),
                filterEngagedSensors:ref("filterEngagedSensorsLatchXplus"),
            )
            {//begin description of autochanger latchXplus children

                closeSensorsLatchXplus ( ComplementarySensors,
                    sensor:ref("closeSensorLatchXplus"),
                    sensorC:ref("closeSensorBLatchXplus")
                )
                {//begin description of autochanger lockSensorslatchXplus children
                    closeSensorLatchXplus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:0, byteNumero:8)
                    closeSensorBLatchXplus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:1, byteNumero:8)
                }//end description of autochanger lockSensorslatchXplus children
                openSensorsLatchXplus ( ComplementarySensors,
                     sensor:ref("openSensorLatchXplus"),
                     sensorC:ref("openSensorBLatchXplus")
                 )     
                 {//begin description of autochanger unlockSensorslatchXplus children
                     openSensorLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:2, byteNumero:8)
                     openSensorBLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:3, byteNumero:8)
                 }//end description of autochanger unlockSensorslatchXplus children
 
                 filterEngagedSensorsLatchXplus ( ComplementarySensors,
                     sensor:ref("filterEngagedSensorLatchXplus"),
                     sensorC:ref("filterEngagedSensorBLatchXplus")
                 )
                 {//begin description of autochanger filterEngagedSensorslatchXplus children
                     filterEngagedSensorLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:4, byteNumero:8)
                     filterEngagedSensorBLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:5, byteNumero:8)
                }//end description of autochanger filterEngagedSensorslatchXplus children

            }//end description of autochanger latchXplus children
            //**********************************************//
            // end of autochanger latchXplus description   //
            //**********************************************//
        }//end description of autochanger latches children
        //*****************************************************************************//
        // end of autochanger latches description
        //*****************************************************************************//
        
        //**************************************************************************//
        //**************************************************************************//
        // autochanger onlineClamps description
        //**************************************************************************//
        //**************************************************************************//
        onlineClamps (AutochangerThreeOnlineClamps, 
            onlineClampXminus:ref("onlineClampXminus"), 
            onlineClampXplus:ref("onlineClampXplus"), 
            onlineClampYminus:ref("onlineClampYminus")) 
        {//begin description of autochanger onlineClamps children
            
            onlineClampXminus(AutochangerOnlineClamp ,
                controller:ref("onlineClampXminusController"),
                closeSensors:ref("onlineClampXminusCloseSensors"),
                openSensors:ref("onlineClampXminusOpenSensors"),
            )
            {//begin description of autochanger onlineClampXminus children
                onlineClampXminusCloseSensors ( ComplementarySensors,
                    sensor:ref("onlineClampXminusCloseSensor"),
                    sensorC:ref("onlineClampXminusCloseSensorC")
                )
                {//begin description of autochanger onlineClampXminusCloseSensors children
                    onlineClampXminusCloseSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:6, byteNumero:1)
                    onlineClampXminusCloseSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:7, byteNumero:1)
                }//end description of autochanger onlineClampXminusCloseSensors children
                
                onlineClampXminusOpenSensors ( ComplementarySensors,
                    sensor: ref("onlineClampXminusOpenSensor"),
                    sensorC: ref("onlineClampXminusOpenSensorC")
                )
                {
                    onlineClampXminusOpenSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 4, byteNumero:1)
                    onlineClampXminusOpenSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 5, byteNumero:1)  
                }
            }//end of  description of autochanger onlineClampXminus children
            
            onlineClampXplus(AutochangerOnlineClamp ,
                controller:ref("onlineClampXplusController"),
                closeSensors:ref("onlineClampXplusCloseSensors"),
                openSensors:ref("onlineClampXplusOpenSensors"),
            )
            {//begin description of autochanger onlineClampXplus children
                onlineClampXplusCloseSensors ( ComplementarySensors,
                    sensor: ref("onlineClampXplusCloseSensor"),
                    sensorC: ref("onlineClampXplusCloseSensorC"),
                )
                {
                    onlineClampXplusCloseSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 6, byteNumero: 9)
                    onlineClampXplusCloseSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 7, byteNumero: 9)
                }
                
                onlineClampXplusOpenSensors ( ComplementarySensors,
                    sensor: ref("onlineClampXplusOpenSensor"),
                    sensorC: ref("onlineClampXplusOpenSensorC"),
                )
                {
                    onlineClampXplusOpenSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName,inputNumero: 4, byteNumero: 9)
                    onlineClampXplusOpenSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 5, byteNumero: 9)
                }
            }//end of  description of autochanger onlineClampXplus children
            
            onlineClampYminus(AutochangerOnlineClamp ,
                controller:ref("onlineClampYminusController"),
                closeSensors:ref("onlineClampYminusCloseSensors"),
                openSensors:ref("onlineClampYminusOpenSensors"),
            )
            {//begin description of autochanger onlineClampYminus children
                onlineClampYminusCloseSensors ( ComplementarySensors,
                    sensor: ref("onlineClampYminusCloseSensor"),
                    sensorC: ref("onlineClampYminusCloseSensorC"),
                )
                {
                    onlineClampYminusCloseSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 2, byteNumero: 2)
                    onlineClampYminusCloseSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 3, byteNumero: 2)
                }
                onlineClampYminusOpenSensors ( ComplementarySensors,
                    sensor: ref("onlineClampYminusOpenSensor"),
                    sensorC: ref("onlineClampYminusOpenSensorC"),
                )
                {
                    onlineClampYminusOpenSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 0, byteNumero: 2)
                    onlineClampYminusOpenSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 1, byteNumero: 2)
                }
            }//end of  description of autochanger onlineClampYminus children
        }//end of  description of autochanger onlineClamps children
        //**************************************************************************//
        // end of autochanger onlineClamps description
        //**************************************************************************//
        inclinometerXminus (Inclinometer, deviceName:acPlutoGatewayName, byteNumero: 6)
        inclinometerXplus (Inclinometer, deviceName:acPlutoGatewayName, byteNumero: 12)


    }//end description of autochanger children
    //*****************************************************************************//
    //*****************************************************************************//
    // end of autochanger description
    //*****************************************************************************//
    //*****************************************************************************//
    //begin description of loader
    loader (Loader)
    {//begin description of loader's children

        carrier(LoaderCarrier,
            handoffSensors:ref("loaderHandoffSensors"),
            storageSensors:ref("loaderStorageSensors"),
            engagedSensors:ref("loaderEngagedSensors")
        )
        {//begin description of loader carrier's children
            loaderEngagedSensors (RedondantSensors,
                sensor:ref("loaderEngagedPositionSensor0"), 
                sensorR: ref("loaderEngagedPositionSensor1")
            )
            {//begin description of loader engagedSensors
                loaderEngagedPositionSensor0 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:6,byteNumero:3)

                loaderEngagedPositionSensor1 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:7,byteNumero:3)
            }//end description of loader engagedSensors
            loaderHandoffSensors (RedondantSensors,
                sensor:ref("loaderHandoffPositionSensor0"), 
                sensorR: ref("loaderHandoffPositionSensor1")
            )
            {//begin description of loader handoffSensors
                loaderHandoffPositionSensor0 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:0,byteNumero:6)

                loaderHandoffPositionSensor1 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:1,byteNumero:6)
            }//end description of loader handoffSensors
            
            loaderStorageSensors (RedondantSensors,
                sensor:ref("loaderStoragePositionSensor0"),
                sensorR:ref("loaderStoragePositionSensor1"),
            )
            {//begin description of loader storageSensors
                //user_to_gateway n° 1
                loaderStoragePositionSensor0 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName, inputNumero:4,byteNumero:3)

                loaderStoragePositionSensor1 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName, inputNumero:5, byteNumero:3)  
            }//end description of loader storageSensors
        }//end description of loader carrier's children

        clamp(LoaderClamp,
            hook1:ref("hook1"),hook2:ref("hook2"), hook3:ref("hook3"),hook4:ref("hook4"),
            forceSensor0:ref("forceSensor0"), forceSensor1:ref("forceSensor1"),
            clampedStatusSensor: ref("clampedStatusSensor"),
            )
        {//begin description of loader clamp's children
            int[] inputNumeroClose = [4,5,6,7];
            int[] inputNumeroOpen = [0,1,2,3];
            for (int i = 1; i<5; i++) {
            
            "hook${i}"(LoaderHook,
                    closeSensor:ref("loaderCloseSensor${i}"), openSensor:ref("loaderOpenSensor${i}"))
                { //user_to_gateway n° 1
                    "loaderCloseSensor${i}" ( DigitalSensor , //closeHookSensor0
                        dioName:loaderPlutoGatewayName, inputNumero:inputNumeroClose[i-1], byteNumero:2)
                       
                    "loaderOpenSensor${i}" ( DigitalSensor , //openHookSensor0
                        dioName:loaderPlutoGatewayName, inputNumero:inputNumeroOpen[i-1], byteNumero:2)
                }
            }
            
            forceSensor0(ForceSensor, deviceName:loaderPlutoGatewayName, byteNumero:4)
            
            forceSensor1(ForceSensor, deviceName:loaderPlutoGatewayName, byteNumero:8)

            // user_to_gateway n° 2
            unclampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:2,byteNumero:6)
            
            underClampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:3,byteNumero:6)
            
            clampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:4,byteNumero:6) 
            
            overClampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:5,byteNumero:6)
        
        }//end description of loader clamp's children

       
        loaderFilterPresenceSensors (RedondantSensors,
            sensor:ref("loaderFilterPresenceSensor0"),
            sensorR:ref("loaderFilterPresenceSensor1"),
        )
        { // user_to_gateway n° 1
            loaderFilterPresenceSensor0(DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:0, byteNumero:3)

            loaderFilterPresenceSensor1(DigitalSensor ,
                dioName:loaderPlutoGatewayName, inputNumero:1, byteNumero:3) 
        }

        loaderOnCameraSensors (RedondantSensors,
            sensor:ref("loaderOnCameraSensor0"),
            sensorR:ref("loaderOnCameraSensor1"),
        )
        { // user_to_gateway n° 1
            loaderOnCameraSensor0(DigitalSensor ,
                dioName:loaderPlutoGatewayName, inputNumero:2, byteNumero:3)

            loaderOnCameraSensor1(DigitalSensor ,
                dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:3)
        }
        //Signals comming from autochanger//
        //AP2 user_to_gateway 3 input 0
        //AF0 user_to_gateway 3 input 1
        //AF1 user_to_gateway 3 input 2
        //AF3 user_to_gateway 3 input 3
        acAP2 (ComplementarySensors,
            sensor:ref("acAP2s"),
            sensorC:ref("acAP2b"),
        ) {
            acAP2s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:0, byteNumero:11)
            acAP2b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:1, byteNumero:11)
        }
        
        acAF0 (ComplementarySensors,
            sensor:ref("acAF0s"),
            sensorC:ref("acAF0b"),
        ) {
            acAF0s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:2, byteNumero:11)
            acAF0b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:11)
        } 
        
        acAF1 (ComplementarySensors,
            sensor:ref("acAF1s"),
            sensorC:ref("acAF1b"),
        ) {
            acAF1s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:4, byteNumero:11)
            acAF1b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:5, byteNumero:11)
        } 
        
        acAF3 (ComplementarySensors,
            sensor:ref("acAF3s"),
            sensorC:ref("acAF3b"),
        ) {
            acAF3s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:6, byteNumero:11)
            acAF3b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:7, byteNumero:11)
        } 
        
        //key lock or permit signal
        keyLockSensors (ComplementarySensors,
            sensor:ref("keyLock"),
            sensorC:ref("keyLockb"),
        ) {
            keyLock (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:0, byteNumero:10)
            keyLockb (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:1, byteNumero:10)
        }
        
        //engineering key
        keyEngSensors (ComplementarySensors,
            sensor:ref("keyEng"),
            sensorC:ref("keyEngb"),
        ) {
            keyEng (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:2, byteNumero:10)
            keyEngb (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:10)
        }
        //end of Signals comming from autochanger// 
            
    }//end description of loader's children
            
} // end description of main (FcsMain)
