Change mode of EV3IRSensor

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

Moderators: roger, gloomyandy, skoehler

Change mode of EV3IRSensor

Postby hyperion » Sat May 10, 2014 5:51 pm

Hello,

I want to switch the mode of an EV3IRSensor. I tried the following code which compiles and runs

use of my class:
Code: Select all
middleIRSensor.setMode(SimpleIRSeekerSensor.DISTANCEMODE);
fieldElements = middleIRSensor.scan();         
middleIRSensor.setMode(SimpleIRSeekerSensor.SEEKMODE);
fieldElements = middleIRSensor.scan();


The class itself
Code: Select all
public class SimpleIRSwitchSensor{
   ...
   public SimpleIRSwitchSensor(){
      sensor = new EV3IRSensor(ConfigUtil.MIDDLEIRPORT);
      sen = new SimpleIRSwitch(sensor.getSeekMode());
   }

        public FieldElement[] scan(){
               samples = sen.getSamples();
        }

        public void setMode(int mode){
      this.mode = mode;   
      if(mode == DISTANCEMODE){
         sen = new SimpleIRSwitch(sensor.getDistanceMode());
      }else{
         sen = new SimpleIRSwitch(sensor.getSeekMode());
      }      
   }
}

class SimpleIRSwitch extends AbstractFilter{
   
   /** samples */
   private float[] sample;

   public SimpleIRSwitch(SampleProvider source) {
      super(source);
       sample = new float[sampleSize];
   }
   
   public float[] getSamples(){
        super.fetchSample(sample, 0);
        return sample;       
     }
}


The problem is, that I receive strange values which are not correct. If I comment the switch mode lines(=>every time in seek mode) the values are correct. So I think there is a problem in the way I change the mode. Maybe the sensor needs to be a specific time in a mode to provide correct values. Do you have any advice for me?

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby esmetaman » Sat May 10, 2014 7:05 pm

Hi,

Take I look this example:
https://github.com/jabrena/livingrobots ... rTest.java

It is used to detect a beacon, but if you change the mode, I think that you could solve your problem.

Cheers
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 290
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: Change mode of EV3IRSensor

Postby gloomyandy » Sat May 10, 2014 10:30 pm

You don't need to explicitly switch modes. Just obtain both of the sample providers (one for each mode) and call fetchSample for whichever one you want to read.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Change mode of EV3IRSensor

Postby hyperion » Sun May 11, 2014 12:02 pm

Thanks for your advice!

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby hyperion » Wed May 14, 2014 10:19 am

Hi,

I now have two sample provider. One for each mode, but I have further problems.

In many situations I receive values in channels although no beacon is sending anymore. I was not able to find the mistake in my code so I believe that there is some problem in the fetchSample method of AbstractFilter.

Code: Select all
private SimpleIRSwitchSensor middleIRSensor;

//in the constructor it will be initialized:
middleIRSensor = new SimpleIRSwitchSensor();
middleIRSensor.setMode(SimpleIRSwitchSensor.DISTANCEMODE);

//later scan will be called
while(true){
   // Scan with ir sensor in distance mode front
   middleFieldElement = middleIRSensor.scan()[0];
   middleIRSensor.setMode(SimpleIRSwitchSensor.SEEKMODE);

   //Scan with ir sensor in seek mode
   fieldElementsFront = middleIRSensor.scan();
   middleIRSensor.setMode(SimpleIRSwitchSensor.DISTANCEMODE);
}


The class SimpleIRSwitchSensor:
Code: Select all

private SimpleSampleProvider senDist;
private SimpleSampleProvider senSeek;
private int mode;

public SimpleIRSwitchSensor(){
      sensor = new EV3IRSensor(ConfigUtil.MIDDLEIRPORT);
      senDist = new SimpleSampleProvider(sensor.getDistanceMode(), 1);
      senSeek = new SimpleSampleProvider(sensor.getSeekMode(), 1);
   }

public void setMode(int mode){
      this.mode = mode;   
}

