• #by-own #raspberrypi #developRobot

Kapitel 14: Starten der Python Programme über Java

Das starten teilt sich in mehrere Schritte auf. Zuerst wird eine Klasse geschrieben, die alle Informationen enthält und die Python Programme zu starten. Die daran implementierten Funktionen werden dann über eine weiter Klasse in jeweils eigene Threads gestartet. So kann jedes Python-Programm unabhängig voneinander laufen.

Um die Programme mit Python starten zu können muss immer der relative Pfad zum Python Programm errechnet werden. Dies geschieht in der Funktion setRelativePythonPath() statt. Zudem sind die Funktionen so geschrieben, das alle paar Sekunden geprüft wird, ob der Sensor noch funktioniert bzw. das Python Skript noch läuft und evtl. neu gestartet werden muss.

package diy.robot.python;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class PythonManager {

	private static String pathRel = "";

	public static void startPythonWsServer() {
		setRealtivePythonPath();
		ProcessBuilder serverPocessBuilder = new ProcessBuilder("python3", pathRel + "/python/py-ws-server.py");
		Process serverProcess = null;
		try {
			serverProcess = serverPocessBuilder.start();
			log.info("Websocket started");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!serverProcess.isAlive()) {
					log.error("Restart WS-Server");
					serverProcess = serverPocessBuilder.start();
				} else {
					log.info("Server is Running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void startDistanceMessureBack() {
		setRealtivePythonPath();
		ProcessBuilder ultrasonicPocessBuilder = new ProcessBuilder("python3",
				pathRel + "/python/ultrasonicBack/ws-ultrasonic.py");
		Process ultrasonicProcess = null;

		try {
			ultrasonicProcess = ultrasonicPocessBuilder.start();
			log.info("Python Distance-Messure started BACK");
		} catch (IOException e) {
			e.printStackTrace();
		}
		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!ultrasonicProcess.isAlive()) {
					log.error("Restart Ultrasonic Sensor");
					ultrasonicProcess = ultrasonicPocessBuilder.start();
				} else {
					log.info("Ultrasonic BACK is running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void startDistanceMessureFront() {
		setRealtivePythonPath();
		ProcessBuilder ultrasonicPocessBuilder = new ProcessBuilder("python3",
				pathRel + "/python/ultrasonicFront/ws-ultrasonic.py");
		Process ultrasonicProcess = null;

		try {
			ultrasonicProcess = ultrasonicPocessBuilder.start();
			log.info("Python Distance-Messure started");
		} catch (IOException e) {
			e.printStackTrace();
		}
		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!ultrasonicProcess.isAlive()) {
					log.error("Restart Ultrasonic Sensor FRONT");
					ultrasonicProcess = ultrasonicPocessBuilder.start();
				} else {
					log.info("Ultrasonic FRONT is running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void startMotorControllListener() {
		setRealtivePythonPath();
		ProcessBuilder motorPocessBuilder = new ProcessBuilder("python3",
				pathRel + "/python/motorSteuerung/ws-DCMotorSteuerung.py");
		Process motorPocess = null;

		try {
			motorPocess = motorPocessBuilder.start();
			log.info("Python motorClient started");
		} catch (Exception e) {
			e.printStackTrace();
		}
		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!motorPocess.isAlive()) {
					log.error("Restart Motor Client");
					motorPocess = motorPocessBuilder.start();
				} else {
					log.info("Motor Client is running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void startlightMessure() {
		setRealtivePythonPath();
		ProcessBuilder lightProcessBuilder = new ProcessBuilder("python3",
				pathRel + "/python/lightSensor/ws-light_sens.py");
		Process lightProcess = null;

		try {
			lightProcess = lightProcessBuilder.start();
			System.out.println("Python Light-Messure started");
		} catch (IOException e) {
			e.printStackTrace();
		}

		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!lightProcess.isAlive()) {
					log.error("Restart Light Sensor");
					lightProcess = lightProcessBuilder.start();
				} else {
					log.info("Light Sensor is running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void startRobotArm() {
		setRealtivePythonPath();
		ProcessBuilder robotArmPocessBuilder = new ProcessBuilder("python3", pathRel + "/python/robotArm/ws-client.py");
		Process robotArmProcess = null;

		try {
			robotArmProcess = robotArmPocessBuilder.start();
			log.info("Python robot arm started");
		} catch (IOException e) {
			e.printStackTrace();
		}
		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!robotArmProcess.isAlive()) {
					log.error("Restart robot arm");
					robotArmProcess = robotArmPocessBuilder.start();
				} else {
					log.info("robot arm is running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void startLaser() {
		setRealtivePythonPath();
		ProcessBuilder laserPocessBuilder = new ProcessBuilder("python3", pathRel + "/python/laser/ws-laser-client.py");
		Process laserPocess = null;

		try {
			laserPocess = laserPocessBuilder.start();
			log.info("Python laser started");
		} catch (Exception e) {
			e.printStackTrace();
		}
		while (true) {
			try {
				TimeUnit.SECONDS.sleep(2L);
				if (!laserPocess.isAlive()) {
					log.error("Restart Laser Client");
					laserPocess = laserPocessBuilder.start();
				} else {
					log.info("Laser Client is running - Check OK");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private static void setRealtivePythonPath() {
		final Class<?> referenceClass = PythonManager.class;
		final URL url = referenceClass.getProtectionDomain().getCodeSource().getLocation();
		if (url.getPath().contains(".jar")) {
			// execution jar Time
			String[] path = url.getPath().split(".jar");
			pathRel = path[0].substring(5, path[0].lastIndexOf("/")); // delete file: (5) end End /DIY-Sna.....jar
			System.out.println(pathRel);
		} else { // here for Debuug Mopde!
			File file = new File(url.getPath()).getParentFile();
			System.out.println(pathRel);
			pathRel = file.getPath();
		}
	}
}

Die Klasse PythonThreadService startet dabei die einzelnen Funktionen in einem eigene Thread (Nebenläufig):

package diy.robot.ThreadPoolManager;

import diy.robot.python.PythonManager;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Service
public class PythonThreadService {

	// ExecutorService executorService = Executors.newFixedThreadPool(6);

	ExecutorService executorService = Executors.newCachedThreadPool();

	@PostConstruct
	public void startAllHardwareServcies() {
		startPythonWebsocketServerThread();
		startPythonMotorThread();
		startPythonUltrasonis();
		startPythonLightSensor();
		startLaser();
		startRobotArm();

	}

	/**
	 * Python WebSocket Server
	 */
	private void startPythonWebsocketServerThread() {

		runNewThread(() -> PythonManager.startPythonWsServer());
	}

	/**
	 * Motors
	 */
	private void startPythonMotorThread() {

		runNewThread(() -> PythonManager.startMotorControllListener());
	}

	/**
	 * Sensor Ultrasonic
	 */
	private void startPythonUltrasonis() {

		runNewThread(() -> PythonManager.startDistanceMessureBack());
		runNewThread(() -> PythonManager.startDistanceMessureFront());
	}

	/**
	 * Start robot Arm
	 */
	private void startRobotArm() {
		runNewThread(() -> PythonManager.startRobotArm());
	}

	/**
	 * Sensor Light
	 */
	private void startPythonLightSensor() {

		runNewThread(() -> PythonManager.startlightMessure());
	}

	/**
	 * Start Laser
	 */
	private void startLaser() {

		runNewThread(() -> PythonManager.startLaser());
	}

	private void runNewThread(Runnable runnable) {
		executorService.execute(runnable);
	}

	/*
	 * Just in case we need some day a thread service with return values
	 */
	private Future<Object> runThreadWithReturnValue(Callable callable) {
		return executorService.submit(callable);
	}
}
© 2019 by-own
Wir benutzen Cookies

Wir nutzen Cookies auf unserer Website. Einige von ihnen sind essenziell für den Betrieb der Seite, während andere uns helfen, diese Website und die Nutzererfahrung zu verbessern (Tracking Cookies). Sie können selbst entscheiden, ob Sie die Cookies zulassen möchten. Bitte beachten Sie, dass bei einer Ablehnung womöglich nicht mehr alle Funktionalitäten der Seite zur Verfügung stehen.