Answers.Body: <p>This is EV3-G code for a PID based on <a href="http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html" rel="nofollow noreferrer">PID Controller for Lego Mindstorms Robots by J Sluka</a>.  It uses the steering parameter of the Move block instead of power levels of the Motor block.  The interesting parts are setting the Kp, Ki, and Kd values.</p>
  
  <p><img src="https://i.sstatic.net/ddB8F.png" alt="enter image description here"></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-09T19:10:33.020Z
Answers.Text: i understand that code. But how to make robot go straight for 5 rotations for example. without waiting between rotations ? thanks
Answers.UserDisplayName: Vuk Lazovic
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-10T02:29:38.793Z
Answers.Text: Good point, this example runs forever. One way to implement stopping after 5 rotations, would be to replace the infinite loop with a loop that runs until the left motor + right motor   > 10 rotations. Obviously, that would be less than ideal.
Answers.UserDisplayName: dfrevert
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-06T22:57:32.423Z
Answers.LastActivityDate: 2014-09-06T22:57:32.423Z
Answers.UserDisplayName: dfrevert
Answers.Body: <p>The best documentation I have found for PID is "A PID Controller For Lego Mindstorms Robots" by J. Sluka</p>
  
  <p>J. Sluka 
  Send me an email at:
  Lego at InPharmix dot com</p>
  
  <p>It is written for the NXT and needs to be updated for the EV3.  But it has really helped me out.  I am working on a maze solver and used PID to follow the wall.  I prefer to program the EV3 in python and have included the code here.</p>
  
  <pre><code>#!/usr/bin/env python3
  # so this script/program can be run from Brickman
  
  from ev3dev.ev3 import *
  from time import sleep
  
  import ev3dev.ev3 as ev3
  
  print('Auto Driver TubeBotEZ.py')
  # File EV3 Python TubeBot.py
  ev3.Sound.speak('python Tube Robot easy 2').wait()
  
  LeftWheel = LargeMotor('outA')
  RightWheel = LargeMotor('outB')
  ir = InfraredSensor()
  # assert ir.connected, "Connect a single infrared sensor to any sensor port"
  
  ts = TouchSensor()
  # assert ts.connected, "Connect a touch sensor to any port"
  # can have 2 statements on same line if use semi colon
  
  # Put the infrared sensor into proximity mode.
  ir.mode = 'IR-PROX'
  
  DelayTime = 0
  Target = 10
  Error = 0
  Integral = 0
  Derivative = 0
  LastError = 0
  Kp = 3
  Ki = 0
  Kd = 0
  PID = 1
  Time = 400
  LeftPower = 1
  RightPower = 1
  MaxTurnPower = 200
  Iteration = 0
  Distance = 0
  SpeedFactor = 300
  y = 0
  Speed = 100
  OldDistance = 1000
  DistanceL = 1
  DistanceR = 2
  
  Beginning = '{:3d}        Start                        Left Distance {:&gt;4.0f}     Right Distance {:&gt;4.0f}'.format(Iteration, DistanceL, DistanceR)
  Ending = '        LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
      LeftPower, RightPower)
  print(Beginning, Ending)
  
  #ev3.Sound.speak('Start').wait()
  sleep(DelayTime)
  Battery = True
  #Sound.speak('Point 1')
  while Battery:
      Leds.all_off()
  #    Leds.set_color(Leds.UP, Leds.GREEN)
  #    Leds.set_color(Leds.DOWN, Leds.GREEN)
      Leds.set_color(Leds.LEFT, Leds.GREEN)
      Leds.set_color(Leds.RIGHT, Leds.GREEN)
      # Phase 1
      if True:
  
  #        Sound.speak('SQUARE WALL')
          sleep(DelayTime)
          DistanceL = ir.value()
          LeftWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
          RightWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
          #sleep(DelayTime)   # Give the motor time to move
          #LeftWheel.stop()
          LeftWheel.wait_while('running')
          RightWheel.wait_while('running')
          #sleep(1)
          DistanceR = ir.value()
          if DistanceL != DistanceR:
              if DistanceL &lt; DistanceR:
                  while DistanceL &lt; DistanceR:
  #                    print('in Left loop')
  
  #                    Sound.speak('Left').wait()
                      sleep(DelayTime)   # Give the motor time to move
                      DistanceR = ir.value()
                      LeftWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
                      RightWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
                      sleep(DelayTime)   # Give the motor time to move
                      LeftWheel.stop()
                      LeftWheel.wait_while('running')
                      sleep(DelayTime)
                      DistanceL = ir.value()
                      Iteration += 1
                      Beginning = '{:3d}      Left      in                    Left Distance {:&gt;4.0f}     Right Distance {:&gt;4.0f}'.format(Iteration, DistanceL, DistanceR)
                      Ending = '        LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
                          LeftPower, RightPower)
                      print(Beginning, Ending)
  #                ev3.Sound.speak('Re set Right').wait()
                  LeftWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
                  RightWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
                  sleep(DelayTime)   # Give the motor time to move
                  LeftWheel.stop()
                  LeftWheel.wait_while('running')
                  sleep(DelayTime)
                  Iteration += 1
                  Beginning = '{:3d}       Left out                     Left Distance {:&gt;4.0f}     Right Distance {:&gt;4.0f}'.format(Iteration, DistanceL, DistanceR)
                  Ending = '        LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
                      LeftPower, RightPower)
                  print(Beginning, Ending)
                  Sound.beep()
              else:
                  while DistanceR &lt; DistanceL:
  #                    print('in while close loop')
  
  #                    ev3.Sound.speak('Right').wait()
                      sleep(DelayTime)
                      DistanceL = ir.value()
                      LeftWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
                      RightWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
                      sleep(DelayTime)  # Give the motor time to move
                      LeftWheel.stop()
                      LeftWheel.wait_while('running')
                      sleep(DelayTime)
                      DistanceR = ir.value()
                      Iteration += 1
                      Beginning = '{:3d}          Right   in                   Left Distance {:&gt;4.0f}     Right Distance {:&gt;4.0f}'.format(Iteration, DistanceL, DistanceR)
                      Ending = '        LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
                          LeftPower, RightPower)
                      print(Beginning, Ending)
  
  #                ev3.Sound.speak('Reset Left').wait()
                  LeftWheel.run_to_rel_pos(position_sp=-30, speed_sp=900, stop_action="hold")
                  RightWheel.run_to_rel_pos(position_sp=30, speed_sp=900, stop_action="hold")
                  sleep(DelayTime)  # Give the motor time to move
                  LeftWheel.stop()
                  LeftWheel.wait_while('running')
                  sleep(DelayTime)
                  Iteration += 1
                  Beginning = '{:3d}          Right   in       out            Left Distance {:&gt;4.0f}     Right Distance {:&gt;4.0f}'.format(Iteration, DistanceL, DistanceR)
                  Ending = '        LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
                      LeftPower, RightPower)
                  print(Beginning, Ending)
  
                  Sound.beep()
  
          Beginning = '{:3d}       Finished                     Left Distance {:&gt;4.0f}     Right Distance {:&gt;4.0f}'.format(Iteration, DistanceL, DistanceR)
          Ending = '        LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
              LeftPower, RightPower)
          print(Beginning, Ending)
          Sound.beep()
  
          Beginning = '{:3d}    Target {:3.0f}    Distance {:&gt;4.0f}'.format(Iteration, Target, Distance)
          Ending = '    Delta {:&gt;4.0f}    Integral {:&gt;5.0f}    Derivative {:&gt;5.0f}    LastError {:&gt;5.0f}    PID {:&gt;5.0f}    SpeedFactor {:&gt;5.0f}    LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
              Error, Integral, Derivative, LastError, PID, SpeedFactor, LeftPower, RightPower)
          print(Beginning, Ending)
          sleep(DelayTime)
  
          while not ts.value():  # Stop program by pressing touch sensor button
                  # Infrared sensor in proximity mode will measure distance to the closest
                  # object in front of it.
  
  #                    Sound.speak('FORWARD')
                      sleep(DelayTime)
                      Iteration += 1
                      Distance = ir.value()
                      if Distance &lt; Target:
  #                        print('in Distance &lt; Target loop')
                          Leds.set_color(Leds.LEFT, Leds.RED)
                          Leds.set_color(Leds.RIGHT, Leds.GREEN)
  
  #                        Sound.speak('RIGHT')
                          sleep(DelayTime)
                      else:
  #                        print('Close else')
                          Leds.set_color(Leds.LEFT, Leds.GREEN)
                          Leds.set_color(Leds.RIGHT, Leds.RED)
  
  #                        Sound.speak('LEFT')
                          sleep(DelayTime)
  
                      Error = Target - Distance
                      Integral += Error
                      Derivative = Error - LastError
  
                      if Integral &lt; -MaxTurnPower:
                          Integral = -MaxTurnPower
                      if Integral &gt; MaxTurnPower:
                          Integral = MaxTurnPower
  
                      if Derivative &lt; -MaxTurnPower:
                          Derivative = -MaxTurnPower
                      if Derivative &gt; MaxTurnPower:
                          Derivatine = MaxTurnPower
  
                      PID = Kp * Error + Ki * Integral + Kd * Derivative
  
                      if PID &lt; -MaxTurnPower:
                          PID = -MaxTurnPower
                      if PID &gt; MaxTurnPower:
                          PID = MaxTurnPower
  
                      LeftPower = SpeedFactor + PID
                      RightPower = SpeedFactor - PID
  
                      if LeftPower &lt; -900:
                          LeftPower = -901
                      if LeftPower &gt; 900:
                          LeftPower = 902
  
                      if RightPower &lt; -900:
                          RightPower = -903
                      if RightPower &gt; 900:
                          RightPower = 904
  
                      Beginning = '{:3d}    Target {:3.0f}    Distance {:&gt;4.0f}'.format(Iteration, Target, Distance)
                      Ending = '    Delta {:&gt;4.0f}    Integral {:&gt;5.0f}    Derivative {:&gt;5.0f}    LastError {:&gt;5.0f}    PID {:&gt;5.0f}    SpeedFactor {:&gt;5.0f}    LeftPower {:&gt;5.0f}    RightPower {:&gt;5.0f}'.format(
                          Error, Integral, Derivative, LastError, PID, SpeedFactor, LeftPower, RightPower)
  
                      print(Beginning, Ending)
                      LeftWheel.run_timed(time_sp=Time, speed_sp=LeftPower)
                      RightWheel.run_timed(time_sp=Time, speed_sp=RightPower)
  
                      LastError = Error
  
  #    Leds.set_color(Leds.UP, Leds.RED)
  #    Leds.set_color(Leds.DOWN, Leds.RED)
      Leds.set_color(Leds.LEFT, Leds.RED)
      Leds.set_color(Leds.RIGHT, Leds.RED)
      LeftWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
      RightWheel.run_to_rel_pos(position_sp=-400, speed_sp=900, stop_action="hold")
      Sound.beep()
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-13T11:30:07.873Z
Answers.Text: That is a great picture of a great EV3-G program written in a great programming  language editor.  I do not understand how your EV3-G editor in 2014 is better than my editor in 2017.  Is it possible that you are using the Macintosh software.
Answers.UserDisplayName: CL plane guy
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-13T11:41:36.643Z
Answers.Text: That is a great picture of a great EV3-G program written in a great programming  language editor.  I do not understand how your EV3-G editor in 2014 is better than my editor in 2017.  Is it possible that you are using the Macintosh software.      Specifically, when you break your code into rows, your wires are equally spaced between the rows.  My editor temporarily does that, but when the last end is anchored, the equal spacing is lost.  My EV3-G editor is up to date for 2017.  What am I missing?
Answers.UserDisplayName: CL plane guy
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-13T23:43:53.117Z
Answers.Text: "your EV3-G editor in 2014 is better than my editor in 2017" - it was written on a PC using the "education" version of EV3-G.  That version has comment blocks, which allow adding comments that travel with the linked blocks. It's available from the "Advanced" tab.  Either version is a free download. The image PID is known to work on the NXT brick, but not EV3. EV3 handles the loops too fast and needs to add a delay before re-entering the loop.
Answers.UserDisplayName: dfrevert
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-12T21:47:28.127Z
Answers.LastActivityDate: 2017-05-12T21:47:28.127Z
Answers.UserDisplayName: CL plane guy
Body: <p>I want to use <a href="https://en.wikipedia.org/wiki/PID_controller" rel="nofollow">PID</a> for my Ev3. I used PID for NXT-G before, but I have never used EV3-G before and don't know how to get PID. Could someone please post a screen shot of the code or upload the file?
  <br></p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-09-06T20:58:44.903Z