public FieldElement[] scan(){   
      FieldElement[] fieldElements = new FieldElement[2];
      LeaderBot leader;
      HunterBot hunter;
      int[] samples;   
      int distance = 0;
      int sector = 0;      
      
      if (mode == SEEKMODE){
         fieldElements = new FieldElement[2];
         samples = senSeek.getSamples();
      }else{
         fieldElements = new FieldElement[1];
         samples = senDist.getSamples();
      }
            
      //In seek mode look for leader/hunter
      if(mode == SEEKMODE){
         //leader   
         distance = samples[ConfigUtil.LEADERCHANNEL*2 -1];
         sector = Math.round(samples[ConfigUtil.LEADERCHANNEL*2-2]);   
         LCD.clear(1);
         if(distance < 100 && distance > 0){
            RelativeCoordinate coordLeader = new RelativeCoordinate(distance, convertValueToAngle(sector));
            leader = new LeaderBot();
            leader.setRelativeCoordinate(coordLeader);
            fieldElements[0] = leader;   
            LCD.drawString("L d:" + distance + " s:" + (int)Math.round(convertValueToAngle(sector)), 0, 1);
         }else{
            fieldElements[0] = null;
         }
         
         //hunter
         distance = samples[ConfigUtil.HUNTERCHANNEL*2 -1];
         sector = Math.round(samples[ConfigUtil.HUNTERCHANNEL*2-2]);
         if(distance < 100 && distance > 0){
            RelativeCoordinate coordHunter = new RelativeCoordinate(distance, (int)Math.round(convertValueToAngle(sector)));
            hunter = new HunterBot();
            hunter.setRelativeCoordinate(coordHunter);
            fieldElements[1] = hunter;            
         }else{
            fieldElements[1] = null;
         }
         
       //In distance mode look for obstacles(obstacles might be obstacles, swarm bots, leader or hunter)
      }else{
         distance = samples[0];
         if(distance < 100){
            fieldElements[0] = new Obstacle(new RelativeCoordinate(convertDistanceValueToCM(samples[0]), 0));
         }else{
            fieldElements[0] = null;
         }
      }   
      return fieldElements;
}


SimpleSampleProvider
Code: Select all
public class SimpleSampleProvider extends AbstractFilter{
   
   /** samples */
   private float[] sample;
   private int factor;

   public SimpleSampleProvider(SampleProvider source, int factor) {
      super(source);
      this.factor = factor;
       sample = new float[sampleSize];
   }
   
   public int[] getSamples(){
        int[] intSamples = new int[sample.length];
        super.fetchSample(sample, 0);
        for(int i = 0; i< sample.length; i++){
           intSamples[i] = (int)(sample[i]*factor);
        }
                  if(sampleSize == 8 && sample[ConfigUtil.HUNTERCHANNEL*2-1] > 0 && sample[ConfigUtil.HUNTERCHANNEL*2-1] < 100){
           Sound.buzz();
        }
        return intSamples;       
     }
}


For debugging purpose I have added the Sound.buzz() to getSamples() of SImpleSampleProvider. If I start the program everything is fine. But if I send with the beacon in Hunterchannel and stop sending in many situations the bot makes buzz() sounds. The LCD which shows me the position of the hunter keeps showing the last position of the hunter beacon. Do you have any idea why super.fetchSample() should return old values instead of giving me the values of the current situation? Additional note: the problem exists only if I switch the mode.

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby gloomyandy » Wed May 14, 2014 1:35 pm

Hi,
your code is too complex for anyone to help out without a lot of effort. I've had a quick look and can't see any obvious problem, but to go further I need code to install and run so that I can see the problem for myself. If you think there is a problem with leJOS please do the following.
1. Make sure you have tested with the latest version of leJOS.
2. Create a simple test program that reproduces your problem. Ideally one that does not involve any complex construction or setup.
3. Post the code along with the details of what version of leJOS you are using and instructions on how to run your program, what you expect to happen and what actually happens.

Remember that the people that develop leJOS do so in their own time. If you want us to help then you need to make things as easy for us as you can.

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

Re: Change mode of EV3IRSensor

Postby hyperion » Thu May 15, 2014 2:06 pm

Thank you very much, I will make a simple example the next days.

You will need two EV3 IR Sensors and a Remote Control.

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby gloomyandy » Thu May 15, 2014 8:01 pm

Please try and create a test with just a single sensor. I only have one and I'm pretty sure that is true of the other developers.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Change mode of EV3IRSensor

Postby hyperion » Fri May 16, 2014 2:55 pm

Hi,

here is the code which demonstrates the problem.

Unfortunately I was not able to meet all your suggestions.
1. Make sure you have tested with the latest version of leJOS.
2. Create a simple test program that reproduces your problem. Ideally one that does not involve any complex construction or setup.
3. Post the code along with the details of what version of leJOS you are using and instructions on how to run your program, what you expect to happen and what actually happens.

1. I am using 0.8.0 alpha. Currently I cannot update to latest beta version. Hope this ist ok for you
2. See below for Simple test programm. You just need one EV3IRSensor in Port S1
3. I am using lejos 0.8.0 alpha. Just run the program on the brick. If you see "press enter to stop" you can take your EV3 Remote Control(with channel 1) and point it to the sensor -> you will here buzzes as long as the beacon is active. Switch it off and on until the brick buzzes while the beacon is off. You will need some trials until this happens.

Class TestIRBeacon
Code: Select all
import lejos.hardware.Button;
import lejos.hardware.Sound;
import lejos.hardware.lcd.LCD;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.EV3IRSensor;

public class IRBeaconTest {
   
   public static final int SEEKMODE = 1;
   public static final int DISTMODE = 2;
   
   private EV3IRSensor sensor;
   private SimpleSampleProvider seek;
   private SimpleSampleProvider distance;
   private int mode;
   
   public IRBeaconTest(){
      sensor = new EV3IRSensor(SensorPort.S1);
      seek = new SimpleSampleProvider(sensor.getSeekMode(), 1);
      distance = new SimpleSampleProvider(sensor.getDistanceMode(), 1);
      this.mode = DISTMODE;
   }
      
   public static void main(String[] args){
      IRBeaconTest test = new IRBeaconTest();
      test.start();
   }
   
   public void start(){      
      int[] samples;
      
      LCD.drawString("press enter to stop", 0, 0);
      
      while (!Button.ENTER.isDown()) {
         if(mode == SEEKMODE){
            samples = seek.getSamples();
            if(samples[0] < 100 && samples[0] > 0){
               Sound.buzz();
            }
            
            mode = DISTMODE;
            
            //... 6cool stuff with samples ...
         }else{
            samples = distance.getSamples();
            
            mode = SEEKMODE;
            
            //... cool stuff with samples ...
         }
      }
   }
}


Class SimpleSampleProvider
Code: Select all
import lejos.robotics.SampleProvider;
import lejos.robotics.filter.AbstractFilter;

public class SimpleSampleProvider extends AbstractFilter{
   
   /** samples */
   private float[] sample;
   private int factor;

   public SimpleSampleProvider(SampleProvider source, int factor) {
      super(source);
      this.factor = factor;
       sample = new float[sampleSize];
   }
   
   public int[] getSamples(){
        int[] intSamples = new int[sample.length];
        super.fetchSample(sample, 0);
        for(int i = 0; i< sample.length; i++){
           intSamples[i] = (int)(sample[i]*factor);
        }       
        return intSamples;       
     }
}


I also uploaded a small video which demonstrates the problem. At 0:18 you can see the problem. Video: http://www.vidup.de/v/2D3Gz/

Thank you for your time!

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby gloomyandy » Fri May 16, 2014 3:17 pm

What happens if you don't use your own filter/sample provider but simply handle the return values from the sensor directly. The simpler the better with test programs. What happens if you don't switch modes? To be honest it sounds like a problem with the actual hardware. It seems that if you turn off the beacon while in DISTANCE mode then you will end up in this state. If that is the case there may not be much we can do about it. If you turn the beacon on again after getting into this state does it work?
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Change mode of EV3IRSensor

Postby hyperion » Fri May 16, 2014 4:45 pm

What happens if you don't use your own filter/sample provider but simply handle the return values from the sensor directly. The simpler the better with test programs.


