Command Based Java Sensors Best Practices

I know that this may trigger some cool discussions as not everyone is doing things the same way… but here it is!!!

We are finally figuring out our sensors… We have micro, limit and prox switch program and working, next is the KOP ultrasonic and navx and encoders… so far we can connect them to the RIO and when we enable the bot, we can display their value on the smartdashboard…

We are about to get the ultrasonic sensor coded and we want to make sure that we put my code so it can be used thoughout…

right now our sensors are in Robot.java class

	public void teleopPeriodic() {
		oi.updateSmart();
		Scheduler.getInstance().run();
		SmartDashboard.putBoolean("Micro Switch", isGearPresent());
		SmartDashboard.putBoolean("Prox Switch", isGearPresent2());
	}
	
	private DigitalInput gearSensor  = new DigitalInput(RobotMap.GEAR_SENSOR_DIO_ID);
	private DigitalInput gearSensor2  = new DigitalInput(RobotMap.GEAR_SENSOR_DIO_ID2);

	public boolean isGearPresent() {
		return !gearSensor.get();
		
	}
	public boolean isGearPresent2() {
		return !gearSensor2.get();
		
	}

They are under the TeleopPeriodic method …

Can use the sensor during our autonomous method or will the code not see it…

Should we move each sensors in its own class? if so where and any example?

Thank you!!!

Sensors are usually declared and instantiated in the appropriate subsystem in parallel with the actuator(s). This allows you to use the sensors with the subsystem in both auto and teleop. The only time I can think of where you would not want to do this was if you needed to access the sensors from a command running in parallel with another command which used the subsystem (there are probably others).

awesome… thank you … let me try that…

how about writing the sensors value to the smartdasjhboard?v where would you recommend those methods?

public void teleopPeriodic() {
	oi.updateSmart();
	Scheduler.getInstance().run();
	SmartDashboard.putBoolean("Micro Switch", isGearPresent());
	SmartDashboard.putBoolean("Prox Switch", isGearPresent2());
}

What I like to do is create all instances in RobotMap and just create references to them in my subsystems. Then I create wrapper functions for the sensor I’m the subsystems. This makes it easy to read and easy to call from commands.

If a sensor is used by one subsystem we declare/instantiate it in the subsystem and have getters for getting info from the sensor

We have had times in the past (no specific example coming to mind unfortunately) that multiple subsystems needed read-access to the same sensors for making decisions. In those situations we have created a separate Subsystem that is never “required” by any class, instantiates the sensor(s) there, has getters to access the data, and has a default command if needed to maintain the sensor operation.

RobotMap for us is mainly physical constants (PWM/CAN channels) and maybe some constants about the subsystems, but never objects, only primitives usually.

Writing output is typically only used for debugging for us, but we do it in the commands that use the sensors (i.e. if we need to graph feedback loop output we do it in that command).

We are new to java so this is very helpful… thank you.

So we move the following into the subsystem class…

	public DigitalInput gearSensor  = new DigitalInput(RobotMap.GEAR_SENSOR_DIO_ID);
	public DigitalInput gearSensor2  = new DigitalInput(RobotMap.GEAR_SENSOR_DIO_ID2);

	public boolean isGearPresent() {
		return !gearSensor.get();
		
	}
	public boolean isGearPresent2() {
		return !gearSensor2.get();
		
	}

Now in Robot.java class our smartdashboard cannot recognize the isGearPresent method…

	SmartDashboard.putBoolean("Micro Switch", isGearPresent());
	SmartDashboard.putBoolean("Prox Switch", isGearPresent2());
}

The particular subsystem would be something like your “gearHanger” class.

To use methods from gearHanger in other classes, you would need to import gearHanger into them, or call them out specifically, e.g. myGearHanger.isGearPresent().

In general, all subsystems and hardware are shared between different modes: autonomous, teleop and even test. So we have a Robot class (some called it RobotMap) that instantiates all the subsystems and sensors. They are all “public”. So any class can reference them. Some sensors are embedded in some subsystems with getter methods, some are just public in the RobotMap depending on how you want to use them.

perfect! thank you so much! i had to change it to static… but i think this will work.

I see this in many example online… for some reasons, most of ours are in each subsystems… little worry about changing them now as we know the code is working… i guess all new stuff we will do that way.

While different teams draw the line between robotMap and robot at different points, and some use external files, our general rule is that everything that the mechanical/wiring teams provided the programmers or need to know from the programmers (depending on which came first) belongs in robotMap. Port numbers, gear ratios, encoder counts. If you print out a copy of robotMap and hand it to the controls team, they can rewire the robot just like it was. That printout of robotMap is also a great reference to keep in the pit team’s clipboard/binder!