LoginSignup
0
1

More than 5 years have passed since last update.

JavaFxとleJOSでEv3ラジコンを作る【後編】

Last updated at Posted at 2017-03-23

はじめに

この記事はleJOSの開発環境が整っていることが前提にしています。
詳しくはこちらの記事を参考にして下さい。

【leJOS】mindstorm-EV3をJavaでプログラミングしよう【環境構築前編】

【leJOS】mindstorm-EV3をJavaでプログラミングしよう【環境構築後編】

概要

この記事は以下の記事の続編となっています。leJOSのリモートコントロール用クラスremoteEv3とJavaFxを使ってEv3を制御するGUIアプリケーションの開発を解説します。

JavaFxとleJOSでEv3ラジコンを作る【前編】

今回作成したものは簡単なラジコンアプリです。
(クリックで動画再生)
IMAGE ALT TEXT HERE

プログラム

 ファイル構成は次のようになっています。
プロジェクト名はJavaFxEv3としました。
スクリーンショット 2017-03-13 23.17.58.png

Form.fxml

ここにGUIを記述します。SceneBuilderを使って編集できます。

Form.fxml
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.Pane?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.FormController">
   <children>
      <Button fx:id="LeftButton" layoutX="100.0" layoutY="180.0" mnemonicParsing="false" onMousePressed="#LeftButtonPressed" onMouseReleased="#LeftButtonReleased" prefHeight="40.0" prefWidth="100.0" text="Left" />
      <Button fx:id="RightButton" layoutX="400.0" layoutY="180.0" mnemonicParsing="false" onMousePressed="#RightButtonPressed" onMouseReleased="#RightButtonReleased" prefHeight="40.0" prefWidth="100.0" text="Right" />
      <Button fx:id="ForwardButton" layoutX="250.0" layoutY="62.0" mnemonicParsing="false" onMousePressed="#ForwardButtonPressed" onMouseReleased="#ForwardButtonReleased" prefHeight="40.0" prefWidth="100.0" text="Forward" />
      <Button fx:id="BackwardButton" layoutX="250.0" layoutY="300.0" mnemonicParsing="false" onMousePressed="#BackwardButtonPressed" onMouseReleased="#BackwardButtonReleased" prefHeight="40.0" prefWidth="100.0" text="Backward" />
   </children>
</Pane>

解説

それぞれのボタンにマウスで押された時と、マウスが離れた時に呼ばれるメソッドを登録しています。onMousePressedにボタンが押された時のメソッド、onMouseReleasedにボタンが離された時のメソッドを登録します。
スクリーンショット 2017-03-18 12.51.02.png

application.css

GUIのスタイルを設定できます。

application.css
/* 背景色の設定 */
.root{  
    -fx-background-color: white;
}
/* ボタンの色設定 */
.button {
    -fx-background-color: slateblue; -fx-text-fill: white;
}
/* ボタンマウスオーバー時の色設定 */
.button:hover{
    -fx-background-color: green; -fx-text-fill: white;
}

Main.java

Main.java
package application;

import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import lejos.remote.ev3.RMIRegulatedMotor;
import lejos.remote.ev3.RemoteEV3;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.fxml.FXMLLoader;


public class Main extends Application {
    public RemoteEV3 ev3 = null;
    public RMIRegulatedMotor leftMotor = null;
    public RMIRegulatedMotor rightMotor = null;

    @Override
    public void start(Stage primaryStage) {
        try {
            //リモートコントロールのためのインスタンス生成
            ev3 = new RemoteEV3("192.168.2.91");
            ev3.setDefault();
            //モーターオブジェクト作成
            leftMotor = ev3.createRegulatedMotor("A", 'L');
            rightMotor = ev3.createRegulatedMotor("B", 'L');
        } catch (RemoteException | MalformedURLException | NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Form.fxml"));
            Pane root = (Pane)loader.load();        
            Scene scene = new Scene(root,600,400);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm()); 

            //コントローラにモーターオブジェクトを渡す
            FormController controller = loader.getController();
            controller.setThisLeftMotor(leftMotor);
            controller.setThisRightMotor(rightMotor);

            //画面表示
            primaryStage.setScene(scene);
            primaryStage.show();

            //画面が閉じられた時の処理
            primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
                  public void handle(WindowEvent we) {
                      System.out.println("Stage is closing");
                      try {
                        leftMotor.close();
                        rightMotor.close();
                      } catch (RemoteException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                      }
                  }
             });        
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