I simplified the program to the following. Problem still exists:
Code: Select all
import lejos.hardware.Button;
import lejos.hardware.Sound;
import lejos.hardware.lcd.LCD;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.EV3IRSensor;
import lejos.hardware.sensor.SensorMode;

public class IRBeaconTest {
   
   public static final int SEEKMODE = 1;
   public static final int DISTMODE = 2;
   
   private EV3IRSensor sensor;
   private int mode;
   private SensorMode seek;
   private SensorMode dist;
   
   public IRBeaconTest(){      
      sensor = new EV3IRSensor(SensorPort.S1);   
      seek = sensor.getSeekMode();
      dist = sensor.getDistanceMode();
      this.mode = DISTMODE;
   }
      
   public static void main(String[] args){
      IRBeaconTest test = new IRBeaconTest();
      test.start();
   }
   
   public void start(){   
      float[] seekSamples = new float[8];
      float[] distSamples = new float[1];
      
      LCD.drawString("press enter to stop", 0, 0);
      
      while (!Button.ENTER.isDown()) {
         if(mode == SEEKMODE){
            seek.fetchSample(seekSamples, 0);
            if(seekSamples[0] < 100 && seekSamples[0] > 0){
               Sound.buzz();
            }
            
            mode = DISTMODE;
            
            //... 6cool stuff with samples ...
         }else{
            dist.fetchSample(distSamples, 0);
            
            mode = SEEKMODE;
            
            //... cool stuff with samples ...
         }
      }
   }
}


What happens if you don't switch modes?

Without switching mode I never had problems.

If you turn the beacon on again after getting into this state does it work?

Yes, as you can see in the video.

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby gloomyandy » Fri May 16, 2014 5:06 pm

Did you try changing things so that you can be sure you are turning the beacon off when in DISTANCE mode? What happens if you do this. My guess is that the problem only happens if you turn it off when in that mode. As I said I'm now pretty sure this is a sensor problem. The fetch sample call simply returns the latest reading from the sensor. Welcome to the world of low cost sensors! You may have to find a way to work around the problem in your own code (or get Lego to fix the problem - good luck with that). It should be pretty easy to detect when the sensor return is not changing, you could then maybe try moving your robot and if it still does not change, ignore the reading until you get something different. Messy but may well work. The only other thing I could suggest is that you reset the sensor using the resetSensor method in the EV3UartPort class if you get what seems like a "stuck reading", not sure if that will help or not though.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Change mode of EV3IRSensor

Postby hyperion » Fri May 23, 2014 8:31 pm

Hi,

I set a breakpoint to line mode = SEEKMODE; after next seek.fetchSample(seekSamples, 0); I got new values in seekSamples.

There are other problems too. Most of the time the provided values from seekMode are completely wrong. Sometimes the distance is negative:)

I would like to try the reset, but unfortunately i cannot access the method because the Port is an EV3Port not an EV3UartPort and EV3Port does not have a reset method. Additionaly the method is protected.
But I expect that the reset may take a while as the creation of a new sensor will take also a few seconds.

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Re: Change mode of EV3IRSensor

Postby gloomyandy » Fri May 23, 2014 9:03 pm

You have the source, you can do anything you want to do. Are you saying you only get negative values if you switch mode, or do you get them at other times? What do you mean by "completely wrong"? How wrong? When is it wrong? If you want help provide data so everyone can see it and maybe comment. As I said, welcome to the world of low cost sensors.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: Change mode of EV3IRSensor

Postby hyperion » Sat May 24, 2014 10:35 am

Hi,

I get only wrong values if I switch the mode.

wrong values when in distance mode: for near distances the sensor provides in most situations 7 or 23 as distance. From 23 and above the sensor provides most of the time more correct values.
wrong values when in seek mode: most of the time the sensors recognizes beacon control at a bearing of -25(-180°), although the beacon is somewhere else.

I do not think that I can handle those problems, so I use a multiplexer to get enough ports to use 2 dedicatet seeker sensors.

Regards,
hyperion
hyperion
New User
 
Posts: 19
Joined: Thu Apr 10, 2014 8:43 am

Next

Return to EV3 Software

Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests

more stuff