Comments.Text: Not clear whether "I used PID for NXT-G" means you wrote a PID in NXT-G for use on an NXT, or you bought a 3rd party PID control for use with an NXT.  Let's assume you want to write the program.  A starting point is: http://e-fisica.fc.up.pt/edicoes/8a-edicao/projectos/robo-sensorizado-com-lego-mindstorms/documentacao/PID%20Controller%20For%20Lego%20Mindstorms%20Robots.pdf (from a google search for "PID NXT").
Comments.UserDisplayName: dfrevert
Tags: <mindstorms><ev3><ev3-g>
Title: Code for PID for EV3-g
UserDisplayName: J_W
ThreadText: # Code for PID for EV3-g
  
  (Asked by: username_0 on 2014-08-02)
  
  I want to use [PID](https://en.wikipedia.org/wiki/PID_controller) for my Ev3. I used PID for NXT-G before, but I have never used EV3-G before and don't know how to get PID. Could someone please post a screen shot of the code or upload the file?
  
  **Tags:** mindstorms, ev3, ev3-g
  > **Comments:**
  > **username_1**: Not clear whether "I used PID for NXT-G" means you wrote a PID in NXT-G for use on an NXT, or you bought a 3rd party PID control for use with an NXT.  Let's assume you want to write the program.  A starting point is: http://e-fisica.fc.up.pt/edicoes/8a-edicao/projectos/robo-sensorizado-com-lego-mindstorms/documentacao/PID%20Controller%20For%20Lego%20Mindstorms%20Robots.pdf (from a google search for "PID NXT").  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2014-09-06. Score: 3
  
  This is EV3-G code for a PID based on [PID Controller for Lego Mindstorms Robots by J Sluka](http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html). It uses the steering parameter of the Move block instead of power levels of the Motor block. The interesting parts are setting the Kp, Ki, and Kd values.
  
  ![enter image description here](https://i.sstatic.net/ddB8F.png)
  
  > **Comments:**
  > **username_2**: i understand that code. But how to make robot go straight for 5 rotations for example. without waiting between rotations ? thanks  
  > **username_1**: Good point, this example runs forever. One way to implement stopping after 5 rotations, would be to replace the infinite loop with a loop that runs until the left motor + right motor   > 10 rotations. Obviously, that would be less than ideal.  
  
  ---
  
  ### Answer by username_3 on 2017-05-12. Score: 1
  
  The best documentation I have found for PID is "A PID Controller For Lego Mindstorms Robots" by J. Sluka
  J. Sluka 
  Send me an email at:
  Lego at InPharmix dot com
  It is written for the NXT and needs to be updated for the EV3.  But it has really helped me out.  I am working on a maze solver and used PID to follow the wall.  I prefer to program the EV3 in python and have included the code here.
  #!/usr/bin/env python3
  # so this script/program can be run from Brickman
  
  from ev3dev.ev3 import *
  from time import sleep
  
  import ev3dev.ev3 as ev3
  
  print('Auto Driver TubeBotEZ.py')
  # File EV3 Python TubeBot.py
  ev3.Sound.speak('python Tube Robot easy 2').wait()
  
  LeftWheel = LargeMotor('outA')
  RightWheel = LargeMotor('outB')
  ir = InfraredSensor()
  # assert ir.connected, "Connect a single infrared sensor to any sensor port"
  
  ts = TouchSensor()
  # assert ts.connected, "Connect a touch sensor to any port"
  # can have 2 statements on same line if use semi colon
  
  # Put the infrared sensor into proximity mode.
  ir.mode = 'IR-PROX'
  
  DelayTime = 0
  Target = 10
  Error = 0
  Integral = 0
  Derivative = 0
  LastError = 0
  Kp = 3
  Ki = 0
  Kd = 0
  PID = 1
  Time = 400
  LeftPower = 1
  RightPower = 1
  MaxTurnPower = 200
  Iteration = 0
  Distance = 0
  SpeedFactor = 300
  y = 0
  Speed = 100
  OldDistance = 1000
  DistanceL = 1
  DistanceR = 2
  
  Beginning = '{:3d}        Start                        Left Distance {:>4.0f}     Right Distance {:>4.0f}'.format(Iteration, DistanceL, DistanceR)
  Ending = '        LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
      LeftPower, RightPower)
  print(Beginning, Ending)
  
  #ev3.Sound.speak('Start').wait()
  sleep(DelayTime)
  Battery = True
  #Sound.speak('Point 1')
  while Battery:
      Leds.all_off()
  #    Leds.set_color(Leds.UP, Leds.GREEN)
  #    Leds.set_color(Leds.DOWN, Leds.GREEN)
      Leds.set_color(Leds.LEFT, Leds.GREEN)
      Leds.set_color(Leds.RIGHT, Leds.GREEN)
      # Phase 1
      if True:
  
  #        Sound.speak('SQUARE WALL')
          sleep(DelayTime)
          DistanceL = ir.value()
          LeftWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
          RightWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
          #sleep(DelayTime)   # Give the motor time to move
          #LeftWheel.stop()
          LeftWheel.wait_while('running')
          RightWheel.wait_while('running')
          #sleep(1)
          DistanceR = ir.value()
          if DistanceL != DistanceR:
              if DistanceL < DistanceR:
                  while DistanceL < DistanceR:
  #                    print('in Left loop')
  
  #                    Sound.speak('Left').wait()
                      sleep(DelayTime)   # Give the motor time to move
                      DistanceR = ir.value()
                      LeftWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
                      RightWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
                      sleep(DelayTime)   # Give the motor time to move
                      LeftWheel.stop()
                      LeftWheel.wait_while('running')
                      sleep(DelayTime)
                      DistanceL = ir.value()
                      Iteration += 1
                      Beginning = '{:3d}      Left      in                    Left Distance {:>4.0f}     Right Distance {:>4.0f}'.format(Iteration, DistanceL, DistanceR)
                      Ending = '        LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
                          LeftPower, RightPower)
                      print(Beginning, Ending)
  #                ev3.Sound.speak('Re set Right').wait()
                  LeftWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
                  RightWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
                  sleep(DelayTime)   # Give the motor time to move
                  LeftWheel.stop()
                  LeftWheel.wait_while('running')
                  sleep(DelayTime)
                  Iteration += 1
                  Beginning = '{:3d}       Left out                     Left Distance {:>4.0f}     Right Distance {:>4.0f}'.format(Iteration, DistanceL, DistanceR)
                  Ending = '        LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
                      LeftPower, RightPower)
                  print(Beginning, Ending)
                  Sound.beep()
              else:
                  while DistanceR < DistanceL:
  #                    print('in while close loop')
  
  #                    ev3.Sound.speak('Right').wait()
                      sleep(DelayTime)
                      DistanceL = ir.value()
                      LeftWheel.run_to_rel_pos(position_sp=20, speed_sp=900, stop_action="hold")
                      RightWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
                      sleep(DelayTime)  # Give the motor time to move
                      LeftWheel.stop()
                      LeftWheel.wait_while('running')
                      sleep(DelayTime)
                      DistanceR = ir.value()
                      Iteration += 1
                      Beginning = '{:3d}          Right   in                   Left Distance {:>4.0f}     Right Distance {:>4.0f}'.format(Iteration, DistanceL, DistanceR)
                      Ending = '        LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
                          LeftPower, RightPower)
                      print(Beginning, Ending)
  
  #                ev3.Sound.speak('Reset Left').wait()
                  LeftWheel.run_to_rel_pos(position_sp=-30, speed_sp=900, stop_action="hold")
                  RightWheel.run_to_rel_pos(position_sp=30, speed_sp=900, stop_action="hold")
                  sleep(DelayTime)  # Give the motor time to move
                  LeftWheel.stop()
                  LeftWheel.wait_while('running')
                  sleep(DelayTime)
                  Iteration += 1
                  Beginning = '{:3d}          Right   in       out            Left Distance {:>4.0f}     Right Distance {:>4.0f}'.format(Iteration, DistanceL, DistanceR)
                  Ending = '        LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
                      LeftPower, RightPower)
                  print(Beginning, Ending)
  
                  Sound.beep()
  
          Beginning = '{:3d}       Finished                     Left Distance {:>4.0f}     Right Distance {:>4.0f}'.format(Iteration, DistanceL, DistanceR)
          Ending = '        LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
              LeftPower, RightPower)
          print(Beginning, Ending)
          Sound.beep()
  
          Beginning = '{:3d}    Target {:3.0f}    Distance {:>4.0f}'.format(Iteration, Target, Distance)
          Ending = '    Delta {:>4.0f}    Integral {:>5.0f}    Derivative {:>5.0f}    LastError {:>5.0f}    PID {:>5.0f}    SpeedFactor {:>5.0f}    LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
              Error, Integral, Derivative, LastError, PID, SpeedFactor, LeftPower, RightPower)
          print(Beginning, Ending)
          sleep(DelayTime)
  
          while not ts.value():  # Stop program by pressing touch sensor button
                  # Infrared sensor in proximity mode will measure distance to the closest
                  # object in front of it.
  
  #                    Sound.speak('FORWARD')
                      sleep(DelayTime)
                      Iteration += 1
                      Distance = ir.value()
                      if Distance < Target:
  #                        print('in Distance < Target loop')
                          Leds.set_color(Leds.LEFT, Leds.RED)
                          Leds.set_color(Leds.RIGHT, Leds.GREEN)
  
  #                        Sound.speak('RIGHT')
                          sleep(DelayTime)
                      else:
  #                        print('Close else')
                          Leds.set_color(Leds.LEFT, Leds.GREEN)
                          Leds.set_color(Leds.RIGHT, Leds.RED)
  
  #                        Sound.speak('LEFT')
                          sleep(DelayTime)
  
                      Error = Target - Distance
                      Integral += Error
                      Derivative = Error - LastError
  
                      if Integral < -MaxTurnPower:
                          Integral = -MaxTurnPower
                      if Integral > MaxTurnPower:
                          Integral = MaxTurnPower
  
                      if Derivative < -MaxTurnPower:
                          Derivative = -MaxTurnPower
                      if Derivative > MaxTurnPower:
                          Derivatine = MaxTurnPower
  
                      PID = Kp * Error + Ki * Integral + Kd * Derivative
  
                      if PID < -MaxTurnPower:
                          PID = -MaxTurnPower
                      if PID > MaxTurnPower:
                          PID = MaxTurnPower
  
                      LeftPower = SpeedFactor + PID
                      RightPower = SpeedFactor - PID
  
                      if LeftPower < -900:
                          LeftPower = -901
                      if LeftPower > 900:
                          LeftPower = 902
  
                      if RightPower < -900:
                          RightPower = -903
                      if RightPower > 900:
                          RightPower = 904
  
                      Beginning = '{:3d}    Target {:3.0f}    Distance {:>4.0f}'.format(Iteration, Target, Distance)
                      Ending = '    Delta {:>4.0f}    Integral {:>5.0f}    Derivative {:>5.0f}    LastError {:>5.0f}    PID {:>5.0f}    SpeedFactor {:>5.0f}    LeftPower {:>5.0f}    RightPower {:>5.0f}'.format(
                          Error, Integral, Derivative, LastError, PID, SpeedFactor, LeftPower, RightPower)
  
                      print(Beginning, Ending)
                      LeftWheel.run_timed(time_sp=Time, speed_sp=LeftPower)
                      RightWheel.run_timed(time_sp=Time, speed_sp=RightPower)
  
                      LastError = Error
  
  #    Leds.set_color(Leds.UP, Leds.RED)
  #    Leds.set_color(Leds.DOWN, Leds.RED)
      Leds.set_color(Leds.LEFT, Leds.RED)
      Leds.set_color(Leds.RIGHT, Leds.RED)
      LeftWheel.run_to_rel_pos(position_sp=-20, speed_sp=900, stop_action="hold")
      RightWheel.run_to_rel_pos(position_sp=-400, speed_sp=900, stop_action="hold")
      Sound.beep()
  
  > **Comments:**
  > **username_3**: That is a great picture of a great EV3-G program written in a great programming  language editor.  I do not understand how your EV3-G editor in 2014 is better than my editor in 2017.  Is it possible that you are using the Macintosh software.  
  > **username_3**: That is a great picture of a great EV3-G program written in a great programming  language editor.  I do not understand how your EV3-G editor in 2014 is better than my editor in 2017.  Is it possible that you are using the Macintosh software.      Specifically, when you break your code into rows, your wires are equally spaced between the rows.  My editor temporarily does that, but when the last end is anchored, the equal spacing is lost.  My EV3-G editor is up to date for 2017.  What am I missing?  
  > **username_1**: "your EV3-G editor in 2014 is better than my editor in 2017" - it was written on a PC using the "education" version of EV3-G.  That version has comment blocks, which allow adding comments that travel with the linked blocks. It's available from the "Advanced" tab.  Either version is a free download. The image PID is known to work on the NXT brick, but not EV3. EV3 handles the loops too fast and needs to add a delay before re-entering the loop.  
  
  ---
  
  