解説

RemoteEv3クラスを使ってモーターにアクセスするオブジェクトを作成します。

            ev3 = new RemoteEV3("192.168.2.91");
            ev3.setDefault();
            //モーターオブジェクト作成
            leftMotor = ev3.createRegulatedMotor("A", 'L');
            rightMotor = ev3.createRegulatedMotor("B", 'L');

モーターオブジェクトをコントローラに渡します。

            //コントローラにモーターオブジェクトを渡す
            FormController controller = loader.getController();
            controller.setThisLeftMotor(leftMotor);
            controller.setThisRightMotor(rightMotor);

プログラム終了時にモーターへのアクセスを閉じるようにします。これを設定しないとプログラムを再度起動した際にエラーが起きてしまいます。

            primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
                  public void handle(WindowEvent we) {
                      System.out.println("Stage is closing");
                      try {
                        leftMotor.close();
                        rightMotor.close();
                      } catch (RemoteException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                      }
                  }
             });      

FormController.java

コントローラ部分です。GUIとメソッドを関連付けします。

FormController.java
package application;

import java.rmi.RemoteException;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import lejos.remote.ev3.RMIRegulatedMotor;

public class FormController {
    public RMIRegulatedMotor thisLeftMotor = null;
    public RMIRegulatedMotor thisRightMotor = null;

    public void setThisLeftMotor(RMIRegulatedMotor leftMotor) {
        thisLeftMotor = leftMotor;
    }

    public void setThisRightMotor(RMIRegulatedMotor rightMotor) {
        thisRightMotor = rightMotor;
    }

    @FXML
    Button LeftButton;
    @FXML
    Button RightButton;
    @FXML
    Button ForwardButton;
    @FXML
    Button BackwardButton;

    @FXML
    void initialize() {
        System.out.println("初期化処理");     
    }

    @FXML
    public void LeftButtonPressed(MouseEvent actionEvent) {
        try {
            thisLeftMotor.forward();
            thisRightMotor.backward();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void LeftButtonReleased(MouseEvent actionEvent) {
        try {
            thisLeftMotor.stop(true);
            thisRightMotor.stop(true);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void RightButtonPressed(MouseEvent actionEvent) {
        try {
            thisLeftMotor.backward();
            thisRightMotor.forward();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void RightButtonReleased(MouseEvent actionEvent) {
        try {
            thisLeftMotor.stop(true);
            thisRightMotor.stop(true);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void ForwardButtonPressed(MouseEvent actionEvent) {
        try {
            thisLeftMotor.forward();
            thisRightMotor.forward();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void ForwardButtonReleased(MouseEvent actionEvent) {
        try {
            thisLeftMotor.stop(true);
            thisRightMotor.stop(true);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void BackwardButtonPressed(MouseEvent actionEvent) {
        try {
            thisLeftMotor.backward();
            thisRightMotor.backward();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void BackwardButtonReleased(MouseEvent actionEvent) {
        try {
            thisLeftMotor.stop(true);
            thisRightMotor.stop(true);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

解説

コントローラ内からモーターオブジェクトにアクセスするためにセッターを定義します。

    public void setThisLeftMotor(RMIRegulatedMotor leftMotor) {
        thisLeftMotor = leftMotor;
    }

    public void setThisRightMotor(RMIRegulatedMotor rightMotor) {
        thisRightMotor = rightMotor;
    }

例えば以下のコードではLeftButtonが押された時に呼び出されるLeftButtonPressedメソッド、LeftButtonが離された時に呼び出されるLeftButtonReleasedメソッドを定義しています。

    @FXML
    public void LeftButtonPressed(MouseEvent actionEvent) {
        try {
            thisLeftMotor.forward();
            thisRightMotor.backward();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @FXML
    public void LeftButtonReleased(MouseEvent actionEvent) {
        try {
            thisLeftMotor.stop(true);
            thisRightMotor.stop(true);
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

まとめ

JavaFxとleJOSのRemoteEv3クラスを使ったGUIアプリの開発方法を紹介しました。
これを使えばセンサー値を取得してGUI上に可視化するといったこともできるでしょう。
RemoteEv3クラスに関してはこちらの記事も参考にして下さい。

【leJOS】JavaでEV3のモーターをリモートコントロールしよう

【leJOS】JavaでEV3のセンサー値をリモートから取得する

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1