LeJOS: два режими сенсора одночасно


Практично всі датчики Lego MIndstorms здатні працювати у кількох режимах, от наприклад інфрачервоний сенсор EV3 Infrared Sensor 45509 можна використовувати як пульт дистанційного керування роботом, як дальномір або ж для пошуку інфрачервоного маячка.

Насправді якщо мова йде про інфрпачервоний сенсор, то дуже корисною є можливість роботи у кількох режимах одночасно, адже зовсім не хочеться купувати додатковий сенсор для вимірювання дистанції якщо комплектний використовується для керування. Така корисна можливість присутня і підтримується у LeJOS, хоча і з певними нюансами.

Спочатку приємна частина: якщо ви хочете одночасно і курувати роботом і вимірювати відстані, то це робиться досить просто. Допоможе наступний код:

// IR Remote
Port port = LocalEV3.get().getPort("S1");
SensorModes sensor = new EV3IRSensor(port);
// Measurement
SampleProvider provider = sensor.getMode("Distance");
float[] sample = new float[provider.sampleSize()];
//
//Some other code here ...
//
byte[] commands = { 0, 0, 0, 0 };
// Get array of commands: one per channel
((EV3IRSensor) sensor).getRemoteCommands(commands, 0, 4);
// Get measured value
provider.fetchSample(sample, 0);
System.out.println(sample[0]);

А тепер нюанси. Прикол у тому, що, хоча ми і використовуємо два різні масиви для роботи з командами від пульта і даними з дальноміра, насправді з самого сенсора вони передаються все одно по одній лінії і, фактично, перемикаючи режими ми просто вибирамо як LeJOS має інтерпретувати отримані дані.

На практиці це означає, що задавши режим “Distance” для сенсора ми на першому каналі від приймача (нульовий елемент масиву commands) отримуватимемо дані від дальноміра. А отже програма, описана отут http://akceptor.org/lejos-prohrama-dystantsijno-kerovanoho-robota/, працюватиме лише якщо ми оберемо для керування роботом перший канал. Бо у цьому випадку команди з пульта перетиратимуть дані від сенсора і, відповідно, при натисненій кнопці на пульті робот буде виконувати команду з пульта, а при відпусканні кнопки оператор switch перейде у стан default (робот зупиниться), а ми зможемо проаналізувати sample[0] і виконати якісь власні дії.

Якщо ж сигнал керування передавати на якомусь іншому каналі, то він практично завжди виявлятиметься меншим від значення дистанції до перешкоди (при відсутності перешкод покази сенсора відстані порядку сотні, а коди команд у нас від 1 до 8) і за рахунок використання нами пошуку максимального значення масиву робот не реагуватиме на команди з пульта.

Вийти з положення можна. Для цього доведеться змінити логіку пошуку мансимального значення у методах maxValue() та maxIndex() таким чином, щоб ігнорувати дані з дальноміра. Наразі я просто вважаю що керувати роботом будуть з одного пульта і тому відмінні від нуля команди не можуть бути присутніми на кількох каналах одночасно.

/**
	 * Returns max. value for array
	 * 
	 * @param bytes
	 *            array
	 * @return max value
	 */
	private static int maxValue(byte[] bytes) {
		if (bytes[3] > 0)
			return bytes[3];
		if (bytes[2] > 0)
			return bytes[2];
		if (bytes[1] > 0)
			return bytes[1];
		if (bytes[0] > 0)
			return bytes[0];
		return 0;
	}

	/**
	 * Returns index of max. element for array
	 * 
	 * @param bytes
	 *            array
	 * @return max element index
	 */
	private static int maxIndex(byte[] bytes) {
		if (bytes[3] > 0)
			return 4;
		if (bytes[2] > 0)
			return 3;
		if (bytes[1] > 0)
			return 2;
		if (bytes[0] > 0)
			return 1;
		return 0;
	}

Також обробку показів дальноміра перенесено у switch (а саме у його default частину). Таким чином обробка сигналу від дальноміра здійснюється лише тоді, коли не розпізнано жодних команд з пульта. Єдиним недоліком такого варіанту можна вважати той факт, що команди від людини мають більший пріорітет аніж покази сенсора, тобто тепер можна змусити робота впертися у стінку і він не зупиниться допоки натиснута кнопка на пульті.

В принципі, це можна назвати і перевагою: згадайте три закони робототехніки і взагалі, ми люди, вінець творіння, а це просто бездушна машина 🙂 Також ми позбулися сторонніх бібліотек, що теж непогано.

Наостанок посилання на клас із програмою: RCRobot4ChannelWithDistanceSensor.java

Почитайте ще оце:

Залиште коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *