Long setup time for sensors

This is where you talk about the EV3 software itself, installation issues, and programming talk.

Moderators: roger, gloomyandy, skoehler

User avatar
jippiee
New User
Posts: 14
Joined: Tue Dec 26, 2017 1:07 am

Long setup time for sensors

Postby jippiee » Sun Feb 11, 2018 12:22 pm

Opening 4 (EV3 Color) Sensors can take quite a while. In the following code i measured the time for the setup to complete.

Code: Select all

   public Run() {
      LocalEV3.get().getLED().setPattern(2);
      long start = System.currentTimeMillis();
      
      setup    = new Setup();
      chassis = setup.getChassis();
      lf       = setup.getLineFollowerDouble();
      
      System.out.println("Outside: " + ((System.currentTimeMillis()-start)) + "ms");
      LocalEV3.get().getLED().setPattern(0);
   }

Code: Select all

   public Setup() {
      
      long start = System.currentTimeMillis();
      
      /* Chassis */
      Wheel leftWheel = WheeledChassis.modelWheel(Motor.B, 6.225).offset(7.275).invert(true);
      Wheel rightWheel = WheeledChassis.modelWheel(Motor.C, 6.225).offset(-7.275).invert(true);
      chassis = new WheeledChassis( new Wheel[] {leftWheel, rightWheel}, WheeledChassis.TYPE_DIFFERENTIAL);      
      chassis.setSpeed(15, 60);            // cm/s      deg/s
      chassis.setAcceleration(100, 900);      // cm/s^2   deg/s^2
      
      System.out.println("Chassis: " + ((System.currentTimeMillis()-start)) + "ms");
      
      /* Sensor 2 :: Inside Left */
      Port port2 = LocalEV3.get().getPort("S2");
      System.out.println("Port: " + ((System.currentTimeMillis()-start)) + "ms");
      sensor2 = new EV3ColorSensor(port2);
      System.out.println("Sensor: " + ((System.currentTimeMillis()-start)) + "ms");
      SampleProvider light2 = sensor2.getRedMode();
      System.out.println("SampleProvider: " + ((System.currentTimeMillis()-start)) + "ms");
      caliLight2 = new LinearCalibrationFilter(light2, caliFile2);
      System.out.println("Filter: " + ((System.currentTimeMillis()-start)) + "ms");
      
      System.out.println("Sensor 2: " + ((System.currentTimeMillis()-start)) + "ms");
      
      /* Sensor 3 :: Inside Right */
      Port port3 = LocalEV3.get().getPort("S3");
      sensor3 = new EV3ColorSensor(port3);
      SampleProvider light3 = sensor3.getRedMode();
      caliLight3 = new LinearCalibrationFilter(light3, caliFile3);
      
      System.out.println("Sensor 3: " + ((System.currentTimeMillis()-start)) + "ms");
      
      /** Sensor 2 :: Inside Left */
//      Port port2 = LocalEV3.get().getPort("S2");
//      sensor2 = new NXTLightSensor(port2);
//      SampleProvider light2 = sensor2.getRedMode();
//      caliLight2 = new LinearCalibrationFilter(light2, caliFile2);
      
      /** Sensor 3 :: Inside Right */
//      Port port3 = LocalEV3.get().getPort("S3");
//      sensor3 = new NXTLightSensor(port3);
//      SampleProvider light3 = sensor3.getRedMode();
//      caliLight3 = new LinearCalibrationFilter(light3, caliFile3);
      
      
      /* Sensor 1 :: Outside Right */
      Port port1 = LocalEV3.get().getPort("S1");
      sensor1 = new EV3ColorSensor(port1);
      color1 = sensor1.getColorIDMode();      
//      SampleProvider light1 = sensor1.getRedMode();
//      caliLight1 = new LinearCalibrationFilter(light1, caliFile1);
            
      System.out.println("Sensor 1: " + ((System.currentTimeMillis()-start)) + "ms");
      
      /* Sensor 4 :: Outside Left */
      Port port4 = LocalEV3.get().getPort("S4");
      sensor4 = new EV3ColorSensor(port4);
      color4 = sensor4.getColorIDMode();
//      SampleProvider light4 = sensor4.getRedMode();
//      caliLight4 = new LinearCalibrationFilter(light4, caliFile4);
      
      System.out.println("Sensor 4: " + ((System.currentTimeMillis()-start)) + "ms");
            
      
      /* Linefollower Double */
      SimplePID pid = new SimplePID(25, 0, 0);
      lfDouble = new DoubleLF(chassis, pid, getInsideLeft(), getInsideRight(), 15);
      
      System.out.println("LFDouble: " + ((System.currentTimeMillis()-start)) + "ms");
      
      System.out.println("Inside: " + ((System.currentTimeMillis()-start)) + "ms");
      
   }
   
   
   public WheeledChassis getChassis() {
      return chassis;
   }
   
   public LineFollower getLineFollowerDouble() {
      return lfDouble;
   }


The output was:
  • Chassis: 908ms
  • Port: 981ms
  • Sensor: 4761ms
  • SampleProvider: 4770ms
  • Filter: 5177ms
  • Sensor 2: 5190ms
  • Sensor 3: 8907ms
  • Sensor 1: 12325ms
  • Sensor 4: 16470ms
  • LFDouble: 16833ms
  • Inside: 16858ms
  • Outside: 17083ms

The total time was 17 sec! From these results one can get the time difference in ms:
  • Chassis: 908
  • Port: 73
  • Sensor: 3780
  • SampleProvider: 9
  • Filter: 407
  • Sensor 2: 13
  • Sensor 3: 3717
  • Sensor 1: 3418
  • Sensor 4: 4145
  • LFDouble: 363
  • Inside: 25
  • Outside: 225

As I can confirm from other tests, each sensor takes about 2.5 - 4.5 seconds to get initialized (see the last 3 sensors).
I broke up the measurement for the first sensor (=sensor 2) even more, and it revealed, that the ca. 3 second wait is due to this line:

Code: Select all

sensor2 = new EV3ColorSensor(port2);

My Robot is built for a timed robot-competition (WRO to be exact) where I'm allowed to start the program beforehand, but it is still a nuisance to wait so long on test runs etc.

Is there a way to initializes the sensors faster, or to parallelize the setup to get a faster setup?

User avatar
gloomyandy
leJOS Team Member
Posts: 6048
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Long setup time for sensors

Postby gloomyandy » Sun Feb 11, 2018 4:30 pm

Yep that is pretty much correct. UART based sensors (basically the new ones from LEGO like the EV3 color, EV3 Ultrasonic, EV3 IR etc.) all take a long time to initialise. You basically don't see this time with the LEGO software because the sensor initialisation time is "hidden" by the LEGO VM (it basically initialises when you first plug the sensor in, or when the VM starts). But with leJOS we initialise each sensor when you first open it. So as you have found out the obvious thing to do is to open the sensors as soon as possible, so they are ready to use when you need them. To take this one step further if it is really important to you use a separate thread to open each "slow" sensor so that if you have say three of them the total wait time will be say two seconds rather than 6. You will however need to ensure that the rest of your code waits for the "open" threads to complete before you actually try to run any code that uses them. But this is pretty simple to do in Java (hint take a look at the "join" method in the Thread class).

Good luck
leJOS news https://lejosnews.wordpress.com/

User avatar
jippiee
New User
Posts: 14
Joined: Tue Dec 26, 2017 1:07 am

Re: Long setup time for sensors

Postby jippiee » Sun Feb 11, 2018 10:24 pm

OK, I tried out adding a separate Thread for each sensor.

