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.description.groovy.CCSBuilder


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 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:1,weight:38,socketName:"socket1")
        filterG (Filter,
            filterID:2,weight:33,socketName:"socket2")
        filterR (Filter,
            filterID:3,weight:30,socketName:"socket3")
        filterI (Filter,
            filterID:4,weight:28,socketName:"socket4")
        filterZ (Filter,
            filterID:5,weight:28,socketName:"socket5")
        filterY (Filter,
            filterID:6,weight:22.5,socketName:"OUT")
        dummyFilter (Filter,
            filterID:10,weight:44.5,socketName:"OUT")
    }//end description of filter manager's children
    // END Filter Manager description
    // ------------------------------
    
    //-------------------------
    // tcp Proxy
    tcpProxy (CanOpenProxy, hardwareBootTimeout:2500) {
        
        canInterface(SimuTcpProxy)      
        //Carousel controllers
        "$clampXminusControllerName" (SimuCarouselClampController,
            nodeID:0x1a,serialNB:"79003317",
            paramsForCurrent:[
                MotorType:11, PositionSensorType:3,PolePairNumber:8,
                ContinuousCurrentLimit:2360,OutputCurrentLimit:4720,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:25],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])  
        
        "$clampXplusControllerName" (SimuCarouselClampController,
            nodeID:0x1b,serialNB:"79003313",
            paramsForCurrent:[MotorType:11, PositionSensorType:3,PolePairNumber:8,
                ContinuousCurrentLimit:2360,OutputCurrentLimit:4720,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:25],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        
        carouselController (SimuCarouselController,
            nodeID:0xc,serialNB:"80003117",
            paramsForCurrent:[
                ContinuousCurrentLimit:3440,
                OutputCurrentLimit:6880,
                MaxSpeedInCurrentMode:2000,
                MotorType:10,PolePairNumber:1,
                PositionSensorType:1],
            paramsForProfilePosition:[
                MinPositionLimit:-300,
                MaxPositionLimit:550000,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        
        // can open devices to read carousel clamps sensors
        hyttc580 (CanOpenDevice,nodeID:0x1d,serialNB:"44110125008180")
        
        // can open devices to read carousel brakes sensors and temperatures
        ai814 (SimuCanOpenADC,nodeID:0x1e,serialNB:"c7yyyyyy",transmissionType:1)
        
        // can open devices to read carousel brakes sensors and temperatures
        pt100 (CanOpenDevice, nodeID:0x1f,serialNB:"c7zzzzzz")
        
        // autochanger can open devices
        //sensors gateway
        "$acPlutoGatewayName" (SimuAutochangerPlutoGateway,
            nodeID:0x6,serialNB:"3269")
        
        brakeSystemGateway (CanOpenPlutoGateway,
            nodeID:0x2b,serialNB:"2071")
        
        tempSensorsDevice (CanOpenDevice,
            nodeID: 0x20, serialNB:"4bb6b")
        
        linearRailMasterController (SimuAutochangerLinearRailController, 
            nodeID:0x2a, serialNB:"80001881",
            plutoGateway:ref("$acPlutoGatewayName"),
            paramsForCurrent:[
                MotorType:10, PositionSensorType:260,PolePairNumber:1,
                ContinuousCurrentLimit:7200,OutputCurrentLimit:14400,
                ThermalTimeConstantWinding:187,
                MaxSpeedInCurrentMode:9140],
            paramsForProfilePosition:[
                ProfileAcceleration:1207,
                ProfileDeceleration:1207,
                MaxProfileVelocity:322,
                QuickStopDeceleration:1207,
                MaxFollowingError:200000,
                ProfileVelocity:281,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
            encoderRibbonMinValue:8161299,
        )
        
        // autochanger can open devices
        linearRailSlaveController (SimuAutochangerLinearRailController, 
            nodeID:0x2c,serialNB:"80001932",plutoGateway:ref("$acPlutoGatewayName"),
            paramsForCurrent:[
                MotorType:10, PositionSensorType:1,PolePairNumber:1,
                ContinuousCurrentLimit:7200,OutputCurrentLimit:14400,
                ThermalTimeConstantWinding:187,
                MaxSpeedInCurrentMode:9140],
            paramsForProfilePosition:[
                ProfileAcceleration:30000,
                ProfileDeceleration:30000,
                ProfileVelocity:7000,
                QuickStopDeceleration:30000,
                MaxFollowingError:7000,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0],
            encoderRibbonMinValue:7449994,
        )
        
        // autochanger can open devices   
        latchXminusController (SimuAutochangerLatchController,  //CanOpenEPOS24-3
            nodeID:0x4,serialNB:"84004711",latchName:"latchXminus",
            plutoGateway:ref("$acPlutoGatewayName"),
            paramsForCurrent:[
                MotorType:1, PositionSensorType:0,PolePairNumber:2,
                ContinuousCurrentLimit:300,OutputCurrentLimit:200,
                ThermalTimeConstantWinding:40,
                MaxSpeedInCurrentMode:100],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        
        // autochanger can open devices
        latchXplusController (SimuAutochangerLatchController,  //CanOpenEPOS24-3
            nodeID:0x5,serialNB:"999XXXX",latchName:"latchXplus",
            plutoGateway:ref("$acPlutoGatewayName"),
            paramsForCurrent:[
                MotorType:1, PositionSensorType:0,PolePairNumber:2,
                ContinuousCurrentLimit:300,OutputCurrentLimit:200,
                ThermalTimeConstantWinding:40,
                MaxSpeedInCurrentMode:100],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        
        // autochanger can open devices
        onlineClampXminusController (SimuAutochangerOnlineClampController, 
            nodeID:0x3a,serialNB:"79011616",
            plutoGateway:ref("$acPlutoGatewayName"),
            onlineClampName:"onlineClampXminus",
            paramsForCurrent:[
                MotorType:1, PositionSensorType:0,PolePairNumber:1,
                ContinuousCurrentLimit:5000,OutputCurrentLimit:4000,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:6930],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomePosition:0]
        )
        
        // autochanger can open devices
        onlineClampXplusController (SimuAutochangerOnlineClampController, 
            nodeID:0x3b,serialNB:"xxxx99999",
            plutoGateway:ref("$acPlutoGatewayName"),
            onlineClampName:"onlineClampXplus",
            paramsForCurrent:[
                MotorType:1, PositionSensorType:0,PolePairNumber:1,
                ContinuousCurrentLimit:5000,OutputCurrentLimit:4000,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:6930],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomePosition:0]
        )
        
        // autochanger can open devices
        onlineClampYminusController (SimuAutochangerOnlineClampController, 
            nodeID:0x3c,serialNB:"xxxx99999",
            plutoGateway:ref("$acPlutoGatewayName"),
            onlineClampName:"onlineClampYminus",
            paramsForCurrent:[
                MotorType:1, PositionSensorType:0,PolePairNumber:1,
                ContinuousCurrentLimit:5000,OutputCurrentLimit:4000,
                ThermalTimeConstantWinding:160,
                MaxSpeedInCurrentMode:6930],
            paramsForProfilePosition:[MotionProfileType:0],
            paramsForHoming:[HomePosition:0]
        )
    }//end description of bridgeToChanger's children
    //----------------------------------------------
    // END Bridge To CHANGER description
    //----------------------------------------------                
    //
    //-------------------------------------------------
    // BEGIN Bridge To LOADER description
    //-------------------------------------------------
    // Loader tcp Proxy
        "$bridgeToLoaderName" (CanOpenProxy, hardwareBootTimeout:1000) {
        
        loaderCanInterface(SimuTcpProxy)
        // description of plutoGateway
        "$loaderPlutoGatewayName" (SimuLoaderPlutoGateway, 
            nodeID:0x1,serialNB:"22d6")
        
        hooksController (SimuLoaderClampController,
            nodeID:0x1b,serialNB:"79007141",
            plutoGateway:ref("$loaderPlutoGatewayName"),
            paramsForCurrent:[
                ContinuousCurrentLimit:3440,
                OutputCurrentLimit:6880,
                MaxSpeedInCurrentMode:2000,
                MotorType:10,PolePairNumber:1,
                PositionSensorType:1],
            paramsForProfilePosition:[
                MinPositionLimit:-300,
                MaxPositionLimit:550000,
                MotionProfileType:0],
            paramsForHoming:[HomeOffset:0])
        carrierController (SimuLoaderCarrierController,
            nodeID:0x1a,serialNB:"80003184",
            plutoGateway:ref("$loaderPlutoGatewayName"),
            paramsForCurrent:[
                ContinuousCurrentLimit:7290,
                OutputCurrentLimit:14580,
                MaxSpeedInCurrentMode:9840,
                MotorType:10,
                PositionSensorType:4,
                ThermalTimeConstantWinding:187,
                PolePairNumber:1],
            paramsForProfilePosition:[
                MinPositionLimit:-250,
                MaxPositionLimit:1037700,
                MotionProfileType:0,
                MaxFollowingError:6000,
                MaxProfileVelocity:227, 
                ProfileVelocity:120,
                ProfileAcceleration:100,
                ProfileDeceleration:100,
                QuickStopDeceleration:10000],
            paramsForHoming:[
                HomeOffset:0,
                HomingAcceleration:1000,
                CurrentThresholdHomingMode:500])
        
    }//end description of Loader bridge's children
    //----------------------------------------------
    // END Bridge To LOADER description
    //----------------------------------------------
        //-------------------------
    // BEGIN Filter Identificator description
    
    filterIdentificator(FilterIdentificator, plutoGateway:ref("$acPlutoGatewayName"))
    {//begin description of filter Identificator's children
        filterIDSensor0 ( DigitalSensor ,
            dioName:acPlutoGatewayName,inputNumero: 0,byteNumero: 5)
        filterIDSensor1 ( DigitalSensor ,
            dioName:acPlutoGatewayName,inputNumero: 1,byteNumero: 5)
        filterIDSensor2 ( DigitalSensor ,
            dioName:acPlutoGatewayName,inputNumero: 2,byteNumero: 5)
        filterIDSensor3 ( DigitalSensor ,
            dioName:acPlutoGatewayName,inputNumero: 3,byteNumero: 5)
        filterIDSensor4 ( DigitalSensor ,
            dioName:acPlutoGatewayName,inputNumero: 4,byteNumero: 5)  
        filterIDSensor5 ( DigitalSensor ,
            dioName:acPlutoGatewayName,inputNumero: 5,byteNumero: 5) 
    }//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

        for (int i = 1; i<6;i++) {
            "socket${i}"( CarouselSocket,
                clampXminus:ref("clampXminus${i}"),
                clampXplus:ref("clampXplus${i}"),
                standbyPosition: standbyPositionSocket[i-1]) {   
                //-------------------------
                // BEGIN clampXminus description
            "clampXminus${i}" (CarouselClamp,
                    filterPresenceSensor:ref("filterPresenceXminus${i}"),
                    lockSensor:ref("lockSensorXminus${i}"),
//                    thermometer:ref("thermometerXminus${i}")
                ) 
                {
                    "filterPresenceXminus${i}" (SimuCarouselClampFilterPresenceSensor,
                        adc:ref("$adcName"), numOfAnalogInput:numOfAnalogInputFilterPresenceSensorXminus[i-1])
                    
                    "lockSensorXminus${i}" (SimuCarouselClampLockSensor,
                        adc:ref("$adcName"), numOfAnalogInput:numOfAnalogInputLockSensorXminus[i-1]) 
                    
//                    "thermometerXminus${i}" (SimuThermometer)
                }
                //-------------------------
                // END clampXminus description
                
                //-------------------------
                // BEGIN clampXplus description
            "clampXplus${i}" (CarouselClamp,
                    filterPresenceSensor:ref("filterPresenceXplus${i}"),
                    lockSensor:ref("lockSensorXplus${i}"),
//                    thermometer:ref("thermometerXplus${i}")
                ) 
                {
                    "filterPresenceXplus${i}" (SimuCarouselClampFilterPresenceSensor,
                        adc:ref("$adcName"), numOfAnalogInput:numOfAnalogInputFilterPresenceSensorXplus[i-1])
                    
                    "lockSensorXplus${i}" (SimuCarouselClampLockSensor,
                        adc:ref("$adcName"), numOfAnalogInput:numOfAnalogInputLockSensorXplus[i-1])
                    
//                    "thermometerXplus${i}" (SimuThermometer)
                }
                //-------------------------
                // END clampXplus description
            } // END carouselSocket /*SOCKET1*/ description 
        }
        // END carouselSocket /*SOCKET5*/ description
    }//end description of carousel's children
    //
    //END Carousel description
    // ------------------------
    
    
    //**************************************************************************//
    //**************************************************************************//
    // autochanger
    //**************************************************************************//
    //**************************************************************************//
    autochanger(Autochanger, plutoGateway:ref("$acPlutoGatewayName")) {
        ////begin description of autochanger
        loaderConnectedSensors (ComplementarySensors,
            sensor:ref("loaderConnectedSensor"),
            sensorC:ref("loaderConnectedSensorC"),
            )
        {//begin description of autochanger loaderConnectedSensors children
            loaderConnectedSensor ( DigitalSensor ,
                dioName:acPlutoGatewayName, inputNumero:4, byteNumero:2)
            loaderConnectedSensorC ( DigitalSensor ,
                dioName:acPlutoGatewayName, inputNumero:5, byteNumero:2)
        }//end description of autochanger loaderConnectedSensors children 
        //**************************************************************************//
        // 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:2, byteNumero:0)
                    closeSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:3, 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:0, byteNumero:0)
                    openSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:1, 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:2, byteNumero:8)
                    closeSensorBLatchXplus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:3, 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:0, byteNumero:8)
                    openSensorBLatchXplus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:1, 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, plutoGateway:ref("$acPlutoGatewayName"), byteNumero: 6)
        inclinometerXplus (Inclinometer, plutoGateway: ref("$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"),
            )
            {//begin description of loader carrier's children 
                loaderHandoffSensors (RedondantSensors,
                    sensor:ref("loaderHandoffPositionSensor0"), 
                    sensorR: ref("loaderHandoffPositionSensor1")
                )
                {//begin description of loader handoffSensors
                    loaderHandoffPositionSensor0 ( DigitalSensor ,
                        dioName:loaderPlutoGatewayName,inputNumero:6,byteNumero:3)

                    loaderHandoffPositionSensor1 ( DigitalSensor ,
                        dioName:loaderPlutoGatewayName,inputNumero:7,byteNumero:3)
                }//end description of loader handoffSensors

                loaderStorageSensors (RedondantSensors,
                    sensor:ref("loaderStoragePositionSensor0"),
                    sensorR:ref("loaderStoragePositionSensor1"),
                )
                {//begin description of loader storageSensors
                    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}"))
                {
                    "loaderCloseSensor${i}" ( DigitalSensor , //closeHookSensor0
                        dioName:loaderPlutoGatewayName, inputNumero:inputNumeroClose[i-1], byteNumero:0)
                       
                    "loaderOpenSensor${i}" ( DigitalSensor , //openHookSensor0
                        dioName:loaderPlutoGatewayName, inputNumero:inputNumeroOpen[i-1], byteNumero:0)
                }
            }
            
            forceSensor0(ForceSensor, byteNumero:4)
            
            forceSensor1(ForceSensor, byteNumero:8)
            
            forceSensorStatus0 ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:2,byteNumero:6)
            
            forceSensorStatus1 ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:3,byteNumero:6)
            
            clampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:4,byteNumero:6)
        
        }//end description of loader clamp's children

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

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

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

                loaderOnCameraSensor1(DigitalSensor ,
                    dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:3)
            }
        }//end description of loader's children
            
} // end description of main (FcsMain)
