package org.vishia.exampleJava2C.java4c;

import org.vishia.exampleJava2C.emulationEnv.MainEmulation.WayActuator;
import org.vishia.exampleJava2C.emulationEnv.MainEmulation.WaySensor;

/**This class is the example main class to control a movement.
 * 
 * @author JcHartmut
 *
 */ 
public class MainController
{
  final WaySensor way1Sensor, way2Sensor;
  
  final WayActuator way1Actuator, way2Actuator;
  
  /** The set value for the way in 0.1mm-units from above -3 m to 3 m. */
  short wWay = 1000;
  
  /**controller offset. */
  int dWay;
  
  /**Simple set value: add 0.5 mm per step */
  short addWay = 5;
  
  final PID_controller pidCtrl1 = new PID_controller();
  

  /**The constructor of this Controller assumes, that the depended instances all built always. 
   * @param broker Interface contains all require methods to depended instances.
   */
  public MainController(iRequireMainController broker)
  { way1Sensor = broker.requireWay1Sensor();
    way2Sensor = broker.requireWay2Sensor();
    way1Actuator = broker.requireWay1Actuator();
    way2Actuator = broker.requireWay2Actuator();
  }
  
 
  /**Gets the set value in units mm*/
  public short getWaySetvalue(){ return wWay; }
  
  /**Gets the offset of the controller on input*/
  public int getWayOffset(){ return dWay; }
  
  
  /**This is the cyclical called method to execute the controlling. */
  public void step()
  {
    //reads the inputs from Hardware, it is in units 1 micrometer.
    int xWay = way1Sensor.getWay();

    //first example: way moves up and down between 1000 and 2000.
    if(wWay >= 2000){ addWay = -5; }
    else if(wWay <= 1000){ addWay = 5; }
    wWay += addWay;
    
    /**difference of way in units 1 Micrometer, range should be -32..32 mm. */
    dWay = xWay - 100 * wWay;

    /**The actuating variable for the movement. It is a voltage for a motor in range -10000 to 10000, unit milliVolt. */
    short yOut;
    if(dWay > 30000)
    { //The way is out of range, move down.
      yOut = -10000;
    }
    else if(dWay < -30000)
    { //The way is out of range, move up.
      yOut = 10000;
    }
    else
    { //because the dway should be in range -3..3 cm (normally in mm-range), the calculation may be done with
      16-bit-accuracy.
      yOut = pidCtrl1.process((short)(-dWay));
    }  
    
    way1Actuator.setMotorVoltage(yOut);
  }

  /**Get the internal value of the integrator of the first way controller. */
  public float getWay11Intg(){ return pidCtrl1.getIntg(); }

  /**This interface contains all requirenesses of the MainController
   * from the external environment. It should be implemented in the constructing class.
   * @author JcHartmut
   *
   */
  public interface iRequireMainController
  { WaySensor requireWay1Sensor();
    WaySensor requireWay2Sensor();
    WayActuator requireWay1Actuator();
    WayActuator requireWay2Actuator();
  }

}