Code: Select all

   public SetupV3() {
      
      /* Chassis */
      // old offset: 7.275
      RegulatedMotor leftMotor = new EV3LargeRegulatedMotor(MotorPort.B);
      RegulatedMotor rightMotor = new EV3LargeRegulatedMotor(MotorPort.C);
      Wheel leftWheel = WheeledChassis.modelWheel(leftMotor, 6.225).offset(7.521).invert(true);
      Wheel rightWheel = WheeledChassis.modelWheel(rightMotor, 6.225).offset(-7.521).invert(true);
      chassis = new WheeledChassis( new Wheel[] {leftWheel, rightWheel}, WheeledChassis.TYPE_DIFFERENTIAL);      
      chassis.setSpeed(linearSpeed, angularSpeed);
      chassis.setAcceleration(linearAcceleration, angularAcceleration);
      
      /* Pilot */
      pilot = new MovePilot(chassis);
      pilot.setLinearSpeed(linearSpeed);
      pilot.setLinearAcceleration(linearAcceleration);      
      pilot.setAngularSpeed(angularSpeed);
      pilot.setAngularAcceleration(angularAcceleration);   
      
      
      
      Thread threadS1 = new Thread(new SensorSetup1());
      threadS1.start();
      
      Thread threadS2 = new Thread(new SensorSetup2());
      threadS2.start();
      
      Thread threadS3 = new Thread(new SensorSetup3());
      threadS3.start();
      
      Thread threadS4 = new Thread(new SensorSetup4());
      threadS4.start();
      
      try {
         threadS1.join();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      try {
         threadS2.join();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      try {
         threadS3.join();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      try {
         threadS4.join();
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      
            
      /* Sensor 2 :: Inside Left */
      SampleProvider light2 = sensor2.getRedMode();
      caliLight2 = new LinearCalibrationFilter(light2, caliFile2);      
      /* Sensor 3 :: Inside Right */
      SampleProvider light3 = sensor3.getRedMode();
      caliLight3 = new LinearCalibrationFilter(light3, caliFile3);
            
      /* Sensor 1 :: Outside Right */
      color1 = sensor1.getColorIDMode();      
      /* Sensor 4 :: Outside Left */
      color4 = sensor4.getColorIDMode();
      
      
      
      /* Linefollower Double */
      SimplePID pidDouble = new SimplePID(25, 0, 0);
      lfDouble = new DoubleLF(chassis, pidDouble, getInsideLeft(), getInsideRight(), 15);
      
      /* Linefollower Single */
      SimplePID pidSingle = new SimplePID(20, 0, 0);
      lfSingle = new SingleLF(chassis, pidSingle, getInsideLeft(), getInsideRight(), -1, 15);
      
   }
   
   
   
   private class SensorSetup1 implements Runnable {
      public void run() {
         Port port1 = LocalEV3.get().getPort("S1");
         sensor1 = new EV3ColorSensor(port1);
      }      
   }
   
   private class SensorSetup2 implements Runnable {
      public void run() {
         Port port2 = LocalEV3.get().getPort("S2");
         sensor2 = new EV3ColorSensor(port2);
      }      
   }
   
   private class SensorSetup3 implements Runnable {
      public void run() {
         Port port3 = LocalEV3.get().getPort("S3");
         sensor3 = new EV3ColorSensor(port3);
      }      
   }
   
   private class SensorSetup4 implements Runnable {
      public void run() {
         Port port4 = LocalEV3.get().getPort("S4");
         sensor4 = new EV3ColorSensor(port4);
      }      
   }
      
   
   
   public WheeledChassis getChassis() {
      return chassis;
   }
   
   public MovePilot getPilot() {
      return pilot;
   }
   
   public DoubleLF getLineFollowerDouble() {
      return lfDouble;
   }
   
   public LineFollower getLineFollowerSingle() {
      return lfSingle;
   }
   
   public SampleProvider getInsideLeft() {
      return caliLight2;
   }
   
   public SampleProvider getInsideRight() {
      return caliLight3;
   }
   
   public SampleProvider getOutsideLeft() {
      return color4;
   }
   
   public SampleProvider getOutsideRight() {
      return color1;
   }
   
   public void close() {
      sensor1.close();
      sensor3.close();
      sensor2.close();
      sensor4.close();
   }

The setup time now is 10-12 seconds, so only a slight improvement. But most floodlights light up about the same time.
Is it necessary to add try/catch blocks around each join()? The other Option was to keep passing on the InterruptedException up to the main method, which didn't sound so reasonable to me.


Return to “EV3 Software”

Who is online

Users browsing this forum: No registered users and 1 guest