Archived
Private
Public Access
1
0

Initial commit

This commit is contained in:
2022-09-04 12:45:01 +02:00
commit f4a01d6a69
11601 changed files with 4206660 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.scripting.IScriptingLanguage;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.File;
import java.util.List;
/**
* Created by Ryan Benasutti on 2/6/2016.
*/
@SuppressWarnings("restriction")
public class AddFileToGistController extends Application {
@FXML
public TextField filenameField;
@FXML
public Button addFileButton, cancelButton;
@FXML
private ComboBox<String> extention;
@FXML // fx:id="langaugeIcon"
private ImageView langaugeIcon; // Value injected by FXMLLoader
private String extentionStr = ".groovy";
private String gitRepo;
@FXML
private TextArea description;
private MenuRefreshEvent refreshevent;
// private GHGist gistID;
public AddFileToGistController(String gitRepo,MenuRefreshEvent event) {
this.gitRepo = gitRepo;
// this.gistID = id;
this.refreshevent = event;
}
@SuppressWarnings("restriction")
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = AssetFactory.loadLayout("layout/addFileToGist.fxml", true);
Parent root;
loader.setController(this);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
extention.getItems().clear();
List<String> langs = ScriptingEngine.getAllLangauges();
ObservableList<String> options = FXCollections.observableArrayList(langs);
//
for(String s:options){
extention.getItems().add(s);
}
extention.getSelectionModel().select("Groovy");
Image icon;
String asset = "Script-Tab-" + extention.getSelectionModel().getSelectedItem() + ".png";
try {
icon = AssetFactory.loadAsset(asset);
langaugeIcon.setImage(icon);
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
extention.setOnAction(event -> {
try {
langaugeIcon.setImage(AssetFactory
.loadAsset(asset));
String key = extention.getSelectionModel().getSelectedItem();
IScriptingLanguage l = ScriptingEngine
.getLangaugesMap()
.get(key);
if(l!=null){
extentionStr= "."+l.getFileExtenetion()
.get(0);
}
else
extentionStr=".groovy";
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
});
Platform.runLater(() -> {
primaryStage.setTitle("Add File to Git Repo "+gitRepo);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.initModality(Modality.WINDOW_MODAL);
primaryStage.setResizable(true);
primaryStage.show();
});
}
@FXML
public void onAddFile(ActionEvent event) {
new Thread(()->{
Platform.runLater(() -> {
Stage stage = (Stage) addFileButton.getScene().getWindow();
stage.close();
});
String text = filenameField.getText();
if(!text.endsWith(extentionStr)){
text=text+extentionStr;
}
String message = description.getText();
if(message == null || message.length()==0){
message = text;
}
if(gitRepo==null){
gitRepo=GistHelper.createNewGist(text, message, true);
}
System.out.println("Adding new file"+text+" to "+gitRepo);
try {
ScriptingEngine.pushCodeToGit(gitRepo, ScriptingEngine.getFullBranch(gitRepo), text, "//Your code here",
message);
File nf = ScriptingEngine.fileFromGit(gitRepo, text);
BowlerStudio.createFileTab(nf);
refreshevent.setToLoggedIn();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
@FXML
public void onCancel(ActionEvent event) {
Platform.runLater(() -> {
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.close();
});
}
}

View File

@@ -0,0 +1,788 @@
package com.neuronrobotics.bowlerstudio;
//import com.neuronrobotics.kinematicschef.InverseKinematicsEngine;
import com.neuronrobotics.bowlerkernel.BowlerKernelBuildInfo;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager;
import com.neuronrobotics.bowlerstudio.creature.MobileBaseLoader;
import com.neuronrobotics.bowlerstudio.scripting.ArduinoLoader;
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
import com.neuronrobotics.bowlerstudio.scripting.StlLoader;
import com.neuronrobotics.imageprovider.NativeResource;
//import com.neuronrobotics.imageprovider.OpenCVJNILoader;
import com.neuronrobotics.javacad.JavaCadBuildInfo;
import com.neuronrobotics.replicator.driver.Slic3r;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.FirmataLink;
import com.neuronrobotics.sdk.addons.kinematics.JavaFXInitializer;
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.common.*;
import com.neuronrobotics.sdk.config.SDKBuildInfo;
import com.neuronrobotics.sdk.util.ThreadUtil;
import eu.mihosoft.vrl.v3d.CSG;
import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase;
import eu.mihosoft.vrl.v3d.svg.ISVGLoadProgress;
import eu.mihosoft.vrl.v3d.svg.SVGLoad;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.TextArea;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.dockfx.DockPane;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.python.antlr.ast.Pass;
import org.reactfx.util.FxTimer;
import org.w3c.dom.Document;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("restriction")
public class BowlerStudio extends Application {
final static SplashScreen splash = null;// = SplashScreen.getSplashScreen();
private static Scene scene;
private static boolean hasnetwork;
private static Console out;
private static TextArea logViewRefStatic = null;
private static String firstVer = "";
private static Stage primaryStage2;
private static File layoutFile;
private static boolean deleteFlag = false;
private static IssueReportingExceptionHandler reporter = new IssueReportingExceptionHandler();
private static String lastVersion;
private static class Console extends OutputStream {
private static final int LengthOfOutputLog = 5000;
ByteList incoming = new ByteList();
Thread update = new Thread() {
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
while (true) {
ThreadUtil.wait(150);
if (incoming.size() > 0)
try {
String text = incoming.asString();
incoming.clear();
if (text != null && text.length() > 0)
appendText(text);
text = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
public Console() {
update.start();
}
@SuppressWarnings("restriction")
public void appendText(String valueOf) {
if (BowlerStudioModularFrame.getBowlerStudioModularFrame() == null) {
return;
}
try {
BowlerStudioModularFrame.getBowlerStudioModularFrame().showTerminal();
} catch (Exception ex) {
// frame not open yet
ex.printStackTrace();
}
if (getLogViewRefStatic() != null) {
String text = getLogViewRefStatic().getText();
if (text.length() > LengthOfOutputLog) {
Platform.runLater(() -> {
try {
getLogViewRefStatic().deleteText(0, text.length() - LengthOfOutputLog);
getLogViewRefStatic().appendText(valueOf);
} catch (Throwable t) {
}
});
} else {
Platform.runLater(() -> {
getLogViewRefStatic().appendText(valueOf);
});
}
}
System.err.print(valueOf);
}
public void write(int b) throws IOException {
incoming.add(b);
// appendText(String.valueOf((char)b));
// if(b=='[')
// new RuntimeException().printStackTrace();
}
}
public static OutputStream getOut() {
if (out == null)
out = new Console();
return out;
}
public static MobileBase loadMobileBaseFromGit(String id, String file) throws Exception {
return MobileBaseLoader.fromGit(id, file);
}
public static void select(MobileBase base) {
if (CreatureLab3dController.getEngine().isAutoHightlight()) {
MobileBaseCadManager.get(base).selectCsgByMobileBase(base);
}
/*
* try {
*
* ArrayList<CSG> csg =
* MobileBaseCadManager.get(base).getBasetoCadMap().get(base);
* CreatureLab3dController.getEngine(). setSelectedCsg(csg.get(0));
* CreatureLab3dController.getEngine(). setSelectedCsg(csg); } catch (Exception
* ex) { System.err.println("Base not loaded yet"); }
*/
}
public static void select(MobileBase base, DHParameterKinematics limb) {
if (CreatureLab3dController.getEngine().isAutoHightlight()) {
MobileBaseCadManager.get(base).selectCsgByLimb(base, limb);
}
/*
* try {
*
* ArrayList<CSG> limCad =
* MobileBaseCadManager.get(base).getDHtoCadMap().get(limb); try {
* CreatureLab3dController.getEngine() .setSelectedCsg(limCad.get(limCad.size()
* - 1)); } catch (Exception ex) { // initialization has no csgs yet }
* CreatureLab3dController.getEngine(). setSelectedCsg(limCad); } catch
* (Exception ex) { System.err.println("Limb not loaded yet"); }
*/
}
public static void select(MobileBase base, LinkConfiguration limb) {
if (CreatureLab3dController.getEngine().isAutoHightlight()) {
MobileBaseCadManager.get(base).selectCsgByLink(base, limb);
}
/*
* try {
*
* ArrayList<CSG> limCad =
* MobileBaseCadManager.get(base).getLinktoCadMap().get(limb);
* CreatureLab3dController.getEngine() .setSelectedCsg(limCad.get(limCad.size()
* - 1)); CreatureLab3dController.getEngine(). setSelectedCsg(limCad); } catch
* (Exception ex) { System.err.println("Limb not loaded yet"); }
*/
}
public static void select(File script, int lineNumber) {
if (CreatureLab3dController.getEngine().isAutoHightlight())
try {
CreatureLab3dController.getEngine().setSelectedCsg(script, lineNumber);
} catch (Exception ex) {
System.err.println("File not found");
}
}
/**
* @param args the command line arguments
* @throws Exception
*/
@SuppressWarnings({ "unchecked", "restriction" })
public static void main(String[] args) throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
if (!StudioBuildInfo.isOS64bit()) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("32 Bit Java Detected");
alert.setHeaderText("Insuffient Ram Capibilities in 32 bit mode");
alert.setContentText("This applications uses more that 4gb of ram\nA 32 bit JVM mode detected: "
+ System.getProperty("os.arch"));
alert.showAndWait();
System.exit(1);
});
}
Log.enableWarningPrint();
renderSplashFrame(2, "Testing Internet");
try {
final URL url = new URL("http://github.com");
final URLConnection conn = url.openConnection();
conn.connect();
conn.getInputStream();
setHasnetwork(true);
} catch (Exception e) {
// we assuming we have no access to the server and run off of the
// cached gists.
setHasnetwork(false);
}
CSG.setDefaultOptType(CSG.OptType.CSG_BOUND);
CSG.setProgressMoniter((currentIndex, finalIndex, type, intermediateShape) -> {
// Remove the default printing
});
eu.mihosoft.vrl.v3d.svg.SVGLoad.getProgressDefault();
eu.mihosoft.vrl.v3d.svg.SVGLoad.setProgressDefault(new ISVGLoadProgress() {
@Override
public void onShape(CSG newShape) {
BowlerStudioController.addCsg(newShape);
}
});
StudioBuildInfo.setBaseBuildInfoClass(BowlerStudio.class);
if (args.length == 0) {
renderSplashFrame(5, "Loging In...");
// ScriptingEngine.logout();
if (PasswordManager.hasNetwork()) {
ScriptingEngine.setLoginManager(new GitHubLoginManager());
try {
ScriptingEngine.login();
renderSplashFrame(10, "Login OK!");
} catch (Exception e) {
// e.printStackTrace();
ScriptingEngine.setupAnyonmous();
renderSplashFrame(10, "No Login Found");
}
}
String myAssets = AssetFactory.getGitSource();
if (PasswordManager.hasNetwork()) {
if (ScriptingEngine.isLoginSuccess()) {
if (BowlerStudio.hasNetwork()) {
ScriptingEngine.setAutoupdate(true);
}
renderSplashFrame(15, "Load Configs");
try {
firstVer = (String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "firstVersion",
StudioBuildInfo.getVersion());
} catch (Throwable t) {
System.out.println("Resetting the configs repo...");
// clear the configs repo
ScriptingEngine.deleteRepo(ConfigurationDatabase.getGitSource());
firstVer = (String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "firstVersion",
StudioBuildInfo.getVersion());
}
ConfigurationDatabase.setObject("BowlerStudioConfigs", "currentVersion",
StudioBuildInfo.getVersion());
renderSplashFrame(16, "Done Load Configs");
// String lastVersion = (String)
// ConfigurationDatabase.getObject("BowlerStudioConfigs",
// "skinBranch",
// StudioBuildInfo.getVersion());
myAssets = (String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "skinRepo",
"https://github.com/madhephaestus/BowlerStudioImageAssets.git");
renderSplashFrame(20, "DL'ing Image Assets");
File gitRepoFile = ScriptingEngine.uriToFile(myAssets);
if (!gitRepoFile.exists()) {
lastVersion = null;
} else
lastVersion = ScriptingEngine.getBranch(myAssets);
System.err.println("Asset Repo " + myAssets);
System.err.println("Asset current ver " + lastVersion);
System.err.println("Asset intended ver " + StudioBuildInfo.getVersion());
if (lastVersion != null && StudioBuildInfo.getVersion().contentEquals(lastVersion)) {
ScriptingEngine.pull(myAssets, StudioBuildInfo.getVersion());
System.err.println("Studio version is the same");
} else {
if (lastVersion != null)
ScriptingEngine.cloneRepo(myAssets, lastVersion);
System.err.println("\n\nnew version\n\n");
try {
if (ScriptingEngine.checkOwner(myAssets)) {
ScriptingEngine.newBranch(myAssets, StudioBuildInfo.getVersion());
} else
throw new NullPointerException();
} catch (NullPointerException ex) {
// not the owner
try {
ScriptingEngine.checkout(myAssets, StudioBuildInfo.getVersion());
} catch (Exception ex1) {
ScriptingEngine.deleteRepo(myAssets);
ScriptingEngine.cloneRepo(myAssets, StudioBuildInfo.getVersion());
}
}
lastVersion = ScriptingEngine.getBranch(myAssets);
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinBranch", lastVersion);
// force the mainline in when a version update happens
// this prevents developers from ending up with unsuable
// version of BowlerStudio
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinRepo", myAssets);
ConfigurationDatabase.save();
}
if (BowlerStudio.hasNetwork()) {
renderSplashFrame(25, "Populating Menu");
}
} else {
renderSplashFrame(20, "DL'ing Image Assets");
ScriptingEngine.cloneRepo(myAssets, null);
ScriptingEngine.checkout(myAssets, StudioBuildInfo.getVersion());
}
}
layoutFile = AssetFactory.loadFile("layout/default.css");
if (layoutFile == null || !layoutFile.exists()) {
ScriptingEngine.deleteRepo(myAssets);
throw new RuntimeException("Style sheet does not exist");
}
// SplashManager.setIcon(AssetFactory.loadAsset("BowlerStudioTrayIcon.png"));
renderSplashFrame(50, "Tutorials...");
// load tutorials repo
Tutorial.getHomeUrl(); // Dowload and launch the Tutorial server
// force the current version in to the version number
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinBranch", StudioBuildInfo.getVersion());
renderSplashFrame(53, "Loading Images");
AssetFactory.setGitSource(
(String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "skinRepo", myAssets),
StudioBuildInfo.getVersion());
renderSplashFrame(54, "Load Assets");
// Download and Load all of the assets
renderSplashFrame(60, "Vitamins...");
// load the vitimins repo so the demo is always snappy
ScriptingEngine.cloneRepo("https://github.com/CommonWealthRobotics/BowlerStudioVitamins.git", null);
renderSplashFrame(80, "Example Robots");
ScriptingEngine.fileFromGit("https://github.com/CommonWealthRobotics/BowlerStudioExampleRobots.git", // git
// repo,
// change
// this
// if
// you
// fork
// this
// demo
"exampleRobots.json"// File from within the Git repo
);
renderSplashFrame(81, "CSG database");
CSGDatabase.setDbFile(new File(ScriptingEngine.getWorkspace().getAbsoluteFile() + "/csgDatabase.json"));
// System.out.println("Loading assets ");
// System.out.println("Loading Main.fxml");
renderSplashFrame(81, "Find arduino");
String arduino = "arduino";
if (NativeResource.isLinux()) {
Slic3r.setExecutableLocation("/usr/bin/slic3r");
} else if (NativeResource.isWindows()) {
arduino = "C:\\Program Files (x86)\\Arduino\\arduino.exe";
if (!new File(arduino).exists()) {
arduino = "C:\\Program Files\\Arduino\\arduino.exe";
}
} else if (NativeResource.isOSX()) {
arduino = "/Applications/Arduino.app/Contents/MacOS/Arduino";
}
try {
if (!new File(arduino).exists() && !NativeResource.isLinux()) {
boolean alreadyNotified = Boolean.getBoolean(ConfigurationDatabase
.getObject("BowlerStudioConfigs", "notifiedArduinoDep", false).toString());
if (!alreadyNotified) {
ConfigurationDatabase.setObject("BowlerStudioConfigs", "notifiedArduinoDep", true);
String adr = arduino;
}
}
System.out.println("Arduino exec found at: " + arduino);
ArduinoLoader.setARDUINOExec(arduino);
} catch (Exception e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
renderSplashFrame(82, "Set up UI");
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// This is a workaround for #8 and is only relavent on osx
// it causes the SwingNodes not to load if not called way ahead
// of time
javafx.scene.text.Font.getFamilies();
} catch (Exception e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
renderSplashFrame(90, "Loading STL Loader");
// Add the engine handeler for STLs
ScriptingEngine.addScriptingLanguage(new StlLoader());
// add a new link provider to the link factory
FirmataLink.addLinkFactory();
// Log.enableInfoPrint();
renderSplashFrame(92, "Preload done");
// ThreadUtil.wait(100);
try {
ScriptingEngine.pull("https://github.com/CommonWealthRobotics/HotfixBowlerStudio.git");
ScriptingEngine.pull("https://github.com/CommonWealthRobotics/DeviceProviders.git");
ScriptingEngine.gitScriptRun("https://github.com/CommonWealthRobotics/HotfixBowlerStudio.git",
"hotfix.groovy", null);
ScriptingEngine.gitScriptRun("https://github.com/CommonWealthRobotics/DeviceProviders.git",
"loadAll.groovy", null);
} catch (Exception e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
launch();
} else {
BowlerKernel.main(args);
}
}
// private static void removeAssets(String myAssets)
// throws InvalidRemoteException, TransportException, GitAPIException, IOException, Exception {
// System.err.println("Clearing assets");
// ScriptingEngine.deleteRepo(myAssets);
// AssetFactory.setGitSource((String) ConfigurationDatabase.getObject("BowlerStudioConfigs", "skinRepo", myAssets),
// StudioBuildInfo.getVersion());
// }
public static void closeSplash() {
SplashManager.closeSplash();
}
public static void renderSplashFrame(int frame, String message) {
SplashManager.renderSplashFrame(frame, message);
}
/**
* open an external web page
*
* @param uri
*/
public static void openExternalWebpage(URL uri) {
Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(uri.toURI());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* @author Sainath
* @version 1.0
* @param url - The URL of the tab that needs to be opened
*/
public static void openUrlInNewTab(URL url) {
BowlerStudioModularFrame.getBowlerStudioModularFrame().openUrlInNewTab(url);
}
/**
* @author Sainath
* @version 1.0
* @param msg - message that needs to be spoken
* @return an integer
*/
public static int speak(String msg) {
return BowlerKernel.speak(msg);
}
public static ScriptingFileWidget createFileTab(File file) {
return BowlerStudioModularFrame.getBowlerStudioModularFrame().createFileTab(file);
}
@SuppressWarnings("restriction")
public static Scene getScene() {
return scene;
}
@SuppressWarnings("restriction")
public static void setScene(Scene s) {
scene = s;
}
@SuppressWarnings("restriction")
public static void clearConsole() {
Platform.runLater(() -> {
if (getLogViewRefStatic() != null)
getLogViewRefStatic().setText("");
});
}
public static boolean hasNetwork() {
return hasnetwork;
}
public static void setHasnetwork(boolean hasnetwork) {
BowlerStudio.hasnetwork = hasnetwork;
}
@SuppressWarnings("restriction")
public static TextArea getLogViewRefStatic() {
return logViewRefStatic;
}
public static void setLogViewRefStatic(@SuppressWarnings("restriction") TextArea logViewRefStatic) {
BowlerStudio.logViewRefStatic = logViewRefStatic;
}
public static void setCreatureLab3d(CreatureLab3dController creatureLab3dController) {
}
@SuppressWarnings("restriction")
@Override
public void start(Stage primaryStage) {
try { // do this ...
Thread thread = Thread.currentThread();
if (thread.getContextClassLoader() == null) {
// seriously Apple??
System.err.println("ContextClassLoader Is Missing! (OSX) ");
thread.setContextClassLoader(getClass().getClassLoader()); // a
// valid
// ClassLoader
// from
// somewhere
// else
}
} catch (SecurityException e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
System.err.println("Class loader: " + Thread.currentThread().getContextClassLoader());
new Thread(() -> {
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
try {
String stylesheet = Application.STYLESHEET_MODENA;// "MODENA" or
// "CASPIAN"
// System.setProperty("javax.userAgentStylesheetUrl",
// stylesheet);
setUserAgentStylesheet(stylesheet);
} catch (Exception | Error e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
// These must be changed before anything starts
PrintStream ps = new PrintStream(getOut());
// System.setErr(ps);
System.setOut(ps);
renderSplashFrame(93, "Loading resources");
try {
BowlerStudioResourceFactory.load();
} catch (Exception e1) {
reporter.uncaughtException(Thread.currentThread(), e1);
}
primaryStage2 = primaryStage;
BowlerStudioModularFrame.setPrimaryStage(primaryStage);
// Initialize your logic here: all @FXML variables will have been
// injected
FXMLLoader mainControllerPanel;
try {
mainControllerPanel = AssetFactory.loadLayout("layout/BowlerStudioModularFrame.fxml");
renderSplashFrame(96, "Setting controller");
mainControllerPanel.setController(new BowlerStudioModularFrame());
// renderSplashFrame(96, "Class loader");
// mainControllerPanel.setClassLoader(BowlerStudioModularFrame.class.getClassLoader());
try {
renderSplashFrame(96, "Controller load");
mainControllerPanel.load();
} catch (Exception e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
renderSplashFrame(96, "UI Launch...");
Scene scene = new Scene(mainControllerPanel.getRoot(), 1024, 768, true);
String nwfile = layoutFile.toURI().toString().replace("file:/", "file:///");
scene.getStylesheets().clear();
scene.getStylesheets().add(nwfile);
System.err.println("Loading CSS from " + nwfile);
Platform.runLater(() -> {
primaryStage.setScene(scene);
System.err.println("Showing main applicaiton");
primaryStage.show();
// initialize the default styles for the dock pane and
// undocked
// nodes using the DockFX
// library's internal Default.css stylesheet
// unlike other custom control libraries this allows the
// user to
// override them globally
// using the style manager just as they can with internal
// JavaFX
// controls
// this must be called after the primary stage is shown
// https://bugs.openjdk.java.net/browse/JDK-8132900
DockPane.initializeDefaultUserAgentStylesheet();
});
primaryStage.setOnCloseRequest(arg0 -> {
// ThreadUtil.wait(100);
closeBowlerStudio();
});
Platform.runLater(() -> {
primaryStage.setTitle("Bowler Studio: v " + StudioBuildInfo.getVersion());
try {
primaryStage.getIcons().add(AssetFactory.loadAsset("BowlerStudioTrayIcon.png"));
} catch (Exception e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
});
;
primaryStage.setResizable(true);
DeviceManager.addDeviceAddedListener(new IDeviceAddedListener() {
@Override
public void onNewDeviceAdded(BowlerAbstractDevice arg0) {
System.err.println("Device connected: " + arg0);
BowlerStudioModularFrame.getBowlerStudioModularFrame().showConectionManager();
}
@Override
public void onDeviceRemoved(BowlerAbstractDevice arg0) {
}
});
Log.enableDebugPrint(false);
// Log.enableWarningPrint();
// Log.enableDebugPrint();
// Log.enableErrorPrint();
FxTimer.runLater(java.time.Duration.ofMillis((int) 2000), () -> {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
System.out.println("Java Version : " + javaVersion);
System.out.println("JavaFX Version : " + javafxVersion);
System.out.println("BowlerStudio First Version: " + firstVer);
System.out.println("Java-Bowler Version: " + SDKBuildInfo.getVersion());
System.out.println("Bowler-Scripting-Kernel Version: " + BowlerKernelBuildInfo.getVersion());
System.out.println("JavaCad Version: " + JavaCadBuildInfo.getVersion());
System.out.println("Welcome to BowlerStudio!");
});
closeSplash();
if (!ScriptingEngine.isLoginSuccess() || PasswordManager.isAnonMode())
BowlerStudioModularFrame.getBowlerStudioModularFrame().menueController.onLogin(null);
} catch (Throwable e) {
reporter.uncaughtException(Thread.currentThread(), e);
}
}).start();
}
@SuppressWarnings("restriction")
public static void closeBowlerStudio() {
Platform.runLater(() -> {
primaryStage2.hide();
});
new Thread() {
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
renderSplashFrame(100, "Saving state..");
ConnectionManager.disconnectAll();
if(PasswordManager.hasNetwork()) {
if (ScriptingEngine.isLoginSuccess() && !PasswordManager.isAnonMode())
ConfigurationDatabase.save();
}
if (isDeleteFlag())
ScriptingEngine.deleteCache();
System.exit(0);
}
}.start();
}
public static void printStackTrace(Throwable e) {
printStackTrace(e, null);
}
public static void printStackTrace(Throwable e, File sourceFile) {
BowlerStudioController.highlightException(sourceFile, e);
}
public static void println(CSG... toDisplay) {
BowlerStudioController.setCsg(Arrays.asList(toDisplay));
}
public static void println(ArrayList<CSG> toDisplay) {
BowlerStudioController.setCsg(toDisplay);
}
public static void print(CSG... toDisplay) {
for (CSG c : Arrays.asList(toDisplay))
BowlerStudioController.addCsg(c);
}
public static void print(ArrayList<CSG> toDisplay) {
for (CSG c : toDisplay)
BowlerStudioController.addCsg(c);
}
public static boolean isDeleteFlag() {
return deleteFlag;
}
public static void setDeleteFlag(boolean deleteFlag) {
BowlerStudio.deleteFlag = deleteFlag;
}
public static void exit() {
closeBowlerStudio();
}
}

View File

@@ -0,0 +1,566 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.bowlerstudio.creature.IMobileBaseUI;
import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager;
import com.neuronrobotics.bowlerstudio.scripting.IScriptEventListener;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
import com.neuronrobotics.bowlerstudio.tabs.LocalFileScriptTab;
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
import com.neuronrobotics.bowlerstudio.threed.Line3D;
import com.neuronrobotics.imageprovider.AbstractImageProvider;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.DMDevice;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.common.NonBowlerDevice;
import com.neuronrobotics.sdk.util.ThreadUtil;
import eu.mihosoft.vrl.v3d.CSG;
import eu.mihosoft.vrl.v3d.Polygon;
import eu.mihosoft.vrl.v3d.Vertex;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.control.Tab;
import javafx.stage.Stage;
import javax.swing.text.BadLocationException;
import org.kohsuke.github.GHRepository;
import org.reactfx.util.FxTimer;
import java.awt.Color;
//import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.time.Duration;
//import org.bytedeco.javacpp.DoublePointer;
@SuppressWarnings("restriction")
public class BowlerStudioController implements IScriptEventListener {
/**
*
*/
private ConnectionManager connectionManager;
private AbstractImageProvider vrCamera;
private static BowlerStudioController bowlerStudioControllerStaticReference = null;
private boolean doneLoadingTutorials = false;
private boolean runningExceptionHighlight = false;
public BowlerStudioController() {
if (getBowlerStudio() != null)
throw new RuntimeException("There can be only one Bowler Studio controller");
bowlerStudioControllerStaticReference = this;
size = ((Number) ConfigurationDatabase.getObject("BowlerStudioConfigs", "fontsize", 12)).intValue();
}
private HashMap<String, Tab> openFiles = new HashMap<>();
private HashMap<String, LocalFileScriptTab> widgets = new HashMap<>();
private int size;
private static IMobileBaseUI mbui = new IMobileBaseUI() {
@Override
public void highlightException(File fileEngineRunByName, Exception ex) {
BowlerStudioController.highlightException(fileEngineRunByName, ex);
}
@Override
public void setAllCSG(Collection<CSG> toAdd, File source) {
try {
BowlerStudioController.setCsg(new ArrayList<>(toAdd));
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override
public void addCSG(Collection<CSG> toAdd, File source) {
// TODO Auto-generated method stub
for (CSG b : toAdd)
BowlerStudioController.addCsg(b);
}
@Override
public Set<CSG> getVisibleCSGs() {
return CreatureLab3dController.getEngine().getCsgMap().keySet();
}
@Override
public void setSelectedCsg(Collection<CSG> selectedCsg) {
CreatureLab3dController.getEngine().setSelectedCsg(new ArrayList<>(selectedCsg));
}
};
public void setFontSize(int size) {
this.size = size;
for (String key : widgets.keySet()) {
widgets.get(key).setFontSize(size);
}
ConfigurationDatabase.setObject("BowlerStudioConfigs", "fontsize", size);
}
// Custom function for creation of New Tabs.
public ScriptingFileWidget createFileTab(File file) {
if (openFiles.get(file.getAbsolutePath()) != null && widgets.get(file.getAbsolutePath()) != null) {
BowlerStudioModularFrame.getBowlerStudioModularFrame()
.setSelectedTab(openFiles.get(file.getAbsolutePath()));
return widgets.get(file.getAbsolutePath()).getScripting();
}
Tab fileTab = new Tab(file.getName());
openFiles.put(file.getAbsolutePath(), fileTab);
try {
Log.warning("Loading local file from: " + file.getAbsolutePath());
LocalFileScriptTab t = new LocalFileScriptTab(file);
new Thread() {
public void run() {
BowlerStudioMenuWorkspace.add(t.getScripting().getGitRepo());
}
}.start();
String key = t.getScripting().getGitRepo() + ":" + t.getScripting().getGitFile();
ArrayList<String> files = new ArrayList<>();
files.add(t.getScripting().getGitRepo());
files.add(t.getScripting().getGitFile());
if(key.length()>3 && files.get(0).length()>0 && files.get(1).length()>0)// catch degenerates
ConfigurationDatabase.setObject("studio-open-git", key, files);
fileTab.setContent(t);
fileTab.setGraphic(
AssetFactory.loadIcon("Script-Tab-" + ScriptingEngine.getShellType(file.getName()) + ".png"));
addTab(fileTab, true);
widgets.put(file.getAbsolutePath(), t);
fileTab.setOnCloseRequest(event -> {
widgets.remove(file.getAbsolutePath());
openFiles.remove(file.getAbsolutePath());
ConfigurationDatabase.removeObject("studio-open-git", key);
t.getScripting().close();
System.out.println("Closing " + file.getAbsolutePath());
});
t.setFontSize(size);
return t.getScripting();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void clearHighlits() {
for (Entry<String, LocalFileScriptTab> set : widgets.entrySet()) {
set.getValue().clearHighlits();
}
}
public void setHighlight(File fileEngineRunByName, int lineNumber, Color color) {
// System.out.println("Highlighting line "+lineNumber+" in
// "+fileEngineRunByName);
if (openFiles.get(fileEngineRunByName.getAbsolutePath()) == null) {
createFileTab(fileEngineRunByName);
ThreadUtil.wait(100);
}
// BowlerStudioModularFrame.getBowlerStudioModularFrame().setSelectedTab(openFiles.get(fileEngineRunByName.getAbsolutePath()));
// System.out.println("Highlighting "+fileEngineRunByName+" at line
// "+lineNumber+" to color "+color);
try {
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(lineNumber, color);
} catch (BadLocationException e) {
// e.printStackTrace();
}
}
public static void highlightException(File fileEngineRunByName, Throwable ex) {
if(bowlerStudioControllerStaticReference!=null)
bowlerStudioControllerStaticReference.highlightExceptionLocal(fileEngineRunByName, ex);
}
public static void clearHighlight() {
bowlerStudioControllerStaticReference.clearHighlits();
}
private void highlightExceptionLocal(File fileEngineRunByName, Throwable ex) {
// THis needs to gate on checking if this thread is running already
if(runningExceptionHighlight) {
ex.printStackTrace();
new RuntimeException("Only one exception Highlight can be called at once!").printStackTrace();
return;
}
new Thread() {
public void run() {
runningExceptionHighlight=true;
setName("Highlighter thread");
if (fileEngineRunByName != null) {
if (openFiles.get(fileEngineRunByName.getAbsolutePath()) == null) {
createFileTab(fileEngineRunByName);
}
BowlerStudioModularFrame.getBowlerStudioModularFrame()
.setSelectedTab(openFiles.get(fileEngineRunByName.getAbsolutePath()));
widgets.get(fileEngineRunByName.getAbsolutePath()).clearHighlits();
// System.out.println("Highlighting "+fileEngineRunByName+" at line
// "+lineNumber+" to color "+color);
StackTraceElement[] stackTrace = ex.getStackTrace();
for (StackTraceElement el : stackTrace) {
try {
// System.out.println("Compairing "+fileEngineRunByName.getName()+" to
// "+el.getFileName());
if (el.getFileName().contentEquals(fileEngineRunByName.getName())) {
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(el.getLineNumber(),
Color.CYAN);
}
} catch (Exception e) {
// StringWriter sw = new StringWriter();
// PrintWriter pw = new PrintWriter(sw);
// e.printStackTrace(pw);
// System.out.println(sw.toString());
}
}
if (ex.getCause() != null) {
for (StackTraceElement el : ex.getCause().getStackTrace()) {
try {
// System.out.println("Compairing "+fileEngineRunByName.getName()+" to
// "+el.getFileName());
if (el.getFileName().contentEquals(fileEngineRunByName.getName())) {
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(el.getLineNumber(),
Color.CYAN);
}
} catch (Exception e) {
// StringWriter sw = new StringWriter();
// PrintWriter pw = new PrintWriter(sw);
// e.printStackTrace(pw);
// System.out.println(sw.toString());
}
}
}
}
try {
if (widgets.get(fileEngineRunByName.getAbsolutePath()) != null) {
String message = ex.getMessage();
// System.out.println(message);
if (message != null && message.contains(fileEngineRunByName.getName()))
try {
int indexOfFile = message.lastIndexOf(fileEngineRunByName.getName());
String fileSub = message.substring(indexOfFile);
String[] fileAndNum = fileSub.split(":");
String FileNum = fileAndNum[1];
int linNum = Integer.parseInt(FileNum.trim());
widgets.get(fileEngineRunByName.getAbsolutePath()).setHighlight(linNum, Color.CYAN);
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
System.out.println(sw.toString());
}
}
} catch (Exception ex1) {
}
try {
String sw = org.apache.commons.lang.exception.ExceptionUtils
.getStackTrace(ex);
System.out.println(sw.toString());
// space out the exception highlights, ensure any sub threads spawned here have time to finish
Thread.sleep(100);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runningExceptionHighlight=false;
}
}.start();
}
public void addTab(Tab tab, boolean closable) {
// new RuntimeException().printStackTrace();
Platform.runLater(() -> {
BowlerStudioModularFrame.getBowlerStudioModularFrame().addTab(tab, closable);
});
}
public static boolean removeObject(Object p) {
if (CSG.class.isInstance(p) ) {
Platform.runLater(() -> {
CreatureLab3dController.getEngine().removeObject((CSG) p);
});
return true;
}
if ( Node.class.isInstance(p) || Polygon.class.isInstance(p)) {
Platform.runLater(() -> {
CreatureLab3dController.getEngine().clearUserNode();
});
return true;
}
// ThreadUtil.wait(20);
return false;
}
// private boolean removeObject(Object p) {
// if (CSG.class.isInstance(p) || Node.class.isInstance(p) || Polygon.class.isInstance(p)) {
// Platform.runLater(() -> {
// CreatureLab3dController.getEngine().removeObjects();
// CreatureLab3dController.getEngine().clearUserNode();
// });
// return true;
// }
// // ThreadUtil.wait(20);
// return false;
// }
public static void setCsg(List<CSG> toadd, File source) {
Platform.runLater(() -> {
CreatureLab3dController.getEngine().removeObjects();
if (toadd != null)
for (CSG c : toadd) {
if(c!=null)
Platform.runLater(() -> CreatureLab3dController.getEngine().addObject(c, source));
}
});
}
public static void setCsg(List<CSG> toadd) {
setCsg(toadd, null);
}
public static void addCsg(CSG toadd) {
addCsg(toadd, null);
}
public static void setUserNode(List<Node> toadd) {
Platform.runLater(() -> {
CreatureLab3dController.getEngine().clearUserNode();
if (toadd != null)
for (Node c : toadd) {
CreatureLab3dController.getEngine().addUserNode(c);
}
});
}
public static void addUserNode(Node toadd) {
Platform.runLater(() -> {
if (toadd != null)
CreatureLab3dController.getEngine().addUserNode(toadd);
});
}
public static void setSelectedCsg(CSG obj) {
CreatureLab3dController.getEngine().setSelectedCsg(obj);
}
public static void addCsg(CSG toadd, File source) {
Platform.runLater(() -> {
if (toadd != null)
CreatureLab3dController.getEngine().addObject(toadd, source);
});
}
public void addObject(Object o, File source) {
if (List.class.isInstance(o)) {
List<Object> c = (List<Object>) o;
for (int i = 0; i < c.size(); i++) {
// Log.warning("Loading array Lists with removals " + c.get(i));
addObject(c.get(i), source);
}
return;
}
if (CSG.class.isInstance(o)) {
CSG csg = (CSG) o;
Platform.runLater(() -> {
// new RuntimeException().printStackTrace();
CreatureLab3dController.getEngine().addObject(csg, source);
});
return;
} else if (Tab.class.isInstance(o)) {
addTab((Tab) o, true);
return;
} else if (Node.class.isInstance(o)) {
addNode((Node) o);
return;
} else if (Polygon.class.isInstance(o)) {
Polygon p = (Polygon) o;
List<Vertex> vertices = p.vertices;
javafx.scene.paint.Color color = new javafx.scene.paint.Color(Math.random() * 0.5 + 0.5,
Math.random() * 0.5 + 0.5, Math.random() * 0.5 + 0.5, 1);
double stroke = 0.5;
for (int i = 1; i < vertices.size(); i++) {
Line3D line = new Line3D(vertices.get(i - 1), vertices.get(i));
line.setStrokeWidth(stroke);
line.setStroke(color);
addNode(line);
}
// Connecting line
Line3D line = new Line3D(vertices.get(0), vertices.get(vertices.size() - 1));
line.setStrokeWidth(stroke);
line.setStroke(color);
addNode(line);
return;
} else if (BowlerAbstractDevice.class.isInstance(o)) {
BowlerAbstractDevice bad = (BowlerAbstractDevice) o;
ConnectionManager.addConnection((BowlerAbstractDevice) o, bad.getScriptingName());
return;
} else if (DMDevice.wrappable(o)) {
BowlerAbstractDevice bad;
try {
bad = new DMDevice(o);
ConnectionManager.addConnection(bad, bad.getScriptingName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void addNode(Node o) {
CreatureLab3dController.getEngine().addUserNode(o);
}
@SuppressWarnings({ "unchecked" })
@Override
public void onScriptFinished(Object result, Object Previous, File source) {
Log.warning("Loading script results " + result + " previous " + Previous);
// this is added in the script engine when the connection manager is
// loaded
clearObjects(Previous);
clearObjects(result);
ThreadUtil.wait(40);
if (List.class.isInstance(result)) {
List<Object> c = (List<Object>) result;
for (int i = 0; i < c.size(); i++) {
// Log.warning("Loading array Lists with removals " + c.get(i));
addObject(c.get(i), source);
}
} else {
addObject(result, source);
}
}
private void clearObjects(Object o) {
if (List.class.isInstance(o)) {
@SuppressWarnings("unchecked")
List<Object> c = (List<Object>) o;
for (int i = 0; i < c.size(); i++) {
clearObjects(c.get(i));
}
} else {
removeObject(o);
}
}
@Override
public void onScriptChanged(String previous, String current, File source) {
}
@Override
public void onScriptError(Throwable except, File source) {
// TODO Auto-generated method stub
}
public void disconnect() {
ConnectionManager.disconnectAll();
}
public Stage getPrimaryStage() {
// TODO Auto-generated method stub
return BowlerStudioModularFrame.getPrimaryStage();
}
public AbstractImageProvider getVrCamera() {
return vrCamera;
}
public void setVrCamera(AbstractImageProvider vrCamera) {
this.vrCamera = vrCamera;
}
public static BowlerStudioController getBowlerStudio() {
return bowlerStudioControllerStaticReference;
}
public static void setup() {
// TODO Auto-generated method stub
}
public static void clearCSG() {
Platform.runLater(() -> {
CreatureLab3dController.getEngine().removeObjects();
});
}
public static void setCsg(CSG legAssembly, File cadScript) {
Platform.runLater(() -> {
CreatureLab3dController.getEngine().removeObjects();
if (legAssembly != null)
Platform.runLater(() -> CreatureLab3dController.getEngine().addObject(legAssembly, cadScript));
});
}
public static void setCsg(MobileBaseCadManager thread, File cadScript) {
setCsg(thread.getAllCad(), cadScript);
}
public boolean isDoneLoadingTutorials() {
return doneLoadingTutorials;
}
public void setDoneLoadingTutorials(boolean doneLoadingTutorials) {
this.doneLoadingTutorials = doneLoadingTutorials;
}
public ConnectionManager getConnectionManager() {
return connectionManager;
}
public void setConnectionManager(ConnectionManager connectionManager) {
this.connectionManager = connectionManager;
}
public static IMobileBaseUI getMobileBaseUI() {
return mbui;
}
}

View File

@@ -0,0 +1,235 @@
package com.neuronrobotics.bowlerstudio;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.AnchorPane;
public class BowlerStudioFXMLController {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="BowlerStudioMenue"
private MenuBar BowlerStudioMenue; // Value injected by FXMLLoader
@FXML // fx:id="CadControlsAnchor"
private AnchorPane CadControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="CadTextSplit"
private SplitPane CadTextSplit; // Value injected by FXMLLoader
@FXML // fx:id="CommandLine"
private AnchorPane CommandLine; // Value injected by FXMLLoader
@FXML // fx:id="CreaturesMenu"
private Menu CreaturesMenu; // Value injected by FXMLLoader
@FXML // fx:id="DriveControlsAnchor"
private AnchorPane DriveControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="GitHubRoot"
private Menu GitHubRoot; // Value injected by FXMLLoader
@FXML // fx:id="TempControlsAnchor"
private AnchorPane TempControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="clearCache"
private MenuItem clearCache; // Value injected by FXMLLoader
@FXML // fx:id="commandLineTitledPane"
private TitledPane commandLineTitledPane; // Value injected by FXMLLoader
@FXML // fx:id="createNewGist"
private MenuItem createNewGist; // Value injected by FXMLLoader
@FXML // fx:id="editorContainer"
private AnchorPane editorContainer; // Value injected by FXMLLoader
@FXML // fx:id="jfx3dControls"
private AnchorPane jfx3dControls; // Value injected by FXMLLoader
@FXML // fx:id="logView"
private AnchorPane logView; // Value injected by FXMLLoader
@FXML // fx:id="logViewRef"
private TextArea logViewRef; // Value injected by FXMLLoader
@FXML // fx:id="logoutGithub"
private MenuItem logoutGithub; // Value injected by FXMLLoader
@FXML // fx:id="myGists"
private Menu myGists; // Value injected by FXMLLoader
@FXML // fx:id="myOrganizations"
private Menu myOrganizations; // Value injected by FXMLLoader
@FXML // fx:id="myRepos"
private Menu myRepos; // Value injected by FXMLLoader
@FXML // fx:id="overlayScrollPanel"
private ScrollPane overlayScrollPanel; // Value injected by FXMLLoader
@FXML // fx:id="viewContainer"
private AnchorPane viewContainer; // Value injected by FXMLLoader
@FXML // fx:id="watchingRepos"
private Menu watchingRepos; // Value injected by FXMLLoader
// Handler for MenuItem[fx:id="clearCache"] onAction
@FXML
void clearScriptCache(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@3d05e65e] onAction
@FXML
void onClose(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@6127215f] onAction
@FXML
void onConnect(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@1d163e1a] onAction
@FXML
void onConnectCHDKCamera(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@3cad92b8] onAction
@FXML
void onConnectCVCamera(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@542487b1] onAction
@FXML
void onConnectFileSourceCamera(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@4845d9d8] onAction
@FXML
void onConnectGamePad(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@36100c4d] onAction
@FXML
void onConnectHokuyoURG(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@7a7cbb68] onAction
@FXML
void onConnectPidSim(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@7d3d14a7] onAction
@FXML
void onConnectURLSourceCamera(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@68e8dfb1] onAction
@FXML
void onConnectVirtual(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[fx:id="createNewGist"] onAction
@FXML
void onCreatenewGist(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@6bfd67ba] onAction
@FXML
void onLoadFile(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@41a2e40f] onAction
@FXML
void onLogin(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[fx:id="logoutGithub"] onAction
@FXML
void onLogout(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@7e3e1a61] onAction
@FXML
void onMobileBaseFromFile(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@57184345] onAction
@FXML
void onMobileBaseFromGit(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@d523af5] onAction
@FXML
void onOpenGitter(ActionEvent event) {
// handle the event here
}
// Handler for MenuItem[javafx.scene.control.MenuItem@2a1c81e] onAction
@FXML
void onPrint(ActionEvent event) {
// handle the event here
}
@FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
assert BowlerStudioMenue != null : "fx:id=\"BowlerStudioMenue\" was not injected: check your FXML file 'Main.fxml'.";
assert CadControlsAnchor != null : "fx:id=\"CadControlsAnchor\" was not injected: check your FXML file 'Main.fxml'.";
assert CadTextSplit != null : "fx:id=\"CadTextSplit\" was not injected: check your FXML file 'Main.fxml'.";
assert CommandLine != null : "fx:id=\"CommandLine\" was not injected: check your FXML file 'Main.fxml'.";
assert CreaturesMenu != null : "fx:id=\"CreaturesMenu\" was not injected: check your FXML file 'Main.fxml'.";
assert DriveControlsAnchor != null : "fx:id=\"DriveControlsAnchor\" was not injected: check your FXML file 'Main.fxml'.";
assert GitHubRoot != null : "fx:id=\"GitHubRoot\" was not injected: check your FXML file 'Main.fxml'.";
assert TempControlsAnchor != null : "fx:id=\"TempControlsAnchor\" was not injected: check your FXML file 'Main.fxml'.";
assert clearCache != null : "fx:id=\"clearCache\" was not injected: check your FXML file 'Main.fxml'.";
assert commandLineTitledPane != null : "fx:id=\"commandLineTitledPane\" was not injected: check your FXML file 'Main.fxml'.";
assert createNewGist != null : "fx:id=\"createNewGist\" was not injected: check your FXML file 'Main.fxml'.";
assert editorContainer != null : "fx:id=\"editorContainer\" was not injected: check your FXML file 'Main.fxml'.";
assert jfx3dControls != null : "fx:id=\"jfx3dControls\" was not injected: check your FXML file 'Main.fxml'.";
assert logView != null : "fx:id=\"logView\" was not injected: check your FXML file 'Main.fxml'.";
assert logViewRef != null : "fx:id=\"logViewRef\" was not injected: check your FXML file 'Main.fxml'.";
assert logoutGithub != null : "fx:id=\"logoutGithub\" was not injected: check your FXML file 'Main.fxml'.";
assert myGists != null : "fx:id=\"myGists\" was not injected: check your FXML file 'Main.fxml'.";
assert myOrganizations != null : "fx:id=\"myOrganizations\" was not injected: check your FXML file 'Main.fxml'.";
assert myRepos != null : "fx:id=\"myRepos\" was not injected: check your FXML file 'Main.fxml'.";
assert overlayScrollPanel != null : "fx:id=\"overlayScrollPanel\" was not injected: check your FXML file 'Main.fxml'.";
assert viewContainer != null : "fx:id=\"viewContainer\" was not injected: check your FXML file 'Main.fxml'.";
assert watchingRepos != null : "fx:id=\"watchingRepos\" was not injected: check your FXML file 'Main.fxml'.";
// Initialize your logic here: all @FXML variables will have been injected
}
}

View File

@@ -0,0 +1,181 @@
package com.neuronrobotics.bowlerstudio;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import javafx.application.Platform;
import javafx.scene.control.Menu;
@SuppressWarnings("restriction")
public class BowlerStudioMenuWorkspace {
private static Menu workspaceMenu;
private static HashMap<String, Object> workspaceData = null;
private static final int maxMenueSize = 15;
private static boolean sorting = false;
private static HashMap<String,Integer> rank = new HashMap<String, Integer>();
private static boolean running = false;
public static void init(Menu workspacemenu) {
if (workspacemenu == null)
throw new RuntimeException();
workspaceMenu = workspacemenu;
}
public static void loginEvent() {
if(running)
return;
running = true;
rank.clear();
workspaceData = ConfigurationDatabase.getParamMap("workspace");
new Thread(()-> {
for (int i=0;i<workspaceData.keySet().size();i++) {
try {
String o = (String) workspaceData.keySet().toArray()[i];
try {
ScriptingEngine.pull(o);
} catch (Exception e) {
workspaceData.remove(o);
i--;
}
} catch (Exception e) {
}
}
running = false;
}).start();
sort();
}
public static void add(String url) {
add(url, BowlerStudioMenu.gitURLtoMessage(url));
}
@SuppressWarnings("unchecked")
public static void add(String url, String menueMessage) {
if (menueMessage == null || menueMessage.length() < 2)
throw new RuntimeException();
ArrayList<String> data;
synchronized (workspaceData) {
if (workspaceData.get(url) == null) {
data = new ArrayList<String>();
data.add(menueMessage);
data.add(new Long(System.currentTimeMillis()).toString());
workspaceData.put(url, data);
System.out.println("Workspace add: "+url);
}
}
//data = (ArrayList<String>) workspaceData.get(url);
//data.set(1, new Long(System.currentTimeMillis()).toString());
sort();
//
}
@SuppressWarnings("unchecked")
private static void sort() {
if (sorting)
return;
sorting = true;
boolean rankChanged=false;
try {
ArrayList<String> myOptions = new ArrayList<String>();
synchronized (workspaceData) {
for (String o : workspaceData.keySet()) {
//System.out.println("Opt: "+o);
myOptions.add(o);
}
}
ArrayList<String> menu = new ArrayList<>();
while (myOptions.size() > 0) {
int bestIndex = 0;
String besturl = (String) myOptions.get(bestIndex);
long newestTime = Long.parseLong(((ArrayList<String>) workspaceData.get(besturl)).get(1));
for (int i = 0; i < myOptions.size(); i++) {
String nowurl = (String) myOptions.get(i);
long myTime = Long.parseLong(((ArrayList<String>) workspaceData.get(nowurl)).get(1));
if (myTime >= newestTime) {
newestTime = myTime;
besturl = nowurl;
bestIndex = i;
}
}
String removedURL = (String) myOptions.remove(bestIndex);
if (menu.size() < maxMenueSize) {
// clone all repos from git
try {
// ScriptingEngine.pull(removedURL);
menu.add(removedURL);
} catch (Exception e) {
// repo is broken or missing
e.printStackTrace();
System.out.println("Removing from workspace: " + removedURL);
synchronized (workspaceData) {
workspaceData.remove(removedURL);
}
}
} else {
System.out.println("Removing from workspace: " + removedURL);
synchronized (workspaceData) {
workspaceData.remove(removedURL);
}
}
}
for(int i=0;i<menu.size();i++) {
String url = menu.get(i);
if(rank.get(url)==null) {
rankChanged=true;
rank.put(url,i);
//System.out.println("Rank firstNoted : "+url+" "+i);
}
if(rank.get(url).intValue()!=i) {
rankChanged=true;
}
rank.put(url,i);
}
if(rankChanged) {
Platform.runLater(() -> {
if (workspaceMenu.getItems() != null)
workspaceMenu.getItems().clear();
new Thread(() -> {
for (String url : menu) {
System.out.println("Workspace : "+url);
ArrayList<String> arrayList = (ArrayList<String>) workspaceData.get(url);
if(arrayList!=null)
BowlerStudioMenu.setUpRepoMenue(workspaceMenu,
url,
false,
false,
arrayList.get(0));
}
sorting = false;
}).start();
});
}else {
sorting = false;
}
} catch (Exception ex) {
ex.printStackTrace();
}
if(rankChanged) {
System.out.println("Sorting workspace...");
new Thread(()->{
ConfigurationDatabase.save();
}).start();
}
}
}

View File

@@ -0,0 +1,407 @@
package com.neuronrobotics.bowlerstudio;
/**
* Sample Skeleton for "BowlerStudioModularFrame.fxml" Controller Class
* You can copy and paste this code into your favorite IDE
**/
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
import com.neuronrobotics.bowlerstudio.tabs.WebTab;
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Tab;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.dockfx.DockNode;
import org.dockfx.DockPane;
import org.dockfx.DockPos;
import java.io.File;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.URL;
import java.util.HashMap;
import java.util.ResourceBundle;
@SuppressWarnings("restriction")
public class BowlerStudioModularFrame {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="editorContainer"
private AnchorPane editorContainer; // Value injected by FXMLLoader
@FXML // fx:id="menurAnchor"
private AnchorPane menurAnchor; // Value injected by FXMLLoader
private Image dockImage;
private DockNode tutorialDockNode;
private DockNode connectionManagerDockNode;
private DockPane dockPane;
public BowlerStudioMenu menueController;
// private InvalidationListener connectionManagerRemover;
private CreatureLab3dController creatureLab3dController;
private DockNode creatureLab3dDockNode;
// private InvalidationListener creatureManagerRemover;
private BowlerStudioController controller;
private static Stage primaryStage;
private static BowlerStudioModularFrame bowlerStudioModularFrame;
private HashMap<Tab, DockNode> webTabs = new HashMap<>();
private HashMap<String, Boolean> isOpen = new HashMap<>();
private Terminal terminal;
private DockNode terminalDockNode;
private boolean startup = false;
private WebTab webtab;
@FXML // This method is called by the FXMLLoader when initialization is
// complete
void initialize() throws Exception {
bowlerStudioModularFrame=this;
assert editorContainer != null : "fx:id=\"editorContainer\" was not injected: check your FXML file 'BowlerStudioModularFrame.fxml'.";
assert menurAnchor != null : "fx:id=\"menurAnchor\" was not injected: check your FXML file 'BowlerStudioModularFrame.fxml'.";
dockPane = new DockPane();
dockImage = AssetFactory.loadAsset("BowlerStudioModularFrameIcon.png");
// final Tab newtab = new Tab();
// newtab.setText("");
// newtab.setClosable(false);
// newtab.setGraphic(AssetFactory.loadIcon("New-Web-Tab.png"));
String homeURL = Tutorial.getHomeUrl();
controller = new BowlerStudioController();
WebTab.setBSController(controller);
webtab = null;
try {
Platform.runLater(()->{
try {
webtab = new WebTab("Tutorial", homeURL, true);
setTutorialDockNode(new DockNode(webtab.getContent(), webtab.getText(), webtab.getGraphic()));
getTutorialDockNode().setPrefSize(1024, 730);
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});;
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
connectionManagerDockNode = new DockNode(ConnectionManager.getConnectionManager().getContent(),
ConnectionManager.getConnectionManager().getText(),
ConnectionManager.getConnectionManager().getGraphic());
connectionManagerDockNode.setPrefSize(200, 700);
// Initial docked setup
addTutorial();
// Add the dock pane to the window
editorContainer.getChildren().add(dockPane);
AnchorPane.setTopAnchor(dockPane, 0.0);
AnchorPane.setRightAnchor(dockPane, 0.0);
AnchorPane.setLeftAnchor(dockPane, 0.0);
AnchorPane.setBottomAnchor(dockPane, 0.0);
FXMLLoader WindowLoader3d;
WindowLoader3d = AssetFactory.loadLayout("layout/CreatureLab.fxml");
creatureLab3dController = new CreatureLab3dController();
BowlerStudio.setCreatureLab3d(creatureLab3dController);
WindowLoader3d.setController(creatureLab3dController);
WindowLoader3d.setClassLoader(CreatureLab3dController.class.getClassLoader());
FXMLLoader commandLine;
commandLine = AssetFactory.loadLayout("layout/Terminal.fxml");
terminal = new Terminal();
commandLine.setController(terminal);
commandLine.setClassLoader(Terminal.class.getClassLoader());
FXMLLoader menueBar;
menueBar = AssetFactory.loadLayout("layout/BowlerStudioMenuBar.fxml");
menueController = new BowlerStudioMenu(this);
menueBar.setController(menueController);
menueBar.setClassLoader(BowlerStudioMenu.class.getClassLoader());
try {
menueBar.load();
WindowLoader3d.load();
commandLine.load();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BorderPane menue = (BorderPane) menueBar.getRoot();
BorderPane threed = (BorderPane) WindowLoader3d.getRoot();
VBox cmd = (VBox) commandLine.getRoot();
creatureLab3dDockNode = new DockNode(threed, "Creature Lab", AssetFactory.loadIcon("CreatureLab-Tab.png"));
creatureLab3dDockNode.setPrefSize(400, 400);
terminalDockNode = new DockNode(cmd, "Terminal", AssetFactory.loadIcon("Command-Line.png"));
terminalDockNode.setPrefSize(400, 400);
// Add the dock pane to the window
menurAnchor.getChildren().add(menue);
AnchorPane.setTopAnchor(menue, 0.0);
AnchorPane.setRightAnchor(menue, 0.0);
AnchorPane.setLeftAnchor(menue, 0.0);
AnchorPane.setBottomAnchor(menue, 0.0);
isOpen.put("showCreatureLab", false);
isOpen.put("showTerminal", false);
isOpen.put("showDevices", false);
// focus on the tutorial to start
Platform.runLater(() -> getTutorialDockNode().requestFocus());
connectionManagerDockNode.onMouseClickedProperty().addListener((a, b, c) -> {
System.err.println("Cloick");
});
}
public void loadMobilebaseFromGit(String id, String file) {
menueController.loadMobilebaseFromGit(id, file);
}
private void addTutorial() {
Platform.runLater(() -> getTutorialDockNode().dock(dockPane, DockPos.LEFT));
}
public void showConectionManager() {
String key = "showDevices";
if (isOpen.get(key) == null) {
isOpen.put(key, false);
}
if (isOpen.get("showTerminal") == null) {
isOpen.put("showTerminal", false);
}
Platform.runLater(() -> {
if (!isOpen.get(key)) {
isOpen.put(key, true);
if (isOpen.get("showTerminal"))
connectionManagerDockNode.dock(dockPane, DockPos.RIGHT, terminalDockNode);
else
connectionManagerDockNode.dock(dockPane, DockPos.BOTTOM, getTutorialDockNode());
connectionManagerDockNode.requestFocus();
connectionManagerDockNode.closedProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable event) {
connectionManagerDockNode.closedProperty().removeListener(this);
isOpen.put(key, false);
}
});
}
Platform.runLater(() -> connectionManagerDockNode.requestFocus());
});
}
public void showTerminal() {
String key = "showTerminal";
if (isOpen.get(key) == null || getTutorialDockNode()==null ||terminalDockNode==null) {
isOpen.put(key, false);
return;
}
if (isOpen.get("showDevices") == null) {
isOpen.put("showDevices", false);
}
if (!isOpen.get(key)) {
isOpen.put(key, true);
Platform.runLater(() -> {
if (isOpen.get("showDevices"))
terminalDockNode.dock(dockPane, DockPos.LEFT, connectionManagerDockNode);
else
terminalDockNode.dock(dockPane, DockPos.BOTTOM, getTutorialDockNode());
terminalDockNode.requestFocus();
if (ScriptingEngine.isLoginSuccess()) {
}
terminalDockNode.closedProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable event) {
terminalDockNode.closedProperty().removeListener(this);
isOpen.put(key, false);
}
});
Platform.runLater(() -> terminalDockNode.requestFocus());
});
}
}
public void showCreatureLab() {
showCreatureLab(0);
}
public void showCreatureLab(int depth) {
String key = "showCreatureLab";
if (!isOpen.get(key)) {
isOpen.put(key, true);
new Thread(() -> {
ThreadUtil.wait(100);
Platform.runLater(() -> {
try {
creatureLab3dDockNode.dock(dockPane, DockPos.RIGHT);
isOpen.put(key, true);
return;
} catch (NullPointerException e) {
// keep trying to open
// e.printStackTrace();
isOpen.put(key, false);
if (depth < 2) {
showCreatureLab(depth + 1);
} else
BowlerStudio.printStackTrace(e);// fail and show
// user
} catch (Exception e) {
isOpen.put(key, false);
BowlerStudio.printStackTrace(e);// fail and show user
}
});
Platform.runLater(() -> creatureLab3dDockNode.closedProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable event) {
creatureLab3dDockNode.closedProperty().removeListener(this);
isOpen.put(key, false);
}
}));
}).start();
}
// else
// Platform.runLater(() -> creatureLab3dDockNode.requestFocus());
}
public DockNode getTutorialDockNode() {
return tutorialDockNode;
}
public void setTutorialDockNode(DockNode tutorialDockNode) {
this.tutorialDockNode = tutorialDockNode;
tutorialDockNode.closableProperty().set(false);
}
public static Stage getPrimaryStage() {
return primaryStage;
}
public static void setPrimaryStage(Stage primaryStage) {
BowlerStudioModularFrame.primaryStage = primaryStage;
}
public ScriptingFileWidget createFileTab(File file) {
// TODO Auto-generated method stub
return controller.createFileTab(file);
}
public void openUrlInNewTab(URL url) {
Platform.runLater(() -> {
try {
if (PasswordManager.getUsername() != null) {
WebTab newTab = new WebTab("Web", url.toExternalForm(), false);
addTab(newTab, true);
}
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
public void closeTab(Tab newTab) {
if (webTabs.get(newTab) != null) {
System.err.println("Closing tab: " + newTab.getText());
DockNode dn=webTabs.get(newTab);
webTabs.remove(newTab);
if(dn!=null)
Platform.runLater(() -> {
try {
dn.undock();
}catch(java.lang.NullPointerException ex) {}
Platform.runLater(() -> dn.close());
if(newTab!=null)
if (newTab.getOnCloseRequest() != null) {
newTab.getOnCloseRequest().handle(null);
}
});
}
}
public void addTab(Tab newTab, boolean b) {
System.err.println("Loading a new tab: " + newTab.getText());
if (webTabs.get(newTab) != null) {
Platform.runLater(() -> webTabs.get(newTab).requestFocus());
} else {
Platform.runLater(() -> {
DockNode dn = new DockNode(newTab.getContent(), newTab.getText(), newTab.getGraphic());
dn.closedProperty().addListener(event -> {
closeTab(newTab);
});
webTabs.put(newTab, dn);
dn.dock(dockPane, DockPos.CENTER, getTutorialDockNode());
});
}
}
public static BowlerStudioModularFrame getBowlerStudioModularFrame() {
return bowlerStudioModularFrame;
}
public void setSelectedTab(Tab tab) {
if (webTabs.get(tab) != null)
Platform.runLater(() -> webTabs.get(tab).requestFocus());
}
}

View File

@@ -0,0 +1,75 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Modality;
import javafx.stage.Stage;
/**
* Created by Ryan Benasutti on 2/6/2016.
*/
public class ChangeAssetRepoController extends Application {
@FXML
private TextField repoField;
@FXML
private Button changeRepoButton, cancelButton;
public ChangeAssetRepoController() {}
@SuppressWarnings("restriction")
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = AssetFactory.loadLayout("layout/changeAssetRepo.fxml", true);
Parent root;
loader.setController(this);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
Platform.runLater(() -> {
primaryStage.setTitle("Change Asset Repository");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.initModality(Modality.WINDOW_MODAL);
primaryStage.setResizable(true);
primaryStage.show();
});
}
@FXML
public void onChangeRepo(ActionEvent event)
{
String repo = repoField.getText()
.replaceAll("git://", "https://");
new Thread(()->{
ConfigurationDatabase.setObject("BowlerStudioConfigs", "skinRepo",
repo);
ConfigurationDatabase.save();
}).start();
Stage stage = (Stage) changeRepoButton.getScene().getWindow();
stage.close();
}
@FXML
public void onCancel(ActionEvent event) {
Platform.runLater(() -> {
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.close();
});
}
}

View File

@@ -0,0 +1,561 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.addons.driving.HokuyoURGDevice;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.threed.VirtualCameraDevice;
import com.neuronrobotics.bowlerstudio.utils.BowlerConnectionMenu;
import com.neuronrobotics.imageprovider.AbstractImageProvider;
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
import com.neuronrobotics.imageprovider.StaticFileProvider;
import com.neuronrobotics.imageprovider.URLImageProvider;
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
import com.neuronrobotics.sdk.addons.kinematics.FirmataBowler;
import com.neuronrobotics.sdk.addons.kinematics.gcodebridge.GcodeDevice;
import com.neuronrobotics.sdk.common.*;
import com.neuronrobotics.sdk.javaxusb.UsbCDCSerialConnection;
import com.neuronrobotics.sdk.network.BowlerTCPClient;
import com.neuronrobotics.sdk.network.UDPBowlerConnection;
import com.neuronrobotics.sdk.serial.SerialConnection;
import com.neuronrobotics.sdk.ui.AbstractConnectionPanel;
import com.neuronrobotics.sdk.util.ThreadUtil;
import com.neuronrobotics.sdk.wireless.bluetooth.BluetoothSerialConnection;
import gnu.io.NRSerialPort;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;
import net.java.games.input.Event;
import org.reactfx.util.FxTimer;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
//import org.bytedeco.javacv.OpenCVFrameGrabber;
public class ConnectionManager extends Tab implements IDeviceAddedListener ,EventHandler<ActionEvent> {
private static VBox rootItem;
private static final ArrayList<PluginManagerWidget> plugins = new ArrayList<PluginManagerWidget>();
//private BowlerStudioController bowlerStudioController;
String formatStr="%1$-40s %2$-60s %3$-40s";
private static final ConnectionManager connectionManager;
private static Button disconnectAll;
private static HBox topLine;
final static Accordion accordion = new Accordion ();
static{
connectionManager = new ConnectionManager();
}
private Node getIcon(String s) {
return new ImageView(new Image(
AbstractConnectionPanel.class.getResourceAsStream(s)));
}
public ConnectionManager() {
if(connectionManager!=null){
throw new RuntimeException("Connection manager is a static singleton, access it using ConnectionManager.getConnectionmanager()");
}
setText("My Devices");
setGraphic(AssetFactory.loadIcon("My-Devices.png"));
rootItem = new VBox(10);
// rootItem.getColumnConstraints().add(new ColumnConstraints(30)); // column 1 is 75 wide
// rootItem. getColumnConstraints().add(new ColumnConstraints(80)); // column 2 is 300 wide
// rootItem.getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
// rootItem.getColumnConstraints().add(new ColumnConstraints(50)); // column 2 is 100 wide
//
topLine = new HBox(20);
disconnectAll = new Button("Disconnect All",AssetFactory.loadIcon("Disconnect-All.png"));
disconnectAll.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
disconnectAll();
}
});
disconnectAll.setDisable(true);
topLine.getChildren().addAll(AssetFactory.loadIcon("Connected-Devices.png"),new Text("Connected Devices"),disconnectAll);
rootItem.getChildren().add(topLine);
rootItem.getChildren().add(accordion);
// rootItem = new CheckBoxTreeItem<String>( String.format(" "+formatStr, "SCRIPTING NAME","DEVICE TYPE","MAC ADDRESS"),
// getIcon("images/connection-icon.png"
// // "images/usb-icon.png"
// ));
// rootItem.setExpanded(true);
// rootItem.setSelected(true);
// rootItem.selectedProperty().addListener(b -> {
// if (!rootItem.isSelected()) {
// disconnectAll();
// }
// });
setContent(rootItem);
DeviceManager.addDeviceAddedListener(this);
}
public static void addConnection(BowlerAbstractDevice newDevice, String name) {
if(!VirtualCameraDevice.class.isInstance(newDevice))
DeviceManager.addConnection(newDevice, name);
}
@Override
public void handle(ActionEvent event) {
// TODO Auto-generated method stub
}
public static ArrayList<PluginManagerWidget> getPlugins() {
return plugins;
}
//
// public BowlerStudioController getBowlerStudioController() {
// return bowlerStudioController;
// }
//
// public void setBowlerStudioController(
// BowlerStudioController bowlerStudioController) {
// this.bowlerStudioController = bowlerStudioController;
// }
public static BowlerAbstractDevice pickConnectedDevice(@SuppressWarnings("rawtypes") Class class1) {
List<String> choices = DeviceManager.listConnectedDevice(class1);
if(!choices.isEmpty()){
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0),
choices);
dialog.setTitle("Bowler Device Chooser");
dialog.setHeaderText("Choose connected bowler device");
dialog.setContentText("Device Name:");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
if (result.isPresent()) {
for (int i = 0; i < plugins.size(); i++) {
if (plugins.get(i).getManager().getName().contains(result.get())) {
return plugins.get(i).getManager().getDevice();
}
}
}
}else{
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Device not availible");
alert.setHeaderText("Connect a "+class1.getSimpleName());
alert.setContentText("A device of type "+class1.getSimpleName()+" is needed");
alert .initModality(Modality.APPLICATION_MODAL);
alert.show();
}
return null;
}
// public BowlerAbstractDevice pickConnectedDevice() {
//
// return pickConnectedDevice(null);
// }
public static void disconnectAll() {
//extract list int thread safe object
Object [] pms= plugins.toArray();
for (int i=0;i<pms.length;i++) {
disconectAndRemoveDevice(((PluginManagerWidget)pms[i]).getManager());
//ThreadUtil.wait(50);
}
}
// public static OpenCVImageProvider onConnectCVCamera() {
// List<String> choices = new ArrayList<>();
// choices.add("0");
// choices.add("1");
// choices.add("2");
// choices.add("3");
// choices.add("4");
//
// ChoiceDialog<String> dialog = new ChoiceDialog<>("0", choices);
// dialog.setTitle("OpenCV Camera Index Chooser");
// dialog.setHeaderText("Choose an OpenCV camera");
// dialog.setContentText("Camera Index:");
//
// // Traditional way to get the response value.
// Optional<String> result = dialog.showAndWait();
//
// // The Java 8 way to get the response value (with lambda expression).
// if (result !=null) {
// String letter = result.get();
// OpenCVImageProvider p = new OpenCVImageProvider(Integer.parseInt(letter));
// String name = "camera"+letter;
// addConnection(p,name);
// return p;
// }
// return null;
//// OpenCVImageProvider p = new OpenCVImageProvider(0);
//// String name = "camera0";
//// application.addConnection(p,name);
//
// }
//
public static void onConnectJavaCVCamera() {
// onConnectCVCamera();
// List<String> choices = new ArrayList<>();
// try {
// String[] des = OpenCVFrameGrabber.getDeviceDescriptions();
// if(des.length==0)
// return;
// for (String s: des){
// choices.add(s);
// }
// } catch (org.bytedeco.javacv.FrameGrabber.Exception |UnsupportedOperationException e1) {
// choices.add("0");
// choices.add("1");
// choices.add("2");
// choices.add("3");
// choices.add("4");
// }
//
// ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
// dialog.setTitle("JavaCV Camera Index Chooser");
// dialog.setHeaderText("Choose an JavaCV camera");
// dialog.setContentText("Camera Index:");
//
// // Traditional way to get the response value.
// Optional<String> result = dialog.showAndWait();
//
// // The Java 8 way to get the response value (with lambda expression).
// result.ifPresent(letter -> {
// JavaCVImageProvider p;
// try {
// p = new JavaCVImageProvider(Integer.parseInt(letter));
// String name = "camera"+letter;
// addConnection(p,name);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// });
//
}
public static void onConnectFileSourceCamera() {
Platform.runLater(()->{});
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Image File");
File f = fileChooser.showOpenDialog(BowlerStudioModularFrame.getPrimaryStage());
if(f!=null){
AbstractImageProvider p = new StaticFileProvider(f);
String name = "image";
addConnection(p,name);
}
}
public static void onConnectURLSourceCamera() {
TextInputDialog dialog = new TextInputDialog("http://neuronrobotics.com/img/AndrewHarrington/2014-09-15-86.jpg");
dialog.setTitle("URL Image Source");
dialog.setHeaderText("This url will be loaded each capture.");
dialog.setContentText("URL ");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
if (result.isPresent()){
URLImageProvider p;
try {
p = new URLImageProvider(new URL(result.get()));
String name = "url";
addConnection(p,name);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void onMarlinGCODE() {
Set<String> ports = NRSerialPort.getAvailableSerialPorts();
List<String> choices = new ArrayList<>();
if(ports.isEmpty())
return;
for (String s: ports){
choices.add(s);
}
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
dialog.setTitle("GCODE Device Serial Port Chooser");
dialog.setHeaderText("Supports Marlin");
dialog.setContentText("GCODE Device Port:");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
// The Java 8 way to get the response value (with lambda expression).
result.ifPresent(letter -> {
GcodeDevice p = new GcodeDevice(new NRSerialPort(letter, 115200));
p.connect();
String name = "GCODE";
addConnection(p,name);
});
}
public static void onConnectHokuyoURG() {
Set<String> ports = NRSerialPort.getAvailableSerialPorts();
List<String> choices = new ArrayList<>();
if(ports.isEmpty())
return;
for (String s: ports){
choices.add(s);
}
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
dialog.setTitle("LIDAR Serial Port Chooser");
dialog.setHeaderText("Supports URG-04LX-UG01");
dialog.setContentText("Lidar Port:");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
// The Java 8 way to get the response value (with lambda expression).
result.ifPresent(letter -> {
HokuyoURGDevice p = new HokuyoURGDevice(new NRSerialPort(letter, 115200));
p.connect();
String name = "lidar";
addConnection(p,name);
});
}
public static void onConnectGamePad(String name ) {
Controller[] ca = ControllerEnvironment.getDefaultEnvironment().getControllers();
List<String> choices = new ArrayList<>();
if(ca.length==0)
return;
for (Controller s: ca){
choices.add(s.getName());
}
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
dialog.setTitle("JInput Game Controller Select");
dialog.setHeaderText("Connect a game controller");
dialog.setContentText("Controller:");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
// The Java 8 way to get the response value (with lambda expression).
result.ifPresent(letter -> {
for(Controller s: ca){
if(letter.contains(s.getName())){
BowlerJInputDevice p =new BowlerJInputDevice(s);
p.connect();
IJInputEventListener l=new IJInputEventListener() {
@Override
public void onEvent(Component comp, Event event1,
float value, String eventString) {
//System.out.println(comp.getName()+" is value= "+value);
}
};
p.addListeners(l);
addConnection(p,name);
return;
}
}
});
}
@Override
public void onNewDeviceAdded(BowlerAbstractDevice newDevice) {
if(VirtualCameraDevice.class.isInstance(newDevice))
return;
PluginManager mp;
Log.debug("Adding a "+newDevice.getClass().getName()+" with name "+newDevice.getScriptingName() );
mp = new PluginManager(newDevice);
BowlerAbstractConnection con = newDevice.getConnection();
Node icon = getIcon("images/connection-icon.png"
// "images/usb-icon.png"
);
if (SerialConnection.class.isInstance(con)) {
icon = getIcon(
// "images/ethernet-icon.png"
"images/usb-icon.png");
} else if (UsbCDCSerialConnection.class.isInstance(con)) {
icon = getIcon(
// "images/ethernet-icon.png"
"images/usb-icon.png");
} else if (BluetoothSerialConnection.class.isInstance(con)) {
icon = getIcon(
// "images/ethernet-icon.png"
"images/bluetooth-icon.png");
} else if (UDPBowlerConnection.class.isInstance(con)
|| BowlerTCPClient.class.isInstance(con)) {
icon = getIcon(
// "images/ethernet-icon.png"
"images/ethernet-icon.png");
}
String line = String.format(formatStr,
newDevice.getScriptingName(),
newDevice.getClass().getSimpleName(),
newDevice.getAddress());
PluginManagerWidget e = new PluginManagerWidget(mp,icon);
plugins.add(e);
Platform.runLater(() -> accordion.getPanes().add(e));
Platform.runLater(() -> disconnectAll.setDisable(false));
mp.setName(newDevice.getScriptingName());
newDevice.addConnectionEventListener(
new IDeviceConnectionEventListener() {
@Override
public void onDisconnect(BowlerAbstractDevice source) {
// clean up after yourself...
//disconectAndRemoveDevice(mp);
for(int i=0;i<plugins.size();i++){
PluginManager p=plugins.get(i).getManager();
if(p.getDevice()==source){
DeviceManager.remove(p.getDevice());
return;
}
}
}
// ignore
@Override
public void onConnect(BowlerAbstractDevice source) {
}
});
if( getBowlerStudioController()!=null)
BowlerStudioModularFrame.getBowlerStudioModularFrame().setSelectedTab(this);
}
private BowlerStudioController getBowlerStudioController() {
// TODO Auto-generated method stub
return BowlerStudioController.getBowlerStudio();
}
private static void disconectAndRemoveDevice(PluginManager mp){
System.out.println("CM Disconnecting " + mp.getName());
Log.warning("Disconnecting " + mp.getName());
if(mp.getDevice().isAvailable() || NonBowlerDevice.class.isInstance(mp))
mp.getDevice().disconnect();
DeviceManager.remove(mp.getDevice());
}
@Override
public void onDeviceRemoved(BowlerAbstractDevice bad) {
Log.warning("Removing Device " + bad.getScriptingName());
//new RuntimeException().printStackTrace();
for(int i=0;i<plugins.size();i++){
PluginManager p=plugins.get(i).getManager();
if(p.getDevice()==bad){
Log.warning("Found Device " + bad.getScriptingName());
//new RuntimeException().printStackTrace();
PluginManagerWidget torem = plugins.remove(i);
Platform.runLater(() ->accordion.getPanes().remove(torem));
if (plugins.isEmpty()){
Platform.runLater(() ->disconnectAll.setDisable(true));
}
return;
}
}
}
public static void addConnection() {
Stage s = new Stage();
new Thread() {
public void run() {
BowlerDatagram.setUseBowlerV4(true);
BowlerConnectionMenu controller = new BowlerConnectionMenu();
try {
controller.start(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
//DeviceManager.addConnection();
}
public static ConnectionManager getConnectionManager() {
return connectionManager;
}
public static void onFirmata() {
Set<String> ports = NRSerialPort.getAvailableSerialPorts();
List<String> choices = new ArrayList<>();
if(ports.isEmpty())
return;
for (String s: ports){
choices.add(s);
}
ChoiceDialog<String> dialog = new ChoiceDialog<>(choices.get(0), choices);
dialog.setTitle("Firmata Device Serial Port Chooser");
dialog.setHeaderText("Supports Firmata");
dialog.setContentText("Firmata Device Port:");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
// The Java 8 way to get the response value (with lambda expression).
result.ifPresent(letter -> {
new Thread(()->{
System.out.print("\nConnecting Firmata...");
FirmataBowler p = new FirmataBowler(letter);
p.connect();
String name = "firmata";
addConnection(p,name);
System.out.print("Done!\n");
}).start();
});
}
}

View File

@@ -0,0 +1,191 @@
package com.neuronrobotics.bowlerstudio;
import java.lang.Thread.UncaughtExceptionHandler;
/**
* Sample Skeleton for "CreatureLab.fxml" Controller Class
* You can copy and paste this code into your favorite IDE
**/
import java.net.URL;
import java.util.ResourceBundle;
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.SubScene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TreeView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
public class CreatureLab3dController {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="CadControlsAnchor"
private AnchorPane CadControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="DriveControlsAnchor"
private AnchorPane DriveControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="TempControlsAnchor"
private AnchorPane TempControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="jfx3dControls"
private AnchorPane jfx3dControls; // Value injected by FXMLLoader
@FXML // fx:id="overlayScrollPanel"
private ScrollPane overlayScrollPanel; // Value injected by FXMLLoader
@FXML // fx:id="viewContainer"
private AnchorPane viewContainer; // Value injected by FXMLLoader
//private SubScene subScene;
protected EventHandler<? super KeyEvent> normalKeyPessHandle = null;
private static BowlerStudio3dEngine engine;
public CreatureLab3dController (){
setEngine(new BowlerStudio3dEngine());
}
public void setOverlayLeft(Node content) {
Platform.runLater(() -> {
overlayScrollPanel.setFitToHeight(true);
overlayScrollPanel.setContent(content);
content.setOpacity(1);
overlayScrollPanel.viewportBoundsProperty()
.addListener((ObservableValue<? extends Bounds> arg0, Bounds arg1, Bounds arg2) -> {
// Node content = overlayScrollPanel.getContent();
//
// System.out.println("Resizing " + arg2);
Platform.runLater(() -> {
overlayScrollPanel.setFitToHeight(true);
/// content.seth
overlayScrollPanel.setContent(content);
});
});
overlayScrollPanel.setVisible(true);
});
}
public void clearOverlayLeft() {
Platform.runLater(() -> {
overlayScrollPanel.setContent(null);
overlayScrollPanel.setVisible(false);
});
}
public void setOverlayTop(Group content) {
Platform.runLater(() -> {
CadControlsAnchor.getChildren().clear();
CadControlsAnchor.getChildren().add(content);
AnchorPane.setTopAnchor(content, 0.0);
AnchorPane.setRightAnchor(content, 0.0);
AnchorPane.setLeftAnchor(content, 0.0);
AnchorPane.setBottomAnchor(content, 0.0);
CadControlsAnchor.setVisible(true);
});
}
public void clearOverlayTop() {
Platform.runLater(() -> {
CadControlsAnchor.getChildren().clear();
CadControlsAnchor.setVisible(false);
});
}
public void setOverlayTopRight(Group content) {
Platform.runLater(() -> {
DriveControlsAnchor.getChildren().clear();
DriveControlsAnchor.getChildren().add(content);
AnchorPane.setTopAnchor(content, 0.0);
AnchorPane.setRightAnchor(content, 0.0);
AnchorPane.setLeftAnchor(content, 0.0);
AnchorPane.setBottomAnchor(content, 0.0);
DriveControlsAnchor.setVisible(true);
});
}
public void clearOverlayTopRight() {
Platform.runLater(() -> {
DriveControlsAnchor.getChildren().clear();
DriveControlsAnchor.setVisible(false);
});
}
public void setOverlayBottomRight(Group content) {
Platform.runLater(() -> {
TempControlsAnchor.getChildren().clear();
TempControlsAnchor.getChildren().add(content);
AnchorPane.setTopAnchor(content, 0.0);
AnchorPane.setRightAnchor(content, 0.0);
AnchorPane.setLeftAnchor(content, 0.0);
AnchorPane.setBottomAnchor(content, 0.0);
TempControlsAnchor.setVisible(true);
});
}
public void clearOverlayBottomRight() {
Platform.runLater(() -> {
TempControlsAnchor.getChildren().clear();
TempControlsAnchor.setVisible(false);
});
}
@FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
assert CadControlsAnchor != null : "fx:id=\"CadControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert DriveControlsAnchor != null : "fx:id=\"DriveControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert TempControlsAnchor != null : "fx:id=\"TempControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert jfx3dControls != null : "fx:id=\"jfx3dControls\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert overlayScrollPanel != null : "fx:id=\"overlayScrollPanel\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert viewContainer != null : "fx:id=\"viewContainer\" was not injected: check your FXML file 'CreatureLab.fxml'.";
clearOverlayLeft();
// Initialize your logic here: all @FXML variables will have been injected
setupUi();
}
private void setupUi() {
Platform.runLater(() -> {
getEngine() .getSubScene().setFocusTraversable(false);
getEngine() .getSubScene().widthProperty().bind(viewContainer.widthProperty());
getEngine() .getSubScene().heightProperty().bind(viewContainer.heightProperty());
});
Platform.runLater(() -> {
jfx3dControls.getChildren().add(getEngine().getControlsBox());
viewContainer.getChildren().add(getEngine() .getSubScene());
AnchorPane.setTopAnchor(getEngine() .getSubScene(), 0.0);
AnchorPane.setRightAnchor(getEngine() .getSubScene(), 0.0);
AnchorPane.setLeftAnchor(getEngine() .getSubScene(), 0.0);
AnchorPane.setBottomAnchor(getEngine() .getSubScene(), 0.0);
});
}
public static BowlerStudio3dEngine getEngine() {
return engine;
}
public static void setEngine(BowlerStudio3dEngine engine) {
CreatureLab3dController.engine = engine;
}
}

View File

@@ -0,0 +1,67 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
public class DeviceSupportPluginMap implements PluginFactory{
private Class<?> device;
private Class<?> plugin;
private PluginFactory factory=null;
DeviceSupportPluginMap(Class<?> device,Class<?> plugin){
this.setDevice(device);
this.setPlugin(plugin);
}
public DeviceSupportPluginMap(Class<?> device,Class<?> plugin, PluginFactory factory){
this.factory = factory;
this.setDevice(device);
this.setPlugin(plugin);
}
public boolean isFactoryProvided(){
return factory!=null;
}
public Class<?> getDevice() {
return device;
}
private void setDevice(Class<?> device) {
if(BowlerAbstractDevice.class.isAssignableFrom(device) || IPidControlNamespace.class.isAssignableFrom(device) )
this.device = device;
else
throw new RuntimeException("Devices must subclass BowlerAbstractDevice or NonBowlerDevice");
}
public Class<?> getPlugin() {
return plugin;
}
private void setPlugin(Class<?> plugin) {
if(AbstractBowlerStudioTab.class.isAssignableFrom(plugin) )
this.plugin = plugin;
else
throw new RuntimeException("Plugins must subclass AbstractBowlerStudioTab");
}
@Override
public String toString(){
return "Device: "+device.getCanonicalName()+" Plugin: "+plugin.getCanonicalName();
}
@Override
public AbstractBowlerStudioTab generateNewPlugin() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if(factory!=null)
return factory.generateNewPlugin();
return (AbstractBowlerStudioTab) Class.forName(
plugin.getName()
).cast(plugin.newInstance()// This is where the new tab allocation is called
)
;
}
}

View File

@@ -0,0 +1,103 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.sdk.util.ThreadUtil;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.jfree.util.Log;
import org.kohsuke.github.GHGist;
import org.kohsuke.github.GHGistBuilder;
import org.kohsuke.github.GHGistFile;
import org.kohsuke.github.GitHub;
import java.io.IOException;
import java.net.URL;
/**
* Created by Ryan Benasutti on 2/5/2016.
*/
public class GistHelper
{
private GistHelper() {}
public static String createNewGist(String filename, String description, boolean isPublic)
{
//TODO: Perhaps this method should throw GitAPIException and IOException
//Setup gist
GitHub gitHub = PasswordManager.getGithub();
GHGistBuilder builder = gitHub.createGist();
builder.file(filename, "//Your code here");
builder.description(description);
builder.public_(isPublic);
//Make gist
return createGistFromBuilder(builder, filename);
}
public static String addFileToGist(String filename, String content, GHGist gistID)
{
GitHub gitHub = PasswordManager.getGithub();
try
{
//Copy from old gist
GHGist oldGist = gistID;
GHGistBuilder builder = gitHub.createGist();
builder.description(oldGist.getDescription());
builder.public_(oldGist.isPublic());
for (String key : oldGist.getFiles().keySet())
builder.file(key, oldGist.getFiles().get(key).getContent());
//Add new file
builder.file(filename, content);
//Make new gist with old filename
return createGistFromBuilder(builder, oldGist.getFiles().values().iterator().next().getFileName());
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private static String createGistFromBuilder(GHGistBuilder builder, String filename)
{
GHGist gist;
try
{
gist = builder.create();
//String gistID = ScriptingEngine.urlToGist(gist.getHtmlUrl());
//BowlerStudio.openUrlInNewTab(new URL(gist.getHtmlUrl()));
System.out.println("Creating repo");
while (true)
{
try
{
ScriptingEngine.fileFromGit(gist.getGitPullUrl(), filename);
break;
}
catch (GitAPIException e)
{
e.printStackTrace();
}
ThreadUtil.wait(500);
Log.warn(filename + " not built yet");
}
System.out.println("Creating gist at " + filename);
return gist.getGitPullUrl();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,96 @@
package com.neuronrobotics.bowlerstudio;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
import com.neuronrobotics.bowlerstudio.scripting.GithubLoginFX;
import com.neuronrobotics.bowlerstudio.scripting.IGitHubLoginManager;
import com.neuronrobotics.bowlerstudio.scripting.IGithubLoginListener;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class GitHubLoginManager implements IGitHubLoginManager {
private boolean loginWindowOpen = false;
private GithubLoginFX githublogin = null;
private Stage stage;
private boolean AnonSelected = false;
private String[] creds;
public GitHubLoginManager() {
}
@SuppressWarnings("restriction")
@Override
public String[] prompt(String username) {
if (AnonSelected) {
return null;
}
boolean loginWas = loginWindowOpen;
if (githublogin != null)
githublogin.reset();
if (stage == null) {
if (!loginWas && githublogin != null)
githublogin.reset();
githublogin = null;
// System.out.println("Calling login from BowlerStudio "+username);
// new RuntimeException().printStackTrace();
FXMLLoader fxmlLoader = BowlerStudioResourceFactory.getGithubLogin();
if (fxmlLoader == null)
return null;
Parent root = fxmlLoader.getRoot();
if (githublogin == null) {
githublogin = fxmlLoader.getController();
githublogin.reset();
Platform.runLater(() -> {
if (!loginWindowOpen) {
githublogin.reset();
githublogin.getUsername().setText(username);
stage = new Stage();
stage.setTitle("GitHub Login");
// stage.initModality(Modality.APPLICATION_MODAL);
githublogin.setStage(stage, root);
stage.centerOnScreen();
loginWindowOpen = true;
stage.setAlwaysOnTop(true);
stage.show();
stage = null;
}
});
}
}
// setContent(root);
do {
// System.err.println("Waiting for user login");
ThreadUtil.wait(100);
} while (!githublogin.isDone());
creds = githublogin.getCreds();
// System.err.println(" login = "+creds);
if (creds == null) {
// System.err.println("Anon mode");
AnonSelected = true;
}
loginWindowOpen = false;
return creds;
}
@Override
public String twoFactorAuthCodePrompt() {
JFrame jframe = new JFrame();
String answer = JOptionPane.showInputDialog(jframe, "Enter 2 factor auth code:");
jframe.dispose();
return answer;
}
}

View File

@@ -0,0 +1,11 @@
package com.neuronrobotics.bowlerstudio;
import javafx.scene.control.Menu;
public interface INewVitaminCallback {
void addVitaminType(String s);
Menu getTypeMenu(String type);
void addSizesToMenu(String size,String type);
}

View File

@@ -0,0 +1,26 @@
package com.neuronrobotics.bowlerstudio;
import java.util.HashMap;
public class MeasurmentConfig {
private String key;
private HashMap<String, Object> configs;
public MeasurmentConfig(String key,HashMap<String, Object> configs){
this.configs = configs;
this.setKey(key);
System.out.println("Adding Measurment "+key+" "+getMeasurment());
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getMeasurment() {
return configs.get(key).toString();
}
public void setMeasurment(String measurment) {
System.out.println("Setting field "+key+" to "+measurment);
configs.put(key, measurment);
}
}

View File

@@ -0,0 +1,5 @@
package com.neuronrobotics.bowlerstudio;
public interface MenuRefreshEvent {
void setToLoggedIn();
}

View File

@@ -0,0 +1,26 @@
package com.neuronrobotics.bowlerstudio;
import javafx.event.Event;
import javafx.event.EventHandler;
public abstract class MenuResettingEventHandler implements EventHandler<Event> {
private Runnable menuReset = null;
public Runnable getMenuReset() {
if(menuReset==null)
menuReset=new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
};
return menuReset;
}
public void setMenuReset(Runnable menuReset) {
this.menuReset = menuReset;
}
}

View File

@@ -0,0 +1,12 @@
package com.neuronrobotics.bowlerstudio;
public class NewCreatureWizard {
public static void run() {
new Thread(()->{
Thread.setDefaultUncaughtExceptionHandler(new IssueReportingExceptionHandler());
}).start();
}
}

View File

@@ -0,0 +1,577 @@
package com.neuronrobotics.bowlerstudio;
/**
* Sample Skeleton for 'newVitaminWizard.fxml' Controller Class
*/
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Optional;
import java.util.ResourceBundle;
import org.kohsuke.github.GHCreateRepositoryBuilder;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.vitamins.Vitamins;
import com.neuronrobotics.sdk.addons.kinematics.JavaFXInitializer;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Menu;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class NewVitaminWizardController extends Application {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="typePane"
private AnchorPane typePane; // Value injected by FXMLLoader
@FXML // fx:id="x1"
private Font x1; // Value injected by FXMLLoader
@FXML // fx:id="x2"
private Color x2; // Value injected by FXMLLoader
@FXML // fx:id="existingTypeRadio"
private RadioButton existingTypeRadio; // Value injected by FXMLLoader
@FXML // fx:id="newTypeRadio"
private RadioButton newTypeRadio; // Value injected by FXMLLoader
@FXML // fx:id="typeComboBox"
private ComboBox<String> typeComboBox; // Value injected by FXMLLoader
@FXML // fx:id="sizePane"
private AnchorPane sizePane; // Value injected by FXMLLoader
@FXML // fx:id="sizeComboBox"
private ComboBox<String> sizeComboBox; // Value injected by FXMLLoader
@FXML // fx:id="measurmentPane"
private AnchorPane measurmentPane; // Value injected by FXMLLoader
@FXML // fx:id="measurmentsTable"
private TableView<MeasurmentConfig> measurmentsTable; // Value injected by FXMLLoader
@FXML
private TextField newTypeNameField;
@FXML
private TextField newSizeField;
@FXML // fx:id="nameColumn"
private TableColumn<MeasurmentConfig, String> nameColumn; // Value injected by FXMLLoader
@FXML // fx:id="measurmentColumn"
private TableColumn<MeasurmentConfig, String> measurmentColumn; // Value injected by FXMLLoader
@FXML // fx:id="isMotor"
private CheckBox isMotor; // Value injected by FXMLLoader
@FXML // fx:id="isShaft"
private CheckBox isShaft; // Value injected by FXMLLoader
@FXML // fx:id="editExisting"
private CheckBox editExisting; // Value injected by FXMLLoader
@FXML // fx:id="editExisting"
private Button newMeasurmentButton;
private static INewVitaminCallback callback=null;
private static Stage primaryStage;
private static String typeOfVitaminString = null;
private static String sizeOfVitaminString = null;
@FXML
void onConfirmAndCreate(ActionEvent event) {
sizePane.setDisable(true);
measurmentPane.setDisable(true);
typePane.setDisable(true);
new Thread(() -> {
try {
if(newTypeRadio.isSelected()) {
if(isShaft.isSelected())
Vitamins.setIsShaft(typeOfVitaminString);
if(isMotor.isSelected())
Vitamins.setIsActuator(typeOfVitaminString);
GitHub github = PasswordManager.getGithub();
String newName =typeOfVitaminString+"CadGenerator";
GHCreateRepositoryBuilder builder = github.createRepository(newName );
builder.description(newName + " Generates CAD vitamins " );
GHRepository gist=null;
try {
gist = builder.create();
}catch(org.kohsuke.github.HttpException ex) {
if(ex.getMessage().contains("name already exists on this account")) {
gist = github.getRepository(PasswordManager.getLoginID()+"/"+newName);
}
}
String gitURL = gist.getHtmlUrl().toExternalForm()+".git";
String filename = typeOfVitaminString+".groovy";
Vitamins.setScript(typeOfVitaminString, gitURL, filename);
String measurments ="";
for(String key:Vitamins.getConfiguration( typeOfVitaminString,sizeOfVitaminString).keySet()) {
measurments+="\n def "+key+"Value = measurments."+key;
}
for(String key:Vitamins.getConfiguration( typeOfVitaminString,sizeOfVitaminString).keySet()) {
String string = key+"Value";
measurments+="\n println \"Measurment "+string+" = \"+"+string;
}
String loader = "import eu.mihosoft.vrl.v3d.parametrics.*;\n" +
"CSG generate(){\n" +
" String type= \""+typeOfVitaminString+"\"\n" +
" if(args==null)\n" +
" args=[\""+sizeOfVitaminString+"\"]\n" +
" // The variable that stores the current size of this vitamin\n"
+ " StringParameter size = new StringParameter( type+\" Default\"," +
"args.get(0)," +
"Vitamins.listVitaminSizes(type))\n" +
" HashMap<String,Object> measurments = Vitamins.getConfiguration( type,size.getStrValue())\n" +
measurments+"\n"+
" // Stub of a CAD object\n"+
" CSG part = new Cube().toCSG()\n"+
" return part\n" +
" .setParameter(size)\n" +
" .setRegenerate({generate()})\n" +
"}\n" +
"return generate() ";
ScriptingEngine.pushCodeToGit(gitURL, ScriptingEngine.getFullBranch(gitURL), filename,
loader, "new CAD loader script");
new Thread(() -> BowlerStudio.createFileTab(Vitamins.getScriptFile(typeOfVitaminString))).start();
}
Vitamins.saveDatabaseForkIfMissing(typeOfVitaminString);
if(newTypeRadio.isSelected()) {
callback.addVitaminType(typeOfVitaminString);
}else
if(!editExisting.isSelected())
callback.addSizesToMenu(sizeOfVitaminString, typeOfVitaminString);
} catch (Exception e1) {
// TODO Auto-generated catch block
new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e1);
}
try {
Platform.runLater(() -> {
this.primaryStage.close();
primaryStage=null;
});
} catch (Exception e) {
// TODO Auto-generated catch block
new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e);
}
}).start();
}
@FXML
void onConfirmSize(ActionEvent event) {
if(!editExisting.isSelected()) {
sizeOfVitaminString = newSizeField.getText();
if(sizeOfVitaminString.length()<2) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("No name specified!");
alert.setHeaderText("Names must be at least 2 charrectors long");
alert.setContentText("Try again...");
alert.showAndWait();
});
return;
}
String slug = BowlerStudioMenu.slugify(sizeOfVitaminString);
if(!sizeOfVitaminString.contentEquals(slug)) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Name Format Wrong");
alert.setHeaderText("Name must be without spaces or special chars");
alert.setContentText("Changed to "+slug+" confirm to continue...");
alert.showAndWait();
Platform.runLater(() -> newSizeField.setText(slug));
});
return;
}
sizeOfVitaminString=slug;
}else {
sizeOfVitaminString=sizeComboBox.getSelectionModel().getSelectedItem();
}
Platform.runLater(() ->nameColumn.setCellValueFactory(new PropertyValueFactory<MeasurmentConfig, String>("key")));
Platform.runLater(() ->measurmentColumn.setCellValueFactory(new PropertyValueFactory<MeasurmentConfig, String>("measurment")));
Platform.runLater(() ->
measurmentColumn
.setCellFactory(
TextFieldTableCell.forTableColumn())
);
Platform.runLater(() ->measurmentsTable.getSelectionModel().cellSelectionEnabledProperty().set(true));
measurmentsTable.setEditable(true);
nameColumn.setEditable(false);
measurmentColumn.setEditable(true);
measurmentColumn.setOnEditCommit(ev -> {
final String value = ev.getNewValue() != null ? (String) ev.getNewValue() : (String) ev.getOldValue();
((MeasurmentConfig) ev.getTableView().getItems().get(ev.getTablePosition().getRow()))
.setMeasurment(value);
measurmentsTable.refresh();
});
if(existingTypeRadio.isSelected()) {
if(!editExisting.isSelected()) {
boolean exists = false;
// for existing types check for existing sizes
ArrayList<String> sizes = Vitamins.listVitaminSizes(typeOfVitaminString);
for(String size:sizes) {
if(size.contentEquals(sizeOfVitaminString))
exists=true;
}
if(exists) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Size already Exists");
alert.setHeaderText("Name must be unique");
alert.setContentText("Rename and confirm to continue...");
alert.showAndWait();
});
return;
}
}
new Thread(() -> {
HashMap<String, Object> configsOld = Vitamins.getConfiguration(typeOfVitaminString, sizeComboBox.getSelectionModel().getSelectedItem());
for(String key:configsOld.keySet()) {
setupKeyValueToTable(key, configsOld.get(key),sizeOfVitaminString);
}
}).start();
}
if(newTypeRadio.isSelected()) {
Vitamins.getConfiguration(typeOfVitaminString, sizeOfVitaminString);
}
if(Vitamins.isActuator(typeOfVitaminString) ||
(newTypeRadio.isSelected() && isMotor.isSelected())
) {
new Thread(() -> {
HashMap<String, Object> required = new HashMap<String, Object>();
required.put("MaxTorqueNewtonmeters", 0.001);
required.put("MaxFreeSpeedRadPerSec", 1);
required.put("massKg", 0.001);
required.put("shaftType", "dShaft");
required.put("shaftSize", "5mm");
setRequiredFields(required);
}).start();
}
new Thread(() -> {
HashMap<String, Object> required = new HashMap<String, Object>();
required.put("massKg", 0.001);
required.put("source", "https://commonwealthrobotics.com");
required.put("price", 0.01);
required.put("massCentroidX", 0.0);
required.put("massCentroidY", 0.0);
required.put("massCentroidZ", 0.0);
setRequiredFields(required);
}).start();
sizePane.setDisable(true);
measurmentPane.setDisable(false);
typePane.setDisable(true);
}
private void setRequiredFields(HashMap<String, Object> required) {
// For each vitamin size in a given type
for(String size:Vitamins.listVitaminSizes(typeOfVitaminString)) {
HashMap<String, Object> configs = Vitamins.getConfiguration(typeOfVitaminString, size);
// For every required key
for(String key:required.keySet()) {
// check to see if the current size has this key already
if(!configs.containsKey(key)) {
// enter a default value, but ensure that the key exists for downstream code
setupKeyValueToTable(key, required.get(key),size);
}
}
}
}
private void setupKeyValueToTable(String key, Object value, String size) {
Vitamins.getConfiguration(typeOfVitaminString, size).put(key, value);
if (size.contentEquals(sizeOfVitaminString))
Platform.runLater(() -> measurmentsTable.getItems()
.add(new MeasurmentConfig(key, Vitamins.getConfiguration(typeOfVitaminString, sizeOfVitaminString))));
}
@FXML
void onConfirmType(ActionEvent event) {
if(newTypeRadio.isSelected()) {
typeOfVitaminString=newTypeNameField.getText();
if(typeOfVitaminString.length()<2) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("No name specified!");
alert.setHeaderText("Names must be at least 2 charrectors long");
alert.setContentText("Try again...");
alert.showAndWait();
});
return;
}
String slug = BowlerStudioMenu.slugify(typeOfVitaminString);
if(!typeOfVitaminString.contentEquals(slug)) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Name Format Wrong");
alert.setHeaderText("Name must be without spaces or special chars");
alert.setContentText("Changed to "+slug+" confirm to continue...");
alert.showAndWait();
Platform.runLater(() -> newTypeNameField.setText(slug));
});
return;
}
typeOfVitaminString=slug;
sizeComboBox.setDisable(true);
editExisting.setDisable(true);
saveAndFork();
}else {
typeOfVitaminString=typeComboBox.getSelectionModel().getSelectedItem();
saveAndFork();
ArrayList<String> sizes = Vitamins.listVitaminSizes(typeOfVitaminString);
boolean hasSize=false;
for(String size:sizes) {
sizeComboBox.getItems().add(size);
if(typeOfVitaminString!=null)
if(size.contentEquals(typeOfVitaminString)) {
hasSize=true;
}
}
if(sizes.size()>0) {
if(hasSize) {
sizeComboBox.getSelectionModel().select(typeOfVitaminString);
}else {
sizeComboBox.getSelectionModel().select(sizes.get(0));
}
}else {
sizeComboBox.setDisable(true);
editExisting.setDisable(true);
editExisting.setSelected(false);
}
}
measurmentPane.setDisable(true);
typePane.setDisable(true);
}
private void saveAndFork() {
new Thread(() -> {
try {
Vitamins.saveDatabaseForkIfMissing(typeOfVitaminString);
sizePane.setDisable(false);
} catch (Exception e) {
// TODO Auto-generated catch block
new IssueReportingExceptionHandler().uncaughtException(Thread.currentThread(), e);
}
}).start();
}
@FXML
void onNewMeasurment(ActionEvent event) {
newMeasurmentButton.setDisable(true);
TextInputDialog dialog = new TextInputDialog("lengthOfThing");
dialog.setTitle("Add new measurment to "+typeOfVitaminString);
dialog.setHeaderText("This measurment will be added to all instances of the vitamin");
dialog.setContentText("New measurment name:");
// Traditional way to get the response value.
Optional<String> result = dialog.showAndWait();
// The Java 8 way to get the response value (with lambda expression).
result.ifPresent(name -> {
TextInputDialog dialog2 = new TextInputDialog("0.0");
dialog2.setTitle("Set value of "+name);
dialog2.setHeaderText("This value will be added to all instances of the vitamin");
dialog2.setContentText(name+" = ");
// Traditional way to get the response value.
Optional<String> result2 = dialog2.showAndWait();
result2.ifPresent(name2 -> {
setupKeyValueToTable(name,name2,sizeOfVitaminString);
for(String size:Vitamins.listVitaminSizes(typeOfVitaminString)) {
Vitamins.getConfiguration(typeOfVitaminString, size).put(name,name2);
}
});
newMeasurmentButton.setDisable(false);
});
}
@FXML
void onSelectExistingTypeMode(ActionEvent event) {
newTypeNameField.setEditable(false);
typeComboBox.setDisable(false);
isShaft.setDisable(true);
isMotor.setDisable(true);
}
@FXML
void onSelectNewTypeMode(ActionEvent event) {
newTypeNameField.setEditable(true);
typeComboBox.setDisable(true);
isShaft.setDisable(false);
isMotor.setDisable(false);
}
@FXML
void onEditExisting(ActionEvent event) {
if(editExisting.isSelected()) {
newSizeField.setEditable(false);
}else {
newSizeField.setEditable(true);
}
}
@FXML
void onIsMotor(ActionEvent event) {
if(isMotor.isSelected())
isShaft.setSelected(false);
}
@FXML
void onIsShaft(ActionEvent event) {
if(isShaft.isSelected())
isMotor.setSelected(false);
}
@FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
assert x1 != null : "fx:id=\"x1\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
assert x2 != null : "fx:id=\"x2\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
assert existingTypeRadio != null : "fx:id=\"existingTypeRadio\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
assert newTypeRadio != null : "fx:id=\"newTypeRadio\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
assert typeComboBox != null : "fx:id=\"typeComboBox\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
assert sizeComboBox != null : "fx:id=\"sizeComboBox\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
assert measurmentsTable != null : "fx:id=\"measurmentsTable\" was not injected: check your FXML file 'newVitaminWizard.fxml'.";
sizePane.setDisable(true);
measurmentPane.setDisable(true);
ToggleGroup groupForType= new ToggleGroup();
existingTypeRadio.setSelected(true);
newTypeRadio.setSelected(false);
existingTypeRadio.setToggleGroup(groupForType);
newTypeRadio.setToggleGroup(groupForType);
newTypeNameField.setEditable(false);
ArrayList<String> types = Vitamins.listVitaminTypes();
for(String s:types) {
typeComboBox.getItems().add(s);
}
if(typeOfVitaminString==null)
typeComboBox.getSelectionModel().select(types.get(0));
else
typeComboBox.getSelectionModel().select(typeOfVitaminString);
isShaft.setDisable(true);
isMotor.setDisable(true);
}
public static void launchWizard(INewVitaminCallback callback) throws Exception {
NewVitaminWizardController.callback=callback;
Platform.runLater(() -> {
Stage s = new Stage();
primaryStage = s;
new Thread(() -> {
NewVitaminWizardController controller = new NewVitaminWizardController();
try {
controller.start(s);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
});
}
public static void main(String [] args) throws Exception {
JavaFXInitializer.go();
NewVitaminWizardController.launchWizard(new INewVitaminCallback() {
@Override
public Menu getTypeMenu(String type) {
System.out.println("Get Vitamin Menu");
return new Menu(type);
}
@Override
public void addVitaminType(String s) {
getTypeMenu(s);
ArrayList<String> sizes = Vitamins.listVitaminSizes(s);
for(String size:sizes) {
addSizesToMenu(size,s);
}
System.out.println("Add addVitaminType "+s);
}
@Override
public void addSizesToMenu(String size, String type) {
System.out.println("Add addSizesToMenu "+type+" "+size );
}
});
}
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = AssetFactory.loadLayout("layout/newVitaminWizard.fxml",true);
Parent root;
//loader.setController(this);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
Platform.runLater(() -> {
primaryStage.setTitle("Edit Vitamins Wizard");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.initModality(Modality.WINDOW_MODAL);
primaryStage.setResizable(true);
primaryStage.show();
});
}
}

View File

@@ -0,0 +1,16 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.neuronrobotics.bowlerstudio;
/**
*
* @author Michael Hoffer &lt;info@michaelhoffer.de&gt;
*/
@FunctionalInterface
public interface OutputFilter {
public boolean onMatch(String s);
}

View File

@@ -0,0 +1,7 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
public interface PluginFactory {
AbstractBowlerStudioTab generateNewPlugin() throws ClassNotFoundException, InstantiationException, IllegalAccessException ;
}

View File

@@ -0,0 +1,310 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.creature.CreatureLab;
import com.neuronrobotics.bowlerstudio.creature.DhLab;
import com.neuronrobotics.bowlerstudio.tabs.*;
import com.neuronrobotics.imageprovider.AbstractImageProvider;
import com.neuronrobotics.nrconsole.plugin.BowlerCam.BowlerCamController;
import com.neuronrobotics.nrconsole.plugin.DeviceConfig.PrinterConiguration;
import com.neuronrobotics.nrconsole.plugin.DyIO.Secheduler.AnamationSequencer;
import com.neuronrobotics.nrconsole.plugin.PID.PIDControl;
import com.neuronrobotics.nrconsole.plugin.bootloader.BootloaderPanel;
import com.neuronrobotics.pidsim.LinearPhysicsEngine;
import com.neuronrobotics.pidsim.PidLab;
import com.neuronrobotics.replicator.driver.NRPrinter;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.FirmataBowler;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.bootloader.NRBootLoader;
import com.neuronrobotics.sdk.bowlercam.device.BowlerCamDevice;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.common.RpcEncapsulation;
import com.neuronrobotics.sdk.dyio.DyIO;
import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
import javafx.application.Platform;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.util.ArrayList;
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
public class PluginManager {
private BowlerAbstractDevice dev;
private static ArrayList<DeviceSupportPluginMap> deviceSupport = new ArrayList<>();
private ArrayList<AbstractBowlerStudioTab> liveTabs = new ArrayList<>();
// add tabs to the support list based on thier class
// adding additional classes here will show up in the default
// tabs list for objects of that type
static{
//DyIO
addPlugin(new DeviceSupportPluginMap(DyIO.class, DyIOControl.class));
addPlugin(new DeviceSupportPluginMap(DyIO.class, AnamationSequencer.class));
//Ipid
addPlugin(new DeviceSupportPluginMap(IPidControlNamespace.class, PIDControl.class));
// Image s
// addPlugin(new DeviceSupportPluginMap(AbstractImageProvider.class, CameraTab.class));
// addPlugin(new DeviceSupportPluginMap(AbstractImageProvider.class, SalientTab.class));
// Bootloader
addPlugin(new DeviceSupportPluginMap(NRBootLoader.class, BootloaderPanel.class));
//BowlerBoard Specific
//addPlugin(new DeviceSupportPlugginMap(BowlerBoardDevice.class, //none yet));
//AbstractKinematicsNR
//addPlugin(new DeviceSupportPluginMap(AbstractKinematicsNR.class, JogKinematicsDevice.class));
//addPlugin(new DeviceSupportPluginMap(AbstractKinematicsNR.class, AdvancedKinematicsController.class));
//addPlugin(new DeviceSupportPluginMap(AbstractKinematicsNR.class, DhLab.class));
addPlugin(new DeviceSupportPluginMap(MobileBase.class, CreatureLab.class));
//NRPrinter
addPlugin(new DeviceSupportPluginMap(NRPrinter.class, PrinterConiguration.class));
//Bowler Cam
addPlugin(new DeviceSupportPluginMap(BowlerCamDevice.class, BowlerCamController.class));
//LinearPhysicsEngine
addPlugin(new DeviceSupportPluginMap(LinearPhysicsEngine.class, PidLab.class));
//Firmata
addPlugin(new DeviceSupportPluginMap(FirmataBowler.class, FirmataTab.class));
}
public PluginManager(BowlerAbstractDevice dev){
this.dev = dev;
if(!dev.isAvailable())
throw new RuntimeException("Device is not reporting availible "+dev.getClass().getSimpleName());
}
public static void addPlugin(DeviceSupportPluginMap newMap){
for(int i=0;i<deviceSupport.size();i++){
try{
if( deviceSupport.get(i).getDevice() == newMap.getDevice() &&
deviceSupport.get(i).getPlugin() == newMap.getPlugin() ){
System.out.println("Removing duplicate plugin: "+deviceSupport.remove(i));
}
}catch(Exception e){
e.printStackTrace();
}
}
Log.debug("Adding Plugin "+newMap);
deviceSupport.add(newMap);
}
public void setName(String name) {
dev.setScriptingName(name);
}
public String getName(){
return dev.getScriptingName();
}
public BowlerAbstractDevice getDevice() {
return dev;
}
private AbstractBowlerStudioTab generateTab(DeviceSupportPluginMap c) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
for(AbstractBowlerStudioTab t: liveTabs){
if(c.getPlugin().isInstance(t)){
// tab already exists, wake it up and return it
t.onTabReOpening();
return t;
}
}
AbstractBowlerStudioTab t=c.generateNewPlugin();
t.setDevice(dev);
liveTabs.add(t);
return t;
}
public void setTree(TreeItem<String> item) {
}
public BowlerStudioController getBowlerStudioController() {
return BowlerStudioController.getBowlerStudio();
}
public Node getBowlerBrowser(){
CheckBoxTreeItem<String> rpc = new CheckBoxTreeItem<> ("Bowler RPC");
TreeView<String> treeView =new TreeView<>(rpc);
treeView.setCellFactory(CheckBoxTreeCell.forTreeView());
if(dev.getConnection()!=null){
rpc.setExpanded(true);
ArrayList<String> nameSpaceList = dev.getNamespaces();
for(String namespace:nameSpaceList){
CheckBoxTreeItem<String> ns = new CheckBoxTreeItem<> (namespace);
ns.setExpanded(false);
rpc.getChildren().add(ns);
ArrayList<RpcEncapsulation> rpcList = dev.getRpcList(namespace);
CheckBoxTreeItem<String> get = new CheckBoxTreeItem<> ("GET");
CheckBoxTreeItem<String> post = new CheckBoxTreeItem<> ("POST");
CheckBoxTreeItem<String> async = new CheckBoxTreeItem<> ("ASYNC");
CheckBoxTreeItem<String> crit = new CheckBoxTreeItem<> ("CRITICAL");
get.setExpanded(false);
ns.getChildren().add(get);
post.setExpanded(false);
ns.getChildren().add(post);
async.setExpanded(false);
ns.getChildren().add(async);
crit.setExpanded(false);
ns.getChildren().add(crit);
for(RpcEncapsulation rpcEnc:rpcList){
CheckBoxTreeItem<String> rc = new CheckBoxTreeItem<> (rpcEnc.getRpc());
rc.setExpanded(false);
switch(rpcEnc.getDownstreamMethod()){
case ASYNCHRONOUS:
async.getChildren().add(rc);
break;
case CRITICAL:
crit.getChildren().add(rc);
break;
case GET:
get.getChildren().add(rc);
break;
case POST:
post.getChildren().add(rc);
break;
default:
break;
}
RpcCommandPanel panel =new RpcCommandPanel(rpcEnc, dev,rc);
// Platform.runLater(()->{
// SwingNode sn = new SwingNode();
// Stage dialog = new Stage();
// dialog.setHeight(panel.getHeight());
// dialog.setWidth(panel.getWidth());
// dialog.initStyle(StageStyle.UTILITY);
// sn.setContent(panel);
// Scene scene = new Scene(new Group(sn));
// dialog.setScene(scene);
// dialog.setOnCloseRequest(event -> {
// rc.setSelected(false);
// });
// rc.selectedProperty().addListener(b ->{
// if(rc.isSelected()){
// dialog.show();
// }else{
// dialog.hide();
// }
// });
// });
}
}
}
return treeView;
}
public ArrayList<TitledPane> getPlugins() {
ArrayList<TitledPane> plugins = new ArrayList<>();
VBox pluginLauncher = new VBox(20);
for( DeviceSupportPluginMap c:deviceSupport){
if(c.getDevice().isInstance(dev)){
Button launcher = new Button("Launch "+c.getPlugin().getSimpleName(), AssetFactory.loadIcon("Plugin-Icon.png"));
try {// These tabs are the select few to autoload when a device of theis type is connected
if( DyIOControl.class ==c.getPlugin() ||
BootloaderPanel.class ==c.getPlugin()||
CreatureLab.class ==c.getPlugin()
){
if(getBowlerStudioController()!=null){
System.out.println("Auto loading "+c.getPlugin().getSimpleName());
Log.warning("Attempting Autoloading "+c);
//if(CreatureLab.class !=c.getPlugin())
launchTab( c,launcher);
//else
// generateTab(c);// dont add the creature lab it uses the overlays
}
}else{
Log.warning("Not autoloading "+c);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
launcher.setOnAction(b ->{
launchTab( c,launcher);
});
pluginLauncher.getChildren().add(launcher);
}
}
TitledPane info = new TitledPane("Device Info", new Text(dev.getClass().getSimpleName()));
TitledPane protocol = new TitledPane("Bowler Protocol", getBowlerBrowser());
TitledPane pluginsPane = new TitledPane("Plugins", pluginLauncher);
info.setGraphic(AssetFactory.loadIcon("Info.png"));
protocol.setGraphic(AssetFactory.loadIcon("BowlerStudio.png"));
pluginsPane.setGraphic(AssetFactory.loadIcon("Plugins.png"));
plugins.add(info);
if(dev.getConnection()!=null)
plugins.add(protocol);
plugins.add(pluginsPane);
return plugins;
}
private void launchTab(DeviceSupportPluginMap c,Button launcher){
new Thread(){
public void run(){
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
setName("Launching "+c.getPlugin().getSimpleName());
try {
AbstractBowlerStudioTab t = generateTab(c);
// allow the threads to finish before adding
//ThreadUtil.wait(50);
getBowlerStudioController().addTab(t, true);
t.setOnCloseRequest(new EventHandler<Event>() {
@Override
public void handle(Event arg0) {
System.out.println("PM is Closing "+t.getText());
t.onTabClosing();
Platform.runLater(()->launcher.setDisable(false));
}
});
Platform.runLater(()->{
launcher.setDisable(true);
});
System.out.println("Launching "+c.getPlugin().getSimpleName());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}.start();
}
}

View File

@@ -0,0 +1,61 @@
package com.neuronrobotics.bowlerstudio;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.sdk.common.Log;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import java.util.ArrayList;
public class PluginManagerWidget extends TitledPane {
private PluginManager manager;
private TextField deviceName = new TextField();
private Button disconnectTHis;
final Accordion accordion = new Accordion ();
public PluginManagerWidget(PluginManager m, Node graphic){
HBox content = new HBox(20);
content.setPadding(new Insets(0, 20, 10, 20));
this.manager = m;
ArrayList<TitledPane> plugins = manager.getPlugins();
accordion.getPanes().addAll(plugins);
disconnectTHis = new Button("Disconnect "+manager.getName(), AssetFactory.loadIcon("Disconnect-Device.png"));
disconnectTHis.setOnMousePressed( event -> {
new Thread(){
public void run(){
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
setName("disconnect plugins");
Log.warning("Disconnect button for "+manager.getName()+" pressed");
getManager().getDevice().disconnect();
}
}.start();
});
setGraphic(AssetFactory.loadIcon("Bowler-Device-In-Manager.png"));
deviceName.setOnAction(event -> {
getManager().setName(deviceName.getText());
setText(manager.getName());
disconnectTHis.setText("Disconnect "+manager.getName());
});
Platform.runLater(()->deviceName.setText(manager.getName()));
content.setHgrow(accordion, Priority.ALWAYS);
content.getChildren().addAll(graphic,disconnectTHis,deviceName,accordion);
setContent(content);
setText(manager.getName());
}
public PluginManager getManager() {
return manager;
}
}

View File

@@ -0,0 +1,176 @@
package com.neuronrobotics.bowlerstudio;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javafx.scene.image.Image;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
public class PsudoSplash {
JFrame interfaceFrame;
private String message = "";
class CustomPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 8749662598444052868L;
private BufferedImage image;
public CustomPanel() {
setOpaque(false);
try {
/*
* Since Images are Application Resources, it's always best to access them in
* the form of a URL, instead of File, as you are doing. Uncomment this below
* line and watch this answer of mine, as to HOW TO ADD IMAGES TO THE PROJECT
* https://stackoverflow.com/a/9866659/1057230 In order to access images with
* getClass().getResource(path) here your Directory structure has to be like
* this Project | ------------------------ | | bin src | | --------- .java files
* | | package image(folder) ( or | .class 404error.jpg files, if no package
* exists.)
*/
image = ImageIO.read(getClass().getResource("splash.png"));
} catch (IOException ioe) {
System.out.println("Unable to fetch image.");
ioe.printStackTrace();
}
}
/*
* Make this one customary habbit, of overriding this method, when you extends a
* JPanel/JComponent, to define it's Preferred Size. Now in this case we want it
* to be as big as the Image itself.
*/
@Override
public Dimension getPreferredSize() {
return (new Dimension(image.getWidth(), image.getHeight()));
}
/*
* This is where the actual Painting Code for the JPanel/JComponent goes. Here
* we will draw the image. Here the first line super.paintComponent(...), means
* we want the JPanel to be drawn the usual Java way first, then later on we
* will add our image to it, by writing the other line, g.drawImage(...).
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
Graphics2D splashGraphics = (Graphics2D) g;
splashGraphics.setComposite(AlphaComposite.Clear);
// splashGraphics.fillRect(65, 270, 200, 40);
splashGraphics.setPaintMode();
splashGraphics.setColor(Color.WHITE);
splashGraphics.drawString(StudioBuildInfo.getVersion(), 65, 45);
splashGraphics.setComposite(AlphaComposite.Clear);
// splashGraphics.fillRect(65, 270, 200, 40);
splashGraphics.setPaintMode();
splashGraphics.setColor(Color.WHITE);
splashGraphics.drawString(getMessage(), 65, 280);
}
}
public PsudoSplash() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
interfaceFrame = new JFrame("Loading BowlerStudio...");
interfaceFrame.setUndecorated(true);
interfaceFrame.setLayout(new BorderLayout());
CustomPanel contentPane = new CustomPanel();
// interfaceFrame.setBackground(Color.black);
interfaceFrame.setContentPane(contentPane);
interfaceFrame.pack();
interfaceFrame.setLocationRelativeTo(null);
interfaceFrame.setVisible(true);
interfaceFrame.setBackground(new Color(0, 0, 0, 0));
try {
interfaceFrame.setIconImage( ImageIO.read(getClass().getResource("splash.png")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
while (interfaceFrame == null)
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// public void setIcon(Image img) {
// BufferedImage image = javafx.embed.swing.SwingFXUtils.fromFXImage(img, null);
// if (interfaceFrame != null)
// interfaceFrame.setIconImage(image);
// }
boolean isVisableSplash() {
if (interfaceFrame != null)
return interfaceFrame.isVisible();
return false;
}
void closeSplashLocal() {
if (interfaceFrame != null)
interfaceFrame.setVisible(false);
}
void updateSplash() {
if (interfaceFrame != null) {
interfaceFrame.invalidate();
interfaceFrame.repaint();
}
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
if (message.length() > 23) {
this.message = message.subSequence(0, 23).toString();
//new RuntimeException().printStackTrace();
} else
this.message = message;
if (interfaceFrame != null) {
interfaceFrame.setVisible(true);
}
}
}

View File

@@ -0,0 +1,191 @@
/*
* RedirectableStream.java
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 20092012 Steinbeis Forschungszentrum (STZ Ölbronn),
* Copyright (c) 20062012 by Michael Hoffer
*
* This file is part of Visual Reflection Library (VRL).
*
* VRL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* as published by the Free Software Foundation.
*
* see: http://opensource.org/licenses/LGPL-3.0
* file://path/to/VRL/src/eu/mihosoft/vrl/resources/license/lgplv3.txt
*
* VRL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* This version of VRL includes copyright notice and attribution requirements.
* According to the LGPL this information must be displayed even if you modify
* the source code of VRL. Neither the VRL Canvas attribution icon nor any
* copyright statement/attribution may be removed.
*
* Attribution Requirements:
*
* If you create derived work you must do three things regarding copyright
* notice and author attribution.
*
* First, the following text must be displayed on the Canvas:
* "based on VRL source code". In this case the VRL canvas icon must be removed.
*
* Second, the copyright notice must remain. It must be reproduced in any
* program that uses VRL.
*
* Third, add an additional notice, stating that you modified VRL. In addition
* you must cite the publications listed below. A suitable notice might read
* "VRL source code modified by YourName 2012".
*
* Note, that these requirements are in full accordance with the LGPL v3
* (see 7. Additional Terms, b).
*
* Publications:
*
* M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library -
* A Framework for Declarative GUI Programming on the Java Platform.
* Computing and Visualization in Science, 2011, in press.
*/
package com.neuronrobotics.bowlerstudio;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.scene.control.TextArea;
/**
*
* @author Michael Hoffer info@michaelhoffer.de
*/
public class RedirectableStream extends PrintStream {
public static PrintStream ORIGINAL_SOUT = System.out;
public static PrintStream ORIGINAL_SERR = System.err;
private final List<TextArea> views = new ArrayList<>();
private boolean redirectToUi;
private boolean redirectToStdOut;
private final List<OutputFilter> filters = new ArrayList<>();
public RedirectableStream(OutputStream out, TextArea... views) {
super(out);
this.views.clear();
for (TextArea textArea : views) {
addView(textArea);
}
setRedirectToStdOut(true);
}
@Override
public synchronized void write(byte[] buf, int off, int len) {
if (isRedirectToUi()) {
invokeAndWait(() -> {
int i = 0;
for (TextArea view : views) {
String s = new String(buf, off, len);
if (filters.get(i).onMatch(s)) {
try {
int startOffSet = view.getText().length();
view.insertText(startOffSet, s);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
i++;
}
});
// view.setCaretPosition(startOffSet + len);
// }
// catch (BadLocationException e) {
// e.printStackTrace();
// Platform.invokeLater(new Runnable() {
//
// @Override
// public void run() {
// // automatically scroll down to the last line
//// view.scrollRectToVisible(
//// new Rectangle(0, view.getHeight() - 1, 1, 1));
//
// }
// });
}
if (isRedirectToStdOut()) {
super.write(buf, off, len);
}
}
public final void addView(TextArea view) {
views.add(view);
filters.add((OutputFilter) (String s) -> {
return true;
});
}
public void setFilter(TextArea view, OutputFilter filter) {
int i = views.indexOf(view);
filters.set(i, filter);
}
/**
* @return the redirectToUi
*/
public boolean isRedirectToUi() {
return redirectToUi;
}
/**
* @param redirectToUi the redirectToUi to set
*/
public void setRedirectToUi(boolean redirectToUi) {
this.redirectToUi = redirectToUi;
}
/**
* @return the redirectToStdOut
*/
public boolean isRedirectToStdOut() {
return redirectToStdOut;
}
/**
* @param redirectToStdOut the redirectToStdOut to set
*/
public final void setRedirectToStdOut(boolean redirectToStdOut) {
this.redirectToStdOut = redirectToStdOut;
}
private static void invokeAndWait(Runnable r) {
if (Platform.isFxApplicationThread()) {
r.run();
} else {
FutureTask<Boolean> task = new FutureTask<>(r, true);
Platform.runLater(task);
try {
task.get(); // like join()
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(RedirectableStream.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

View File

@@ -0,0 +1,149 @@
package com.neuronrobotics.bowlerstudio;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javafx.scene.control.CheckBoxTreeItem;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.tree.DefaultMutableTreeNode;
import net.miginfocom.swing.MigLayout;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.BowlerDataType;
import com.neuronrobotics.sdk.common.BowlerDatagram;
import com.neuronrobotics.sdk.common.RpcEncapsulation;
import com.neuronrobotics.sdk.genericdevice.GenericDevice;
public class RpcCommandPanel extends JPanel implements ActionListener {
/**
*
*/
private static final long serialVersionUID = -9199252749669892888L;
private BowlerAbstractDevice device;
private RpcEncapsulation rpc;
private CheckBoxTreeItem<?> rpcDhild;
private boolean commandsEnabled=false;
private ArrayList<JTextField> tx = new ArrayList<>();
private ArrayList<JLabel> rx = new ArrayList<>();
private JButton send = new JButton("Send");
private JLabel txRpc = new JLabel("****");
private JLabel rxRpc = new JLabel("****");
public RpcCommandPanel(RpcEncapsulation rpc,BowlerAbstractDevice device, CheckBoxTreeItem<?> rpcDhild){
this.setRpcDhild(rpcDhild);
this.setRpc(rpc);
this.setDevice(device);
setLayout(new MigLayout());
add(new JLabel("Namespace"), "cell 0 0,alignx leading");
add(new JLabel(rpc.getNamespace().split(";")[0]), "cell 1 0,alignx leading");
add(new JLabel("Method"), "cell 0 1,alignx leading");
add(new JLabel(rpc.getDownstreamMethod().toString()), "cell 1 1,alignx leading");
add(new JLabel("RPC"), "cell 0 2,alignx leading");
add(new JLabel(rpc.getRpc()), "cell 1 2,alignx leading");
add(new JLabel("Tx>>"), "cell 0 3,alignx leading");
txRpc.setText(rpc.getRpc());
add(txRpc, "cell 0 3,alignx leading");
add(new JLabel("Rx<<"), "cell 0 4,alignx leading");
add(rxRpc, "cell 0 4,alignx leading");
add(send,"cell 2 3,alignx leading");
JPanel txPanel = new JPanel(new MigLayout());
JPanel rxPanel = new JPanel(new MigLayout());
int i=0;
for (BowlerDataType s:rpc.getDownstreamArguments()){
JTextField tmp= new JTextField(5);
tmp.setText("0");
txPanel.add(new JLabel(s.toString()), "cell "+i+" 0,alignx leading");
tx.add(tmp);
i++;
}
i=0;
for (BowlerDataType s:rpc.getUpstreamArguments()){
JLabel tmp= new JLabel();
tmp.setText("0");
rxPanel.add(new JLabel(s.toString()), "cell "+i+" 0,alignx leading");
rx.add(tmp);
i++;
}
i=0;
for(JTextField t:tx){
txPanel.add(t, "cell "+i+" 1,alignx leading");
i++;
}
i=0;
for(JLabel t:rx){
rxPanel.add(t, "cell "+i+" 1,alignx leading");
i++;
}
add(txPanel, "cell 1 3,alignx leading");
add(rxPanel, "cell 1 4,alignx leading");
send.addActionListener(this);
}
public RpcEncapsulation getRpc() {
return rpc;
}
private void setRpc(RpcEncapsulation rpc) {
this.rpc = rpc;
}
public BowlerAbstractDevice getDevice() {
return device;
}
private void setDevice(BowlerAbstractDevice device) {
this.device = device;
}
public CheckBoxTreeItem<?> getRpcDhild() {
return rpcDhild;
}
public void setRpcDhild(CheckBoxTreeItem<?> rpcDhild) {
this.rpcDhild = rpcDhild;
}
public void enableCommands() {
if(commandsEnabled)
return;
commandsEnabled = true;
}
@Override
public void actionPerformed(ActionEvent arg0) {
Object[] values = new Object[tx.size()];
for (int i=0;i<values.length;i++){
if(rpc.getDownstreamArguments()[i] == BowlerDataType.ASCII)
values[i] = tx.get(i).getText();
else
values[i] = Integer.parseInt(tx.get(i).getText());
}
BowlerDatagram bd =device.send(rpc.getCommand(values));
rxRpc.setText(bd.getRPC());
Object [] up = rpc.parseResponse(bd);
for(int i=0;i<up.length;i++){
if(up[i]!=null)
rx.get(i).setText(up[i].toString());
else{
rx.get(i).setText("Null");
}
}
}
}

View File

@@ -0,0 +1,90 @@
package com.neuronrobotics.bowlerstudio;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
import javafx.scene.image.Image;
public class SplashManager {
private static Graphics2D splashGraphics;
private static boolean loadFirst = true;
private static PsudoSplash psudo = null;
public static void closeSplash() {
if(isVisableSplash())
closeSplashLocal();
}
private static void closeSplashLocal() {
if (BowlerStudio.splash != null) {
BowlerStudio.splash.close();
splashGraphics = null;
return;
}
psudo.closeSplashLocal();
}
private static boolean isVisableSplash() {
if (BowlerStudio.splash != null)
return BowlerStudio.splash.isVisible();
return psudo.isVisableSplash();
}
private static void updateSplash() {
if (BowlerStudio.splash != null) {
BowlerStudio.splash.update();
return;
}
psudo.updateSplash();
}
public static void renderSplashFrame(int frame, String message) {
if (loadFirst) {
loadFirst = false;
initialize();
}
String string = frame + "% " + message;
System.err.println(" Splash Rendering " + frame + " " + message);
if (psudo != null) {
psudo.setMessage(string);
updateSplash();
}else if (splashGraphics != null && isVisableSplash()) {
splashGraphics.setComposite(AlphaComposite.Clear);
splashGraphics.fillRect(65, 270, 200, 40);
splashGraphics.setPaintMode();
splashGraphics.setColor(Color.WHITE);
splashGraphics.drawString(string, 65, 280);
// Platform.runLater(() -> {
updateSplash();
// });
}
}
private static void initialize() {
if (BowlerStudio.splash != null) {
try {
splashGraphics = BowlerStudio.splash.createGraphics();
} catch (IllegalStateException e) {
}
} else {
System.err.println("No splash screen availible!");
psudo = new PsudoSplash();
}
if (psudo == null)
if (splashGraphics != null && isVisableSplash()) {
splashGraphics.setComposite(AlphaComposite.Clear);
splashGraphics.fillRect(65, 270, 200, 40);
splashGraphics.setPaintMode();
splashGraphics.setColor(Color.WHITE);
splashGraphics.drawString(StudioBuildInfo.getVersion(), 65, 45);
updateSplash();
}
}
}

View File

@@ -0,0 +1,268 @@
package com.neuronrobotics.bowlerstudio;
/**
* Sample Skeleton for "Terminal.fxml" Controller Class
* You can copy and paste this code into your favorite IDE
**/
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class Terminal {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="executionBox"
private TextField executionBox; // Value injected by FXMLLoader
@FXML // fx:id="langaugeIcon"
private ImageView langaugeIcon; // Value injected by FXMLLoader
@FXML // fx:id="langauges"
private ComboBox<String> langauges; // Value injected by FXMLLoader
@FXML // fx:id="outputBox"
private TextArea outputBox; // Value injected by FXMLLoader
private ArrayList<String> history = new ArrayList<>();
private int historyIndex = 0;
private boolean running = false;
private Thread scriptRunner = null;
@SuppressWarnings("restriction")
@FXML // This method is called by the FXMLLoader when initialization is
// complete
void initialize() {
assert executionBox != null : "fx:id=\"executionBox\" was not injected: check your FXML file 'Terminal.fxml'.";
assert langaugeIcon != null : "fx:id=\"langaugeIcon\" was not injected: check your FXML file 'Terminal.fxml'.";
assert langauges != null : "fx:id=\"langauges\" was not injected: check your FXML file 'Terminal.fxml'.";
assert outputBox != null : "fx:id=\"outputBox\" was not injected: check your FXML file 'Terminal.fxml'.";
BowlerStudio.setLogViewRefStatic(outputBox);
// Initialize your logic here: all @FXML variables will have been
// injected
langauges.getItems().clear();
executionBox.setOnAction(event -> {
new Thread() {
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
startStopAction();
}
}.start();
});
executionBox.setPrefWidth(80 * 4);
executionBox.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
// Platform.runLater(() -> {
if ((event.getCode() == KeyCode.UP || event.getCode() == KeyCode.DOWN)) {
System.err.println("Key pressed " + event.getCode() + " history index = " + historyIndex
+ " history size= " + history.size());
if (historyIndex == 0) {
String text = executionBox.getText();
if (text.length() > 0) {
// store what was in the box into he history
history.add(text);
}
}
if (event.getCode() == KeyCode.UP)
historyIndex++;
else
historyIndex--;
if (!history.isEmpty()) {
if (historyIndex > history.size()) {
historyIndex = history.size();
}
if (historyIndex < 0)
historyIndex = 0;
// History index established
if (historyIndex > 0)
Platform.runLater(() -> {
executionBox.setText(history.get(history.size() - historyIndex));
});
else
Platform.runLater(() -> {
executionBox.setText("");
});
}
event.consume();
}
// });
});
try {
history = BowlerKernel.loadHistory();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
BowlerKernel.writeHistory(history);
}
});
List<String> langs = ScriptingEngine.getAllLangauges();
ObservableList<String> options = FXCollections.observableArrayList(langs);
//
for(String s:options){
langauges.getItems().add(s);
}
langauges.getSelectionModel().select("Groovy");
Image icon;
try {
icon = AssetFactory.loadAsset("Script-Tab-" + langauges.getSelectionModel().getSelectedItem() + ".png");
langaugeIcon.setImage(icon);
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
langauges.setOnAction(event -> {
try {
langaugeIcon.setImage(AssetFactory
.loadAsset("Script-Tab-" + langauges.getSelectionModel().getSelectedItem() + ".png"));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
});
}
private void reset() {
running = false;
}
private void start(String code) {
running = true;
scriptRunner = new Thread() {
@SuppressWarnings("restriction")
public void run() {
try {
ScriptingEngine.inlineScriptStringRun(code, null,
langauges.getSelectionModel().getSelectedItem());
reset();
} catch (groovy.lang.MissingPropertyException | org.python.core.PyException d) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Device missing error");
String message = "This script needs a device connected: ";
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
d.printStackTrace(pw);
BowlerStudioController.highlightException(null, d);
String stackTrace = sw.toString();
if (stackTrace.contains("dyio"))
message += "dyio";
else if (stackTrace.contains("camera"))
message += "camera";
else if (stackTrace.contains("gamepad"))
message += "gamepad";
else
message += stackTrace;
alert.setHeaderText(message);
alert.setContentText("You need to connect it before running again");
alert.showAndWait();
if (stackTrace.contains("dyio"))
ConnectionManager.addConnection();
// else if (stackTrace.contains("camera"))
// ConnectionManager.addConnection(new OpenCVImageProvider(0), "camera0");
else if (stackTrace.contains("gamepad"))
ConnectionManager.onConnectGamePad("gamepad");
reset();
});
} catch (Exception ex) {
System.err.println("Script exception of type= " + ex.getClass().getName());
Platform.runLater(() -> {
reset();
});
BowlerStudioController.highlightException(null, ex);
}
}
};
scriptRunner.start();
}
private void startStopAction() {
String text = executionBox.getText();
text += "\r\n";
Platform.runLater(() -> {
executionBox.setText("");
});
System.out.println(text);
history.add(text);
BowlerKernel.writeHistory(history);
if (historyIndex != 0)
historyIndex--;
else
historyIndex = 0;
if (running)
stop();
else
start(text);
}
public void stop() {
// TODO Auto-generated method stub
reset();
if (scriptRunner != null)
while (scriptRunner.isAlive()) {
Log.debug("Interrupting");
ThreadUtil.wait(10);
try {
scriptRunner.interrupt();
scriptRunner.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,92 @@
package com.neuronrobotics.bowlerstudio;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.BowlerDataType;
import com.neuronrobotics.sdk.common.BowlerDatagram;
import com.neuronrobotics.sdk.common.BowlerMethod;
import com.neuronrobotics.sdk.common.DeviceManager;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.common.MACAddress;
import com.neuronrobotics.sdk.common.RpcEncapsulation;
import com.neuronrobotics.sdk.common.device.server.BowlerAbstractDeviceServerNamespace;
import com.neuronrobotics.sdk.common.device.server.BowlerAbstractServer;
import com.neuronrobotics.sdk.common.device.server.IBowlerCommandProcessor;
import com.neuronrobotics.sdk.network.BowlerTCPClient;
import com.neuronrobotics.sdk.network.UDPBowlerConnection;
public class TestServer {
private TestServer() {
}
public static void main(String[] args) throws Exception {
class SampleBowlerServer extends BowlerAbstractServer {
BowlerAbstractDeviceServerNamespace ns = new BowlerAbstractDeviceServerNamespace(
getMacAddress(), "test.thingy.*;0.3;;") {
};
public SampleBowlerServer() {
super(new MACAddress());
ns.addRpc(new RpcEncapsulation(ns.getNamespaceIndex(), ns
.getNamespace(), "test", BowlerMethod.GET,
new BowlerDataType[] { BowlerDataType.I32,
BowlerDataType.I32, BowlerDataType.I32 },// send 3
// integers
BowlerMethod.POST, new BowlerDataType[] {
BowlerDataType.I32, BowlerDataType.I32,
BowlerDataType.I32 }, // get 3 integers back
new IBowlerCommandProcessor() {
public Object[] process(Object[] data) {
for (int i = 0; i < data.length; i++) {
System.out.println("Server Got # " + data[i]);
}
return new Object[] { 37,42, 999999};
}
}));
addBowlerDeviceServerNamespace(ns);
Log.info("Starting UDP");
try {
startNetworkServer(1865);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// starts the UDP server
// this also starts tcp server on port+1, in this case 1866
}
}
class SampleBowlerClient extends BowlerAbstractDevice {
public void runCommand() {
Object[] args = send("test.thingy.*;0.3;;", BowlerMethod.GET, "test",
new Object[] { 36, 83, 13 });// send some numbers
for (int i = 0; i < args.length; i++) {
System.out.println("Client Received # " + args[i]);
}
}
@Override
public void onAsyncResponse(BowlerDatagram data) {
}// no async in this demo
}
SampleBowlerClient client = new SampleBowlerClient();
//client.setConnection(new UDPBowlerConnection(InetAddress.getByName("127.0.0.1"), 1865));
// Alternately you can use the tcp connection
client.setConnection( new BowlerTCPClient("127.0.0.1",1866));
DeviceManager.addConnection(client, "sampleClient");
client.runCommand();// runs our test command from client to server and
// back
}
}

View File

@@ -0,0 +1,94 @@
package com.neuronrobotics.bowlerstudio;
import java.io.File;
import java.io.IOException;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.bowlerstudio.assets.StudioBuildInfo;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.sdk.util.ThreadUtil;
public class Tutorial {
private static int WEBSERVER_PORT = 37037;
private static String HOME_Local_URL_ROOT = null;
private static String HOME_URL =null;
private static String HOME_Local_URL = null;
private static boolean doneLoadingTutorials;
private static Boolean startedLoadingTutorials = false;
public static String getHomeUrl() throws Exception{
File i=null;
do{
i= ScriptingEngine.fileFromGit(
(String)ConfigurationDatabase.getObject("BowlerStudioConfigs", "tutorialSource",
"https://github.com/CommonWealthRobotics/CommonWealthRobotics.github.io.git"),
(String)ConfigurationDatabase.getObject("BowlerStudioConfigs", "tutorialBranch",
"master"), // the default branch is source, so this needs to
// be specified
"index.html");
}while(!i.exists());
HOME_Local_URL_ROOT=(String)ConfigurationDatabase.getObject("BowlerStudioConfigs", "tutorialBaseUrl",
"/BowlerStudio/Welcome-To-BowlerStudio/");
File indexOfTutorial=i;
if(!doneLoadingTutorials ){
if(!startedLoadingTutorials){
//synchronized(startedLoadingTutorials){
startedLoadingTutorials = true;
//}
new Thread(){
public void run(){
Thread.currentThread().setUncaughtExceptionHandler(new IssueReportingExceptionHandler());
//HOME_Local_URL = indexOfTutorial.toURI().toString().replace("file:/", "file:///");
Server server = new Server(WEBSERVER_PORT);
ServerConnector connector = new ServerConnector(server);
server.setConnectors(new Connector[] { connector });
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
System.out.println("Serving "+ indexOfTutorial.getParent());
resource_handler.setResourceBase(indexOfTutorial.getParent());
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
try {
server.start();
WEBSERVER_PORT= connector.getLocalPort();
HOME_Local_URL = "http://localhost:"+WEBSERVER_PORT+HOME_Local_URL_ROOT;
doneLoadingTutorials = true;
server.join();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}.start();
}
long start = System.currentTimeMillis();
// wait up to 30 seconds for menue to load, then fail over to the web version
while(! doneLoadingTutorials && (System.currentTimeMillis()-start<3000)){
ThreadUtil.wait(100);
}
if(doneLoadingTutorials )
HOME_URL = HOME_Local_URL;
else
HOME_URL= "http://CommonWealthRobotics.com"+HOME_Local_URL_ROOT;
}
return HOME_URL;
}
}

View File

@@ -0,0 +1,187 @@
package com.neuronrobotics.bowlerstudio.assets;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import com.neuronrobotics.bowlerstudio.BowlerStudio;
import com.neuronrobotics.bowlerstudio.scripting.GithubLoginFX;
import com.neuronrobotics.bowlerstudio.tabs.DyIOPanel;
import com.neuronrobotics.bowlerstudio.tabs.DyIOchannelWidget;
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
import com.neuronrobotics.sdk.dyio.DyIOChannelMode;
import javafx.fxml.FXMLLoader;
import javafx.scene.image.Image;
public class BowlerStudioResourceFactory {
private static final Map<DyIOChannelMode, Image> lookup = new HashMap<>();
private static Image chanHighlight;
private static Image chanUpdate;
private static Image chanDefault;
private static final ArrayList<FXMLLoader> fxmlLoaders = new ArrayList<>();
private static FXMLLoader mainPanel;
private static FXMLLoader githubLogin;
private static FXMLLoader mainControllerPanel;
private static boolean loaded=false;
private BowlerStudioResourceFactory() {
}
public static FXMLLoader getLoader(int channelIndex) {
return fxmlLoaders.get(channelIndex);
}
@SuppressWarnings("restriction")
public static void load() throws Exception {
if(loaded)
return;
loaded=true;
try {
BowlerStudio.renderSplashFrame( 94,"Loading DyIO");
mainPanel = AssetFactory.loadLayout("layout/DyIOPanel.fxml");
//mainPanel.setController(new DyIOPanel());
mainPanel.setClassLoader(DyIOPanel.class.getClassLoader());
BowlerStudio.renderSplashFrame( 95,"Loading GitHub");
githubLogin = AssetFactory.loadLayout("layout/githublogin.fxml");
//githubLogin.setController(new GithubLoginFX());
githubLogin.setClassLoader(GithubLoginFX.class.getClassLoader());
} catch (InvalidRemoteException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (TransportException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (GitAPIException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (DyIOChannelMode cm : EnumSet.allOf(DyIOChannelMode.class)) {
Image image;
//
try {
image = AssetFactory.loadAsset("dyio/icon-" + cm.toSlug() + ".png");
} catch (NullPointerException e) {
image = AssetFactory.loadAsset("dyio/icon-off.png");
}
lookup.put(cm, image);
}
setChanHighlight(AssetFactory.loadAsset("dyio/channel-highlight.png"));
setChanDefault(AssetFactory.loadAsset("dyio/channel-default.png"));
setChanUpdate(AssetFactory.loadAsset("dyio/channel-update.png"));
for (int i = 0; i < 24; i++) {
// generate the control widgets
FXMLLoader fxmlLoader;
try {
fxmlLoader = AssetFactory.loadLayout("layout/DyIOChannelContorol.fxml", true);
//fxmlLoader.setController(new DyIOchannelWidget());
fxmlLoader.setClassLoader(DyIOchannelWidget.class.getClassLoader());
try {
fxmlLoader.load();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
fxmlLoaders.add(fxmlLoader);
} catch (InvalidRemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransportException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GitAPIException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
mainPanel.load();
} catch (IOException ex) {
Logger.getLogger(BowlerStudio.class.getName()).log(Level.SEVERE, null, ex);
}
try {
githubLogin.load();
} catch (IOException e) {
Logger.getLogger(BowlerStudio.class.getName()).log(Level.SEVERE, null, e);
}
}// stub to force a load from the static in a specific thread
public static Image getModeImage(DyIOChannelMode mode) {
return lookup.get(mode);
}
public static Image getChanHighlight() {
return chanHighlight;
}
public static void setChanHighlight(Image chanHighlight) {
BowlerStudioResourceFactory.chanHighlight = chanHighlight;
}
public static Image getChanUpdate() {
return chanUpdate;
}
public static void setChanUpdate(Image chanUpdate) {
BowlerStudioResourceFactory.chanUpdate = chanUpdate;
}
public static Image getChanDefault() {
return chanDefault;
}
public static void setChanDefault(Image chanDefault) {
BowlerStudioResourceFactory.chanDefault = chanDefault;
}
public static FXMLLoader getMainPanel() {
return mainPanel;
}
public static void setMainPanel(FXMLLoader mainPanel) {
BowlerStudioResourceFactory.mainPanel = mainPanel;
}
public static FXMLLoader getGithubLogin() {
return githubLogin;
}
public static void setGithubLogin(FXMLLoader githubLogin) {
BowlerStudioResourceFactory.githubLogin = githubLogin;
}
public static FXMLLoader getMainControllerPanel() {
return mainControllerPanel;
}
public static void setMainControllerPanel(FXMLLoader mainControllerPanel) {
BowlerStudioResourceFactory.mainControllerPanel = mainControllerPanel;
}
}

View File

@@ -0,0 +1,45 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.util.ArrayList;
public abstract class AbstractGameController {
private ArrayList<IGameControllerUpdateListener> listeners = new ArrayList<>();
public void addIGameControllerUpdateListener(IGameControllerUpdateListener l){
if(!listeners.contains(l))
listeners.add(l);
}
public void removeIGameControllerUpdateListener(IGameControllerUpdateListener l){
if(listeners.contains(l))
listeners.remove(l);
}
public void clearIGameControllerUpdateListener(){
listeners.clear();
}
protected void fireGameControllerUpdate(){
}
public abstract double getControls0Plus();
public abstract double getControls0Minus();
public abstract double getControls1Plus();
public abstract double getControls1Minus();
public abstract double getControls2Plus();
public abstract double getControls2Minus();
public abstract double getControls3Plus();
public abstract double getControls3Minus();
public abstract double getNavUp();
public abstract double getNavDown();
public abstract double getNavLeft();
public abstract double getNavRight();
public abstract double getActionLeft();
public abstract double getActionRight();
}

View File

@@ -0,0 +1,78 @@
package com.neuronrobotics.bowlerstudio.creature;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import javafx.scene.Group;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
public class AdjustbodyMassWidget extends Group {
private MobileBase device;
private MobileBaseCadManager manager;
double textToNum(TextField mass) {
try {
return Double.parseDouble(mass.getText().trim());
}catch(Throwable t) {
mass.setText("0");
return 0;
}
}
public AdjustbodyMassWidget(MobileBase device) {
this.device = device;
manager = MobileBaseCadManager.get(device);
GridPane pane = new GridPane();
TextField mass = new TextField(CreatureLab.getFormatted(device.getMassKg()));
mass.setOnAction(event -> {
device.setMassKg(textToNum(mass));
if(manager!=null)manager.generateCad();
});
TransformNR currentCentroid = device.getCenterOfMassFromCentroid();
TextField massx = new TextField(CreatureLab.getFormatted(currentCentroid.getX()));
massx.setOnAction(event -> {
currentCentroid.setX(textToNum(massx));
device.setCenterOfMassFromCentroid(currentCentroid);
;
if(manager!=null)manager.generateCad();
});
TextField massy = new TextField(CreatureLab.getFormatted(currentCentroid.getY()));
massy.setOnAction(event -> {
currentCentroid.setY(textToNum(massy));
device.setCenterOfMassFromCentroid(currentCentroid);
;
if(manager!=null)manager.generateCad();
});
TextField massz = new TextField(CreatureLab.getFormatted(currentCentroid.getZ()));
massz.setOnAction(event -> {
currentCentroid.setZ(textToNum(massz));
device.setCenterOfMassFromCentroid(currentCentroid);
;
if(manager!=null)manager.generateCad();
});
pane.add(new Text("Mass"), 0, 0);
pane.add(mass, 1, 0);
pane.add(new Text("Mass Centroid x"), 0, 1);
pane.add(massx, 1, 1);
pane.add(new Text("Mass Centroid y"), 0, 2);
pane.add(massy, 1, 2);
pane.add(new Text("Mass Centroid z"), 0, 3);
pane.add(massz, 1,3);
getChildren().add(pane);
}
}

View File

@@ -0,0 +1,203 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import com.neuronrobotics.replicator.driver.BowlerBoardDevice;
import com.neuronrobotics.replicator.driver.NRPrinter;
public class CartesianPanel extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
private BowlerBoardDevice delt;
private NRPrinter printer;
private JLabel jLabel0;
private JLabel jLabel1;
private JLabel jLabel2;
private JLabel jLabel3;
private JLabel jLabel4;
private JTextField jTextField0;
private JTextField jTextField1;
private JTextField jTextField2;
private JTextField jTextField3;
private JTextField jTextField4;
private JButton jButton0;
public void setDevices(BowlerBoardDevice delt, NRPrinter printer) {
this.delt = delt;
this.printer = printer;
}
private void initComponents() {
setLayout(new GridLayout(6, 4));
add(getJLabel0());
add(getJTextField0());
add(getJLabel1());
add(getJTextField1());
add(getJLabel2());
add(getJTextField2());
add(getJLabel3());
add(getJTextField3());
add(getJLabel4());
add(getJTextField4());
add(getJButton0());
setSize(358, 291);
}
private JButton getJButton0() {
if (jButton0 == null) {
jButton0 = new JButton();
jButton0.setText("Update Robot");
}
return jButton0;
}
private JTextField getJTextField4() {
if (jTextField4 == null) {
jTextField4 = new JTextField();
jTextField4.setText("tempTarget");
jTextField4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jTextField4ActionActionPerformed(event);
}
});
}
return jTextField4;
}
private JTextField getJTextField3() {
if (jTextField3 == null) {
jTextField3 = new JTextField();
jTextField3.setText("extrudeTarget");
jTextField3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jTextField3ActionActionPerformed(event);
}
});
}
return jTextField3;
}
private JTextField getJTextField2() {
if (jTextField2 == null) {
jTextField2 = new JTextField();
jTextField2.setText("ztarget");
jTextField2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jTextField2ActionActionPerformed(event);
}
});
}
return jTextField2;
}
private JTextField getJTextField1() {
if (jTextField1 == null) {
jTextField1 = new JTextField();
jTextField1.setText("ytarget");
jTextField1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jTextField1ActionActionPerformed(event);
}
});
}
return jTextField1;
}
private JTextField getJTextField0() {
if (jTextField0 == null) {
jTextField0 = new JTextField();
jTextField0.setText("xtarget");
jTextField0.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jTextField0ActionActionPerformed(event);
}
});
}
return jTextField0;
}
private JLabel getJLabel4() {
if (jLabel4 == null) {
jLabel4 = new JLabel();
jLabel4.setText("Temp");
}
return jLabel4;
}
private JLabel getJLabel3() {
if (jLabel3 == null) {
jLabel3 = new JLabel();
jLabel3.setText("Extrude");
}
return jLabel3;
}
private JLabel getJLabel2() {
if (jLabel2 == null) {
jLabel2 = new JLabel();
jLabel2.setText("Z");
}
return jLabel2;
}
private JLabel getJLabel1() {
if (jLabel1 == null) {
jLabel1 = new JLabel();
jLabel1.setText("Y");
}
return jLabel1;
}
private JLabel getJLabel0() {
if (jLabel0 == null) {
jLabel0 = new JLabel();
jLabel0.setText("X");
}
return jLabel0;
}
public CartesianPanel() {
initComponents();
}
private void jTextField4ActionActionPerformed(ActionEvent event) {
//set temp
}
private void jTextField3ActionActionPerformed(ActionEvent event) {
//set extrude
}
private void jTextField2ActionActionPerformed(ActionEvent event) {
//set z
}
private void jTextField1ActionActionPerformed(ActionEvent event) {
//set y
}
private void jTextField0ActionActionPerformed(ActionEvent event) {
// set x
}
}

View File

@@ -0,0 +1,297 @@
package com.neuronrobotics.bowlerstudio.creature;
import com.neuronrobotics.bowlerstudio.BowlerStudio;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.BowlerStudioModularFrame;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
import com.neuronrobotics.bowlerstudio.util.FileWatchDeviceWrapper;
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.DhInverseSolver;
import com.neuronrobotics.sdk.addons.kinematics.IDriveEngine;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.HBox;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import javafx.scene.control.ToggleButton;
public class CreatureLab extends AbstractBowlerStudioTab implements IOnEngineeringUnitsChange {
private BowlerAbstractDevice pm;
private IDriveEngine defaultDriveEngine;
// private DhInverseSolver defaultDHSolver;
private Menu localMenue;
private ProgressIndicator pi;
private MobileBaseCadManager baseManager;
private CheckBox autoRegen = new CheckBox("Auto-Regnerate CAD");
Parent root;
private BowlerJInputDevice gameController = null;
CreatureLabControlsTab tab = new CreatureLabControlsTab();;
@Override
public void onTabClosing() {
baseManager.onTabClosing();
}
@Override
public String[] getMyNameSpaces() {
// TODO Auto-generated method stub
return new String[0];
}
@SuppressWarnings({ "restriction", "restriction" })
@Override
public void initializeUI(BowlerAbstractDevice pm) {
setGraphic(AssetFactory.loadIcon("CreatureLab-Tab.png"));
this.pm = pm;
autoRegen.setSelected(true);
autoRegen.setOnAction(event -> {
baseManager.setAutoRegen(autoRegen.isSelected());
if (autoRegen.isSelected()) {
generateCad();
}
});
// TODO Auto-generated method stub
setText(pm.getScriptingName());
try {
ScriptingEngine.setAutoupdate(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
MobileBase device = (MobileBase) pm;
// Button save = new Button("Save Configuration");
FXMLLoader loader;
try {
loader = AssetFactory.loadLayout("layout/CreatureLabControlsTab.fxml", true);
Platform.runLater(() -> {
loader.setController(tab);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
try {
root = loader.load();
finishLoading(device);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
private void finishLoading(MobileBase device) {
TreeView<String> tree = null;
TreeItem<String> rootItem = null;
try {
rootItem = new TreeItem<String>(device.getScriptingName(), AssetFactory.loadIcon("creature.png"));
} catch (Exception e) {
rootItem = new TreeItem<String>(device.getScriptingName());
}
tree = new TreeView<>(rootItem);
AnchorPane treebox1 = tab.getTreeBox();
treebox1.getChildren().clear();
treebox1.getChildren().add(tree);
AnchorPane.setTopAnchor(tree, 0.0);
AnchorPane.setLeftAnchor(tree, 0.0);
AnchorPane.setRightAnchor(tree, 0.0);
AnchorPane.setBottomAnchor(tree, 0.0);
rootItem.setExpanded(true);
HashMap<TreeItem<String>, Runnable> callbackMapForTreeitems = new HashMap<>();
HashMap<TreeItem<String>, Group> widgetMapForTreeitems = new HashMap<>();
try {
MobleBaseMenueFactory.load(device, tree, rootItem, callbackMapForTreeitems, widgetMapForTreeitems, this);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tree.setPrefWidth(325);
tree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
JogWidget walkWidget = new JogWidget(device);
tree.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
@Override
public void changed(ObservableValue<?> observable, Object oldValue, Object newValue) {
@SuppressWarnings("unchecked")
TreeItem<String> treeItem = (TreeItem<String>) newValue;
new Thread() {
public void run() {
if (walkWidget.getGameController() != null)
setGameController(walkWidget.getGameController());
if (callbackMapForTreeitems.get(treeItem) != null) {
callbackMapForTreeitems.get(treeItem).run();
}
if (widgetMapForTreeitems.get(treeItem) != null) {
Platform.runLater(() -> {
tab.getControlsBox().getChildren().clear();
Group g = widgetMapForTreeitems.get(treeItem);
tab.getControlsBox().getChildren().add(g);
AnchorPane.setTopAnchor(g, 0.0);
AnchorPane.setLeftAnchor(g, 0.0);
AnchorPane.setRightAnchor(g, 0.0);
AnchorPane.setBottomAnchor(g, 0.0);
});
} else {
Platform.runLater(() -> {
tab.getControlsBox().getChildren().clear();
});
BowlerStudio.select(device);
walkWidget.setGameController(getController());
}
}
}.start();
}
});
VBox progress = new VBox(10);
final ToggleGroup group = new ToggleGroup();
RadioButton rb1 = new RadioButton();
rb1.setToggleGroup(group);
rb1.setSelected(true);
rb1.setOnAction(event -> {
setCadMode(false);
});
RadioButton rb2 = new RadioButton();
rb2.setToggleGroup(group);
rb2.fire();
rb2.setOnAction(event -> {
setCadMode(true);
});
HBox radioOptions = new HBox(10);
radioOptions.getChildren().addAll(new Label("Cad"), rb1, rb2, new Label("Config"));
pi = new ProgressIndicator(0);
baseManager = MobileBaseCadManager.get(device, BowlerStudioController.getMobileBaseUI());
pi.progressProperty().bindBidirectional(baseManager.getProcesIndictor());
HBox progressIndicatorPanel = new HBox(10);
progressIndicatorPanel.getChildren().addAll(new Label("Cad Progress:"), pi);
progress.getChildren().addAll(progressIndicatorPanel, autoRegen, radioOptions);
progress.setStyle("-fx-background-color: #FFFFFF;");
progress.setOpacity(.7);
// progress.setMinHeight(150);
progress.setPrefSize(325, 150);
tab.setOverlayTop(progress);
tab.setOverlayTopRight(walkWidget);
BowlerStudioModularFrame.getBowlerStudioModularFrame().showCreatureLab();
setCadMode(true);// start the UI in config mode
generateCad();
setContent(root);
}
private void setCadMode(boolean mode) {
new Thread(() -> {
baseManager.setConfigurationViewerMode(mode);
baseManager.setAutoRegen(autoRegen.isSelected());
if (autoRegen.isSelected()) {
generateCad();
}
}).start();
}
public void generateCad() {
// new Exception().printStackTrace();
baseManager.generateCad();
}
@Override
public void onTabReOpening() {
baseManager.setCadScript(baseManager.getCadScript());
try {
if (autoRegen.isSelected())
generateCad();
} catch (Exception ex) {
}
}
public static String getFormatted(double value) {
return String.format("%4.3f%n", (double) value);
}
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
// TODO Auto-generated method stub
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
if (autoRegen.isSelected())
generateCad();
}
public BowlerJInputDevice getController() {
return getGameController();
}
public BowlerJInputDevice getGameController() {
return gameController;
}
public void setGameController(BowlerJInputDevice bowlerJInputDevice) {
this.gameController = bowlerJInputDevice;
}
public void setGitDhEngine(String gitsId, String file, DHParameterKinematics dh) {
MobileBaseLoader.get(baseManager.getMobileBase()).setDefaultDhParameterKinematics(dh);
}
public void setGitCadEngine(String gitsId, String file, MobileBase device)
throws InvalidRemoteException, TransportException, GitAPIException, IOException {
baseManager.setGitCadEngine(gitsId, file, device);
}
public void setGitCadEngine(String gitsId, String file, DHParameterKinematics dh)
throws InvalidRemoteException, TransportException, GitAPIException, IOException {
baseManager.setGitCadEngine(gitsId, file, dh);
}
public void setGitWalkingEngine(String git, String file, MobileBase device) {
MobileBaseLoader.get(baseManager.getMobileBase()).setGitWalkingEngine(git, file, device);
}
}

View File

@@ -0,0 +1,76 @@
package com.neuronrobotics.bowlerstudio.creature;
import javafx.fxml.FXML;
import javafx.scene.control.TreeView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
public class CreatureLabControlsTab {
@FXML
private AnchorPane walkingBox;
@FXML
private AnchorPane controlsBox;
@FXML
private AnchorPane progressBar;
@FXML
private AnchorPane treeBox;
public AnchorPane getWalkingBox() {
return walkingBox;
}
public void setWalkingBox(AnchorPane walkingBox) {
this.walkingBox = walkingBox;
}
public AnchorPane getControlsBox() {
return controlsBox;
}
public void setControlsBox(AnchorPane controlsBox) {
this.controlsBox = controlsBox;
}
// public AnchorPane getProgressBar() {
// return progressBar;
// }
public void setProgressBar(AnchorPane progressBar) {
this.progressBar = progressBar;
}
public AnchorPane getTreeBox() {
return treeBox;
}
public void setTreeBox(AnchorPane treeBox) {
this.treeBox = treeBox;
}
public void setOverlayTop(VBox progress) {
// TODO Auto-generated method stub
progressBar.getChildren().clear();
progressBar.getChildren().add(progress);
AnchorPane.setTopAnchor(progress, 0.0);
AnchorPane.setLeftAnchor(progress, 0.0);
AnchorPane.setRightAnchor(progress, 0.0);
AnchorPane.setBottomAnchor(progress, 0.0);
}
public void setOverlayTopRight(JogWidget walkWidget) {
// TODO Auto-generated method stub
walkingBox.getChildren().clear();
walkingBox.getChildren().add(walkWidget);
AnchorPane.setTopAnchor(walkWidget, 0.0);
AnchorPane.setLeftAnchor(walkWidget, 0.0);
AnchorPane.setRightAnchor(walkWidget, 0.0);
AnchorPane.setBottomAnchor(walkWidget, 0.0);
}
}

View File

@@ -0,0 +1,194 @@
package com.neuronrobotics.bowlerstudio.creature;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.CreatureLab3dController;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.physics.MobileBasePhysicsManager;
import com.neuronrobotics.bowlerstudio.physics.PhysicsEngine;
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.addons.kinematics.imu.IMUUpdate;
import com.neuronrobotics.sdk.addons.kinematics.imu.IMUUpdateListener;
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
import com.neuronrobotics.sdk.util.ThreadUtil;
import eu.mihosoft.vrl.v3d.CSG;
import javafx.application.Platform;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class CreaturePhysicsWidget extends GridPane implements IMUUpdateListener {
Button runstop = new Button("Run", AssetFactory.loadIcon("Run.png"));
Button pauseresume = new Button("Pause", AssetFactory.loadIcon("Pause.png"));
Button step = new Button("Step", AssetFactory.loadIcon("Step.png"));
TextField msLoopTime =new TextField("20") ;
int msLoopTimeInt =0;
private boolean run=false;
private boolean takestep=false;
private boolean pause=false;
Thread physicsThread =null;
private Set<CSG> oldParts=null;
private MobileBase base;
@SuppressWarnings("restriction")
public CreaturePhysicsWidget(MobileBase base){
this.base = base;
base.addConnectionEventListener(new IDeviceConnectionEventListener() {
@Override
public void onDisconnect(BowlerAbstractDevice arg0) {
Platform.runLater(()->{
stop();
});
}
@Override
public void onConnect(BowlerAbstractDevice arg0) {}
});
add(runstop,0,0);
add(pauseresume,1,0);
add(step,2,0);
add(new Label("MS loop"),3,0);
add(msLoopTime,4,0);
pauseresume.setDisable(true);
step.setDisable(true);
pauseresume.setOnAction(event->{
if(!isPause()){
pauseresume.setGraphic(AssetFactory.loadIcon("Resume.png"));
pauseresume.setText("Resume");
step.setDisable(false);
}else{
pauseresume.setGraphic(AssetFactory.loadIcon("Pause.png"));
pauseresume.setText("Pause");
step.setDisable(true);
}
setPause(!isPause());
});
step.setOnAction(event->{
setTakestep(true);
});
runstop.setOnAction(event->{
if(isRun()){
stop();
// new Thread(){
// public void run(){
// ThreadUtil.wait(50);
// System.gc();// clean up any objects created by the physics engine
// }
// }.start();
}else{
//System.gc();// clean up any objects created by the physics engine
runstop.setGraphic(AssetFactory.loadIcon("Stop.png"));
runstop.setText("Stop");
msLoopTime.setDisable(true);
pauseresume.setDisable(false);
base.getImu().addvirtualListeners(this);
new Thread(){
public void run(){
while(MobileBaseCadManager.get( base).getProcesIndictor().get()<1){
ThreadUtil.wait(10);
}
HashMap<LinkConfiguration, ArrayList<CSG>> simplecad = MobileBaseCadManager.getSimplecad(base) ;
ArrayList<CSG> baseCad=MobileBaseCadManager.getBaseCad(base);
base.DriveArc(new TransformNR(.01,0,0,new RotationNR()), 0);
PhysicsEngine.get().clear();
MobileBasePhysicsManager m =new MobileBasePhysicsManager(base, baseCad, simplecad);
//BowlerStudio3dEngine threeD = BowlerStudioController.getBowlerStudio().getJfx3dmanager();
oldParts = CreatureLab3dController.getEngine().getCsgMap().keySet();
BowlerStudioController.setCsg(PhysicsEngine.get().getCsgFromEngine());
int loopTiming = (int) Double.parseDouble(msLoopTime.getText());
physicsThread = new Thread(){
public void run(){
try{
while(!Thread.interrupted() && isRun()){
while(!Thread.interrupted() && isPause() && isTakestep()==false){
ThreadUtil.wait(loopTiming);
}
setTakestep(false);
long start = System.currentTimeMillis();
PhysicsEngine.get().stepMs(loopTiming);
long took = (System.currentTimeMillis() - start);
if (took < loopTiming)
ThreadUtil.wait((int) (loopTiming - took)/4);
else{
if(took>loopTiming*2)
System.out.println("ERROR Real time broken by: "+took+"ms");
}
}
PhysicsEngine.get().clear();
m.clear();
}catch(Exception e){
e.printStackTrace();
}
}
};
physicsThread.start();
}
}.start();
}
setRun(!isRun());
});
}
private void stop() {
runstop.setGraphic(AssetFactory.loadIcon("Run.png"));
runstop.setText("Run");
if(physicsThread!=null)
physicsThread.interrupt();
msLoopTime.setDisable(false);
pauseresume.setDisable(true);
if(oldParts!=null){
ArrayList<CSG>oldp=new ArrayList<>();
for(CSG c:oldParts){
oldp.add(c);
}
BowlerStudioController.setCsg(oldp);
oldParts=null;
}
base.getImu().removevirtualListeners(this);
}
public boolean isTakestep() {
return takestep;
}
public void setTakestep(boolean takestep) {
this.takestep = takestep;
}
public boolean isPause() {
return pause;
}
public void setPause(boolean pause) {
this.pause = pause;
}
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
@Override
public void onIMUUpdate(IMUUpdate arg0) {
// System.err.println("X = "+arg0.getxAcceleration()+
// " Y = "+arg0.getyAcceleration()+
// " Z = "+arg0.getzAcceleration()+
// " rX = "+arg0.getRotxAcceleration()+
// " rY = "+arg0.getRotyAcceleration()+
// " rZ = "+arg0.getRotzAcceleration()
//
// );
}
}

View File

@@ -0,0 +1,154 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.time.Duration;
import org.reactfx.util.FxTimer;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.DhLinkType;
import com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR;
import com.neuronrobotics.sdk.addons.kinematics.JointLimit;
import com.neuronrobotics.sdk.common.Log;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.text.Text;
@SuppressWarnings("restriction")
public class DHLinkWidget extends Group implements IJointSpaceUpdateListenerNR {
private AbstractKinematicsNR device;
private DHParameterKinematics dhdevice;
private int linkIndex;
private EngineeringUnitsSliderWidget setpoint;
private Button del;
public DHLinkWidget(int linkIndex, DHLink dhlink, AbstractKinematicsNR device2, Button del,IOnEngineeringUnitsChange externalListener, MobileBaseCadManager manager ) {
this.linkIndex = linkIndex;
this.device = device2;
if(DHParameterKinematics.class.isInstance(device2)){
dhdevice=(DHParameterKinematics)device2;
}
this.del = del;
AbstractLink abstractLink = device2.getAbstractLink(linkIndex);
TextField name = new TextField(abstractLink.getLinkConfiguration().getName());
name.setMaxWidth(100.0);
name.setOnAction(event -> {
abstractLink.getLinkConfiguration().setName(name.getText());
});
setpoint = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
// TODO Auto-generated method stub
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
double newAngleDegrees) {
try {
device2.setDesiredJointAxisValue(linkIndex, setpoint.getValue(), 2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
},
abstractLink.getMinEngineeringUnits(),
abstractLink.getMaxEngineeringUnits(),
device2.getCurrentJointSpaceVector()[linkIndex],
180,dhlink.getLinkType()==DhLinkType.ROTORY?"degrees":"mm");
final Accordion accordion = new Accordion();
if(dhdevice!=null)
accordion.getPanes().add(new TitledPane("Configure D-H", new DhSettingsWidget(dhdevice.getChain().getLinks().get(linkIndex),dhdevice,externalListener)));
accordion.getPanes().add(new TitledPane("Configure Link", new LinkConfigurationWidget(abstractLink.getLinkConfiguration(), device2.getFactory(),setpoint,manager)));
GridPane panel = new GridPane();
panel.getColumnConstraints().add(new ColumnConstraints(80)); // column 1 is 75 wide
panel.getColumnConstraints().add(new ColumnConstraints(30)); // column 1 is 75 wide
panel.getColumnConstraints().add(new ColumnConstraints(120)); // column 2 is 300 wide
panel.add( del,
0,
0);
panel.add( new Text("#"+linkIndex),
1,
0);
panel.add( name,
2,
0);
panel.add( setpoint,
3,
0);
panel.add( accordion,
2,
1);
getChildren().add(panel);
}
public void changed(ObservableValue<? extends Boolean> observableValue,
Boolean wasChanging,
Boolean changing) {
}
@Override
public void onJointSpaceUpdate(AbstractKinematicsNR source, double[] joints) {
Platform.runLater(()->{
try{
setpoint.setValue(joints[linkIndex]);
}catch(ArrayIndexOutOfBoundsException ex){
return;
}
});
}
@Override
public void onJointSpaceTargetUpdate(AbstractKinematicsNR source,
double[] joints) {
// TODO Auto-generated method stub
}
@Override
public void onJointSpaceLimit(AbstractKinematicsNR source, int axis,
JointLimit event) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,19 @@
package com.neuronrobotics.bowlerstudio.creature;
import javax.swing.JPanel;
import com.neuronrobotics.replicator.driver.NRPrinter;
import com.neuronrobotics.replicator.driver.StateBasedControllerConfiguration;
public abstract class DeviceSettingsBase extends JPanel {
private NRPrinter printer;
public DeviceSettingsBase(NRPrinter _printer){
printer = _printer;
}
public abstract StateBasedControllerConfiguration getStateBasedControllerSettings();
public abstract void setStateBasedControllerSettings(StateBasedControllerConfiguration _state);
}

View File

@@ -0,0 +1,287 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import eu.mihosoft.vrl.v3d.STL;
import java.nio.file.Path;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.util.ArrayList;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.util.FileWatchDeviceWrapper;
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
import com.neuronrobotics.nrconsole.util.GroovyFilter;
import com.neuronrobotics.nrconsole.util.XmlFilter;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.DHChain;
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.DhInverseSolver;
import com.neuronrobotics.sdk.addons.kinematics.IDriveEngine;
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.LinkFactory;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.util.IFileChangeListener;
import eu.mihosoft.vrl.v3d.CSG;
import eu.mihosoft.vrl.v3d.Cube;
import eu.mihosoft.vrl.v3d.Transform;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.FileChooser.ExtensionFilter;
public class DhChainWidget extends Group implements IDeviceConnectionEventListener{
private File currentFile=null;
private VBox links;
private VBox controls;
JogWidget jog = null;
private AbstractKinematicsNR device;
private DHParameterKinematics dhdevice=null;
private MobileBase mbase=null;
private MobileBaseCadManager manager=null;
private File kinematicsFile;
private ArrayList<DHLinkWidget> widgets = new ArrayList<>();
private IOnEngineeringUnitsChange externalListener;
public DhChainWidget(AbstractKinematicsNR device2,IOnEngineeringUnitsChange externalListener){
this.device = device2;
this.externalListener = externalListener;
device.addConnectionEventListener(this);
if(DHParameterKinematics.class.isInstance(device2)){
dhdevice=(DHParameterKinematics)device2;
}
if(MobileBase.class.isInstance(device2)){
mbase=(MobileBase)device2;
manager=MobileBaseCadManager.get(mbase);
}
links = new VBox(20);
controls = new VBox(10);
jog = new JogWidget(device);
VBox advanced = new VBox(10);
Button save = new Button("Save Configuration");
Button add = new Button("Add Link");
Button refresh = new Button("Generate CAD");
Button kinematics = new Button("Set Kinematics");
kinematics.setOnAction(event -> {
new Thread(){
public void run(){
if(getKinematicsFile()==null)
setKinematicsFile(ScriptingEngine.getLastFile());
setKinematicsFile(FileSelectionFactory.GetFile(getKinematicsFile(),
new ExtensionFilter("Kinematics Script","*.groovy","*.java","*.txt")));
if (getKinematicsFile() == null) {
return;
}
setKinematics();
}
}.start();
});
save.setOnAction(event -> {
new Thread(){
public void run(){
File last = FileSelectionFactory.GetFile(currentFile==null?
ScriptingEngine.getWorkspace():
new File(ScriptingEngine.getWorkspace().getAbsolutePath()+"/"+currentFile.getName()),
new ExtensionFilter("MobileBase XML","*.xml","*.XML"));
if (last != null) {
try {
Files.write(Paths.get(last.getAbsolutePath()),device.getXml().getBytes() );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
});
add.setOnAction(event -> {
LinkConfiguration newLink = new LinkConfiguration();
if(dhdevice!=null)dhdevice.addNewLink(newLink,new DHLink(0, 0, 0, 0));
onTabReOpening();
});
refresh.setOnAction(event -> {
onTabReOpening();
});
advanced.getChildren().add(new TransformWidget("Base to Global",
device.getFiducialToGlobalTransform(),new IOnTransformChange() {
@Override
public void onTransformFinished(TransformNR newTrans) {
// TODO Auto-generated method stub
}
@Override
public void onTransformChaging(TransformNR newTrans) {
Log.debug("Base to Global"+newTrans.toString());
device.setGlobalToFiducialTransform(newTrans);
device.getCurrentTaskSpaceTransform();
}
}
));
advanced.getChildren().add(save);
advanced.getChildren().add(add);
advanced.getChildren().add(refresh);
advanced.getChildren().add(kinematics);
Accordion advancedPanel = new Accordion();
advancedPanel.getPanes().add(new TitledPane("Advanced Options", advanced));
controls.getChildren().add(jog);
if(mbase==null){
controls.getChildren().add(advancedPanel);
controls.getChildren().add(new TransformWidget("Place Limb",
device.getRobotToFiducialTransform(), new IOnTransformChange() {
@Override
public void onTransformFinished(TransformNR newTrans) {
// Force a cad regeneration
externalListener.onSliderDoneMoving(null, 0);
}
@Override
public void onTransformChaging(TransformNR newTrans) {
Log.debug("Limb to base"+newTrans.toString());
device.setRobotToFiducialTransform(newTrans);
device.getCurrentTaskSpaceTransform();
//this calls the render update function attachec as the on jointspace update
double[] joint=device2.getCurrentJointSpaceVector();
dhdevice.getChain().getChain(joint);
Platform.runLater(()->dhdevice.onJointSpaceUpdate(dhdevice, joint));
}
}
));
}else{
controls.getChildren().add(kinematics);
}
onTabReOpening();
getChildren().add(new ScrollPane(links));
}
private void setKinematics(){
if(getKinematicsFile()!=null){
try{
if(mbase!=null){
mbase.setWalkingDriveEngine( (IDriveEngine) ScriptingEngine.inlineFileScriptRun(getKinematicsFile(), null));
}else if (dhdevice != null){
dhdevice.setInverseSolver((DhInverseSolver) ScriptingEngine.inlineFileScriptRun(getKinematicsFile(), null));
}
}catch(Exception e){
BowlerStudioController.highlightException(getKinematicsFile(), e);
}
}
}
public void onTabReOpening() {
for(DHLinkWidget wid:widgets){
device.removeJointSpaceUpdateListener(wid);
}
widgets.clear();
links.getChildren().clear();
ArrayList<DHLink> dhLinks=null;
if(dhdevice!=null)
dhLinks = dhdevice.getChain().getLinks();
links.getChildren().add(controls);
for(int i=0;i<device.getFactory().getLinkConfigurations().size();i++){
Log.warning("Adding Link Widget: "+i);
DHLink dh=null;
if(dhdevice!=null)
dh=dhLinks.get(i);
Button del = new Button("Delete");
final int linkIndex=i;
del.setOnAction(event -> {
LinkFactory factory =device.getFactory();
//remove the link listener while the number of links could chnage
factory.removeLinkListener(device);
if(dhdevice!=null){
DHChain chain = dhdevice.getDhChain() ;
chain.getLinks().remove(linkIndex);
factory.deleteLink(linkIndex);
//set the modified kinematics chain
dhdevice.setChain(chain);
}else{
factory.deleteLink(linkIndex);
}
//once the new link configuration is set up, re add the listener
factory.addLinkListener(device);
onTabReOpening();
});
DHLinkWidget w = new DHLinkWidget(i,
dh,
device,
del,
externalListener,manager);
widgets.add(w);
links.getChildren().add(w);
device.addJointSpaceListener(w);
}
//BowlerStudioController.setCsg(csg);
jog.home();
}
public File getKinematicsFile() {
return kinematicsFile;
}
public void setKinematicsFile(File kinematicsFile) {
FileWatchDeviceWrapper.watch(device, kinematicsFile, (fileThatChanged, event) -> {
try {
setKinematics();
} catch (Exception ex) {
ex.printStackTrace();
}
});
this.kinematicsFile = kinematicsFile;
}
@Override
public void onDisconnect(BowlerAbstractDevice source) {
}
@Override
public void onConnect(BowlerAbstractDevice source) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,24 @@
package com.neuronrobotics.bowlerstudio.creature;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.GridPane;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.Log;
public class DhLab extends CreatureLab {
@Override
public void initializeUI(BowlerAbstractDevice pm) {
super.initializeUI(pm);
setText("DH Lab");
}
}

View File

@@ -0,0 +1,108 @@
package com.neuronrobotics.bowlerstudio.creature;
import javafx.application.Platform;
import javafx.scene.control.Accordion;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.text.Text;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
public class DhSettingsWidget extends javafx.scene.Group implements IOnEngineeringUnitsChange {
private DHLink dhLink;
private EngineeringUnitsSliderWidget delta;
private EngineeringUnitsSliderWidget theta;
private EngineeringUnitsSliderWidget alpha;
private EngineeringUnitsSliderWidget radius;
private DHParameterKinematics device2;
private IOnEngineeringUnitsChange externalListener;
public DhSettingsWidget(DHLink dhLink,DHParameterKinematics device2,IOnEngineeringUnitsChange externalListener ){
this.dhLink = dhLink;
this.device2 = device2;
this.externalListener = externalListener;
delta= new EngineeringUnitsSliderWidget(this,
0,
200,
dhLink.getDelta(),
180," mm ");
theta = new EngineeringUnitsSliderWidget(this,
-180,
180,
Math.toDegrees(dhLink.getTheta()),
180,"degrees");
radius= new EngineeringUnitsSliderWidget(this,
0,
200,
dhLink.getRadius(),
180," mm ");
alpha = new EngineeringUnitsSliderWidget(this,
-180,
180,
Math.toDegrees(dhLink.getAlpha()),
180,"degrees");
GridPane gridpane = new GridPane();
gridpane.getColumnConstraints().add(new ColumnConstraints(120)); // column 1 is 75 wide
gridpane.getColumnConstraints().add(new ColumnConstraints(320)); // column 2 is 300 wide
gridpane.getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
gridpane.getRowConstraints().add(new RowConstraints(50)); //
gridpane.getRowConstraints().add(new RowConstraints(50)); //
gridpane.getRowConstraints().add(new RowConstraints(50)); //
gridpane.getRowConstraints().add(new RowConstraints(50)); //
gridpane.add(new Text("Delta (Height)"), 0, 0);
gridpane.add(delta, 1, 0);
gridpane.add(new Text("Radius (Length)"), 0, 1);
gridpane.add(radius, 1, 1);
gridpane.getColumnConstraints().add(new ColumnConstraints(120)); // column 1 is 75 wide
gridpane.getColumnConstraints().add(new ColumnConstraints(320)); // column 2 is 300 wide
gridpane.getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
gridpane.getRowConstraints().add(new RowConstraints(50)); //
gridpane.getRowConstraints().add(new RowConstraints(50)); //
gridpane.add(new Text("Theta"), 0, 2);
gridpane.add(theta, 1, 2);
gridpane.add(new Text("Alpha"), 0, 3);
gridpane.add(alpha, 1, 3);
getChildren().add(gridpane);
}
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
dhLink.setTheta(Math.toRadians(theta.getValue()));
dhLink.setAlpha(Math.toRadians(alpha.getValue()));
dhLink.setRadius(radius.getValue());
dhLink.setDelta(delta.getValue());
if(externalListener!=null)
externalListener.onSliderMoving(source, newAngleDegrees);
//this calls the render update function attachec as the on jointspace update
double[] joint=device2.getCurrentJointSpaceVector();
device2.getChain().getChain(joint);
Platform.runLater(()->device2.onJointSpaceUpdate(device2, joint));
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
double newAngleDegrees) {
// TODO Auto-generated method stub
if(externalListener!=null)
externalListener.onSliderDoneMoving(source, newAngleDegrees);
}
}

View File

@@ -0,0 +1,188 @@
package com.neuronrobotics.bowlerstudio.creature;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
@SuppressWarnings("restriction")
public class EngineeringUnitsSliderWidget extends GridPane implements ChangeListener<Number>{
private TextField setpointValue;
private Slider setpoint;
private IOnEngineeringUnitsChange listener;
private boolean intCast=false;
private boolean allowResize=true;
public EngineeringUnitsSliderWidget(IOnEngineeringUnitsChange listener,double min, double max, double current, double width, String units, boolean intCast){
this(listener, min, max, current, width, units);
this.intCast = intCast;
}
public EngineeringUnitsSliderWidget(IOnEngineeringUnitsChange listener, double current, double width, String units){
this(listener, current/2, current*2, current, width, units);
}
public EngineeringUnitsSliderWidget(IOnEngineeringUnitsChange listener, double min, double max, double current, double width, String units){
this.setListener(listener);
setpoint = new Slider();
if(min>max){
double minStart = min;
min=max;
max=minStart;
}
if(min>current)
min=current;
if(max<current)
max=current;
double range = Math.abs(max-min);
if(range<1){
min=min-100;
max = max+100;
range=200;
}
setpoint.setMin(min);
setpoint.setMax(max);
setpoint.setValue(current);
setpoint.setShowTickLabels(true);
setpoint.setShowTickMarks(true);
//setpoint.setSnapToTicks(true);
setpoint.setMajorTickUnit(range);
setpoint.setMinorTickCount(5);
//setpoint.setBlockIncrement(range/100);
setpointValue = new TextField(getFormatted(current));
setpointValue.setOnAction(event -> {
String txt =setpointValue.getText();
double val =Double.parseDouble(txt);
System.out.println("Setpoint Text changed to "+val);
Platform.runLater(() -> {
setValueLocal(val);
getListener().onSliderMoving(this,val);
getListener().onSliderDoneMoving(this,val);
});
});
setpoint.setMaxWidth(width);
setpoint.valueChangingProperty().addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
try {
double val =Double.parseDouble(setpointValue.getText());
System.err.println("Slider done moving = "+newValue);
if(!newValue)
getListener().onSliderDoneMoving(this,val);
}catch(java.lang.NumberFormatException ex) {
setValueLocal(0);
return;
}
});
setpoint.valueProperty().addListener(this);
String unitsString = "("+units+")";
getColumnConstraints().add(new ColumnConstraints(width+20)); // column 2 is 100 wide
getColumnConstraints().add(new ColumnConstraints(100)); // column 2 is 100 wide
getColumnConstraints().add(new ColumnConstraints(unitsString.length()*7)); // column 2 is 100 wide
add( setpoint,
0,
0);
add( setpointValue,
1,
0);
add( new Text(unitsString),
2,
0);
}
public void setUpperBound(double newBound){
setpoint.setMax(newBound);
}
public void setLowerBound(double newBound){
setpoint.setMin(newBound);
}
@Override
public void changed(ObservableValue<? extends Number> observable,
Number oldValue, Number newValue) {
updateValue();
}
private void updateValue(){
Platform.runLater(() -> {
setpointValue.setText(getFormatted(setpoint.getValue()));
getListener().onSliderMoving(this,setpoint.getValue());
});
}
public void setValue(double value){
Platform.runLater(() -> {
setValueLocal(value);
});
}
private void setValueLocal(double value) {
setpoint.valueProperty().removeListener(this);
double val = value;
if(val>setpoint.getMax()){
if(isAllowResize())
setpoint.setMax(val);
else
val=setpoint.getMax();
}if(val<setpoint.getMin()){
if(isAllowResize())
setpoint.setMin(val);
else
val=setpoint.getMin();
}
double range = Math.abs(setpoint.getMax()-setpoint.getMin());
setpoint.setMajorTickUnit(range);
setpoint.setValue(val);
setpointValue.setText(getFormatted(setpoint.getValue()));
setpoint.valueProperty().addListener(this);
//System.out.println("Setpoint changed to "+val);
}
public double getValue(){
return setpoint.getValue();
}
public String getFormatted(double value){
if(intCast)
return String.valueOf((int)value);
return String.format("%8.2f", (double)value);
}
public IOnEngineeringUnitsChange getListener() {
if(listener==null)
return new IOnEngineeringUnitsChange() {
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source,
double newAngleDegrees) {
// TODO Auto-generated method stub
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
double newAngleDegrees) {
// TODO Auto-generated method stub
}
};
return listener;
}
public void setListener(IOnEngineeringUnitsChange listener) {
this.listener = listener;
}
public boolean isAllowResize() {
return allowResize;
}
public void setAllowResize(boolean allowResize) {
this.allowResize = allowResize;
}
}

View File

@@ -0,0 +1,5 @@
package com.neuronrobotics.bowlerstudio.creature;
public interface IGameControllerUpdateListener {
public void onControllerUpdate(AbstractGameController source);
}

View File

@@ -0,0 +1,5 @@
package com.neuronrobotics.bowlerstudio.creature;
public interface IGistPromptCompletionListener {
public void done(String gitsId, String file);
}

View File

@@ -0,0 +1,6 @@
package com.neuronrobotics.bowlerstudio.creature;
public interface IOnEngineeringUnitsChange {
public void onSliderMoving(EngineeringUnitsSliderWidget source,double newAngleDegrees);
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,double newAngleDegrees);
}

View File

@@ -0,0 +1,8 @@
package com.neuronrobotics.bowlerstudio.creature;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
public interface IOnTransformChange {
public abstract void onTransformChaging(TransformNR newTrans);
public abstract void onTransformFinished(TransformNR newTrans);
}

View File

@@ -0,0 +1,39 @@
package com.neuronrobotics.bowlerstudio.creature;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
public class JogKinematicsDevice extends AbstractBowlerStudioTab{
@Override
public void onTabClosing() {
// TODO Auto-generated method stub
}
@Override
public String[] getMyNameSpaces() {
// TODO Auto-generated method stub
return new String[]{"bcs.cartesian.*"};
}
@Override
public void initializeUI(BowlerAbstractDevice pm) {
setContent(new JogWidget((AbstractKinematicsNR) pm));
setText("Jog Kinematics Devices");
onTabReOpening();
}
@Override
public void onTabReOpening() {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,197 @@
package com.neuronrobotics.bowlerstudio.creature;
/**
* Sample Skeleton for "jogTrainerWidget.fxml" Controller Class
* You can copy and paste this code into your favorite IDE
**/
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.stage.Modality;
import javafx.stage.Stage;
import net.java.games.input.Component;
import net.java.games.input.Event;
import java.net.URL;
import java.util.ResourceBundle;
public class JogTrainerWidget extends Application implements IJInputEventListener {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="linkMinus"
private ImageView linkMinus; // Value injected by FXMLLoader
@FXML // fx:id="linkPlus"
private ImageView linkPlus; // Value injected by FXMLLoader
@FXML // fx:id="linkval"
private TextField linkval; // Value injected by FXMLLoader
@FXML // fx:id="rotzMinus"
private ImageView rotzMinus; // Value injected by FXMLLoader
@FXML // fx:id="rotzPlus"
private ImageView rotzPlus; // Value injected by FXMLLoader
@FXML // fx:id="rzval"
private TextField rzval; // Value injected by FXMLLoader
@FXML // fx:id="xminus"
private ImageView xminus; // Value injected by FXMLLoader
@FXML // fx:id="xplus"
private ImageView xplus; // Value injected by FXMLLoader
// WARNING: fx:id="xval" cannot be injected: several objects share the same fx:id;
@FXML // fx:id="yminus"
private ImageView yminus; // Value injected by FXMLLoader
@FXML // fx:id="yplus"
private ImageView yplus; // Value injected by FXMLLoader
@FXML // fx:id="yval"
private TextField xval; // Value injected by FXMLLoader
@FXML // fx:id="yval"
private TextField yval; // Value injected by FXMLLoader
@FXML // fx:id="zminus"
private ImageView zminus; // Value injected by FXMLLoader
@FXML // fx:id="zplus"
private ImageView zplus; // Value injected by FXMLLoader
@FXML // fx:id="zval"
private TextField zval; // Value injected by FXMLLoader
private Stage primaryStage;
private BowlerJInputDevice gameController;
private String paramsKey;
private TextField selected=null;
public JogTrainerWidget(BowlerJInputDevice gameController) {
this.gameController = gameController;
paramsKey = gameController.getController().getName();
gameController.addListeners(this);
}
// Handler for Button[Button[id=null, styleClass=button]] onAction
@FXML
void configure(ActionEvent event) {
primaryStage.close();
new Thread(()->{
//linkval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogLink", "x"));
ConfigurationDatabase.setObject(paramsKey, "jogLink", linkval.getText());
// xval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinx", "x"));
ConfigurationDatabase.setObject(paramsKey, "jogKinx", xval.getText());
//yval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKiny", "y"));
ConfigurationDatabase.setObject(paramsKey, "jogKiny", yval.getText());
//zval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinz", "rz"));
ConfigurationDatabase.setObject(paramsKey, "jogKinz", zval.getText());
//rzval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinslider", "slider"));
ConfigurationDatabase.setObject(paramsKey, "jogKinslider", rzval.getText());
ConfigurationDatabase.save();
}).start();
gameController.removeListeners(this);
}
@FXML
void selectTraining(MouseEvent event) {
if(TextField.class.isInstance(event.getSource()))
selected = (TextField) event.getSource();
}
@SuppressWarnings("restriction")
@Override
public void start(Stage primaryStage) throws Exception
{
this.primaryStage = primaryStage;
FXMLLoader loader = AssetFactory.loadLayout("layout/jogTrainerWidget.fxml", true);
Parent root;
loader.setController(this);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
Platform.runLater(() -> {
primaryStage.setTitle("Configure the controller");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.initModality(Modality.WINDOW_MODAL);
primaryStage.setResizable(true);
primaryStage.show();
});
}
@FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
assert linkMinus != null : "fx:id=\"linkMinus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert linkPlus != null : "fx:id=\"linkPlus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert linkval != null : "fx:id=\"linkval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert rotzMinus != null : "fx:id=\"rotzMinus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert rotzPlus != null : "fx:id=\"rotzPlus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert rzval != null : "fx:id=\"rzval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert xminus != null : "fx:id=\"xminus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert xplus != null : "fx:id=\"xplus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert yminus != null : "fx:id=\"yminus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert yplus != null : "fx:id=\"yplus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert yval != null : "fx:id=\"yval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert zminus != null : "fx:id=\"zminus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert zplus != null : "fx:id=\"zplus\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
assert zval != null : "fx:id=\"zval\" was not injected: check your FXML file 'jogTrainerWidget.fxml'.";
// Initialize your logic here: all @FXML variables will have been injected
try {
xplus.setImage(AssetFactory.loadAsset("Plus-X.png"));
xminus.setImage(AssetFactory.loadAsset("Minus-X.png"));
yplus.setImage(AssetFactory.loadAsset("Plus-Y.png"));
yminus.setImage(AssetFactory.loadAsset("Minus-Y.png"));
zplus.setImage(AssetFactory.loadAsset("Plus-Z.png"));
zminus.setImage(AssetFactory.loadAsset("Minus-Z.png"));
rotzPlus.setImage(AssetFactory.loadAsset("Rotation-Z.png"));
rotzMinus.setImage(AssetFactory.loadAsset("Rotation-Neg-Z.png"));
linkPlus.setImage(AssetFactory.loadAsset("Move-Single-Motor.png"));
linkMinus.setImage(AssetFactory.loadAsset("Move-Single-Motor.png"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Platform.runLater(()->{
linkval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogLink", "x"));
xval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinx", "x"));
yval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKiny", "y"));
zval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinz", "rz"));
rzval.setText((String) ConfigurationDatabase.getObject(paramsKey, "jogKinslider", "slider"));
});
}
@Override
public void onEvent(Component arg0, Event arg1, float value, String arg3) {
if(Math.abs(value)>0.75 && selected!=null){
Platform.runLater(()->selected.setText(arg0.getName()));
}
}
}

View File

@@ -0,0 +1,548 @@
package com.neuronrobotics.bowlerstudio.creature;
import com.neuronrobotics.bowlerstudio.ConnectionManager;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.ITaskSpaceUpdateListenerNR;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import com.neuronrobotics.sdk.common.DeviceManager;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.scene.control.*;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;
import net.java.games.input.Component;
import net.java.games.input.Controller;
import org.reactfx.util.FxTimer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import javax.management.RuntimeErrorException;
public class JogWidget extends GridPane implements ITaskSpaceUpdateListenerNR, IOnTransformChange,IJInputEventListener {
double defauletSpeed=0.05;
private AbstractKinematicsNR kin;
private MobileBase mobilebase=null;
Button px = new Button("", AssetFactory.loadIcon("Plus-X.png"));
Button nx = new Button("",AssetFactory.loadIcon("Minus-X.png"));
Button py = new Button("",AssetFactory.loadIcon("Plus-Y.png"));
Button ny = new Button("",AssetFactory.loadIcon("Minus-Y.png"));
Button pz = new Button("",AssetFactory.loadIcon("Plus-Z.png"));
Button nz = new Button("",AssetFactory.loadIcon("Minus-Z.png"));
Button home = new Button("",AssetFactory.loadIcon("Home.png"));
Button game = new Button("Add Game Controller",AssetFactory.loadIcon("Add-Game-Controller.png"));
Button conf = new Button("Configure...",AssetFactory.loadIcon("Configure-Game-Controller.png"));
TextField increment=new TextField(Double.toString(defauletSpeed));
TextField sec=new TextField("0.01");
private TransformWidget transform;
private BowlerJInputDevice gameController=null;
double x,y,rz,slider=0;
private boolean stop=true;
private jogThread jogTHreadHandle;
private String paramsKey;
private GridPane buttons;
private static ArrayList<JogWidget> allWidgets=new ArrayList<JogWidget>();
public JogWidget(AbstractKinematicsNR kinimatics){
allWidgets.add(this);
this.setKin(kinimatics);
if(MobileBase.class.isInstance(kinimatics)){
py = new Button("",AssetFactory.loadIcon("Rotation-Z.png"));
ny = new Button("",AssetFactory.loadIcon("Rotation-Neg-Z.png"));
}
getKin().addPoseUpdateListener(this);
px.setOnMousePressed( event -> {try {handle( (Button)event.getSource()); }catch(Throwable T) {T.printStackTrace();}});
nx.setOnMousePressed( event ->{try { handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
py.setOnMousePressed( event ->{try { handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
ny.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
pz.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
nz.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
home.setOnMousePressed( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
px.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
nx.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
py.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
ny.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
pz.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
nz.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
home.setOnMouseReleased( event -> {try {handle( (Button)event.getSource() ); }catch(Throwable T) {T.printStackTrace();}});
game.setOnAction(event -> {
if(getGameController() == null){
setGameController((BowlerJInputDevice) DeviceManager.getSpecificDevice(BowlerJInputDevice.class, "jogController"));
if(getGameController()==null){
ConnectionManager.onConnectGamePad("jogController");
setGameController((BowlerJInputDevice) DeviceManager.getSpecificDevice(BowlerJInputDevice.class, "jogController"));
}
}else{
RemoveGameController();
}
});
conf.setOnAction(event -> {
if(getGameController() != null){
runControllerMap();
}
});
buttons = new GridPane();
buttons.getColumnConstraints().add(new ColumnConstraints(80)); // column 1 is 75 wide
buttons.getColumnConstraints().add(new ColumnConstraints(80)); // column 2 is 300 wide
buttons.getColumnConstraints().add(new ColumnConstraints(80)); // column 2 is 100 wide
buttons.getRowConstraints().add(new RowConstraints(40)); //
buttons. getRowConstraints().add(new RowConstraints(40)); //
buttons. getRowConstraints().add(new RowConstraints(40)); //
buttons.getRowConstraints().add(new RowConstraints(40)); //
buttons.add( py,
0,
1);
buttons.add( home,
1,
1);
buttons.add( ny,
2,
1);
buttons.add( px,
1,
0);
buttons.add( nx,
1,
2);
buttons.add( increment,
0,
3);
buttons.add( new Label("m/s"),
1,
3);
buttons.add( sec,
2,
3);
buttons.add( new Label("sec"),
3,
3);
if(!MobileBase.class.isInstance(kinimatics)){
buttons.add( pz,
3,
0);
buttons.add( nz,
3,
1);
}
add( buttons,
0,
0);
setTransform(new TransformWidget("Current Pose", getKin().getCurrentPoseTarget(), this));
Accordion advancedPanel = new Accordion();
advancedPanel.getPanes().add(new TitledPane("Current Position", getTransform()));
add( advancedPanel,
0,
1);
jogTHreadHandle = new jogThread();
jogTHreadHandle.start();
controllerLoop();
}
private BowlerJInputDevice RemoveGameController() {
BowlerJInputDevice stale = getGameController();
getGameController().removeListeners(this);
game.setText("Add Game Controller");
setGameController(null);
return stale;
}
private void handle(final Button button ){
if(!button.isPressed()){
// button released
//Log.info(button.getText()+" Button released ");
try {
TransformNR t = getKin().getCurrentTaskSpaceTransform();
getKin().setDesiredTaskSpaceTransform(t, 0);
} catch (Exception e) {
e.printStackTrace();
}
if(button == px){
x=0;
}
if(button == nx){
x=0;
}
if(mobilebase==null){
if(button == py){
y=0;
}
if(button == ny){
y=0;
}
}else{
if(button == py){
rz=0;
}
if(button == ny){
rz=0;
}
}
if(button == pz){
slider=0;
}
if(button == nz){
slider=0;
}
stop=true;
return;
}else{
Log.warning(button.getText()+" Button pressed ");
}
if(button == px){
x=1;
}
if(button == nx){
x=-1;
}
if(mobilebase==null){
if(button == py){
y=1;
}
if(button == ny){
y=-1;
}
}else{
if(button == py){
rz=1;
}
if(button == ny){
rz=-1;
}
}
if(button == pz){
slider=1;
}
if(button == nz){
slider=-1;
}
if(button == home){
home();
stop=true;
return;
}
stop=false;
controllerLoop();
}
public void home(){
if(getMobilebase()!=null){
getMobilebase().setGlobalToFiducialTransform(new TransformNR());
for(DHParameterKinematics c:getMobilebase().getAllDHChains()){
homeLimb(c);
}
}else{
homeLimb(getKin());
}
}
private void homeLimb(AbstractKinematicsNR c) {
double[] joints = c.getCurrentJointSpaceVector();
for (int i = 0; i < c.getNumberOfLinks(); i++) {
joints[i] = 0;
}
try {
c.setDesiredJointSpaceVector(joints, 0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onTaskSpaceUpdate(AbstractKinematicsNR source, TransformNR pose) {
// TODO Auto-generated method stub
if(pose != null &&getTransform()!=null)
Platform.runLater(new Runnable() {
@Override
public void run() {
getTransform().updatePose(pose);
}
});
}
@Override
public void onTargetTaskSpaceUpdate(AbstractKinematicsNR source,
TransformNR pose) {
if(pose != null &&getTransform()!=null)
Platform.runLater(new Runnable() {
@Override
public void run() {
getTransform().updatePose(pose);
}
});
}
@Override
public void onTransformChaging(TransformNR newTrans) {
// TODO Auto-generated method stub
}
@Override
public void onTransformFinished(TransformNR newTrans) {
try {
getKin().setDesiredTaskSpaceTransform(newTrans, Double.parseDouble(sec.getText()));
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public AbstractKinematicsNR getKin() {
return kin;
}
public void setKin(AbstractKinematicsNR kin) {
if(!kin.isAvailable())
kin.connect();
if(MobileBase.class.isInstance(kin))
setMobilebase((MobileBase)kin);
this.kin = kin;
try {
kin.setDesiredTaskSpaceTransform( kin.calcHome(),0);
} catch (Exception e) {}
}
private void controllerLoop(){
//System.out.println("controllerLoop");
double seconds=.1;
if(getGameController()!=null || stop==false){
try{
seconds =Double.parseDouble(sec.getText());
if(!stop){
double inc;
try{
inc = Double.parseDouble(increment.getText())*1000*seconds;//convert to mm
}catch(Exception e){
inc=defauletSpeed;
Platform.runLater(() -> {
try{
increment.setText(Double.toString(defauletSpeed));
}catch(Exception ex){
ex.printStackTrace();
}
});
}
//double rxl=0;
double ryl=inc/20*slider;
double rzl=inc/2*rz;
TransformNR current = new TransformNR(0,0,0,new RotationNR( 0,rzl, 0));
current.translateX(inc*x);
current.translateY(inc*y);
current.translateZ(inc*slider);
try {
if(getMobilebase()==null){
current = getKin().getCurrentPoseTarget();
current.translateX(inc*x);
current.translateY(inc*y);
current.translateZ(inc*slider);
current.setRotation(new RotationNR());
TransformNR toSet = current.copy();
double toSeconds=seconds;
jogTHreadHandle.setToSet(toSet, toSeconds);
//Log.enableDebugPrint();
//System.out.println("Loop Jogging to: "+toSet);
}else{
TransformNR toSet = current.copy();
double toSeconds=seconds;
jogTHreadHandle.setToSet(toSet, toSeconds);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch(Exception e){
e.printStackTrace();
}
if(seconds<.01){
seconds=.01;
sec.setText(".01");
}
FxTimer.runLater(
Duration.ofMillis((int)(seconds*1000.0)) ,new Runnable() {
@Override
public void run() {
controllerLoop();
//System.out.println("Controller loop!");
}
});
}
}
private class jogThread extends Thread{
private boolean controlThreadRunning=false;
private TransformNR toSet;
private double toSeconds=.016;
public void run(){
setName("Jog Widget Set Drive Arc Command "+getKin().getScriptingName());
while(kin.isAvailable()){
//System.out.println("Jog loop");
if(controlThreadRunning){
if(getMobilebase()==null){
try {
//Log.enableDebugPrint();
//System.out.println("Jogging to: "+toSet);
getKin().setDesiredTaskSpaceTransform(toSet, toSeconds);
} catch (Exception e) {
e.printStackTrace();
//BowlerStudioController.highlightException(null, e);
}
}else{
//toSet.setZ(0);
try {
getMobilebase().DriveArc(toSet, toSeconds);
} catch (Exception e) {
e.printStackTrace();
//BowlerStudioController.highlightException(null, e);
}
}
controlThreadRunning=false;
}
ThreadUtil.wait((int) (toSeconds*1000));
}
new RuntimeException("Jog thread finished").printStackTrace();
}
public void setToSet(TransformNR toSet,double toSeconds) {
this.toSet = toSet.copy();
this.toSeconds = toSeconds;
controlThreadRunning=true;
}
}
@Override
public void onEvent(Component comp, net.java.games.input.Event event,
float value, String eventString) {
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKiny", "y")))
x=value;
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKinz", "rz")))
y=value;
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKinx", "x")))
rz=-value;
if(comp.getName().toLowerCase().contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogKinslider", "slider")))
slider=-value;
if(Math.abs(x)<.01)
x=0;
if(Math.abs(y)<.01)
y=0;
if(Math.abs(rz)<.01)
rz=0;
if(Math.abs(slider)<.01)
slider=0;
if(x==0.0&&y==0.0 &&rz==0.0&&slider==0) {
//System.out.println("Stoping on="+comp.getName());
stop=true;
try {
getKin().setDesiredTaskSpaceTransform(getKin().getCurrentTaskSpaceTransform(), 0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else
stop=false;
}
public MobileBase getMobilebase() {
return mobilebase;
}
public void setMobilebase(MobileBase mobilebase) {
this.mobilebase = mobilebase;
}
public BowlerJInputDevice getGameController() {
return gameController;
}
public void setGameController(BowlerJInputDevice gameController) {
this.gameController = gameController;
if(gameController!=null){
getGameController().clearListeners();
getGameController().addListeners(this);
game.setText("Remove Game Controller");
controllerLoop();
Controller hwController = gameController.getController();
paramsKey = hwController.getName();
HashMap<String, Object> map = ConfigurationDatabase.getParamMap(paramsKey);
boolean hasmap = false;
if(map.containsKey("jogKinx")&&
map.containsKey("jogKiny") &&
map.containsKey("jogKinz") &&
map.containsKey("jogKinslider")
){
hasmap=true;
}
if(!hasmap){
runControllerMap();
}
}
}
private void runControllerMap() {
Stage s = new Stage();
new Thread(){
public void run(){
JogTrainerWidget controller = new JogTrainerWidget(gameController);
try {
controller.start( s);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
public TransformWidget getTransform() {
return transform;
}
public void setTransform(TransformWidget transform) {
this.transform = transform;
}
}

View File

@@ -0,0 +1,625 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.reactfx.util.FxTimer;
import com.neuronrobotics.bowlerstudio.BowlerStudio;
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.vitamins.Vitamins;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.LinkFactory;
import com.neuronrobotics.sdk.addons.kinematics.LinkType;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
import java.time.Duration;
@SuppressWarnings("restriction")
public class LinkConfigurationWidget extends GridPane {
// private int index;
private LinkConfiguration conf;
private EngineeringUnitsSliderWidget zero;
private EngineeringUnitsSliderWidget lowerBound;
private EngineeringUnitsSliderWidget upperBound;
private AbstractLink activLink;
private MobileBaseCadManager manager;
private EngineeringUnitsSliderWidget setpointSLider;
double textToNum(TextField mass) {
try {
return Double.parseDouble(mass.getText().trim());
} catch (Throwable t) {
mass.setText("0");
return 0;
}
}
public LinkConfigurationWidget(LinkConfiguration congiuration, LinkFactory factory,
EngineeringUnitsSliderWidget slide, MobileBaseCadManager manager) {
// this.index = index;
// this.congiuration = congiuration;
conf = congiuration;
this.setpointSLider = slide;
this.manager = manager;
activLink = factory.getLink(conf);
getColumnConstraints().add(new ColumnConstraints(150)); // column 1 is 75 wide
getColumnConstraints().add(new ColumnConstraints(200)); // column 2 is 300 wide
getColumnConstraints().add(new ColumnConstraints(200)); // column 2 is 300 wide
setHgap(20);
TextField mass = new TextField(CreatureLab.getFormatted(conf.getMassKg()));
mass.setOnAction(event -> {
conf.setMassKg(textToNum(mass));
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
if (manager != null)
manager.generateCad();
});
TransformNR currentCentroid = conf.getCenterOfMassFromCentroid();
TextField massx = new TextField(CreatureLab.getFormatted(currentCentroid.getX()));
massx.setOnAction(event -> {
currentCentroid.setX(textToNum(massx));
conf.setCenterOfMassFromCentroid(currentCentroid);
;
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
if (manager != null)
manager.generateCad();
});
TextField massy = new TextField(CreatureLab.getFormatted(currentCentroid.getY()));
massy.setOnAction(event -> {
currentCentroid.setY(textToNum(massy));
conf.setCenterOfMassFromCentroid(currentCentroid);
;
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
if (manager != null)
manager.generateCad();
});
TextField massz = new TextField(CreatureLab.getFormatted(currentCentroid.getZ()));
massz.setOnAction(event -> {
currentCentroid.setZ(textToNum(massz));
conf.setCenterOfMassFromCentroid(currentCentroid);
;
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
if (manager != null)
manager.generateCad();
});
TextField scale = new TextField(CreatureLab.getFormatted(conf.getScale()));
scale.setOnAction(event -> {
conf.setScale(textToNum(scale));
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
if (manager != null)
manager.generateCad();
});
Button editShaft = new Button("Edit " + conf.getShaftSize());
editShaft.setOnAction(event -> {
new Thread() {
public void run() {
try {
String type = conf.getShaftType();
String id = conf.getShaftSize();
edit(type, id, Vitamins.getConfiguration(type, id));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
});
Button newShaft = new Button("New " + conf.getShaftType());
newShaft.setOnAction(event -> {
TextInputDialog d = new TextInputDialog("NewSize");
d.setTitle("Wizard for new " + conf.getShaftType());
d.setHeaderText("Enter th Side ID for a new " + conf.getShaftType());
d.setContentText("Size:");
// Traditional way to get the response value.
Optional<String> result = d.showAndWait();
if (result.isPresent()) {
// Create the custom dialog.
String id = result.get();
String type = conf.getShaftType();
new Thread() {
public void run() {
try {
test(type);
Vitamins.newVitamin(id, type);
edit(type, id, Vitamins.getConfiguration(type, conf.getShaftSize()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
});
Button newHardware = new Button("New " + conf.getElectroMechanicalType());
Button editHardware = new Button("Edit " + conf.getElectroMechanicalSize());
final ComboBox<String> shaftSize = new ComboBox<>();
final ComboBox<String> shaftType = new ComboBox<>();
for (String s : Vitamins.listVitaminSizes(conf.getShaftType())) {
shaftSize.getItems().add(s);
}
shaftSize.setOnAction(event -> {
String motorsize = shaftSize.getSelectionModel().getSelectedItem();
String motortype = shaftType.getSelectionModel().getSelectedItem();
if (motorsize == null || motortype == null)
return;
conf.setShaftSize(motorsize);
conf.setShaftType(motortype);
setShaftSize(editShaft, newShaft, motorsize);
if (manager != null)
manager.generateCad();
});
shaftSize.getSelectionModel().select(conf.getShaftSize());
for (String vitaminsType : Vitamins.listVitaminTypes()) {
HashMap<String, Object> meta = Vitamins.getMeta(vitaminsType);
if (meta != null && meta.containsKey("shaft"))
shaftType.getItems().add(vitaminsType);
}
shaftType.setOnAction(event -> {
String selectedItem = shaftType.getSelectionModel().getSelectedItem();
setShaftType(editShaft, newShaft, shaftSize, selectedItem);
});
shaftType.getSelectionModel().select(conf.getShaftType());
final ComboBox<String> emHardwareType = new ComboBox<>();
final ComboBox<String> emHardwareSize = new ComboBox<>();
for (String s : Vitamins.listVitaminSizes(conf.getElectroMechanicalType())) {
emHardwareSize.getItems().add(s);
}
emHardwareSize.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
String motortype = emHardwareType.getSelectionModel().getSelectedItem();
String motorsize = emHardwareSize.getSelectionModel().getSelectedItem();
if (motorsize == null || motortype == null)
return;
conf.setElectroMechanicalType(motortype);
conf.setElectroMechanicalSize(motorsize);
newHardware.setText("New " + conf.getElectroMechanicalType());
editHardware.setText("Edit " + conf.getElectroMechanicalSize());
HashMap<String, Object> vitaminData = Vitamins.getConfiguration(conf.getElectroMechanicalType(),
conf.getElectroMechanicalSize());
System.out.println("New size " + vitaminData);
String shafttype = (String) vitaminData.get("shaftType");
String shaftsize = (String) vitaminData.get("shaftSize");
Platform.runLater(() -> {
setShaftType(editShaft, newShaft, shaftSize, shafttype);
FxTimer.runLater(Duration.ofMillis(20), () -> {
setShaftSize(editShaft, newShaft, shaftsize);
FxTimer.runLater(Duration.ofMillis(200), new Runnable() {
@Override
public void run() {
System.out.println("Settting shaft size: " + shaftsize + " of " + shafttype);
Platform.runLater(() -> shaftType.getSelectionModel().select(shafttype));
Platform.runLater(() -> shaftSize.getSelectionModel().select(shaftsize));
}
});
});
});
conf.setShaftSize(shaftsize);
conf.setShaftType(shafttype);
if (manager != null)
manager.generateCad();
}
});
emHardwareSize.getSelectionModel().select(conf.getElectroMechanicalSize());
for (String vitaminsType : Vitamins.listVitaminTypes()) {
HashMap<String, Object> meta = Vitamins.getMeta(vitaminsType);
if (meta != null && meta.containsKey("actuator"))
emHardwareType.getItems().add(vitaminsType);
}
emHardwareType.setOnAction(event -> {
String selectedItem = emHardwareType.getSelectionModel().getSelectedItem();
if (selectedItem == null)
return;
System.out.println("New hwType " + selectedItem);
emHardwareSize.getItems().clear();
for (String s : Vitamins.listVitaminSizes(selectedItem)) {
emHardwareSize.getItems().add(s);
}
newHardware.setText("New " + conf.getElectroMechanicalType());
editHardware.setText("Edit " + conf.getElectroMechanicalSize());
});
emHardwareType.getSelectionModel().select(conf.getElectroMechanicalType());
// Actuator editing
editHardware.setOnAction(event -> {
new Thread() {
public void run() {
try {
String type = conf.getElectroMechanicalType();
String id = conf.getElectroMechanicalSize();
edit(type, id, Vitamins.getConfiguration(type, id));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
});
newHardware.setOnAction(event -> {
TextInputDialog d = new TextInputDialog("NewSize");
d.setTitle("Wizard for new " + conf.getElectroMechanicalType());
d.setHeaderText("Enter th Side ID for a new " + conf.getElectroMechanicalType());
d.setContentText("Size:");
// Traditional way to get the response value.
Optional<String> result = d.showAndWait();
if (result.isPresent()) {
// Create the custom dialog.
String id = result.get();
String type = conf.getElectroMechanicalType();
new Thread() {
public void run() {
try {
test(type);
Vitamins.newVitamin(id, type);
edit(type, id, Vitamins.getConfiguration(type, conf.getElectroMechanicalSize()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
});
TextField deviceName = new TextField(congiuration.getDeviceScriptingName());
deviceName.setOnAction(event -> {
conf.setDeviceScriptingName(deviceName.getText());
factory.refreshHardwareLayer(conf);
activLink = factory.getLink(conf);
System.out.println("Link device to " + conf.getDeviceScriptingName());
if (manager != null)
manager.generateCad();
});
add(new Text("Scale To Degrees "), 0, 0);
add(scale, 1, 0);
add(new Text("(unitless)"), 2, 0);
lowerBound = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
double eng = setLowerBound(newAngleDegrees);
activLink.setUseLimits(false);
activLink.setTargetEngineeringUnits(eng);
activLink.flush(0);
activLink.setUseLimits(true);
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
try {
activLink.setUseLimits(false);
activLink.setTargetEngineeringUnits(setLowerBound(newAngleDegrees) + 0.01);
activLink.flush(0);
activLink.setUseLimits(true);
if (manager != null)
manager.generateCad();
zero.setLowerBound(newAngleDegrees);
} catch (Exception ex) {
BowlerStudio.printStackTrace(ex);
}
}
}, conf.getLowerLimit() < 1 ? conf.getLowerLimit() : 1, // min
conf.getStaticOffset(), // max
conf.getLowerLimit(), // current
150, "device units", true);
upperBound = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
double eng = setUpperBound(newAngleDegrees - 0.00001);
activLink.setUseLimits(false);
activLink.setTargetEngineeringUnits(eng);
activLink.flush(0);
activLink.setUseLimits(true);
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
activLink.setUseLimits(false);
activLink.setTargetEngineeringUnits(setUpperBound(newAngleDegrees) - 0.00001);
activLink.flush(0);
activLink.setUseLimits(true);
zero.setUpperBound(newAngleDegrees);
if (manager != null)
manager.generateCad();
}
}, conf.getStaticOffset(), conf.getUpperLimit() > 180 ? conf.getUpperLimit() : 180, conf.getUpperLimit(), 150,
"device units", true);
zero = new EngineeringUnitsSliderWidget(new IOnEngineeringUnitsChange() {
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
conf.setStaticOffset(newAngleDegrees);
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
setLowerBound(conf.getLowerLimit());
setUpperBound(conf.getUpperLimit());
setpointSLider.setValue(0);
activLink.setTargetEngineeringUnits(0);
activLink.flush(0);
upperBound.setLowerBound(newAngleDegrees);
lowerBound.setUpperBound(newAngleDegrees);
if (manager != null)
manager.generateCad();
}
}, conf.getLowerLimit(), conf.getUpperLimit(), conf.getStaticOffset(), 150, "device units", true);
final ComboBox<String> channel = new ComboBox<>();
for (int i = 0; i < 24; i++) {
channel.getItems().add(Integer.toString(i));
}
channel.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
conf.setHardwareIndex(Integer.parseInt(channel.getSelectionModel().getSelectedItem()));
factory.refreshHardwareLayer(conf);
activLink = factory.getLink(conf);
System.out.println("Link channel to " + conf.getTypeString());
if (manager != null)
manager.generateCad();
}
});
channel.getSelectionModel().select(conf.getHardwareIndex());
final ComboBox<String> comboBox = new ComboBox<>();
for (LinkType type : LinkType.values()) {
comboBox.getItems().add(type.getName());
}
comboBox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
conf.setType(LinkType.fromString(comboBox.getSelectionModel().getSelectedItem()));
System.out.println("Link type changed to " + conf.getTypeString());
if (manager != null)
manager.generateCad();
}
});
comboBox.getSelectionModel().select(conf.getTypeString().toString());
add(new Text("Zero Degrees Value"), 0, 1);
add(zero, 1, 1);
add(new Text("Upper bound"), 0, 2);
add(upperBound, 1, 2);
add(new Text("Lower bound"), 0, 3);
add(lowerBound, 1, 3);
add(new Text("Link Type"), 0, 4);
add(comboBox, 1, 4);
add(new Text("Link Hardware Index"), 0, 5);
add(channel, 1, 5);
add(new Text("Device Scripting Name"), 0, 6);
add(deviceName, 1, 6);
add(new Text("Mass"), 0, 7);
add(mass, 1, 7);
add(new Text("Mass Centroid x"), 0, 8);
add(massx, 1, 8);
add(new Text("Mass Centroid y"), 0, 9);
add(massy, 1, 9);
add(new Text("Mass Centroid z"), 0, 10);
add(massz, 1, 10);
// link hardware
add(new Text("Hardware Type"), 0, 11);
add(emHardwareType, 1, 11);
add(new Text("Hardware Size"), 0, 12);
add(emHardwareSize, 1, 12);
add(editHardware, 2, 12);
add(newHardware, 1, 13);
// link shaft
add(new Text("Shaft Type"), 0, 14);
add(shaftType, 1, 14);
add(new Text("Shaft Size"), 0, 15);
add(shaftSize, 1, 15);
add(editShaft, 2, 15);
add(newShaft, 1, 16);
}
private double setUpperBound(double newAngleDegrees) {
conf.setUpperLimit(newAngleDegrees);
double eng = 0;
if (conf.getScale() < 0) {
eng = (activLink.getMinEngineeringUnits());
setpointSLider.setLowerBound(eng);
} else {
eng = (activLink.getMaxEngineeringUnits());
setpointSLider.setUpperBound(eng);
}
return eng;
}
private double setLowerBound(double newAngleDegrees) {
conf.setLowerLimit(newAngleDegrees);
double eng = 0;
if (conf.getScale() > 0) {
eng = (activLink.getMinEngineeringUnits());
setpointSLider.setLowerBound(eng);
} else {
eng = (activLink.getMaxEngineeringUnits());
setpointSLider.setUpperBound(eng);
}
return eng;
}
private void setShaftSize(Button editShaft, Button newShaft, String selectedItem) {
if (selectedItem == null) {
newShaft.setText("");
editShaft.setText("");
return;
}
editShaft.setText("Edit " + selectedItem);
}
private void setShaftType(Button editShaft, Button newShaft, final ComboBox<String> shaftSize,
String selectedItem) {
shaftSize.getItems().clear();
if (selectedItem == null)
return;
for (String s : Vitamins.listVitaminSizes(selectedItem)) {
shaftSize.getItems().add(s);
}
newShaft.setText("New " + selectedItem);
// editShaft.setText("Edit "+ conf.getShaftSize());
}
private void test(String type) throws IOException {
try {
Vitamins.saveDatabase(type);
} catch (org.eclipse.jgit.api.errors.TransportException e) {
GitHub github = PasswordManager.getGithub();
GHRepository repo = github.getUser("madhephaestus").getRepository("Hardware-Dimensions");
GHRepository forked = repo.fork();
System.out.println("Vitamins forked to " + forked.getGitTransportUrl());
Vitamins.setGitRepoDatabase(
"https://github.com/" + github.getMyself().getLogin() + "/Hardware-Dimensions.git");
System.out.println("Loading new files");
//
} catch (Exception ex) {
// ex.printStackTrace(MainController.getOut());
}
}
private void edit(String type, String id, HashMap<String, Object> startingConf) throws Exception {
System.out.println("Configuration for " + conf.getElectroMechanicalSize());
System.out.println("Saving to for " + id);
test(type);
Platform.runLater(() -> {
Alert dialog = new Alert(AlertType.CONFIRMATION);
dialog.setTitle("Edit Hardware Wizard");
dialog.setHeaderText("Update the hardare configurations");
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
HashMap<String, TextField> valueFields = new HashMap<>();
int row = 0;
for (Map.Entry<String, Object> entry : startingConf.entrySet()) {
TextField username = new TextField();
username.setText(entry.getValue().toString());
grid.add(new Label(entry.getKey()), 0, row);
grid.add(username, 1, row);
valueFields.put(entry.getKey(), username);
row++;
}
dialog.getDialogPane().setContent(grid);
Optional<ButtonType> r = dialog.showAndWait();
if (r.get() == ButtonType.OK) {
new Thread() {
public void run() {
for (Map.Entry<String, TextField> entry : valueFields.entrySet()) {
try {
Vitamins.setParameter(type, id, entry.getKey(), (Object) entry.getValue().getText());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
Vitamins.saveDatabase(type);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
});
}
}

View File

@@ -0,0 +1,280 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.time.Duration;
import org.reactfx.util.FxTimer;
import com.neuronrobotics.bowlerstudio.assets.ConfigurationDatabase;
import com.neuronrobotics.sdk.addons.gamepad.BowlerJInputDevice;
import com.neuronrobotics.sdk.addons.gamepad.IJInputEventListener;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
import com.neuronrobotics.sdk.addons.kinematics.AbstractLink;
import com.neuronrobotics.sdk.addons.kinematics.DHLink;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.DhLinkType;
import com.neuronrobotics.sdk.addons.kinematics.IJointSpaceUpdateListenerNR;
import com.neuronrobotics.sdk.addons.kinematics.ILinkListener;
import com.neuronrobotics.sdk.addons.kinematics.JointLimit;
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.pid.PIDLimitEvent;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.text.Text;
import net.java.games.input.Component;
import net.java.games.input.Controller;
import net.java.games.input.Event;
@SuppressWarnings("restriction")
public class LinkSliderWidget extends Group implements IJInputEventListener, IOnEngineeringUnitsChange, ILinkListener {
private AbstractKinematicsNR device;
private DHParameterKinematics dhdevice;
private int linkIndex;
private EngineeringUnitsSliderWidget setpoint;
private BowlerJInputDevice controller;
private jogThread jogTHreadHandle;
private double slider;
private boolean stop;
private double seconds;
private String paramsKey;
private AbstractLink abstractLink;
// private EngineeringUnitsSliderWidget slide;
public LinkSliderWidget(int linkIndex, DHLink dhlink, AbstractKinematicsNR d) {
this.linkIndex = linkIndex;
this.device = d;
if (DHParameterKinematics.class.isInstance(device)) {
dhdevice = (DHParameterKinematics) device;
}
abstractLink = device.getAbstractLink(linkIndex);
TextField name = new TextField(abstractLink.getLinkConfiguration().getName());
name.setMaxWidth(100.0);
name.setOnAction(event -> {
abstractLink.getLinkConfiguration().setName(name.getText());
});
setSetpoint(new EngineeringUnitsSliderWidget(this, abstractLink.getMinEngineeringUnits(),
abstractLink.getMaxEngineeringUnits(), device.getCurrentJointSpaceVector()[linkIndex], 180,
dhlink.getLinkType() == DhLinkType.ROTORY ? "degrees" : "mm"));
GridPane panel = new GridPane();
panel.getColumnConstraints().add(new ColumnConstraints(30)); // column 1
// is 75
// wide
panel.getColumnConstraints().add(new ColumnConstraints(120)); // column
// 1 is
// 75
// wide
panel.getColumnConstraints().add(new ColumnConstraints(120)); // column
// 2 is
// 300
// wide
panel.add(new Text("#" + linkIndex), 0, 0);
panel.add(name, 1, 0);
panel.add(getSetpoint(), 2, 0);
getChildren().add(panel);
abstractLink.addLinkListener(this);
// device.addJointSpaceListener(this);
}
public void setUpperBound(double newBound) {
getSetpoint().setUpperBound(newBound);
}
public void setLowerBound(double newBound) {
getSetpoint().setLowerBound(newBound);
}
// public void changed(ObservableValue<? extends Boolean> observableValue,
// Boolean wasChanging,
// Boolean changing) {
//
// }
//
// @Override
// public void onJointSpaceUpdate(AbstractKinematicsNR source, double[] joints)
// {
//
// try {
// setpoint.setValue(joints[linkIndex]);
// } catch (ArrayIndexOutOfBoundsException ex) {
// return;
// }
//
//
// }
//
// @Override
// public void onJointSpaceTargetUpdate(AbstractKinematicsNR source, double[]
// joints) {
// // TODO Auto-generated method stub
// System.out.println("targe update");
// }
//
// @Override
// public void onJointSpaceLimit(AbstractKinematicsNR source, int axis,
// JointLimit event) {
// // TODO Auto-generated method stub
// System.out.println("limit update");
//
// }
private void controllerLoop() {
seconds = .1;
if (getGameController() != null || stop == false) {
if (!stop) {
jogTHreadHandle.setToSet(slider + getSetpoint().getValue(), seconds);
}
FxTimer.runLater(Duration.ofMillis((int) (seconds * 1000.0)), new Runnable() {
@Override
public void run() {
controllerLoop();
}
});
}
}
private class jogThread extends Thread {
private boolean controlThreadRunning = false;
private double toSeconds = seconds;
private double newValue;
public void run() {
setName("Jog Link Slider");
while (device.isAvailable()) {
if (controlThreadRunning) {
try {
device.setDesiredJointAxisValue(linkIndex, newValue, toSeconds);
getSetpoint().setValue(newValue);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
controlThreadRunning = false;
}
ThreadUtil.wait((int) (toSeconds * 1000));
}
}
public void setToSet(double newValue, double toSeconds) {
this.newValue = newValue;
this.toSeconds = toSeconds;
controlThreadRunning = true;
}
}
public void setGameController(BowlerJInputDevice controller) {
this.controller = controller;
if (controller != null && jogTHreadHandle == null) {
jogTHreadHandle = new jogThread();
jogTHreadHandle.start();
}
if (controller != null) {
Controller hwController = controller.getController();
paramsKey = hwController.getName();
System.err.println("Controller key: " + paramsKey);
getGameController().clearListeners();
getGameController().addListeners(this);
controllerLoop();
}
}
public BowlerJInputDevice getGameController() {
return controller;
}
@Override
public void onEvent(Component comp, net.java.games.input.Event event, float value, String eventString) {
if (comp.getName().toLowerCase()
.contentEquals((String) ConfigurationDatabase.getObject(paramsKey, "jogLink", "x")))
slider = -value;
if (Math.abs(slider) < .01)
slider = 0;
if (slider == 0) {
// System.out.println("Stoping on="+comp.getName());
stop = true;
} else
stop = false;
}
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
// TODO Auto-generated method stub
try {
if (newAngleDegrees > device.getAbstractLink(linkIndex).getMaxEngineeringUnits()) {
newAngleDegrees=device.getAbstractLink(linkIndex).getMaxEngineeringUnits();
}
if(newAngleDegrees <device.getAbstractLink(linkIndex).getMinEngineeringUnits()) {
newAngleDegrees=device.getAbstractLink(linkIndex).getMinEngineeringUnits();
}
device.setDesiredJointAxisValue(linkIndex, newAngleDegrees, 0);
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
;
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
}
@Override
public void onLinkLimit(AbstractLink arg0, PIDLimitEvent arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLinkPositionUpdate(AbstractLink arg0, double arg1) {
// TODO Auto-generated method stub
try {
getSetpoint().setValue(arg1);
} catch (ArrayIndexOutOfBoundsException ex) {
return;
}
}
public EngineeringUnitsSliderWidget getSetpoint() {
return setpoint;
}
public void setSetpoint(EngineeringUnitsSliderWidget setpoint) {
this.setpoint = setpoint;
}
}

View File

@@ -0,0 +1,109 @@
package com.neuronrobotics.bowlerstudio.creature;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
import com.neuronrobotics.replicator.driver.NRPrinter;
import com.neuronrobotics.replicator.driver.StateBasedControllerConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.AbstractKinematicsNR;
//import com.neuronrobotics.sdk.addons.kinematics.gui.SampleGuiNR;
public class PrinterConfiguration extends JPanel {
/**
*
*/
private static final long serialVersionUID = -1890177802795201269L;
//private SampleGuiNR gui = new SampleGuiNR();
private StateBasedControllerConfiguration state;
private JTextField kp = new JTextField(10);
private JTextField ki = new JTextField(10);
private JTextField kd = new JTextField(10);
private JTextField vkp = new JTextField(10);
private JTextField vkd = new JTextField(10);
private JTextField mmPos = new JTextField(10);
private JTextField maxVel = new JTextField(10);
private JTextField baseRad = new JTextField(10);
private JTextField EErad = new JTextField(10);
private JTextField maxz = new JTextField(10);
private JTextField minz = new JTextField(10);
private JTextField rodlen = new JTextField(10);
private JCheckBox hardPos = new JCheckBox("Use Hard Positioning");
private JButton update=new JButton("Update");
private NRPrinter printer;
private JPanel controls;
public PrinterConfiguration(){
setLayout(new MigLayout());
controls = new JPanel(new MigLayout());
controls.add(new JLabel("kP"));controls.add(kp,"wrap");
controls.add(new JLabel("kI"));controls.add(ki,"wrap");
controls.add(new JLabel("kD"));controls.add(kd,"wrap");
controls.add(new JLabel("VkP"));controls.add(vkp,"wrap");
controls.add(new JLabel("VkD"));controls.add(vkd,"wrap");
controls.add(new JLabel("Resolution (mm)"));controls.add(mmPos,"wrap");
controls.add(new JLabel("Maximum Velocity (mm/s)"));controls.add(maxVel,"wrap");
controls.add(new JLabel("Base Radius(mm)"));controls.add(baseRad,"wrap");
controls.add(new JLabel("End Effector Radius(mm)"));controls.add(EErad,"wrap");
controls.add(new JLabel("Maximum Z(mm)"));controls.add(maxz,"wrap");
controls.add(new JLabel("Minimum Z(mm)"));controls.add(minz,"wrap");
controls.add(new JLabel("Rod Length(mm)"));controls.add(rodlen,"wrap");
controls.add(hardPos,"wrap");
controls.add(update,"wrap");
update.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
state.setkP(Double.parseDouble(kp.getText()));
state.setkI(Double.parseDouble(ki.getText()));
state.setkD(Double.parseDouble(kd.getText()));
state.setvKP(Double.parseDouble(vkp.getText()));
state.setvKD(Double.parseDouble(vkd.getText()));
state.setMmPositionResolution(Double.parseDouble(mmPos.getText()));
state.setMaximumMMperSec(Double.parseDouble(maxVel.getText()));
state.setBaseRadius(Double.parseDouble(baseRad.getText()));
state.setEndEffectorRadius(Double.parseDouble(EErad.getText()));
state.setMaxZ(Double.parseDouble(maxz.getText()));
state.setMinZ(Double.parseDouble(minz.getText()));
state.setRodLength(Double.parseDouble(rodlen.getText()));
state.setUseHardPositioning(hardPos.isSelected());
printer.setStateBasedControllerConfiguration(state);
}
});
}
public void setKinematicsModel(AbstractKinematicsNR p) {
// gui.setKinematicsModel(p);
// if(NRPrinter.class.isInstance(p)){
// this.printer = (NRPrinter)p;
// state = printer.getStateBasedControllerConfiguration();
// kp.setText(Double.toString(state.getkP()));
// ki.setText(Double.toString(state.getkI()));
// kd.setText(Double.toString(state.getkD()));
// vkp.setText(Double.toString(state.getvKP()));
// vkd.setText(Double.toString(state.getvKD()));
// mmPos.setText(Double.toString(state.getMmPositionResolution()));
// maxVel.setText(Double.toString(state.getMaximumMMperSec()));
// baseRad.setText(Double.toString(state.getBaseRadius()));
// EErad.setText(Double.toString(state.getEndEffectorRadius()));
// maxz.setText(Double.toString(state.getMaxZ()));
// minz.setText(Double.toString(state.getMinZ()));
// rodlen.setText(Double.toString(state.getRodLength()));
// hardPos.setSelected(state.isUseHardPositioning());
// add(controls,"wrap");
// }
// add(gui,"wrap");
}
}

View File

@@ -0,0 +1,183 @@
package com.neuronrobotics.bowlerstudio.creature;
import Jama.Matrix;
import com.neuronrobotics.bowlerstudio.threed.BowlerStudio3dEngine;
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import com.neuronrobotics.sdk.common.Log;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
public class TransformWidget extends GridPane implements IOnEngineeringUnitsChange, EventHandler<ActionEvent> {
private IOnTransformChange onChange;
//EngineeringUnitsSliderWidget rw;
private EngineeringUnitsSliderWidget tilt;
private EngineeringUnitsSliderWidget elevation;
private EngineeringUnitsSliderWidget azimeth;
private EngineeringUnitsSliderWidget tx;
private EngineeringUnitsSliderWidget ty;
private EngineeringUnitsSliderWidget tz;
// private TextField tx;
// private TextField ty;
// private TextField tz;
private TransformNR initialState;
public TransformWidget(String title, TransformNR is, IOnTransformChange onChange){
this.initialState = is;
this.onChange = onChange;
// tx = new TextField(CreatureLab.getFormatted(initialState.getX()));
// ty = new TextField(CreatureLab.getFormatted(initialState.getY()));
// tz = new TextField(CreatureLab.getFormatted(initialState.getZ()));
// tx.setOnAction(this);
// ty.setOnAction(this);
// tz.setOnAction(this);
tx = new EngineeringUnitsSliderWidget(this, initialState.getX(), 100,"mm");
ty = new EngineeringUnitsSliderWidget(this, initialState.getY(), 100,"mm");
tz = new EngineeringUnitsSliderWidget(this, initialState.getZ(), 100,"mm");
RotationNR rot = initialState.getRotation();
double t=0;
try{
t=Math.toDegrees(rot.getRotationTilt());
}catch(Exception ex){
ex.printStackTrace();
}
double e=0;
try{
e=Math.toDegrees(rot.getRotationElevation());
}catch(Exception ex){
ex.printStackTrace();
}
double a=0;
try{
a=Math.toDegrees(rot.getRotationAzimuth());
}catch(Exception ex){
ex.printStackTrace();
}
tilt = new EngineeringUnitsSliderWidget(this, -179.99, 179.99, t, 100,"degrees");
elevation = new EngineeringUnitsSliderWidget(this, -89.99, 89.99, e, 100,"degrees");
azimeth = new EngineeringUnitsSliderWidget(this, -179.99, 179.99, a, 100,"degrees");
tilt.setAllowResize(false);
elevation.setAllowResize(false);
azimeth.setAllowResize(false);
getColumnConstraints().add(new ColumnConstraints(30)); // translate text
getColumnConstraints().add(new ColumnConstraints(200)); // translate values
getColumnConstraints().add(new ColumnConstraints(60)); // units
getColumnConstraints().add(new ColumnConstraints(60)); // rotate text
setHgap(20);// gab between elements
add( new Text(title),
1, 0);
// add( new Text("(r)W"),
// 3, 0);
// add( rw,
// 4, 0);
// These all seem out of order here, but it is because the
// screen is rotating the orenation of this interface from BowlerStudio3dEngine.getOffsetforvisualization()
//X line
add( new Text("X"),
0, 1);
add( tx,
1, 1);
add( new Text("Tilt"),
3, 1);
add( tilt,
4, 1);
//Y line
add( new Text("Y"),
0, 2);
add( ty,
1, 2);
add( new Text("Elevation"),
3, 2);
add( elevation,
4, 2);
//Z line
add( new Text("Z"),
0, 3);
add( tz,
1, 3);
add( new Text("Azimuth"),
3, 3);
add( azimeth,
4, 3);
}
private TransformNR getCurrent(){
TransformNR tmp = new TransformNR(
tx.getValue(),
ty.getValue(),
tz.getValue(),
new RotationNR(
tilt.getValue(),
azimeth.getValue(),
elevation.getValue()
));
return tmp;
}
@Override
public void onSliderMoving(EngineeringUnitsSliderWidget source, double newAngleDegrees) {
onChange.onTransformChaging(getCurrent());
}
@Override
public void onSliderDoneMoving(EngineeringUnitsSliderWidget source,
double newAngleDegrees) {
handle(null);
}
@Override
public void handle(ActionEvent event) {
onChange.onTransformChaging(getCurrent());
onChange.onTransformFinished(getCurrent());
}
public void updatePose(TransformNR p) {
TransformNR pose = p;
tx.setValue(pose.getX());
ty.setValue(pose.getY());
tz.setValue(pose.getZ());
RotationNR rot = pose.getRotation();
double t=0;
try{
t=Math.toDegrees(rot.getRotationTilt());
}catch(Exception ex){
ex.printStackTrace();
}
double e=0;
try{
e=Math.toDegrees(rot.getRotationElevation());
}catch(Exception ex){
ex.printStackTrace();
}
double a=0;
try{
a=Math.toDegrees(rot.getRotationAzimuth());
}catch(Exception ex){
ex.printStackTrace();
}
tilt.setValue(t);
elevation .setValue(e);
azimeth .setValue(a);
}
}

View File

@@ -0,0 +1,111 @@
package com.neuronrobotics.bowlerstudio.scripting;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.control.PasswordField;
import javafx.stage.Stage;
public class GithubLoginFX implements javafx.fxml.Initializable {
@FXML
private TextField username;
@FXML PasswordField password;
private boolean done=false;
private String [] creds = new String[]{"",""};
private Stage stage;
private Parent root;
private Scene scene;
@Override
public void initialize(URL location, ResourceBundle resources) {
reset();
}
public void reset(){
done=false;
setCreds(new String[]{"",""});
password.clear();
getUsername().clear();
}
@FXML public void anonMode() {
setCreds(null);
try {
// this should make anon mode stick
ScriptingEngine.setupAnyonmous();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finish();
}
private void finish(){
stage.close();
stage.hide();
done=true;
}
@FXML public void login() {
getCreds()[0]= getUsername().getText();
getCreds()[1]= password.getText();
if(getCreds()[0]==null||getCreds()[1]==null){
setCreds(null);
}else if(getCreds()[0].equals("")||getCreds()[1].equals("")){
setCreds(null);
}
finish();
}
@FXML public void focusOnPw() {
password.requestFocus();
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
public String [] getCreds() {
return creds;
}
public void setCreds(String [] creds) {
this.creds = creds;
}
public void setStage(Stage stage, Parent root) {
this.stage = stage;
if(this.root==null){
this.root = root;
scene= new Scene(root);
}
stage.setScene(scene);
}
public TextField getUsername() {
return username;
}
public void setUsername(TextField username) {
this.username = username;
}
}

View File

@@ -0,0 +1,16 @@
package com.neuronrobotics.bowlerstudio.scripting;
import java.io.File;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
public interface IScriptEventListener {
void onScriptFinished( Object result,Object pervious, File source);
void onScriptChanged(String previous, String current, File source);
void onScriptError( Throwable except, File source);
}

View File

@@ -0,0 +1,569 @@
package com.neuronrobotics.bowlerstudio.scripting;
import com.neuronrobotics.bowlerstudio.BowlerStudio;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.ConnectionManager;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.util.FileChangeWatcher;
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
import com.neuronrobotics.nrconsole.util.CommitWidget;
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.util.IFileChangeListener;
import com.neuronrobotics.sdk.util.ThreadUtil;
import eu.mihosoft.vrl.v3d.parametrics.CSGDatabase;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.FileChooser.ExtensionFilter;
import org.eclipse.jgit.api.Git;
import org.reactfx.util.FxTimer;
import java.awt.*;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Scanner;
@SuppressWarnings("unused")
public class ScriptingFileWidget extends BorderPane implements
IFileChangeListener {
private boolean running = false;
private Thread scriptRunner = null;
private Dimension codeDimentions = new Dimension(1168, 768);
//Label fileLabel = new Label();
private Object scriptResult;
private String codeText="";
private ArrayList<IScriptEventListener> listeners = new ArrayList<>();
private Button runfx = new Button("Run");
private Button publish = new Button("Publish");
private String addr;
boolean loadGist = false;
private ScriptingWidgetType type;
final TextField fileListBox = new TextField();
final TextField fileNameBox = new TextField();
private File currentFile = null;
private HBox controlPane;
private String currentGist;
private boolean updateneeded = false;
private IScriptingLanguage langaugeType;
private ImageView image=new ImageView();
public ScriptingFileWidget(File currentFile) throws IOException {
this(ScriptingWidgetType.FILE);
this.currentFile = currentFile;
loadCodeFromFile(currentFile);
boolean isOwnedByLoggedInUser= ScriptingEngine.checkOwner(currentFile);
publish.setDisable(!isOwnedByLoggedInUser);
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
publish.setGraphic(AssetFactory.loadIcon("Publish.png"));
try {
image.setImage(AssetFactory.loadAsset("Script-Tab-"+ScriptingEngine.getShellType(currentFile.getName())+".png"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void startStopAction(){
runfx.setDisable(true);
if (running)
stop();
else
start();
runfx.setDisable(false);
}
private ScriptingFileWidget(ScriptingWidgetType type) {
this.type = type;
runfx.setOnAction(e -> {
new Thread(){
public void run(){
if(langaugeType.getIsTextFile())
save();
//do not attempt to save no binary files
startStopAction();
}
}.start();
});
publish.setOnAction(e -> {
new Thread(()->{
save();
CommitWidget.commit(currentFile, getCode());
}).start();
});
// runsaveAs.setOnAction(e -> {
// new Thread(){
// public void run(){
// updateFile();
// save();
// }
// }.start();
//
// });
// String ctrlSave = "CTRL Save";
// fileLabel.setOnMouseEntered(e -> {
// Platform.runLater(() -> {
// ThreadUtil.wait(10);
// fileLabel.setText(currentFile.getAbsolutePath());
// });
// });
//
// fileLabel.setOnMouseExited(e -> {
// Platform.runLater(() -> {
// ThreadUtil.wait(10);
// fileLabel.setText(currentFile.getName());
// });
// });
// Set up the run controls and the code area
// The BorderPane has the same areas laid out as the
// BorderLayout layout manager
setPadding(new Insets(1, 0, 3, 10));
controlPane = new HBox(20);
double lengthScalar = fileNameBox.getFont().getSize()*1.5;
fileNameBox.textProperty().addListener((ov, prevText, currText) -> {
// Do this in a Platform.runLater because of Textfield has no padding at first time and so on
Platform.runLater(() -> {
Text text = new Text(currText);
text.setFont(fileNameBox.getFont()); // Set the same font, so the size is the same
double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
+ fileNameBox.getPadding().getLeft() + fileNameBox.getPadding().getRight() // Add the padding of the TextField
+ lengthScalar; // Add some spacing
fileNameBox.setPrefWidth(width); // Set the width
fileNameBox.positionCaret(fileNameBox.getCaretPosition()); // If you remove this line, it flashes a little bit
});
});
fileListBox.textProperty().addListener((ov, prevText, currText) -> {
// Do this in a Platform.runLater because of Textfield has no padding at first time and so on
Platform.runLater(() -> {
Text text = new Text(currText);
text.setFont(fileListBox.getFont()); // Set the same font, so the size is the same
double width = text.getLayoutBounds().getWidth() // This big is the Text in the TextField
+ fileListBox.getPadding().getLeft() + fileListBox.getPadding().getRight() // Add the padding of the TextField
+ lengthScalar; // Add some spacing
fileListBox.setPrefWidth(width); // Set the width
fileListBox.positionCaret(fileListBox.getCaretPosition()); // If you remove this line, it flashes a little bit
});
});
controlPane.getChildren().add(runfx);
controlPane.getChildren().add(image);
controlPane.getChildren().add(publish);
controlPane.getChildren().add(new Label("file:"));
controlPane.getChildren().add(fileNameBox);
fileNameBox.setMaxWidth(Double.MAX_VALUE);
controlPane.getChildren().add(new Label("git:"));
controlPane.getChildren().add(fileListBox);
fileListBox.setMaxWidth(Double.MAX_VALUE);
controlPane.setMaxWidth(Double.MAX_VALUE);
// put the flowpane in the top area of the BorderPane
setTop(controlPane);
addIScriptEventListener(BowlerStudioController.getBowlerStudio());
reset();
}
private void reset() {
running = false;
Platform.runLater(() -> {
runfx.setText("Run");
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
runfx.setBackground(new Background(new BackgroundFill(Color.LIGHTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
});
}
public void addIScriptEventListener(IScriptEventListener l) {
if (!listeners.contains(l))
listeners.add(l);
}
public void removeIScriptEventListener(IScriptEventListener l) {
if (listeners.contains(l))
listeners.remove(l);
}
public void stop() {
// TODO Auto-generated method stub
reset();
if (scriptRunner != null)
while (scriptRunner.isAlive()) {
Log.debug("Interrupting");
ThreadUtil.wait(10);
try {
scriptRunner.interrupt();
scriptRunner.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void loadCodeFromFile(File currentFile) throws IOException {
if (!currentFile.exists()) {
currentFile.createNewFile();
}
setUpFile(currentFile);
if(!langaugeType.getIsTextFile())
setCode("Binary File");
else
setCode(new String(Files.readAllBytes(currentFile.toPath())));
}
private void start() {
try{
if(!currentFile.getName().contentEquals("csgDatabase.json")){
String[] gitID = ScriptingEngine.findGitTagFromFile(currentFile);
String remoteURI=gitID[0];
ArrayList<String> f = ScriptingEngine.filesInGit(remoteURI);
for (String s:f){
if(s.contentEquals("csgDatabase.json")){
File dbFile = ScriptingEngine.fileFromGit(gitID[0], s);
if(!CSGDatabase.getDbFile().equals(dbFile))
CSGDatabase.setDbFile(dbFile);
CSGDatabase.saveDatabase();
}
}
}
}catch(Exception e){
//ignore CSG database
e.printStackTrace();
}
BowlerStudio.clearConsole();
BowlerStudioController.clearHighlight();
try {
ScriptingEngine.setAutoupdate(false);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
running = true;
Platform.runLater(()->{
runfx.setText("Stop");
runfx.setGraphic(AssetFactory.loadIcon("Stop.png"));
runfx.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
});
scriptRunner = new Thread() {
public void run() {
// String name;
// try{
// name = currentFile.getName();
// }catch (NullPointerException e){
// name="";
// }
try {
Object obj = ScriptingEngine.inlineFileScriptRun(currentFile, null);
for (IScriptEventListener l : listeners) {
l.onScriptFinished(obj, scriptResult,currentFile);
}
scriptResult = obj;
reset();
}
catch (groovy.lang.MissingPropertyException |org.python.core.PyException d){
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Variable missing error");
String message = "This script needs a variable defined before you use it: ";
String stackTrace = d.getMessage();
if(stackTrace.contains("dyio"))
message+="dyio";
else if(stackTrace.contains("camera"))
message+="camera";
else if(stackTrace.contains("gamepad"))
message+="gamepad";
else
message+=stackTrace;
alert.setHeaderText(message);
alert.showAndWait();
if(stackTrace.contains("dyio"))
ConnectionManager.addConnection();
// else if(stackTrace.contains("camera"))
// ConnectionManager.addConnection(new OpenCVImageProvider(0),"camera0");
else if(stackTrace.contains("gamepad"))
ConnectionManager.onConnectGamePad("gamepad");
reset();
});
BowlerStudioController.highlightException(currentFile, d);
}
catch (Throwable ex) {
System.err.println("Script exception of type= "+ex.getClass().getName());
try{
if (ex.getMessage().contains("sleep interrupted")) {
append("\n" + currentFile + " Interupted\n");
} else{
BowlerStudioController.highlightException(currentFile, new Exception(ex));
}
}catch(Exception e){
e.printStackTrace();
BowlerStudioController.highlightException(currentFile, new Exception(ex));
}
reset();
for (IScriptEventListener l : listeners) {
try {
l.onScriptError(new Exception(ex),currentFile);
}catch (Throwable e) {}
}
}
}
};
try {
scriptRunner.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void append(String s) {
System.out.println(s);
}
public String getGitRepo(){
return fileListBox.getText();
}
public String getGitFile(){
return fileNameBox.getText();
}
private void setUpFile(File f) {
currentFile = f;
String langType = ScriptingEngine.getShellType(currentFile.getName());
try {
image.setImage(AssetFactory.loadAsset("Script-Tab-"+ScriptingEngine.getShellType(currentFile.getName())+".png"));
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
langaugeType = ScriptingEngine.getLangaugesMap().get(langType);
//ScriptingEngine.setLastFile(f);
Git git;
try {
git = ScriptingEngine.locateGit(currentFile);
String remote= git.getRepository().getConfig().getString("remote", "origin", "url");
Platform.runLater(() -> {
//fileListBox.setMinWidth(remote.getBytes().length*10);
fileListBox.setText(remote);
//fileListBox.res
fileNameBox.setText(ScriptingEngine.findLocalPath(f, git));
// These values are display only, so if hte user tries to change them, they reset
// the use of text field for static dats is so the user cna copy the vlaues and use them in their scritpts
fileNameBox.textProperty().addListener((observable, oldValue, newValue) -> {
fileNameBox.setText(ScriptingEngine.findLocalPath(f, git));
});
fileListBox.textProperty().addListener((observable, oldValue, newValue) -> {
fileListBox.setText(remote);
});
git.close();
});
} catch (Exception e1) {
Platform.runLater(() -> {
fileListBox.setText("none");
fileListBox.setMinWidth(40);
fileNameBox.setText(f.getAbsolutePath());
// These values are display only, so if hte user tries to change them, they reset
// the use of text field for static dats is so the user cna copy the vlaues and use them in their scritpts
fileNameBox.textProperty().addListener((observable, oldValue, newValue) -> {
fileNameBox.setText(f.getAbsolutePath());
});
fileListBox.textProperty().addListener((observable, oldValue, newValue) -> {
fileListBox.setText("none");
});
});
e1.printStackTrace();
}
if(!langaugeType.getIsTextFile())
return;
try {
getWatcher().addIFileChangeListener(this);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void updateFile() {
File last = FileSelectionFactory.GetFile( currentFile==null?
ScriptingEngine.getWorkspace():
new File(ScriptingEngine.getWorkspace().getAbsolutePath()+"/"+currentFile.getName()),
true,
new ExtensionFilter("Save Script","*"));
if (last != null) {
setUpFile(last);
}
}
public void open() {
updateFile();
try {
setCode(new String(Files.readAllBytes(currentFile.toPath())));
} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
}
public void save() {
// TODO Auto-generated method stub
try {
System.out.println("Writing file contents");
BufferedWriter writer = new BufferedWriter(new FileWriter(
currentFile));
writer.write(getCode());
writer.close();
} catch (Exception ex) {
// ex.printStackTrace();
}
}
@Override
public void onFileChange(File fileThatChanged,
@SuppressWarnings("rawtypes") WatchEvent event) {
if(updateneeded)
return;
updateneeded=true;
try {
getWatcher().removeIFileChangeListener(this);
FxTimer.runLater(
Duration.ofMillis(500) ,new Runnable() {
@Override
public void run() {
updateneeded=false;
// TODO Auto-generated method stub
if (fileThatChanged.getAbsolutePath().contains(
currentFile.getAbsolutePath())) {
System.out.println("Code in " + fileThatChanged.getAbsolutePath()
+ " changed");
Platform.runLater(() -> {
try {
String content = new String(Files.readAllBytes(Paths
.get(fileThatChanged.getAbsolutePath())));
if(content.length()>2)// ensures tha the file contents never get wiped out on the user
setCode(content);
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
getWatcher().addIFileChangeListener(ScriptingFileWidget.this);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
} else {
// System.out.println("Othr Code in "+fileThatChanged.getAbsolutePath()+" changed");
}
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getCode() {
return codeText;
}
public void setCode(String string) {
String pervious = codeText;
codeText = string;
// System.out.println(codeText);
for (int i=0;i<listeners.size();i++ ) {
listeners.get(i).onScriptChanged(pervious, string,currentFile);
}
}
public String getFileName() {
if(currentFile!=null)
return currentFile.getName();
else
return "Web";
}
public FileChangeWatcher getWatcher() throws IOException {
return FileChangeWatcher.watch(currentFile);
}
public void close(){
try {
getWatcher().removeIFileChangeListener(this);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,419 @@
package com.neuronrobotics.bowlerstudio.scripting;
import com.neuronrobotics.bowlerstudio.BowlerStudio;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.ConnectionManager;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
//import com.neuronrobotics.imageprovider.OpenCVImageProvider;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import org.kohsuke.github.GHGist;
import org.kohsuke.github.GHGistFile;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SuppressWarnings({ "unused", "restriction" })
public class ScriptingWebWidget extends BorderPane implements ChangeListener<Object> {
private boolean running = false;
private Thread scriptRunner = null;
private Dimension codeDimentions = new Dimension(1168, 768);
// Label fileLabel = new Label();
private Object scriptResult;
private String codeText = "";
private ArrayList<IScriptEventListener> listeners = new ArrayList<>();
private Button runfx = new Button("Run");;
private Button edit = new Button("Edit...");
private WebEngine engine;
private String addr;
boolean loadGist = false;
private ScriptingWidgetType type;
final ComboBox<String> fileListBox = new ComboBox<>();
private File currentFile = null;
private HBox controlPane;
private String currentGit;
private String currentGist;
private boolean isOwnedByLoggedInUser;
private ImageView image = new ImageView();
public ScriptingWebWidget(File currentFile, String currentGist, WebEngine engine)
throws IOException, InterruptedException {
this(ScriptingWidgetType.GIST);
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
edit.setGraphic(AssetFactory.loadIcon("Edit-Script.png"));
this.currentFile = currentFile;
try {
loadCodeFromGist(currentGist, engine);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void startStopAction() {
runfx.setDisable(true);
if (running)
stop();
else
start();
runfx.setDisable(false);
}
public ScriptingWebWidget(ScriptingWidgetType type) {
this.type = type;
runfx.setOnAction(e -> {
new Thread() {
public void run() {
startStopAction();
}
}.start();
});
edit.setOnAction(e -> {
new Thread() {
public void run() {
if (isOwnedByLoggedInUser)
BowlerStudio.createFileTab(currentFile);
else {
// todo fork git repo
System.out.println("Making Fork...");
GHGist newGist;
try {
newGist = ScriptingEngine.fork(currentGist);
Map<String, GHGistFile> fileMap = newGist.getFiles();
if (fileMap.size() == 1) {
String filename = (String) fileMap.keySet().toArray()[0];
String url = newGist.getGitPullUrl();
File file = ScriptingEngine.fileFromGit(url, filename);
BowlerStudio.createFileTab(file);
} else {
BowlerStudio.openUrlInNewTab(newGist.getHtmlUrl());
}
} catch (Exception e1) {
BowlerStudioController.highlightException(currentFile, e1);
}
}
}
}.start();
});
setPadding(new Insets(1, 0, 3, 10));
controlPane = new HBox(20);
controlPane.getChildren().add(runfx);
controlPane.getChildren().add(image);
controlPane.getChildren().add(edit);
controlPane.getChildren().add(fileListBox);
// put the flowpane in the top area of the BorderPane
setTop(controlPane);
addIScriptEventListener(BowlerStudioController.getBowlerStudio());
reset();
}
private void reset() {
running = false;
Platform.runLater(() -> {
runfx.setText("Run");
runfx.setGraphic(AssetFactory.loadIcon("Run.png"));
runfx.setBackground(new Background(new BackgroundFill(Color.LIGHTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
});
}
public void addIScriptEventListener(IScriptEventListener l) {
if (!listeners.contains(l))
listeners.add(l);
}
public void removeIScriptEventListener(IScriptEventListener l) {
if (listeners.contains(l))
listeners.remove(l);
}
public void stop() {
// TODO Auto-generated method stub
reset();
if (scriptRunner != null)
while (scriptRunner.isAlive()) {
Log.debug("Interrupting");
ThreadUtil.wait(10);
try {
scriptRunner.interrupt();
scriptRunner.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// public void loadCodeFromFile(File currentFile) throws IOException {
// if (!currentFile.exists()) {
// currentFile.createNewFile();
// }
// setUpFile(currentFile);
// setCode(new String(Files.readAllBytes(currentFile.toPath())));
// }
private void loadGitLocal(String id, String file) {
// System.out.println("Loading "+file+" from "+id);
String[] code;
try {
code = ScriptingEngine.codeFromGit(id, file);
if (code != null) {
setCode(code[0]);
currentFile = ScriptingEngine.fileFromGit(id, file);
}
isOwnedByLoggedInUser = ScriptingEngine.checkOwner(currentFile);
Platform.runLater(() -> {
if (isOwnedByLoggedInUser) {
edit.setText("Edit...");
edit.setGraphic(AssetFactory.loadIcon("Edit-Script.png"));
} else {
edit.setText("Make Copy");
edit.setGraphic(AssetFactory.loadIcon("Make-Copy-Script.png"));
}
});
try {
image.setImage(AssetFactory
.loadAsset("Script-Tab-" + ScriptingEngine.getShellType(currentFile.getName()) + ".png"));
} catch (Exception e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
System.out.println(sw.toString());
}
}
public void loadCodeFromGist(String a, WebEngine e) throws Exception {
// new Thread(()->{
addr = a;
engine = e;
loadGist = true;
fileListBox.valueProperty().removeListener(this);
Platform.runLater(() -> runfx.setDisable(true));
Platform.runLater(() -> edit.setDisable(true));
Platform.runLater(() -> fileListBox.getItems().clear());
List<String> gists = ScriptingEngine.getCurrentGist(addr, engine);
ArrayList<String> fileList;
if (!gists.isEmpty()) {
currentGist = gists.get(0);
currentGit = "https://gist.github.com/" + currentGist + ".git";
} else if (addr.contains("https://github.com/")) {
if (a.endsWith("/")) {
a = a.substring(0, a.length() - 1);
}
currentGit = a + ".git";
} else {
return;
}
ArrayList<String> tmp = ScriptingEngine.filesInGit(currentGit);
fileList = new ArrayList<>();
for (String s : tmp) {
if (!s.contains("csgDatabase.json"))// filter out configuration files from the list
fileList.add(s);
}
// for(String s:fileList){
// System.out.println("GITS: "+s);
// }
if (!fileList.isEmpty())
loadGitLocal(currentGit, fileList.get(0));
Platform.runLater(() -> {
for (String s : fileList) {
fileListBox.getItems().add(s);
}
if (!fileList.isEmpty()) {
fileListBox.setValue(fileList.get(0));
fileListBox.valueProperty().addListener(this);
Platform.runLater(() -> runfx.setDisable(false));
Platform.runLater(() -> edit.setDisable(false));
}
});
// }).start();
}
private void start() {
BowlerStudio.clearConsole();
try {
ScriptingEngine.setAutoupdate(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
running = true;
Platform.runLater(() -> {
runfx.setText("Stop");
runfx.setGraphic(AssetFactory.loadIcon("Stop.png"));
runfx.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
});
scriptRunner = new Thread() {
public void run() {
String name;
try {
name = currentFile.getName();
} catch (NullPointerException e) {
name = "";
}
try {
Object obj = ScriptingEngine.inlineScriptRun(currentFile, null, ScriptingEngine.getShellType(name));
for (IScriptEventListener l : listeners) {
l.onScriptFinished(obj, scriptResult, currentFile);
}
scriptResult = obj;
reset();
} catch (groovy.lang.MissingPropertyException | org.python.core.PyException d) {
Platform.runLater(() -> {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Device missing error");
String message = "This script needs a device connected: ";
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
d.printStackTrace(pw);
String stackTrace = sw.toString();
if (stackTrace.contains("dyio"))
message += "dyio";
else if (stackTrace.contains("camera"))
message += "camera";
else if (stackTrace.contains("gamepad"))
message += "gamepad";
else
message += stackTrace;
alert.setHeaderText(message);
alert.setContentText("You need to connect it before running again");
alert.showAndWait();
if (stackTrace.contains("dyio"))
ConnectionManager.addConnection();
// else if (stackTrace.contains("camera"))
// ConnectionManager.addConnection(new OpenCVImageProvider(0), "camera0");
else if (stackTrace.contains("gamepad"))
ConnectionManager.onConnectGamePad("gamepad");
reset();
});
} catch (Throwable ex) {
System.err.println("Script exception of type= " + ex.getClass().getName());
Platform.runLater(() -> {
try {
if (ex.getMessage().contains("sleep interrupted")) {
append("\n" + currentFile + " Interupted\n");
} else {
BowlerStudio.printStackTrace(ex,currentFile);
}
} catch (Throwable e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
append("\n" + currentFile + " \n" + sw + "\n");
}
reset();
});
for (IScriptEventListener l : listeners) {
l.onScriptError(ex, currentFile);
}
BowlerStudio.printStackTrace(ex,currentFile);
}
}
};
try {
// if (loadGist)
// loadCodeFromGist(addr, engine);
scriptRunner.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void append(String s) {
System.out.println(s);
}
public String getCode() {
return codeText;
}
public void setCode(String string) {
String pervious = codeText;
codeText = string;
// System.out.println(codeText);
for (IScriptEventListener l : listeners) {
l.onScriptChanged(pervious, string, currentFile);
}
}
public String getFileName() {
if (currentFile != null)
return currentFile.getName();
else
return "Web";
}
@Override
public void changed(@SuppressWarnings("rawtypes") ObservableValue observable, Object oldValue, Object newValue) {
loadGitLocal(currentGit, (String) newValue);
}
}

View File

@@ -0,0 +1,8 @@
package com.neuronrobotics.bowlerstudio.scripting;
public enum ScriptingWidgetType {
FILE,
WEB,
GIST,
CREATURE
}

View File

@@ -0,0 +1,40 @@
package com.neuronrobotics.bowlerstudio.scripting;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import com.neuronrobotics.bowlerstudio.vitamins.Vitamins;
import eu.mihosoft.vrl.v3d.CSG;
public class StlLoader implements IScriptingLanguage {
@Override
public Object inlineScriptRun(File code, ArrayList<Object> args) throws Exception {
CSG sllLoaded = Vitamins.get(code);
return sllLoaded;
}
@Override
public Object inlineScriptRun(String code, ArrayList<Object> args) throws Exception {
throw new RuntimeException("This engine only supports files");
}
@Override
public String getShellType() {
// TODO Auto-generated method stub
return "Stl";
}
@Override
public boolean getIsTextFile() {
// TODO Auto-generated method stub
return false;
}
@Override
public ArrayList<String> getFileExtenetion() {
// TODO Auto-generated method stub
return new ArrayList<>(Arrays.asList("stl"));
}
}

View File

@@ -0,0 +1,121 @@
package com.neuronrobotics.bowlerstudio.tabs;
import java.util.ArrayList;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.BowlerStudioModularFrame;
import com.neuronrobotics.bowlerstudio.creature.MobileBaseCadManager;
import com.neuronrobotics.sdk.addons.kinematics.DHParameterKinematics;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.common.BowlerAbstractConnection;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.common.IConnectionEventListener;
import com.neuronrobotics.sdk.common.IDeviceConnectionEventListener;
import com.sun.javafx.scene.control.behavior.TabPaneBehavior;
import com.sun.javafx.scene.control.skin.TabPaneSkin;
import eu.mihosoft.vrl.v3d.CSG;
import javafx.application.Platform;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.Tab;
public abstract class AbstractBowlerStudioTab extends Tab implements EventHandler<Event> {
private boolean active = false;
ArrayList<String> myNames =null;
private EventHandler<Event> localCopyOfEventHandler;
public abstract void onTabClosing();
public abstract String[] getMyNameSpaces();
public abstract void initializeUI(BowlerAbstractDevice pm);
public abstract void onTabReOpening();
public void setDevice(BowlerAbstractDevice pm){
myNames = new ArrayList<> ();
if(getMyNameSpaces().length>0){
for(int i=0;i<getMyNameSpaces().length;i++){
myNames.add(getMyNameSpaces()[i]);
}
if(!isMyNamespace(pm.getNamespaces())){
throw new RuntimeException("Device and namespaces are incompatible ");
}
}
setOnCloseRequest(this);
initializeUI(pm);
pm.addConnectionEventListener(new IDeviceConnectionEventListener() {
@Override
public void onDisconnect(BowlerAbstractDevice source) {
//if the device disconnects, close the tab
if(source ==pm && source !=null ) {
requestClose();
if(MobileBase.class.isInstance(pm)) {
MobileBase dev = (MobileBase)pm;
try {
for(CSG p:MobileBaseCadManager.get(dev).getBasetoCadMap().get(dev))
BowlerStudioController.removeObject(p);
for(DHParameterKinematics leg:dev.getAllDHChains())
for(CSG p:MobileBaseCadManager.get(dev).getDHtoCadMap().get(leg))
BowlerStudioController.removeObject(p);
}catch(Throwable e) {}
}
}
else {
// Not a bug, expected to ensure one device disconnects the rest of the dependent devices
// System.err.println("Device type was "+source.getClass()+" named "+source.getScriptingName()+" expected "+pm.getClass()+" named "+pm.getScriptingName());
// new Exception().printStackTrace();
}
}
@Override
public void onConnect(BowlerAbstractDevice source) {
// TODO Auto-generated method stub
}
});
}
public boolean isMyNamespace(ArrayList<String> names) {
if (names == null)
return false;
for(String s:names){
for(String m:myNames){
if(s.contains(m)){
setActive(true);
}
}
}
return isAcvive();
}
@Override
public void setOnCloseRequest(EventHandler<Event> value){
this.localCopyOfEventHandler = value;
super.setOnCloseRequest(value);
System.err.println(" A close requested for "+getText());
}
public void requestClose() {
BowlerStudioModularFrame.getBowlerStudioModularFrame().closeTab(this);
}
//
private TabPaneBehavior getBehavior() {
return ((TabPaneSkin) getTabPane().getSkin()).getBehavior();
}
public void setActive(boolean a){
active=a;
}
public boolean isAcvive() {
return active;
}
@Override
public void handle(Event event){
System.out.println("Closing "+getText());
onTabClosing();
}
}

View File

@@ -0,0 +1,46 @@
package com.neuronrobotics.bowlerstudio.tabs;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import com.neuronrobotics.sdk.dyio.DyIO;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
public class DyIOControl extends AbstractBowlerStudioTab {
private DyIO dyio;
DyIOPanel controller ;
@Override
public void onTabClosing() {
// TODO Auto-generated method stub
}
@Override
public String[] getMyNameSpaces() {
// TODO Auto-generated method stub
return new String[]{"neuronrobotics.dyio.*"};
}
@Override
public void initializeUI(BowlerAbstractDevice pm) {
this.dyio = (DyIO)pm;
setGraphic(AssetFactory.loadIcon("DyIO-Tab.png"));
setText(dyio.getScriptingName());
FXMLLoader fxmlLoader = BowlerStudioResourceFactory.getMainPanel();
Parent root = fxmlLoader.getRoot();
controller = fxmlLoader.getController();
controller.setDyIO(dyio);
setContent(root);
}
@Override
public void onTabReOpening() {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,425 @@
package com.neuronrobotics.bowlerstudio.tabs;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
import com.neuronrobotics.sdk.dyio.DyIO;
import com.neuronrobotics.sdk.dyio.DyIOChannel;
import com.neuronrobotics.sdk.dyio.DyIOChannelMode;
import com.neuronrobotics.sdk.util.ThreadUtil;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.util.Callback;
import org.reactfx.util.FxTimer;
import java.net.URL;
import java.time.Duration;
import java.util.ArrayList;
import java.util.ResourceBundle;
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
public class DyIOPanel implements Initializable {
private ArrayList<ComboBox<String>> channelTypeSelectors = new ArrayList<>() ;
private ArrayList<ImageView> channelButtonSelectors = new ArrayList<>() ;
private ArrayList<Label> channelValue = new ArrayList<>() ;
private ArrayList<Parent> controlWidgets = new ArrayList<>() ;
private ArrayList<Boolean> displayFlash = new ArrayList<>() ;
private DyIO dyio;
private boolean initialized=false;
@FXML ImageView chanButton23;
@FXML ImageView chanButton22;
@FXML ImageView chanButton21;
@FXML ImageView chanButton20;
@FXML ImageView chanButton19;
@FXML ImageView chanButton18;
@FXML ImageView chanButton17;
@FXML ImageView chanButton16;
@FXML ImageView chanButton15;
@FXML ImageView chanButton14;
@FXML ImageView chanButton13;
@FXML ImageView chanButton12;
@FXML ImageView chanButton11;
@FXML ImageView chanButton10;
@FXML ImageView chanButton9;
@FXML ImageView chanButton8;
@FXML ImageView chanButton7;
@FXML ImageView chanButton6;
@FXML ImageView chanButton5;
@FXML ImageView chanButton4;
@FXML ImageView chanButton3;
@FXML ImageView chanButton2;
@FXML ImageView chanButton1;
@FXML ImageView chanButton0;
@FXML ImageView background;
@FXML ComboBox<String> channelType23;
@FXML ComboBox<String> channelType22;
@FXML ComboBox<String> channelType21;
@FXML ComboBox<String> channelType20;
@FXML ComboBox<String> channelType19;
@FXML ComboBox<String> channelType18;
@FXML ComboBox<String> channelType17;
@FXML ComboBox<String> channelType16;
@FXML ComboBox<String> channelType15;
@FXML ComboBox<String> channelType14;
@FXML ComboBox<String> channelType13;
@FXML ComboBox<String> channelType12;
@FXML ComboBox<String> channelType11;
@FXML ComboBox<String> channelType10;
@FXML ComboBox<String> channelType9;
@FXML ComboBox<String> channelType8;
@FXML ComboBox<String> channelType7;
@FXML ComboBox<String> channelType6;
@FXML ComboBox<String> channelType5;
@FXML ComboBox<String> channelType4;
@FXML ComboBox<String> channelType3;
@FXML ComboBox<String> channelType2;
@FXML ComboBox<String> channelType1;
@FXML ComboBox<String> channelType0;
@FXML Circle centerled;
@FXML Label channelValue0;
@FXML Label channelValue1;
@FXML Label channelValue2;
@FXML Label channelValue3;
@FXML Label channelValue4;
@FXML Label channelValue5;
@FXML Label channelValue6;
@FXML Label channelValue7;
@FXML Label channelValue8;
@FXML Label channelValue9;
@FXML Label channelValue10;
@FXML Label channelValue11;
@FXML Label channelValue12;
@FXML Label channelValue13;
@FXML Label channelValue14;
@FXML Label channelValue15;
@FXML Label channelValue16;
@FXML Label channelValue17;
@FXML Label channelValue18;
@FXML Label channelValue19;
@FXML Label channelValue20;
@FXML Label channelValue21;
@FXML Label channelValue22;
@FXML Label channelValue23;
@FXML AnchorPane controlWidgetPanel;
public void setDyIO(DyIO d){
d.setServoPowerSafeMode(false);// disable the browout when using the UI
channelTypeSelectors.add( channelType0);
channelTypeSelectors.add( channelType1);
channelTypeSelectors.add( channelType2);
channelTypeSelectors.add( channelType3);
channelTypeSelectors.add( channelType4);
channelTypeSelectors.add( channelType5);
channelTypeSelectors.add( channelType6);
channelTypeSelectors.add( channelType7);
channelTypeSelectors.add( channelType8);
channelTypeSelectors.add( channelType9);
channelTypeSelectors.add( channelType10);
channelTypeSelectors.add( channelType11);
channelTypeSelectors.add( channelType12);
channelTypeSelectors.add( channelType13);
channelTypeSelectors.add( channelType14);
channelTypeSelectors.add( channelType15);
channelTypeSelectors.add( channelType16);
channelTypeSelectors.add( channelType17);
channelTypeSelectors.add( channelType18);
channelTypeSelectors.add( channelType19);
channelTypeSelectors.add( channelType20);
channelTypeSelectors.add( channelType21);
channelTypeSelectors.add( channelType22);
channelTypeSelectors.add( channelType23);
channelButtonSelectors.add( chanButton0);
channelButtonSelectors.add( chanButton1);
channelButtonSelectors.add( chanButton2);
channelButtonSelectors.add( chanButton3);
channelButtonSelectors.add( chanButton4);
channelButtonSelectors.add( chanButton5);
channelButtonSelectors.add( chanButton6);
channelButtonSelectors.add( chanButton7);
channelButtonSelectors.add( chanButton8);
channelButtonSelectors.add( chanButton9);
channelButtonSelectors.add( chanButton10);
channelButtonSelectors.add( chanButton11);
channelButtonSelectors.add( chanButton12);
channelButtonSelectors.add( chanButton13);
channelButtonSelectors.add( chanButton14);
channelButtonSelectors.add( chanButton15);
channelButtonSelectors.add( chanButton16);
channelButtonSelectors.add( chanButton17);
channelButtonSelectors.add( chanButton18);
channelButtonSelectors.add( chanButton19);
channelButtonSelectors.add( chanButton20);
channelButtonSelectors.add( chanButton21);
channelButtonSelectors.add( chanButton22);
channelButtonSelectors.add( chanButton23);
//Values
channelValue.add( channelValue0);
channelValue.add( channelValue1);
channelValue.add( channelValue2);
channelValue.add( channelValue3);
channelValue.add( channelValue4);
channelValue.add( channelValue5);
channelValue.add( channelValue6);
channelValue.add( channelValue7);
channelValue.add( channelValue8);
channelValue.add( channelValue9);
channelValue.add( channelValue10);
channelValue.add( channelValue11);
channelValue.add( channelValue12);
channelValue.add( channelValue13);
channelValue.add( channelValue14);
channelValue.add( channelValue15);
channelValue.add( channelValue16);
channelValue.add( channelValue17);
channelValue.add( channelValue18);
channelValue.add( channelValue19);
channelValue.add( channelValue20);
channelValue.add( channelValue21);
channelValue.add( channelValue22);
channelValue.add( channelValue23);
try {
background.setImage(AssetFactory.loadAsset("dyio/dyio-red2.png"));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.dyio = d;
for (int i = 0; i < 24; i++) {
int index = i;
ObservableList<String> items = FXCollections.observableArrayList();
DyIOChannel chan = dyio.getChannel(index);
displayFlash.add(new Boolean(true));
Platform.runLater(()->channelValue.get(index).setText(Integer.toString(chan.getValue())));
Platform.runLater(()->displayFlash( index,chan.getCachedValue()));
chan.addChannelEventListener(e -> {
displayFlash( index,e.getValue());
});
channelButtonSelectors.get(index).setOnMouseEntered(event -> {
Platform.runLater(()->
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanHighlight()));
});
channelButtonSelectors.get(index).setOnMouseExited(event -> {
Platform.runLater(()->
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanDefault()));
});
channelTypeSelectors.get(index);
ArrayList<DyIOChannelMode> modesAvailible = dyio
.getAvailibleChannelModes(index);
for (DyIOChannelMode m : modesAvailible) {
items.add(m.toSlug());
}
Callback<ListView<String>, ListCell<String>> callback =new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> p) {
return new ListCell<String>() {
Label name = new Label();
Label icon = new Label();
private final HBox cell;
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
cell = new HBox(5);
//HERE, ADD YOUR PRE-MADE HBOX CODE
name.setTextFill(Color.BLACK);
cell.getChildren().add(icon);
cell.getChildren().add(name);
}
@Override protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setGraphic(null);
} else {
name.setText(item);
icon.setGraphic(new ImageView(BowlerStudioResourceFactory.getModeImage(DyIOChannelMode.getFromSlug(item))));
setGraphic(cell);
//HERE IS WHERE YOU GET THE LABEL AND NAME
}
}
};
}
};
Platform.runLater(()->{
channelTypeSelectors.get(index).setButtonCell(callback.call(null));
channelTypeSelectors.get(index).setCellFactory(callback);
channelTypeSelectors.get(index).setItems(items);
});
setChannelModeList(index);
dyio.getChannel(index).addChannelModeChangeListener(newMode -> {
setChannelModeList(index);
});
}
new Thread(){
public void run(){
setName("DyIOchannelWidget Setting channel value ");
for (int index = 0; index < 24; index++) {
int i=index;
FXMLLoader fxmlLoader= BowlerStudioResourceFactory.getLoader(i);
Parent root = fxmlLoader.getRoot();
DyIOchannelWidget controller = fxmlLoader.getController();
controller.setChannel(dyio.getChannel(i));
controller.setVisable(false);
controlWidgets.add(root);
}
initialized=true;
while(dyio.isAvailable()){
for(int i=0;i<24;i++){
DyIOchannelWidget controller =BowlerStudioResourceFactory.getLoader(i).getController();
if(controller.isFireValue()){
controller.setFireValue(false);
dyio.setValue(i,controller.getLatestValue());
if(dyio.getMode(i)==DyIOChannelMode.SERVO_OUT && dyio.getChannel(i).getCachedMode()){
dyio.getChannel(i).flush();
}
}
controller.updateValue();
}
ThreadUtil.wait(50);
}
}
}.start();
}
private void displayFlash(int index,int value){
// set the value label text
if(displayFlash.get(index)){
displayFlash.set(index, false);
Platform.runLater(()->{
channelValue.get(index).setText(Integer.toString(value));
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanUpdate());
FxTimer.runLater(
Duration.ofMillis(200) ,new Runnable() {
@Override
public void run() {
channelButtonSelectors.get(index).setImage(BowlerStudioResourceFactory.getChanDefault());
displayFlash.set(index, true);
}
});
});
}
}
@FXML public void channelClicked(MouseEvent event) {
int index=getIndex( event);
System.err.println("Channel was clicked: "+index);
if(!initialized)
return;
setControlWidget( index);
}
private int getIndex(Event event){
for(int i=0;i<24;i++){
if(channelTypeSelectors.get(i).equals(event.getSource())){
return i;
}
if(channelButtonSelectors.get(i).equals(event.getSource())){
return i;
}
}
throw new RuntimeException("This event did not come from this system...");
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
private void setChannelModeList(int index){
DyIOChannel chan =dyio.getChannel(index);
Platform.runLater(()->{
ComboBox<String> selector = channelTypeSelectors.get(index);
String current =null;
for(String m:selector.getItems()){
if(chan.getMode().toSlug().contentEquals(m)){
current=m;
}
}
String tmp =current;
selector.setValue(tmp);
});
}
private void setControlWidget(int index){
for(int i=0;i<24;i++){
DyIOchannelWidget controller =BowlerStudioResourceFactory.getLoader(i).getController();
controller.setVisable(false);
}
DyIOchannelWidget mine = BowlerStudioResourceFactory.getLoader(index).getController();
Platform.runLater(()->{
if(!initialized)
return;
synchronized (controlWidgetPanel) {
controlWidgetPanel.getChildren().clear();
controlWidgetPanel.getChildren().add(controlWidgets.get(index));
}
mine.setVisable(true);
});
}
@FXML public void onChannelSelect(ActionEvent event) {
int index =getIndex( event);
ComboBox<String> comboBox = channelTypeSelectors.get(index);
String v = comboBox.getValue();
if(v==null)
return;
DyIOChannelMode value = DyIOChannelMode.getFromSlug(v);
if(!initialized)
return;
new Thread(){
public void run(){
setName("Running set mode thread");
dyio.setMode(index, value);
setControlWidget( index);
}
}.start();
}
}

View File

@@ -0,0 +1,376 @@
package com.neuronrobotics.bowlerstudio.tabs;
import javax.swing.SwingUtilities;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.python.core.exceptions;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.assets.BowlerStudioResourceFactory;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.sdk.common.Log;
//import com.neuronrobotics.nrconsole.plugin.DyIO.DyIOConsole;
import com.neuronrobotics.sdk.dyio.DyIOChannel;
import com.neuronrobotics.sdk.dyio.DyIOChannelEvent;
import com.neuronrobotics.sdk.dyio.DyIOChannelMode;
import com.neuronrobotics.sdk.dyio.IChannelEventListener;
import com.neuronrobotics.sdk.dyio.peripherals.ServoChannel;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.SwingNode;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.paint.Color;
public class DyIOchannelWidget {
private boolean fireValue=false;
private int latestValue=0;
private boolean isVisable=false;
private final class ChangeListenerImplementation implements
ChangeListener<Number> {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
int newVal = new_val.intValue();
chanValue.setText(Integer.toString(newVal));
if(currentMode==DyIOChannelMode.SERVO_OUT ){
if(timeSlider.getValue()>.1){
//servo should only set on release when time is defined
return;
}
}
setLatestValue(newVal);
setFireValue(true);
}
}
@FXML Button setListenerButton;
@FXML AnchorPane listenerCodeBox;
@FXML LineChart<Integer,Integer> channelGraph;
@FXML Slider timeSlider;
@FXML Slider positionSlider;
@FXML Label chanValue;
@FXML Label deviceType;
@FXML Label deviceNumber;
@FXML ImageView deviceModeIcon;
private DyIOChannel channel;
private XYChart.Series<Integer, Integer> series = new XYChart.Series<Integer, Integer>();
private long startTime=0;
@FXML Label secondsLabel;
private IChannelEventListener myLocalListener=null;
private RSyntaxTextArea textArea;
private SwingNode sn;
private RTextScrollPane sp;
private ServoChannel srv= null;
private DyIOChannelMode currentMode;
private ChangeListenerImplementation imp = new ChangeListenerImplementation();
@FXML NumberAxis graphValueAxis;
@FXML NumberAxis graphTimeAxis;
private Integer value=null;
public void setChannel(DyIOChannel c){
this.channel = c;
startTime=System.currentTimeMillis();
setMode( channel.getMode());
Platform.runLater(()->deviceNumber.setText(Integer.toString(channel.getChannelNumber())));
Platform.runLater(()->chanValue.setText(Integer.toString(channel.getValue())));
Platform.runLater(()->secondsLabel.setText(String.format("%.2f", 0.0)));
Platform.runLater(()->positionSlider.setValue(channel.getValue()));
Platform.runLater(()->graphValueAxis.setAnimated(false));
Platform.runLater(()->graphTimeAxis.setAnimated(false));
Platform.runLater(()->positionSlider.valueProperty().addListener(imp));
positionSlider.valueChangingProperty().addListener((ChangeListener<Boolean>) (observable, oldValue, newValue) -> {
chanValue.setText(Integer.toString((int) positionSlider.getValue()));
if(currentMode==DyIOChannelMode.SERVO_OUT && timeSlider.getValue()>.1){
new Thread(){
public void run(){
Platform.runLater(()->setName("Setting servo Pos"));
//int ll = Log.getMinimumPrintLevel();
try{
//Log.enableInfoPrint();
srv.SetPosition((int) positionSlider.getValue(), timeSlider.getValue());
if(srv.getChannel().getCachedMode())
srv.getChannel().flush();
}catch(Exception ex){
ex.printStackTrace();
}
//Log.setMinimumPrintLevel(ll);
}
}.start();
}
});
timeSlider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
secondsLabel.setText(String.format("%.2f", new_val));
}
});
channel.addChannelModeChangeListener(newMode -> {
setMode( newMode);
});
channel.addChannelEventListener(new IChannelEventListener() {
@Override
public void onChannelEvent(DyIOChannelEvent dyioEvent) {
if(isVisable()){
setValue(new Integer(dyioEvent.getValue()));
}
}
});
Platform.runLater(()->{
channelGraph.getData().clear();
try{
channelGraph.getData().add(series);
}catch(Exception e){}
});
setUpListenerPanel();
Platform.runLater(()->setListenerButton.setBackground(new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY))));
}
public void updateValue(){
if(getValue()!=null){
int current = getValue();
Data<Integer, Integer> newChart = new XYChart.Data<Integer, Integer>(
(int) (startTime-System.currentTimeMillis()),
current);
Platform.runLater(()->chanValue.setText(Integer.toString(current)));
if(!positionSlider.isValueChanging()){// only updae the slider position if the user is not sliding it
Platform.runLater(()->{
if(positionSlider==null)
return;
positionSlider.valueProperty().removeListener(imp);
positionSlider.setValue(current);
setLatestValue(current);
setFireValue(false);
positionSlider.valueProperty().addListener(imp);
});
}
Platform.runLater(()->{
if(series.getData().size()>10){// if you keep many more points in the graph it will lag the rendering realy badly
series.getData().remove(0);
}
Platform.runLater(()->{
series.getData().add(newChart);
value=null;
});
});
}
}
private void setMode(DyIOChannelMode newMode){
currentMode = newMode;
Platform.runLater(()->{
deviceModeIcon.setImage(BowlerStudioResourceFactory.getModeImage(newMode));
series.setName(currentMode.toSlug()+" values");
deviceType.setText(currentMode.toSlug());
//set slider bounds
graphValueAxis.setAutoRanging(false);
switch(currentMode){
case ANALOG_IN:
positionSlider.setMin(0);
positionSlider.setMax(1024);
graphValueAxis.setLowerBound(0);
graphValueAxis.setUpperBound(1024);
break;
case COUNT_IN_DIR:
case COUNT_IN_HOME:
case COUNT_IN_INT:
case COUNT_OUT_DIR:
case COUNT_OUT_HOME:
case COUNT_OUT_INT:
positionSlider.setMin(-5000);
positionSlider.setMax(5000);
graphValueAxis.setLowerBound(-5000);
graphValueAxis.setUpperBound(5000);
break;
case DC_MOTOR_DIR:
case DC_MOTOR_VEL:
case PWM_OUT:
case SERVO_OUT:
positionSlider.setMin(0);
positionSlider.setMax(255);
graphValueAxis.setLowerBound(0);
graphValueAxis.setUpperBound(255);
break;
case DIGITAL_IN:
case DIGITAL_OUT:
positionSlider.setMin(0);
positionSlider.setMax(1);
graphValueAxis.setLowerBound(0);
graphValueAxis.setUpperBound(1);
break;
default:
break;
}
// allow slider to be disabled for inputs
switch(currentMode){
case ANALOG_IN:
case COUNT_IN_DIR:
case COUNT_IN_HOME:
case COUNT_IN_INT:
case DIGITAL_IN:
timeSlider.setDisable(true);
positionSlider.setDisable(true);
break;
default:
timeSlider.setDisable(false);
positionSlider.setDisable(false);
break;
}
setLatestValue(channel.getValue());
if(currentMode==DyIOChannelMode.SERVO_OUT && srv==null){
new Thread(){
public void run(){
setName("Connectiong servo object");
srv = new ServoChannel(channel);
}
}.start();
}
});
}
@FXML public void onListenerButtonClicked(ActionEvent event) {
new Thread(){
public void run(){
setName("compiling listener");
try{
if(myLocalListener==null){
Platform.runLater(()->{
sn.setDisable(true);
textArea.setEditable(false);
});
myLocalListener=(IChannelEventListener) ScriptingEngine.inlineScriptStringRun(textArea.getText(), null, "Groovy");
channel.addChannelEventListener(myLocalListener);
Platform.runLater(()->{
setListenerButton.setText("Kill Listener");
setListenerButton.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
});
}else{
channel.removeChannelEventListener(myLocalListener);
Platform.runLater(()->{
sn.setDisable(false);
textArea.setEditable(true);
myLocalListener=null;
setListenerButton.setBackground(new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY)));
setListenerButton.setText("Set Listener");
});
}
}catch(Exception e){
BowlerStudioController.highlightException(null, e);
}
}
}.start();
}
private void setUpListenerPanel(){
//Platform.runLater(()->{
textArea = new RSyntaxTextArea(15, 80);
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_GROOVY);
textArea.setCodeFoldingEnabled(true);
textArea.setText("return new IChannelEventListener() { \n"+
"\tpublic \n"
+ "\tvoid onChannelEvent(DyIOChannelEvent dyioEvent){\n"+
"\t\tprintln \"From Listener=\"+dyioEvent.getValue();\n"+
"\t}\n"+
"}"
);
sp = new RTextScrollPane(textArea);
sn = new SwingNode();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
sn.setContent(sp);
}
});
Platform.runLater(()->listenerCodeBox.getChildren().setAll(sn));
listenerCodeBox.setFocusTraversable(false);
sn.setOnMouseEntered(mouseEvent -> {
sn.requestFocus();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textArea.requestFocusInWindow();
}
});
});
//});
}
public boolean isVisable() {
return isVisable;
}
public void setVisable(boolean isVisable) {
Platform.runLater(()->series.getData().clear());
this.isVisable = isVisable;
}
public boolean isFireValue() {
return fireValue;
}
public void setFireValue(boolean fireValue) {
this.fireValue = fireValue;
}
public int getLatestValue() {
return latestValue;
}
public void setLatestValue(int latestValue) {
this.latestValue = latestValue;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}

View File

@@ -0,0 +1,56 @@
package com.neuronrobotics.bowlerstudio.tabs;
import javax.swing.JFrame;
import org.firmata4j.IODevice;
import org.firmata4j.firmata.FirmataDevice;
import org.firmata4j.ui.JPinboard;
import com.neuronrobotics.sdk.addons.kinematics.FirmataBowler;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
import javafx.embed.swing.SwingNode;
import javafx.scene.control.ScrollPane;
public class FirmataTab extends AbstractBowlerStudioTab {
@Override
public void onTabClosing() {
// TODO Auto-generated method stub
}
@Override
public String[] getMyNameSpaces() {
// TODO Auto-generated method stub
return new String[0];
}
@Override
public void initializeUI(BowlerAbstractDevice pm) {
FirmataDevice device =( (FirmataBowler) pm).getFirmataDevice();
// TODO Auto-generated method stub
JFrame frame = new JFrame("Pinboard Example");
frame.add(new JPinboard(device ));
frame.pack();
frame.setVisible(true);
JPinboard pinboard = new JPinboard(device );
pinboard.setVisible(true);
SwingNode sn = new SwingNode();
sn.setContent(pinboard);
ScrollPane s1 = new ScrollPane();
s1.setContent(sn);
setContent(s1);
setText("Firmata Pinpoard");
onTabReOpening();
}
@Override
public void onTabReOpening() {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,510 @@
package com.neuronrobotics.bowlerstudio.tabs;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.time.Duration;
import java.util.HashMap;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.reactfx.util.FxTimer;
import javax.swing.AbstractAction;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.Highlighter.HighlightPainter;
import javafx.application.Platform;
import javafx.embed.swing.MySwingNode;
import javafx.event.EventHandler;
import javafx.scene.layout.VBox;
import com.neuronrobotics.bowlerstudio.BowlerStudio;
import com.neuronrobotics.bowlerstudio.IssueReportingExceptionHandler;
import com.neuronrobotics.bowlerstudio.scripting.IScriptEventListener;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingFileWidget;
import com.neuronrobotics.bowlerstudio.utils.FindTextWidget;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class LocalFileScriptTab extends VBox implements IScriptEventListener, EventHandler<WindowEvent> {
private static final UncaughtExceptionHandler ISSUE_REPORTING_EXCEPTION_HANDLER =new UncaughtExceptionHandler() {
IssueReportingExceptionHandler reporter = new IssueReportingExceptionHandler();
@Override
public void uncaughtException(Thread t, Throwable e) {
if(reporter.getTitle(e).contains("java.awt.datatransfer.DataFlavor at line 503")) {
System.err.println("Known bug in the Swing system, nothing we can do but ignore it");
e.printStackTrace();
return;
}
reporter.uncaughtException(t, e);
}
};// new IssueReportingExceptionHandler();
private long lastRefresh = 0;
private ScriptingFileWidget scripting;
IScriptEventListener l = null;
private MySwingNode swingNode;
private RTextScrollPane spscrollPane;
private Highlighter highlighter;
private HighlightPainter painter;
private int lineSelected = 0;
private MyRSyntaxTextArea textArea = new MyRSyntaxTextArea(200, 300);
private final File file;
private Font myFont;
private static HashMap<String, String> langaugeMapping = new HashMap<>();
private static LocalFileScriptTab selectedTab = null;
static {
SwingUtilities.invokeLater(() -> Thread.setDefaultUncaughtExceptionHandler(new IssueReportingExceptionHandler()));
}
public class MyRSyntaxTextArea extends RSyntaxTextArea implements ComponentListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public MyRSyntaxTextArea() {
this.addComponentListener(this);
}
public MyRSyntaxTextArea(int i, int j) {
super(i, j);
}
public void componentResized(ComponentEvent e) {
System.err.println("componentResized");
}
public void componentHidden(ComponentEvent e) {
System.err.println("componentHidden");
}
public void componentMoved(ComponentEvent e) {
System.err.println("componentMoved");
}
public void componentShown(ComponentEvent e) {
System.err.println("componentShown");
}
}
public static void setExtentionSyntaxType(String shellType, String syntax) {
langaugeMapping.put(shellType, syntax);
}
public LocalFileScriptTab(File file) throws IOException {
Thread.setDefaultUncaughtExceptionHandler(new IssueReportingExceptionHandler());
this.file = file;
setScripting(new ScriptingFileWidget(file));
setSpacing(5);
l = this;
getScripting().addIScriptEventListener(l);
String type;
String shellType = ScriptingEngine.getShellType(file.getName());
switch (shellType) {
case "Clojure":
type = SyntaxConstants.SYNTAX_STYLE_CLOJURE;
break;
default:
type = langaugeMapping.get(shellType);
if (type == null) {
type = SyntaxConstants.SYNTAX_STYLE_NONE;
if (shellType.toLowerCase().contains("arduino")) {
type = SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS;
}
}
case "JSON":
type = SyntaxConstants.SYNTAX_STYLE_JSON;
break;
case "ArduingScriptingLangauge":
type = SyntaxConstants.SYNTAX_STYLE_LISP;
break;
case "Arduino":
type = SyntaxConstants.SYNTAX_STYLE_CPLUSPLUS;
break;
case "Groovy":
type = SyntaxConstants.SYNTAX_STYLE_GROOVY;
break;
case "Jython":
type = SyntaxConstants.SYNTAX_STYLE_PYTHON;
break;
case "MobilBaseXML":
type = SyntaxConstants.SYNTAX_STYLE_XML;
break;
case "Kotlin":
type = SyntaxConstants.SYNTAX_STYLE_JAVA;
break;
case "SVG":
type = SyntaxConstants.SYNTAX_STYLE_XML;
break;
}
textArea.setSyntaxEditingStyle(type);
textArea.setCodeFoldingEnabled(true);
textArea.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
}
@Override
public void insertUpdate(DocumentEvent e) {
}
@Override
public void changedUpdate(DocumentEvent arg0) {
System.err.println("changedUpdate " + file);
new Thread() {
public void run() {
getScripting().removeIScriptEventListener(l);
getScripting().setCode(textArea.getText());
getScripting().addIScriptEventListener(l);
}
}.start();
}
});
textArea.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
// Lets start with some default values for the line and column.
int linenum = 1;
int columnnum = 1;
// We create a try catch to catch any exceptions. We will simply
// ignore such an error for our demonstration.
try {
// First we find the position of the caret. This is the
// number of where the caret is in relation to the start of
// the JTextArea
// in the upper left corner. We use this position to find
// offset values (eg what line we are on for the given
// position as well as
// what position that line starts on.
int caretpos = textArea.getCaretPosition();
linenum = textArea.getLineOfOffset(caretpos);
// We subtract the offset of where our line starts from the
// overall caret position.
// So lets say that we are on line 5 and that line starts at
// caret position 100, if our caret position is currently
// 106
// we know that we must be on column 6 of line 5.
columnnum = caretpos - textArea.getLineStartOffset(linenum);
// We have to add one here because line numbers start at 0
// for getLineOfOffset and we want it to start at 1 for
// display.
linenum += 1;
} catch (Exception ex) {
ex.printStackTrace();
}
if (lineSelected != linenum) {
lineSelected = linenum;
// System.err.println("Select "+lineSelected);
new Thread(() -> {
BowlerStudio.select(file, lineSelected);
}).start();
}
}
});
textArea.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 2) {
highlighter.removeAllHighlights();
}
// System.out.println("Number of click: " + e.getClickCount());
// System.out.println("Click position (X, Y): " + e.getX() + ",
// " + e.getY());
}
});
spscrollPane = new RTextScrollPane(textArea);
swingNode = new MySwingNode(this);
SwingUtilities.invokeLater(() -> swingNode.setContent(spscrollPane));
getScripting().setFocusTraversable(false);
getChildren().setAll(swingNode, getScripting());
swingNode.setOnMouseEntered(mouseEvent -> {
//System.err.println("On mouse entered " + file.getName());
//resizeEvent();
SwingUtilities.invokeLater(() ->{
resizeEvent();
setSelectedTab(this);
// spscrollPane.setSize((int) spscrollPane.getWidth(), (int) spscrollPane.getHeight());
// spscrollPane.invalidate();
// spscrollPane.repaint();
// textArea.invalidate();
// textArea.repaint();
// textArea.requestFocusInWindow();
// FxTimer.runLater(Duration.ofMillis((int) 16), () -> {
// swingNode.requestFocus();
// });
});
});
// textArea
KeyStroke keystroke = KeyStroke.getKeyStroke(KeyEvent.VK_F, KeyEvent.CTRL_MASK);
textArea.getInputMap().put(keystroke, "f");
textArea.getActionMap().put("f", new AbstractAction() {
/**
*
*/
private static final long serialVersionUID = -4698223073831405851L;
public void actionPerformed(ActionEvent e) {
findTextWidget();
}
});
myFont = textArea.getFont();
highlighter = textArea.getHighlighter();
painter = new DefaultHighlighter.DefaultHighlightPainter(Color.pink);
highlighter.removeAllHighlights();
// widthProperty().addListener((w, o, n) -> {
// resizeEvent();
//
// });
// heightProperty().addListener((w, o, n) -> {
// resizeEvent();
// });
SwingUtilities.invokeLater(() -> {
if (getScripting() != null && getScripting().getCode() != null) {
onScriptChanged(null, getScripting().getCode(), file);
}
});
}
private void resizeEvent() {
if (!((lastRefresh + 60) < System.currentTimeMillis())||
spscrollPane.getVerticalScrollBar().getValueIsAdjusting()||
spscrollPane.getHorizontalScrollBar().getValueIsAdjusting()) {
return;
}
lastRefresh = System.currentTimeMillis();
SwingUtilities.invokeLater(() ->{
spscrollPane.setSize((int) spscrollPane.getWidth(), (int) spscrollPane.getHeight());
spscrollPane.invalidate();
spscrollPane.repaint();
textArea.invalidate();
textArea.repaint();
textArea.requestFocusInWindow();
FxTimer.runLater(Duration.ofMillis((int) 16), () -> {
swingNode.setContent(spscrollPane);
swingNode.requestFocus();
});
});
}
@Override
public void onScriptFinished(Object result, Object previous, File source) {
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// textArea.requestFocusInWindow();
// }
// });
}
@Override
public void onScriptChanged(String previous, String current, File source) {
// int place = textArea.getCaretPosition();
// System.err.println("Carrot position is= "+place);
// codeArea.replaceText(current);
// codeArea.setCursor(place);
if (current.length() > 3 && !textArea.getText().contentEquals(current)) {// no
// empty
// writes
SwingUtilities.invokeLater(() -> {
textArea.setText(current);
if (previous == null)
SwingUtilities.invokeLater(() -> textArea.setCaretPosition(0));
});
}
}
@Override
public void onScriptError(Throwable except, File source) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("script error");
textArea.requestFocusInWindow();
}
});
}
public void findTextWidget() {
Platform.runLater(() -> {
Stage s = new Stage();
new Thread() {
public void run() {
Thread.setDefaultUncaughtExceptionHandler(ISSUE_REPORTING_EXCEPTION_HANDLER);
FindTextWidget controller = new FindTextWidget();
controller.setTextArea(textArea);
try {
controller.start(s);
} catch (Exception e) {
ISSUE_REPORTING_EXCEPTION_HANDLER.uncaughtException(Thread.currentThread(), e);
}
}
}.start();
});
}
@Override
public void handle(WindowEvent event) {
getScripting().stop();
}
public ScriptingFileWidget getScripting() {
return scripting;
}
public void setScripting(ScriptingFileWidget scripting) {
this.scripting = scripting;
}
public void setHighlight(int lineNumber, Color color) throws BadLocationException {
if (textArea == null) {
return;
}
painter = new DefaultHighlighter.DefaultHighlightPainter(color);
int startIndex = textArea.getLineStartOffset(lineNumber - 1);
int endIndex = textArea.getLineEndOffset(lineNumber - 1);
try {
SwingUtilities.invokeLater(() -> {
textArea.moveCaretPosition(startIndex);
});
} catch (Error | Exception ex) {
ex.printStackTrace();
}
SwingUtilities.invokeLater(() -> {
try {
textArea.getHighlighter().addHighlight(startIndex, endIndex, painter);
} catch (BadLocationException e) {
ISSUE_REPORTING_EXCEPTION_HANDLER.uncaughtException(Thread.currentThread(), e);
}
});
}
public void clearHighlits() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
highlighter.removeAllHighlights();
}
});
}
public int getFontSize() {
return myFont.getSize();
}
public void setFontSize(int size) {
myFont = new Font(myFont.getName(), myFont.getStyle(), size);
setFontLoop();
}
private void setFontLoop() {
FxTimer.runLater(Duration.ofMillis(200), new Runnable() {
@Override
public void run() {
Thread.setDefaultUncaughtExceptionHandler(ISSUE_REPORTING_EXCEPTION_HANDLER);
SwingUtilities.invokeLater(() -> {
try {
textArea.setFont(myFont);
} catch (Throwable ex) {
//ISSUE_REPORTING_EXCEPTION_HANDLER.uncaughtException(Thread.currentThread(), ex);
setFontLoop();
}
});
}
});
}
public static LocalFileScriptTab getSelectedTab() {
return selectedTab;
}
public static void setSelectedTab(LocalFileScriptTab selectedTab) {
//System.err.println("Currently selected "+selectedTab.file.getAbsolutePath());
LocalFileScriptTab.selectedTab = selectedTab;
}
public void insertString(String string) {
int caretpos = textArea.getCaretPosition();
String text = textArea.getText();
String substring = text.substring(0,caretpos);
String substring2;
try {
substring2 = text.substring(caretpos,text.length());
}catch(java.lang.StringIndexOutOfBoundsException ex) {
substring2="";
}
String combined = substring+string+substring2;
onScriptChanged(text, combined, file);
SwingUtilities.invokeLater(() -> {
textArea.setCaretPosition(caretpos+string.length());
});
}
}

View File

@@ -0,0 +1,384 @@
package com.neuronrobotics.bowlerstudio.tabs;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.Tutorial;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.bowlerstudio.scripting.PasswordManager;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingEngine;
import com.neuronrobotics.bowlerstudio.scripting.ScriptingWebWidget;
import com.neuronrobotics.sdk.common.Log;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory;
import javafx.scene.web.WebView;
import org.reactfx.util.FxTimer;
import java.awt.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
public class WebTab extends Tab implements EventHandler<Event>{
private String Current_URL = "http://gist.github.com/";
private WebTab myTab;
boolean loaded=false;
boolean initialized=false;
private WebView webView;
private WebEngine webEngine;
private VBox vBox;
private Button goButton = new Button("");
private Button homeButton = new Button("");
private Button backButton = new Button("");
private Button forwardButton = new Button("");
private TextField urlField;
//private String currentAddress;
private ScriptingWebWidget scripting;
private Graphics2D splashGraphics;
private static boolean firstBoot=true;
private boolean isTutorialTab =false;
private boolean finishedLoadingScriptingWidget;
private static BowlerStudioController controller;
public WebTab(String title, String Url) throws IOException, InterruptedException{
this(title,Url,false);
}
@SuppressWarnings("restriction")
public WebTab(String title, String Url,boolean isTutorialTab) throws IOException, InterruptedException{
if(isTutorialTab){
setGraphic(AssetFactory.loadIcon("Tutorial-Tab.png"));
}else
setGraphic(AssetFactory.loadIcon("Web-Tab.png"));
goButton.setGraphic(AssetFactory.loadIcon("Go-Refresh.png"));
homeButton.setGraphic(AssetFactory.loadIcon("Home.png"));
backButton.setGraphic(AssetFactory.loadIcon("Back-Button.png"));
forwardButton.setGraphic(AssetFactory.loadIcon("Forward-Button.png"));
this.isTutorialTab = isTutorialTab;
myTab = this;
if(title==null)
myTab.setText(" ");
else
myTab.setText(title);
Log.debug("Loading Gist Tab: "+Url);
webView = new WebView();
webEngine = webView.getEngine();
//webEngine.setUserAgent("bowlerstudio");
if(Url!=null)
Current_URL=Url;
loaded=false;
setOnCloseRequest(this);
webEngine.getLoadWorker().workDoneProperty().addListener((ChangeListener<Number>) (observableValue, oldValue, newValue) -> Platform.runLater(() -> {
if(!(newValue.intValue()<100)){
//System.err.println("Just finished! "+webEngine.getLocation());
new Thread(){
public void run(){
if(!initialized){
initialized=true;
loaded=true;
setName("Start finalizing components");
finishLoadingComponents();
}
else{
try {
getScripting().loadCodeFromGist(Current_URL, webEngine);
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
}
}.start();
}else{
loaded=false;
// if(splashGraphics!=null && splash.isVisible()){
// //BowlerStudio.renderSplashFrame(splashGraphics, newValue.intValue());
// //splash.update();
// }
//System.err.println("Not Done Loading to: "+webEngine.getLocation());
}
}));
urlField = new TextField(Current_URL);
webEngine.locationProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable1,String oldValue, String newValue) {
//System.out.println("Location Changed: "+newValue);
Platform.runLater(() -> {
urlField.setText(newValue);
});
}
});
//goButton.setDefaultButton(true);
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<Object>() {
public void changed(ObservableValue<?> observable,
Object oldValue, Object newValue) {
if (State.SUCCEEDED == newValue) {
Current_URL = urlField.getText().startsWith("http://")|| urlField.getText().startsWith("https://")|| urlField.getText().startsWith("file:")
? urlField.getText()
: "http://" + urlField.getText();
Log.debug("Load Worker State Changed "+Current_URL);
if( !processNewTab(urlField.getText())){
goBack();
}
}else{
//Log.error("State load fault: "+newValue+" object:" +observable);
}
}
});
backButton.setOnAction(arg0 -> {
goBack();
});
forwardButton.setOnAction(arg0 -> {
// TODO Auto-generated method stub
goForward();
});
homeButton.setOnAction(arg0 -> {
// TODO Auto-generated method stub
try {
loadUrl(Tutorial.getHomeUrl());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
// Layout logic
HBox hBox = new HBox(5);
hBox.getChildren().setAll(backButton,forwardButton,homeButton,goButton,urlField);
HBox.setHgrow(urlField, Priority.ALWAYS);
vBox = new VBox(5);
vBox.getChildren().setAll(hBox, webView);
VBox.setVgrow(webView, Priority.ALWAYS);
myTab.setContent(vBox);
//Action definition for the Button Go.
EventHandler<ActionEvent> goAction = event -> {
Log.debug("Hitting load");
if(processNewTab(urlField.getText())){
Log.debug("Loading "+Current_URL);
loadUrl( Current_URL);
}
};
urlField.setOnAction(goAction);
goButton.setOnAction(goAction);
//Once all components are loaded, load URL
FxTimer.runLater(
Duration.ofMillis(200) ,new Runnable() {
@Override
public void run() { goAction.handle(null);}
});
}
public void loadUrl(String url){
if(processNewTab(Current_URL)){
Platform.runLater(() -> {
webEngine.load(url);
});
}
}
private boolean processNewTab(String url){
Current_URL = urlField.getText().startsWith("http://") || urlField.getText().startsWith("https://") || urlField.getText().startsWith("file:")
? urlField.getText()
: "http://" + urlField.getText();
if(isTutorialTab ){
if( !((Current_URL.toLowerCase().contains("commonwealthrobotics.com") ||
Current_URL.contains("gist.github.com/"+PasswordManager.getUsername() )||
Current_URL.contains("localhost") ))){
try {
Log.error("Non demo page found, opening new tab "+Current_URL);
BowlerStudioController.getBowlerStudio().addTab(new WebTab(null, Current_URL), true);
return false;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}else{
Log.debug("no load new tab");
if(getScripting()!=null){
try{
myTab.setText(getScripting().getFileName());
}catch(java.lang.NullPointerException ex){
try {
getScripting().loadCodeFromGist(Current_URL, webEngine);
myTab.setText(getScripting().getFileName());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return true;
}
private void finishLoadingComponents(){
//System.err.println("Finalizing: "+webEngine.getLocation());
try{
if(getScripting()!=null){
//when navagating to a new file, stop the script that is running
getScripting().stop();
}
}catch(Exception E){
E.printStackTrace();
}
new Thread() {
public void run() {
finishedLoadingScriptingWidget=false;
try{
setScripting(new ScriptingWebWidget( null ,Current_URL, webEngine));
Platform.runLater(() -> {
vBox.getChildren().add(getScripting());
if(!isTutorialTab){
Platform.runLater(()->{
try{
myTab.setText(getScripting().getFileName());
}catch(java.lang.NullPointerException ex){
// web page contains no gist
ex.printStackTrace();
myTab.setText("Web");
}
loadCode();
});
}
else
finishedLoadingScriptingWidget=true;
});
}catch(Exception ex){
ex.printStackTrace();
finishedLoadingScriptingWidget=true;
}
}
}.start();
}
private void loadCode(){
new Thread(()->{
System.out.println("Downloading code from "+Current_URL);
try {
getScripting().loadCodeFromGist(Current_URL, webEngine);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
public String goBack()
{
//new Exception().printStackTrace(System.err);
final WebHistory history=webEngine.getHistory();
ObservableList<WebHistory.Entry> entryList=history.getEntries();
int currentIndex=history.getCurrentIndex();
// Out("currentIndex = "+currentIndex);
// Out(entryList.toString().replace("],","]\n"));
Platform.runLater(() ->{
try{
history.go(-1);
}catch(Exception e){
// e.printStackTrace();
}
});
return entryList.get(currentIndex>0?currentIndex-1:currentIndex).getUrl();
}
public String goForward()
{
final WebHistory history=webEngine.getHistory();
ObservableList<WebHistory.Entry> entryList=history.getEntries();
int currentIndex=history.getCurrentIndex();
// Out("currentIndex = "+currentIndex);
// Out(entryList.toString().replace("],","]\n"));
Platform.runLater(() -> {
try {
history.go(1);
} catch (IndexOutOfBoundsException ex) {
}
});
return entryList.get(currentIndex<entryList.size()-1?currentIndex+1:currentIndex).getUrl();
}
public static String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}
@Override
public void handle(Event event) {
if(getScripting()!=null)
getScripting().stop();
}
public ScriptingWebWidget getScripting() {
return scripting;
}
public void setScripting(ScriptingWebWidget scripting) {
this.scripting = scripting;
scripting.addIScriptEventListener(controller);
}
public static void setBSController(BowlerStudioController controller) {
WebTab.controller = controller;
}
}

View File

@@ -0,0 +1,133 @@
package com.neuronrobotics.bowlerstudio.threed;
import javafx.application.Platform;
/*
* Axis.java 1.0 98/11/25
*
* Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/*
* Getting Started with the Java 3D API
* written in Java 3D
*
* This program demonstrates:
* 1. writing a visual object class
* In this program, Axis class defines a visual object
* This particular class extends Shape3D
* See the text for a discussion.
* 2. Using LineArray to draw 3D lines.
*/
import javafx.scene.Group;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Line;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Affine;
// TODO: Auto-generated Javadoc
/**
* The Class Axis.
*/
public class Axis extends Group {
private Line3D xAxis;
private Line3D yAxis;
private Line3D zAxis;
private Label xText;
private Label yText;
private Label zText;
/**
* Instantiates a new axis.
*/
public Axis() {
this(50);
}
// //////////////////////////////////////////
//
// create axis visual object
/**
* Instantiates a new axis.
*
* @param i the i
*/
//
public Axis(int i) {
Affine xp = new Affine();
xp.setTx(i/2);
xText = new Label("+X");
xText.getTransforms().add(xp);
Affine yp = new Affine();
yp.setTy(i/2);
yText = new Label("+Y");
yText.getTransforms().add(yp);
//zp.setTz(i/2);
Affine zTextAffine = new Affine();
zTextAffine.setTz(i/2);
zTextAffine.setTx(i/2);
zTextAffine.appendRotation(-90, 0, 0, 0, 1, 0, 0);
zTextAffine.appendRotation(180, 0, 0, 0, 0, 0, 1);
zText = new Label("+Z");
zText.getTransforms().add(zTextAffine);
//zText.smoothProperty().set(false);
double strokWidth=0.1;
double inset = 0;
xAxis = new Line3D(0,inset,0,i,inset,0);
yAxis = new Line3D(inset,0,0,inset,i,0);
zAxis = new Line3D(inset,0,0,inset,0,i);
xAxis.setStrokeWidth(strokWidth);
xAxis.setStroke(Color.RED);
yAxis.setStrokeWidth(strokWidth);
yAxis.setStroke(Color.GREEN);
zAxis.setStrokeWidth(strokWidth);
zAxis.setStroke(Color.BLUE);
show();
}
public void show(){
Platform.runLater(()->getChildren().addAll(xAxis,yAxis,zAxis,xText,yText,zText));
}
public void hide(){
Platform.runLater(()->getChildren().removeAll(xAxis,yAxis,zAxis,xText,yText,zText));
}
} // end of class Axis

View File

@@ -0,0 +1,56 @@
package com.neuronrobotics.bowlerstudio.threed;
/**
* Sample Skeleton for "CreatureLab.fxml" Controller Class
* You can copy and paste this code into your favorite IDE
**/
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
public class CreaturelLabController {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="CadControlsAnchor"
private AnchorPane CadControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="DriveControlsAnchor"
private AnchorPane DriveControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="TempControlsAnchor"
private AnchorPane TempControlsAnchor; // Value injected by FXMLLoader
@FXML // fx:id="jfx3dControls"
private AnchorPane jfx3dControls; // Value injected by FXMLLoader
@FXML // fx:id="overlayScrollPanel"
private ScrollPane overlayScrollPanel; // Value injected by FXMLLoader
@FXML // fx:id="viewContainer"
private AnchorPane viewContainer; // Value injected by FXMLLoader
@FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
assert CadControlsAnchor != null : "fx:id=\"CadControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert DriveControlsAnchor != null : "fx:id=\"DriveControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert TempControlsAnchor != null : "fx:id=\"TempControlsAnchor\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert jfx3dControls != null : "fx:id=\"jfx3dControls\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert overlayScrollPanel != null : "fx:id=\"overlayScrollPanel\" was not injected: check your FXML file 'CreatureLab.fxml'.";
assert viewContainer != null : "fx:id=\"viewContainer\" was not injected: check your FXML file 'CreatureLab.fxml'.";
// Initialize your logic here: all @FXML variables will have been injected
}
}

View File

@@ -0,0 +1,78 @@
package com.neuronrobotics.bowlerstudio.threed;
import javax.vecmath.Matrix4f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;
import com.bulletphysics.collision.broadphase.BroadphaseInterface;
import com.bulletphysics.collision.broadphase.DbvtBroadphase;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.CollisionShape;
import com.bulletphysics.collision.shapes.SphereShape;
import com.bulletphysics.collision.shapes.StaticPlaneShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.RigidBodyConstructionInfo;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
public class Jbullet {
public static void main(String[] args) {
BroadphaseInterface broadphase = new DbvtBroadphase();
DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);
SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();
DiscreteDynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver,
collisionConfiguration);
// set the gravity of our world
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));
// setup our collision shapes
CollisionShape groundShape = new StaticPlaneShape(new Vector3f(0, 1, 0), 1);
CollisionShape fallShape = new SphereShape(1);
// setup the motion state
DefaultMotionState groundMotionState = new DefaultMotionState(
new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, -1, 0), 1.0f)));
RigidBodyConstructionInfo groundRigidBodyCI = new RigidBodyConstructionInfo(0, groundMotionState, groundShape,
new Vector3f(0, 0, 0));
RigidBody groundRigidBody = new RigidBody(groundRigidBodyCI);
dynamicsWorld.addRigidBody(groundRigidBody); // add our ground to the
// dynamic world..
// setup the motion state for the ball
DefaultMotionState fallMotionState = new DefaultMotionState(
new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, 100, 0), 1.0f)));
// This we're going to give mass so it responds to gravity
int mass = 1;
Vector3f fallInertia = new Vector3f(0, 0, 0);
fallShape.calculateLocalInertia(mass, fallInertia);
RigidBodyConstructionInfo fallRigidBodyCI = new RigidBodyConstructionInfo(mass, fallMotionState, fallShape,
fallInertia);
RigidBody fallRigidBody = new RigidBody(fallRigidBodyCI);
// now we add it to our physics simulation
dynamicsWorld.addRigidBody(fallRigidBody);
for (int i = 0; i < 300; i++) {
dynamicsWorld.stepSimulation(1 / 60.f, 10);
Transform trans = new Transform();
fallRigidBody.getMotionState().getWorldTransform(trans);
System.out.println("sphere height: " + trans.origin.y);
}
}
}

View File

@@ -0,0 +1,104 @@
package com.neuronrobotics.bowlerstudio.threed;
import javafx.application.Platform;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Cylinder;
import javafx.scene.transform.Affine;
import eu.mihosoft.vrl.v3d.Vector3d;
import eu.mihosoft.vrl.v3d.Vertex;
public class Line3D extends Cylinder {
private double endZ = 0;
private double startZ=0;
public Line3D(Vertex start, Vertex end){
this(start.pos,
end.pos );
}
public Line3D(double [] start, double[] end){
this(start[0],start[1],start[2],
end[0],end[1],end[2] );
}
public Line3D(Vector3d start, Vector3d end){
this(start.x,start.y,start.z,
end.x,end.y,end.z );
}
public Line3D(
double endX,
double endY,
double endZ){
this(0,0,0,endX,endY,endZ);
}
public Line3D(double startX,
double startY,
double startZ,
double endX,
double endY,
double endZ){
super(0.1,
Math.sqrt( Math.pow(endX-startX, 2)+
Math.pow(endY-startY, 2)+
Math.pow(endZ-startZ, 2))
);
double xdiff = endX-startX;
double ydiff = endY-startY;
double zdiff = endZ-startZ;
double lineLen = getHeight();
double xyProjection = Math.sqrt( Math.pow(xdiff, 2)+
Math.pow(ydiff, 2)
);
double rotZ = Math.toDegrees(Math.atan2(xdiff, ydiff));
double rotY = Math.toDegrees(Math.atan2(xyProjection, zdiff));
Affine xy = new Affine();
xy.appendRotation(-90-rotY, 0, 0, 0, 0, 1, 0);
Affine orent = new Affine();
orent.appendRotation(90, 0, 0, 0, 0, 0, 1);
Affine orent2 = new Affine();
orent.setTx(lineLen/2);
Affine zp = new Affine();
zp.appendRotation(-90-rotZ, 0, 0, 0, 0, 0, 1);
Affine zTrans = new Affine();
zTrans.setTx(startX);
zTrans.setTy(startY);
zTrans.setTz(startZ);
getTransforms().add(zTrans);
getTransforms().add(zp);
getTransforms().add(xy);
getTransforms().add(orent);
getTransforms().add(orent2);
}
public double getEndZ() {
return endZ;
}
public void setEndZ(double endZ) {
this.endZ = endZ;
}
public double getStartZ() {
return startZ;
}
public void setStartZ(double startZ) {
this.startZ = startZ;
}
public void setStrokeWidth(double radius){
setRadius(radius/2);
}
public void setStroke(Color color) {
Platform.runLater(() -> setMaterial(new PhongMaterial(color)));
}
}

View File

@@ -0,0 +1,110 @@
package com.neuronrobotics.bowlerstudio.threed;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import com.neuronrobotics.bowlerstudio.physics.TransformFactory;
import com.neuronrobotics.imageprovider.AbstractImageProvider;
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Translate;
public class VirtualCameraDevice extends AbstractImageProvider {
private static final int DEFAULT_ZOOM_DEPTH = -1500;
private PerspectiveCamera camera;
private Group hand;
private final Group cameraFrame = new Group();
private double zoomDepth = getDefaultZoomDepth();
private Affine zoomAffine = new Affine();
private static final Affine offset =new Affine();
private Group manipulationFrame;
static {
Platform.runLater(()->TransformFactory.nrToAffine(
new TransformNR(0, 0, 0, new RotationNR(180,0,0)),offset
));
}
public VirtualCameraDevice(PerspectiveCamera camera, Group hand){
this.hand = hand;
this.setCamera(camera);
setScriptingName("virtualCameraDevice");
//System.out.println("Setting camera frame transform");
manipulationFrame = new Group();
camera.getTransforms().add(zoomAffine);
cameraFrame.getTransforms().add(getOffset());
manipulationFrame.getChildren().addAll(camera, hand);
cameraFrame.getChildren().add(manipulationFrame);
//new RuntimeException().printStackTrace();
setZoomDepth(DEFAULT_ZOOM_DEPTH);
}
@Override
public void setGlobalPositionListener(Affine affine) {
super.setGlobalPositionListener(affine);
manipulationFrame.getTransforms().clear();
manipulationFrame.getTransforms().add(affine);
}
@Override
protected boolean captureNewImage(BufferedImage imageData) {
// TODO Auto-generated method stub
return false;
}
@Override
public void disconnectDeviceImp() { }
@Override
public boolean connectDeviceImp() {
return true;
}
@Override
public ArrayList<String> getNamespacesImp() {
return new ArrayList<>();
}
public PerspectiveCamera getCamera() {
return camera;
}
public Group getCameraGroup() {
return getCameraFrame();
}
private void setCamera(PerspectiveCamera camera) {
this.camera = camera;
}
public Group getCameraFrame() {
return cameraFrame;
}
public double getZoomDepth() {
return zoomDepth;
}
public void setZoomDepth(double zoomDepth) {
if(zoomDepth>-2)
zoomDepth=-2;
if(zoomDepth<-5000)
zoomDepth=-5000;
this.zoomDepth = zoomDepth;
zoomAffine.setTz(getZoomDepth());
}
public BufferedImage captureNewImage() {
// TODO Auto-generated method stub
return null;
}
public static int getDefaultZoomDepth() {
return DEFAULT_ZOOM_DEPTH;
}
public static Affine getOffset() {
return offset;
}
}

View File

@@ -0,0 +1,80 @@
package com.neuronrobotics.bowlerstudio.threed;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.sdk.addons.kinematics.IDriveEngine;
import com.neuronrobotics.sdk.addons.kinematics.MobileBase;
import com.neuronrobotics.sdk.addons.kinematics.math.RotationNR;
import com.neuronrobotics.sdk.addons.kinematics.math.TransformNR;
import java.io.FileInputStream;
import java.util.ArrayList;
public class VirtualCameraMobileBase extends MobileBase {
private final static class IDriveEngineImplementation implements IDriveEngine {
double azOffset =0;
double elOffset =0;
double tlOffset =0;
TransformNR pureTrans = new TransformNR();
@Override
public void DriveVelocityStraight(MobileBase source, double cmPerSecond) {
// TODO Auto-generated method stub
}
@Override
public void DriveVelocityArc(MobileBase source, double degreesPerSecond, double cmRadius) {
// TODO Auto-generated method stub
}
@Override
public void DriveArc(MobileBase source, TransformNR newPose, double seconds) {
try{
pureTrans.setX(newPose.getX());
pureTrans.setY(newPose.getY());
pureTrans.setZ(newPose.getZ());
TransformNR global= source.getFiducialToGlobalTransform().times(pureTrans);
//RotationNR finalRot = TransformNR(0,0,0,globalRot).times(newPose).getRotation();
//System.out.println("Azumuth = "+az+" elevation = "+el+" tilt = "+tl);
// Rotation n = newPose.getRotation().getStorage();
// Rotation g = global.getRotation().getStorage();
// Rotation nr =n.compose(g, RotationNR.getConvention());
global.setRotation( new RotationNR(
tlOffset+(Math.toDegrees(newPose.getRotation().getRotationTilt() + global.getRotation().getRotationTilt())%360),
azOffset+(Math.toDegrees(newPose.getRotation().getRotationAzimuth() + global.getRotation().getRotationAzimuth())%360),
elOffset+Math.toDegrees(newPose.getRotation().getRotationElevation() + global.getRotation().getRotationElevation())
));
// global.getRotation().setStorage(nr);
//System.err.println("Camera tilt="+global);
// New target calculated appliaed to global offset
source.setGlobalToFiducialTransform(global);
}catch (Exception ex){
ex.printStackTrace();
}
}
}
private static IDriveEngine de = new IDriveEngineImplementation();
private static ArrayList<VirtualCameraMobileBase> bases= new ArrayList<VirtualCameraMobileBase>();
public VirtualCameraMobileBase() throws Exception{
//super (IOUtils.toInputStream(ScriptingEngine.codeFromGistID("bfa504cdfba41b132c5d","flyingCamera.xml")[0], "UTF-8"));
super(new FileInputStream(AssetFactory.loadFile("layout/flyingCamera.xml")));
//setDriveType(DrivingType.WALKING);
setWalkingDriveEngine(getDriveEngine());
bases.add(this);
}
public static IDriveEngine getDriveEngine() {
return de;
}
public static void setDriveEngine(IDriveEngine de) {
VirtualCameraMobileBase.de = de;
for(VirtualCameraMobileBase base:bases){
base.setWalkingDriveEngine(getDriveEngine());
}
}
}

View File

@@ -0,0 +1,336 @@
/*
* Copyright (c) 2011, 2013 Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.neuronrobotics.bowlerstudio.threed;
import javafx.scene.Group;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Translate;
// TODO: Auto-generated Javadoc
/**
* The Class Xform.
*/
public class Xform extends Group {
/**
* The Enum RotateOrder.
*/
public enum RotateOrder {
/** The xyz. */
XYZ,
/** The xzy. */
XZY,
/** The yxz. */
YXZ,
/** The yzx. */
YZX,
/** The zxy. */
ZXY,
/** The zyx. */
ZYX
}
/** The t. */
public Translate t = new Translate();
/** The p. */
public Translate p = new Translate();
/** The ip. */
public Translate ip = new Translate();
/** The rx. */
public Rotate rx = new Rotate();
{ rx.setAxis(Rotate.X_AXIS); }
/** The ry. */
public Rotate ry = new Rotate();
{ ry.setAxis(Rotate.Y_AXIS); }
/** The rz. */
public Rotate rz = new Rotate();
{ rz.setAxis(Rotate.Z_AXIS); }
/** The s. */
public Scale s = new Scale();
/**
* Instantiates a new xform.
*/
public Xform() {
super();
getTransforms().addAll(t, rz, ry, rx, s);
}
/**
* Instantiates a new xform.
*
* @param rotateOrder the rotate order
*/
public Xform(RotateOrder rotateOrder) {
super();
// choose the order of rotations based on the rotateOrder
switch (rotateOrder) {
case XYZ:
getTransforms().addAll(t, p, rz, ry, rx, s, ip);
break;
case XZY:
getTransforms().addAll(t, p, ry, rz, rx, s, ip);
break;
case YXZ:
getTransforms().addAll(t, p, rz, rx, ry, s, ip);
break;
case YZX:
getTransforms().addAll(t, p, rx, rz, ry, s, ip); // For Camera
break;
case ZXY:
getTransforms().addAll(t, p, ry, rx, rz, s, ip);
break;
case ZYX:
getTransforms().addAll(t, p, rx, ry, rz, s, ip);
break;
}
}
/**
* Sets the translate.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setTranslate(double x, double y, double z) {
t.setX(x);
t.setY(y);
t.setZ(z);
}
/**
* Sets the translate.
*
* @param x the x
* @param y the y
*/
public void setTranslate(double x, double y) {
t.setX(x);
t.setY(y);
}
// Cannot override these methods as they are final:
// public void setTranslateX(double x) { t.setX(x); }
// public void setTranslateY(double y) { t.setY(y); }
// public void setTranslateZ(double z) { t.setZ(z); }
/**
* Sets the tx.
*
* @param x the new tx
*/
// Use these methods instead:
public void setTx(double x) { t.setX(x); }
/**
* Sets the ty.
*
* @param y the new ty
*/
public void setTy(double y) { t.setY(y); }
/**
* Sets the tz.
*
* @param z the new tz
*/
public void setTz(double z) { t.setZ(z); }
/**
* Sets the rotate.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setRotate(double x, double y, double z) {
rx.setAngle(x);
ry.setAngle(y);
rz.setAngle(z);
}
/**
* Sets the rotate x.
*
* @param x the new rotate x
*/
public void setRotateX(double x) { rx.setAngle(x); }
/**
* Sets the rotate y.
*
* @param y the new rotate y
*/
public void setRotateY(double y) { ry.setAngle(y); }
/**
* Sets the rotate z.
*
* @param z the new rotate z
*/
public void setRotateZ(double z) { rz.setAngle(z); }
/**
* Sets the rx.
*
* @param x the new rx
*/
public void setRx(double x) { rx.setAngle(x); }
/**
* Sets the ry.
*
* @param y the new ry
*/
public void setRy(double y) { ry.setAngle(y); }
/**
* Sets the rz.
*
* @param z the new rz
*/
public void setRz(double z) { rz.setAngle(z); }
/**
* Sets the scale.
*
* @param scaleFactor the new scale
*/
public void setScale(double scaleFactor) {
s.setX(scaleFactor);
s.setY(scaleFactor);
s.setZ(scaleFactor);
}
/**
* Sets the scale.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setScale(double x, double y, double z) {
s.setX(x);
s.setY(y);
s.setZ(z);
}
// Cannot override these methods as they are final:
// public void setScaleX(double x) { s.setX(x); }
// public void setScaleY(double y) { s.setY(y); }
// public void setScaleZ(double z) { s.setZ(z); }
/**
* Sets the sx.
*
* @param x the new sx
*/
// Use these methods instead:
public void setSx(double x) { s.setX(x); }
/**
* Sets the sy.
*
* @param y the new sy
*/
public void setSy(double y) { s.setY(y); }
/**
* Sets the sz.
*
* @param z the new sz
*/
public void setSz(double z) { s.setZ(z); }
/**
* Sets the pivot.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setPivot(double x, double y, double z) {
p.setX(x);
p.setY(y);
p.setZ(z);
ip.setX(-x);
ip.setY(-y);
ip.setZ(-z);
}
/**
* Reset.
*/
public void reset() {
t.setX(0.0);
t.setY(0.0);
t.setZ(0.0);
rx.setAngle(0.0);
ry.setAngle(0.0);
rz.setAngle(0.0);
s.setX(1.0);
s.setY(1.0);
s.setZ(1.0);
p.setX(0.0);
p.setY(0.0);
p.setZ(0.0);
ip.setX(0.0);
ip.setY(0.0);
ip.setZ(0.0);
}
/**
* Reset tsp.
*/
public void resetTSP() {
t.setX(0.0);
t.setY(0.0);
t.setZ(0.0);
s.setX(1.0);
s.setY(1.0);
s.setZ(1.0);
p.setX(0.0);
p.setY(0.0);
p.setZ(0.0);
ip.setX(0.0);
ip.setY(0.0);
ip.setZ(0.0);
}
}

View File

@@ -0,0 +1,246 @@
package com.neuronrobotics.bowlerstudio.utils;
import com.neuronrobotics.bowlerstudio.BowlerStudioController;
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import com.neuronrobotics.sdk.common.BowlerDatagram;
import com.neuronrobotics.sdk.common.DeviceManager;
import com.neuronrobotics.sdk.common.Log;
import com.neuronrobotics.sdk.network.BowlerTCPClient;
import com.neuronrobotics.sdk.network.UDPBowlerConnection;
import com.neuronrobotics.sdk.serial.SerialConnection;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.net.InetAddress;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
/**
* Sample Skeleton for "BowlerConnectionMenue.fxml" Controller Class
* You can copy and paste this code into your favorite IDE
**/
public class BowlerConnectionMenu extends Application {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="baudrate"
private TextField baudrate; // Value injected by FXMLLoader
@FXML // fx:id="connectNetwork"
private Button connectNetwork; // Value injected by FXMLLoader
@FXML // fx:id="connectSerial"
private Button connectSerial; // Value injected by FXMLLoader
@FXML // fx:id="portOptions"
private ComboBox<String> portOptions; // Value injected by FXMLLoader
@FXML
private ComboBox<String> ipSelector;
@FXML // fx:id="portType"
private ToggleGroup portType; // Value injected by FXMLLoader
@FXML // fx:id="searchNetwork"
private Button searchNetwork; // Value injected by FXMLLoader
@FXML // fx:id="searchSerial"
private Button searchSerial; // Value injected by FXMLLoader
@FXML // fx:id="tcpPort"
private TextField tcpPort; // Value injected by FXMLLoader
@FXML // fx:id="tcpSelect"
private RadioButton tcpSelect; // Value injected by FXMLLoader
@FXML // fx:id="udpPort"
private TextField udpPort; // Value injected by FXMLLoader
@FXML // fx:id="udpSelect"
private RadioButton udpSelect; // Value injected by FXMLLoader
private UDPBowlerConnection clnt;
private int defaultPortNum = 1865;
private Stage primaryStage;
private String port;
private int baud;
@FXML // This method is called by the FXMLLoader when initialization is
// complete
void initialize() {
System.err.println("Initializing conection Dialog");
assert baudrate != null : "fx:id=\"baudrate\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert connectNetwork != null : "fx:id=\"connectNetwork\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert connectSerial != null : "fx:id=\"connectSerial\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert portOptions != null : "fx:id=\"portOptions\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert portType != null : "fx:id=\"portType\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert searchNetwork != null : "fx:id=\"searchNetwork\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert searchSerial != null : "fx:id=\"searchSerial\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert tcpPort != null : "fx:id=\"tcpPort\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert tcpSelect != null : "fx:id=\"tcpSelect\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert udpPort != null : "fx:id=\"udpPort\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert udpSelect != null : "fx:id=\"udpSelect\" was not injected: check your FXML file 'BowlerConnectionMenue.fxml'.";
assert ipSelector != null : "fx:id=\"ipSelector\" was not injected: check your FXML file 'BowlerConnectionMenu.fxml'.";
runsearchSerial();
runsearchNetwork();
searchNetwork.setOnAction(event -> {
runsearchNetwork();
});
searchSerial.setOnAction(event -> {
runsearchSerial();
});
connectNetwork.setOnAction(event -> {
runconnectNetwork();
primaryStage.hide();
});
connectSerial.setOnAction(event -> {
runconnectSerial();
primaryStage.hide();
});
}
private void runconnectSerial() {
new Thread(() -> {
for (int i = 0; i < 3; i++) {
SerialConnection ser=null;
try {
BowlerDatagram.setUseBowlerV4(true);
baud = Integer.parseInt(baudrate.getText());
if (baud < 0) {
throw new NumberFormatException();
}
port = portOptions.getSelectionModel().getSelectedItem().toString();
int level = Log.getMinimumPrintLevel();
//Log.enableInfoPrint();
ser = new SerialConnection(port, baud);
DeviceManager.addConnection(ser);
return;
} catch (Exception e) {
System.out.println("false start " + port + " at baud " + baud + " is not responding");
BowlerStudioController.highlightException(null, e);
e.printStackTrace();
if (ser!=null)
ser.disconnect();
}
}
System.out.println("Connection failed! " + port + " at baud " + baud + " is not responding");
}).start();
}
private void runconnectNetwork() {
new Thread(() -> {
int port;
String ip = ipSelector.getSelectionModel().getSelectedItem().toString();
if (udpSelect.isSelected()) {
port = Integer.parseInt(udpPort.getText());
try {
clnt = new UDPBowlerConnection(InetAddress.getByName(ip), port);
DeviceManager.addConnection(clnt);
} catch (Exception e) {
System.out.println("Connection failed! " + ip + " at port " + ip + " is not responding");
BowlerStudioController.highlightException(null, e);
if (clnt != null)
clnt.disconnect();
}
} else {
port = Integer.parseInt(tcpPort.getText());
BowlerTCPClient tcp = null;
try {
tcp = new BowlerTCPClient(ip, port);
DeviceManager.addConnection(tcp);
} catch (Exception e) {
System.out.println("Connection failed! " + ip + " at port " + ip + " is not responding");
BowlerStudioController.highlightException(null, e);
if (tcp != null)
tcp.disconnect();
}
}
}).start();
}
private void runsearchSerial() {
Platform.runLater(() -> {
portOptions.getItems().clear();
new Thread(() -> {
for (String s : SerialConnection.getAvailableSerialPorts()) {
Platform.runLater(() -> portOptions.getItems().add(s));
}
}).start();
});
}
private void runsearchNetwork() {
Platform.runLater(() -> {
ipSelector.getItems().clear();
Platform.runLater(() -> ipSelector.getItems().add("127.0.0.1"));
new Thread(() -> {
// System.out.println("Searching for UDP devices, please
// wait...");
int prt;
try {
prt = new Integer(udpPort.getText());
} catch (NumberFormatException e) {
prt = defaultPortNum;
Platform.runLater(() -> udpPort.setText(new Integer(defaultPortNum).toString()));
}
clnt = new UDPBowlerConnection(prt);
ArrayList<InetAddress> addrs = clnt.getAllAddresses();
for (InetAddress i : addrs) {
Platform.runLater(() -> ipSelector.getItems().add(i.getHostAddress()));
}
}).start();
});
}
@SuppressWarnings("restriction")
@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
FXMLLoader loader = AssetFactory.loadLayout("layout/BowlerConnectionMenu.fxml", true);
Parent root;
loader.setController(this);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
Platform.runLater(() -> {
primaryStage.setTitle("Bowler Device Connection");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.initModality(Modality.WINDOW_MODAL);
primaryStage.setResizable(true);
primaryStage.show();
});
}
}

View File

@@ -0,0 +1,232 @@
package com.neuronrobotics.bowlerstudio.utils;
/**
* Sample Skeleton for 'findWidget.fxml' Controller Class
*/
import com.neuronrobotics.bowlerstudio.assets.AssetFactory;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import java.awt.*;
import java.net.URL;
import java.util.ResourceBundle;
public class FindTextWidget extends Application {
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // fx:id="matchCase"
private CheckBox matchCase; // Value injected by FXMLLoader
@FXML // fx:id="findBox"
private TextField findBox; // Value injected by FXMLLoader
@FXML // fx:id="replaceBox"
private TextField replaceBox; // Value injected by FXMLLoader
private Stage primaryStage;
private RSyntaxTextArea textArea;
private int pos = 0;
private int find(double direction) {
// SwingUtilities.invokeLater(() -> {
try {
// System.out.println("Got ctrl f "+
// textArea.getSelectedText());
// Get the text to find...convert it to
// lower
// case for eaiser comparision
String find = findBox.getText();
if (!matchCase.isSelected()) {
find = find.toLowerCase();
}
// Focus the text area, otherwise the
// highlighting won't show up
textArea.requestFocusInWindow();
// Make sure we have a valid search term
if (find != null && find.length() > 0) {
Document document = textArea.getDocument();
int findLength = find.length();
try {
boolean found = false;
// Rest the search position if we're
// at
// the end of the document
if (pos + findLength > document.getLength()) {
pos = 0;
}
if (pos < 0) {
pos = document.getLength() - findLength;
}
// While we haven't reached the
// end...
// "<=" Correction
while (pos + findLength <= document.getLength() && pos >= 0) {
// Extract the text from teh
// docuemnt
String match = document.getText(pos, findLength);
if (!matchCase.isSelected()) {
match = match.toLowerCase();
}
// Check to see if it matches or
// request
if (match.equals(find)) {
found = true;
break;
}
pos += 1 * direction;
}
int baseOfFind = pos;
// Did we find something...
if (found) {
SwingUtilities.invokeLater(() -> {
// Get the rectangle of the
// where
// the text would be visible...
Rectangle viewRect;
try {
viewRect = textArea.modelToView(pos);
// Scroll to make the rectangle
// visible
textArea.scrollRectToVisible(viewRect);
// Highlight the text
textArea.setCaretPosition((int) (pos));
textArea.moveCaretPosition(pos + findLength);
// Move the search position
// beyond
// the current match
pos += findLength * direction;
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
return baseOfFind;
} catch (Exception exp) {
exp.printStackTrace();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
// });
return pos;
}
private void replace(double direction) {
new Thread(() -> {
String find = findBox.getText();
String replace = replaceBox.getText();
if(replace==null)
replace="";
String current = textArea.getText();
int intLengthOfRemove = find.length();
if(pos>=intLengthOfRemove){
String firstHalf = current.substring(0,pos-intLengthOfRemove);
String secondtHalf = current.substring(pos );
if(direction>0) {
if(secondtHalf.length()<=intLengthOfRemove) {
//bail
return;
}
}
else {
if(firstHalf.length()<=intLengthOfRemove) {
//bail
return;
}
}
String newContent = firstHalf + replace + secondtHalf;
SwingUtilities.invokeLater(() ->{
textArea.setText(newContent);
find(direction);
});
}else{
find(direction);
}
}).start();
}
@FXML
void findPrevious(ActionEvent event) {
find(-1);
}
@FXML
void findNext(ActionEvent event) {
find(1);
}
@FXML
void replaceNext(ActionEvent event) {
replace(1);
}
@FXML
void replacePrevious(ActionEvent event) {
replace(-1);
}
@FXML // This method is called by the FXMLLoader when initialization is
// complete
void initialize() {
assert matchCase != null : "fx:id=\"matchCase\" was not injected: check your FXML file 'findWidget.fxml'.";
assert findBox != null : "fx:id=\"findBox\" was not injected: check your FXML file 'findWidget.fxml'.";
assert replaceBox != null : "fx:id=\"replaceBox\" was not injected: check your FXML file 'findWidget.fxml'.";
if (textArea.getSelectedText() != null) {
Platform.runLater(() -> findBox.setText(textArea.getSelectedText()));
}
}
@SuppressWarnings("restriction")
@Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
FXMLLoader loader = AssetFactory.loadLayout("layout/findWidget.fxml", true);
Parent root;
loader.setController(this);
// This is needed when loading on MAC
loader.setClassLoader(getClass().getClassLoader());
root = loader.load();
Platform.runLater(() -> {
primaryStage.setTitle("Find/Replace");
Scene scene = new Scene(root);
primaryStage.setScene(scene);
// primaryStage.initModality(Modality.WINDOW_MODAL);
primaryStage.setResizable(true);
primaryStage.show();
});
}
public void setTextArea(RSyntaxTextArea textArea) {
this.textArea = textArea;
pos = 0;
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,35 @@
package com.neuronrobotics.bowlerstudio.utils;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
import eu.mihosoft.vrl.v3d.CSG;
import eu.mihosoft.vrl.v3d.Polygon;
import eu.mihosoft.vrl.v3d.Slice;
import eu.mihosoft.vrl.v3d.Transform;
import eu.mihosoft.vrl.v3d.svg.SVGExporter;
@SuppressWarnings("restriction")
public class SVGFactory{
public static File exportSVG(CSG currentCsg, File defaultDir) {
System.out.println("Starting SVG ...");
File baseDirForFiles = FileSelectionFactory.GetFile(defaultDir, true);
if (!baseDirForFiles.getAbsolutePath().toLowerCase().endsWith(".svg"))
baseDirForFiles = new File(baseDirForFiles.getAbsolutePath() + ".svg");
try {
SVGExporter.export(currentCsg, baseDirForFiles);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("SVG at "+baseDirForFiles);
return baseDirForFiles.getParentFile();
}
}

View File

@@ -0,0 +1,51 @@
package com.neuronrobotics.graphing;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import com.neuronrobotics.sdk.common.SDKInfo;
public class CSVWriter {
private CSVWriter() {
}
public static void WriteToCSV(ArrayList<GraphDataElement> dataTable, String filename) {
String out = "";
synchronized(dataTable){
for(int j =0;j< dataTable.size();j++) {
out+=dataTable.get(j).getTimestamp();
for (int i=0;i<dataTable.get(j).getData().length;i++) {
out+=","+dataTable.get(j).getData()[i];
}
out+="\r\n";
}
}
try{
// Create file
FileWriter fstream = new FileWriter(filename);
BufferedWriter outPut = new BufferedWriter(fstream);
outPut.write(out);
//Close the output stream
outPut.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
File dir1 = new File (".");
try {
String dir;
if(SDKInfo.isWindows)
dir=dir1.getCanonicalPath()+"\\";
else
dir=dir1.getCanonicalPath()+"/";
JOptionPane.showMessageDialog(null, "Saved data to file: "+dir+filename, "PID Save", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
}
}
}

View File

@@ -0,0 +1,53 @@
package com.neuronrobotics.graphing;
import javafx.application.Platform;
import org.jfree.data.xy.XYSeries;
public class DataChannel {
private String title;
private XYSeries series;
private static long startTime = System.currentTimeMillis();
private long lastTime = System.currentTimeMillis();
public DataChannel(String title) {
this.title = title;
series = new XYSeries(toString());
}
public String toString() {
return title;
}
public void graphValue(double value) {
if((lastTime+100)>System.currentTimeMillis())
return;
lastTime= System.currentTimeMillis();
// try{
// Platform.runLater(()-> {
// long time = System.currentTimeMillis() - startTime ;
// if(series != null)
// series.add((double) time/1000, value);
// while(series.getItemCount()>3000){
// Platform.runLater(()-> {
// series.remove(0);
// });
// }
// });
// }catch(IllegalStateException ex){
// //application not yet loaded
// }
}
public XYSeries getSeries() {
return series;
}
public static void restart() {
startTime = System.currentTimeMillis();
}
public void clear() {
series.clear();
}
}

View File

@@ -0,0 +1,9 @@
package com.neuronrobotics.graphing;
import java.io.File;
public interface DataWriter {
public void setFile(File f);
public void addData(DataChannel c);
public void cleanup();
}

View File

@@ -0,0 +1,87 @@
package com.neuronrobotics.graphing;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import org.jfree.data.xy.XYDataItem;
public class ExcelWriter implements DataWriter {
private WorkbookSettings wbSettings = new WorkbookSettings();
private WritableWorkbook workbook;
private WritableSheet excelSheet;
private int lineOffset = 0;
public ExcelWriter() {
wbSettings.setLocale(new Locale("en", "EN"));
}
private void addNumber(int column, int row, double d) throws WriteException, RowsExceededException {
Number number;
number = new Number(column, row, d);
excelSheet.addCell(number);
}
private void addLabel(int column, int row, String s) throws WriteException, RowsExceededException {
Label label;
label = new Label(column, row, s);
excelSheet.addCell(label);
}
public void setFile(File f) {
try {
workbook = Workbook.createWorkbook(f, wbSettings);
workbook.createSheet("Data", 0);
excelSheet = workbook.getSheet(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void addData(DataChannel c) {
try {
int col = 1;
addLabel(lineOffset, 0, c.toString() + " Time (ms)");
addLabel(lineOffset+1, 0, c.toString() + " Value");
for(Object o : c.getSeries().getItems()) {
XYDataItem i = (XYDataItem) o;
addNumber(lineOffset, col, i.getXValue());
addNumber(lineOffset+1, col, i.getYValue());
col++;
}
} catch (RowsExceededException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (WriteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lineOffset+=2;
}
public void cleanup() {
try {
workbook.write();
workbook.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,23 @@
package com.neuronrobotics.graphing;
public class GraphDataElement {
private long ms;
private double [] data;
public GraphDataElement(long currentTimeMillis, double [] data) {
setTimestamp(currentTimeMillis);
this.setData(data);
}
public void setData(double [] data) {
this.data = data;
}
public double [] getData() {
return data;
}
public void setTimestamp(long ms) {
this.ms = ms;
}
public long getTimestamp() {
return ms;
}
}

View File

@@ -0,0 +1,26 @@
package com.neuronrobotics.graphing;
import javax.swing.JFrame;
import javax.swing.JLabel;
import net.miginfocom.swing.MigLayout;
public class GraphingOptionsDialog extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
@SuppressWarnings("unused")
private GraphingWindow window;
public GraphingOptionsDialog(GraphingWindow window) {
this.window = window;
setLayout(new MigLayout());
setTitle("Graphing Options");
add(new JLabel("Graphing Options"));
pack();
setLocationRelativeTo(null);
}
}

View File

@@ -0,0 +1,211 @@
package com.neuronrobotics.graphing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.Range;
import org.jfree.data.xy.XYSeriesCollection;
public class GraphingWindow extends JPanel {
private XYSeriesCollection xyDataset;
private ChartPanel chartPanel;
private ValueAxis axis;
private JTextField length = new JTextField(5);
private JSlider window = new JSlider(1, 100);
private JSlider scale = new JSlider(1, 100);
private ArrayList<DataChannel> dataChannels = new ArrayList<>();
/**
* long
*/
private static final long serialVersionUID = 2171583604829088880L;
public GraphingWindow() {
setName("DyIO Graph");
xyDataset = new XYSeriesCollection();
JFreeChart chart = ChartFactory.createXYLineChart(
"Live Data",
"Time",
"Value",
xyDataset,
PlotOrientation.VERTICAL,
true,
false,
false);
chartPanel = new ChartPanel(chart);
XYPlot plot = (XYPlot) chart.getPlot();
axis = plot.getDomainAxis();
scale.setValue(100);
setDefaultWindow();
scale.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if(window.getValue() ==100) {
setDefaultWindow();
}else {
setMovedWindow(window.getValue());
}
}
});
window.setValue(100);
window.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if(window.getValue() ==100) {
setDefaultWindow();
}else {
setMovedWindow(window.getValue());
}
}
});
length.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() != '\n' && (e.getKeyChar() < '0' || e.getKeyChar() > '9')) {
e.consume();
}
}
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
});
length.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int value;
try {
value = Integer.parseInt(length.getText());
} catch(Exception e) {
value = scale.getMaximum();
}
axis.setFixedAutoRange(value);
length.setText(String.valueOf(value));
scale.setValue(value);
invalidate();
repaint();
}
});
JButton clearBtn = new JButton("Clear Data");
clearBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
for(DataChannel dc : dataChannels) {
dc.clear();
}
}
});
JPanel options = new JPanel(new MigLayout());
options.add(new JLabel("Range Size:"));
options.add(scale);
options.add(length);
options.add(new JLabel("seconds"));
options.add(clearBtn, "east");
setLayout(new BorderLayout());
setSize(new Dimension(500, 400));
add(chartPanel, BorderLayout.CENTER);
add(options, BorderLayout.SOUTH);
JPanel opt= new JPanel(new MigLayout());
opt.add(new JLabel("View Window"));
opt.add(window);
JPanel slidingWindow= new JPanel(new MigLayout());
slidingWindow.add(options, "wrap");
slidingWindow.add(opt, "wrap");
add(slidingWindow, BorderLayout.SOUTH);
}
private void setDefaultWindow() {
axis.setAutoRange(true);
axis.setFixedAutoRange(scale.getValue());
length.setText(String.valueOf(scale.getValue()));
//invalidate();
repaint();
}
private void setMovedWindow(double percent) {
axis.setAutoRange(false);
Range total = xyDataset.getDomainBounds(true);
double lower =total.getLowerBound();
double upper =total.getUpperBound();
double loc = (upper -lower)*percent/100;
double sLower =loc-(scale.getValue()/2);
double sUpper =loc+(scale.getValue()/2);
axis.setRange(sLower, sUpper);
length.setText(String.valueOf(scale.getValue()));
//invalidate();
//repaint();
}
public void addDataset(DataChannel data) {
if(!dataChannels.contains(data)) {
dataChannels.add(data);
}
if(!(xyDataset.indexOf(data.getSeries()) > -1)) {
showDataChannel(data);
}
}
public void removeDataset(DataChannel data) {
if(!dataChannels.contains(data)) {
dataChannels.add(data);
}
if(xyDataset.indexOf(data.getSeries()) > -1) {
hideDataChannel(data);
}
}
public void hideDataChannel(DataChannel data) {
xyDataset.removeSeries(data.getSeries());
}
public void showDataChannel(DataChannel data) {
xyDataset.addSeries(data.getSeries());
}
}

View File

@@ -0,0 +1,47 @@
package com.neuronrobotics.nrconsole.plugin.BowlerCam;
import javafx.embed.swing.SwingNode;
import javafx.scene.control.ScrollPane;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
import com.neuronrobotics.sdk.bowlercam.device.BowlerCamDevice;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
public class BowlerCamController extends AbstractBowlerStudioTab{
private BowlerCamPanel bcp = new BowlerCamPanel();
@Override
public void onTabClosing() {
// TODO Auto-generated method stub
}
@Override
public String[] getMyNameSpaces() {
// TODO Auto-generated method stub
return new String[] {"neuronrobotics.bowlercam.*"};
}
@Override
public void initializeUI(BowlerAbstractDevice pm) {
bcp.setConnection((BowlerCamDevice)pm);
SwingNode sn = new SwingNode();
sn.setContent(bcp);
ScrollPane s1 = new ScrollPane();
s1.setContent(sn);
setContent(s1);
setText("BowlerCam Control");
onTabReOpening();
}
@Override
public void onTabReOpening() {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,177 @@
package com.neuronrobotics.nrconsole.plugin.BowlerCam;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.text.NumberFormat;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
import com.neuronrobotics.sdk.bowlercam.device.BowlerCamDevice;
import com.neuronrobotics.sdk.bowlercam.device.IWebcamImageListener;
import com.neuronrobotics.sdk.common.BowlerAbstractConnection;
import com.neuronrobotics.sdk.util.ThreadUtil;
public class BowlerCamPanel extends JPanel implements IWebcamImageListener {
/**
* long
*/
private static final long serialVersionUID = 8710018539364791015L;
private BowlerCamDevice cam = new BowlerCamDevice();
private JPanel directPanel = new JPanel(new MigLayout());
private JPanel bcPanel = new JPanel(new MigLayout());
private JPanel images = new JPanel(new MigLayout());
private JPanel controls = new JPanel(new MigLayout());
private JPanel sliders = new JPanel(new MigLayout());
private JLabel fps = new JLabel("FPS: ");
private JLabel thr = new JLabel("");
private RGBSlider target = new RGBSlider("Target Color");
//private RGBSlider vector = new RGBSlider("Vector Color");
private JSlider threshhold = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 104);
private JFormattedTextField min = new JFormattedTextField(NumberFormat.getNumberInstance());
private JFormattedTextField max = new JFormattedTextField(NumberFormat.getNumberInstance());
private JFormattedTextField scale = new JFormattedTextField(NumberFormat.getNumberInstance());
private JCheckBox within = new JCheckBox("Within Threshhold");
private JButton update = new JButton("Update Processor");
private BufferedImage unaltered=null;
private BufferedImage processedIm=null;
private long time;
double scaleSet = 1;
public BowlerCamPanel() {
setName("Bowler Camera");
images.add(directPanel);
images.add(bcPanel);
bcPanel.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mouseEntered(MouseEvent arg0) {}
public void mouseClicked(MouseEvent arg0) {
Color cl = new Color(unaltered.getRGB(arg0.getX(), arg0.getY()));
getTargetColor().setColor(cl);
}
});
sliders.add(fps,"wrap");
target.setColor(33,240, 246);
sliders.add(target);
controls.add(new JLabel("Threshhold"),"wrap");
controls.add(threshhold);
controls.add(thr,"wrap");
thr.setText(Integer.toString(threshhold.getValue()));
controls.add(within,"wrap");
within.setSelected(true);
controls.add(new JLabel("Image Scale"));
controls.add(scale,"wrap");
scale.setText(Double.toString(scaleSet));
min.setText("5");
max.setText("100000");
controls.add(new JLabel("Minimum pixles per blob"));
controls.add(min,"wrap");
controls.add(new JLabel("Maximum pixles per blob"));
controls.add(max,"wrap");
update.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int minimum= Integer.parseInt(min.getText());
int maximum= Integer.parseInt(max.getText());
cam.updateFilter(target.getColor(), threshhold.getValue(), within.isSelected(),minimum, maximum);
}
});
controls.add(update);
JPanel tmp2 = new JPanel(new MigLayout());
tmp2.add(sliders);
tmp2.add(controls);
add(tmp2,"wrap");
add(images,"wrap");
}
public boolean setConnection(BowlerCamDevice connection) {
try {
cam=connection;
cam.addWebcamImageListener(this);
cam.startHighSpeedAutoCapture(0,scaleSet,5);
cam.startHighSpeedAutoCapture(1,scaleSet,5);
new displayThread().start();
}catch(Exception ex) {
return false;
}
return true;
}
private void displayImage() {
thr.setText(Integer.toString(threshhold.getValue()));
target.getColor();
if(scaleSet != Double.parseDouble(scale.getText())){
//System.out.println("Resetting scale : "+scale.getText());
scaleSet = Double.parseDouble(scale.getText());
cam.startHighSpeedAutoCapture(0,scaleSet,0);
}
updateImage(unaltered ,bcPanel);
updateImage(processedIm,directPanel);
}
protected RGBSlider getTargetColor() {
return target;
}
private void updateImage(BufferedImage imageUpdate, JPanel p){
if(imageUpdate ==null)
return;
p.removeAll();
JLabel l = new JLabel();
l.setIcon(new ImageIcon(imageUpdate));
p.add(l);
p.invalidate();
}
public void onNewImage(int camera,BufferedImage image) {
//System.out.println("Got image: "+camera+" at "+System.currentTimeMillis());
if(camera == 0){
double s=((double)(System.currentTimeMillis()-time))/1000.0;
fps.setText("FPS: "+(int)(1/(s)));
time = System.currentTimeMillis();
unaltered=image;
//process();
//displayImage();
}
if(camera == 1){
processedIm=image;
}
}
private class displayThread extends Thread{
public void run() {
while(cam.isAvailable()) {
ThreadUtil.wait(200);
displayImage();
}
cam.disconnect();
cam.stopAutoCapture(0);
cam.stopAutoCapture(1);
//System.out.println("Bowler cam exiting");
}
}
}

View File

@@ -0,0 +1,102 @@
package com.neuronrobotics.nrconsole.plugin.BowlerCam;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import net.miginfocom.swing.MigLayout;
public class RGBSlider extends JPanel {
JSlider r = new JSlider(SwingConstants.VERTICAL, 0, 255, 128);
JSlider g = new JSlider(SwingConstants.VERTICAL, 0, 255, 128);
JSlider b = new JSlider(SwingConstants.VERTICAL, 0, 255, 128);
JLabel rl = new JLabel("128");
JLabel gl = new JLabel("128");
JLabel bl = new JLabel("128");
ColorBox c = new ColorBox(Color.gray);
/**
*
*/
private static final long serialVersionUID = 1L;
public RGBSlider(String name){
setLayout(new MigLayout());
r.setMajorTickSpacing(15);
g.setMajorTickSpacing(15);
b.setMajorTickSpacing(15);
r.setPaintTicks(true);
g.setPaintTicks(true);
b.setPaintTicks(true);
JPanel rc = new JPanel(new MigLayout());
JPanel gc = new JPanel(new MigLayout());
JPanel bc = new JPanel(new MigLayout());
rc.add(new JLabel("R"));
rc.add(rl,"wrap");
rc.add(r);
gc.add(new JLabel("G"));
gc.add(gl,"wrap");
gc.add(g);
bc.add(new JLabel("B"));
bc.add(bl,"wrap");
bc.add(b);
JPanel slides = new JPanel(new MigLayout());
slides.add(new JLabel(name),"wrap");
slides.add(rc);
slides.add(gc);
slides.add(bc);
add(slides,"wrap");
add(c,"wrap");
}
public void setColor(int r,int g,int b){
this.r.setValue(r);
this.g.setValue(g);
this.b.setValue(b);
getColor();
}
public void setColor(Color c){
this.r.setValue(c.getRed());
this.g.setValue(c.getGreen());
this.b.setValue(c.getBlue());
getColor();
}
public Color getColor(){
rl.setText(Integer.toString(r.getValue()));
gl.setText(Integer.toString(g.getValue()));
bl.setText(Integer.toString(b.getValue()));
Color now =new Color(r.getValue(),g.getValue(),b.getValue());
c.setColor(now);
setBackground(now);
return now;
}
private class ColorBox extends JPanel
{
/**
* long
*/
private static final long serialVersionUID = 1L;
public ColorBox(Color backColor){
setSize(400, 400);
setColor(backColor);
}
public void setColor(Color c) {
setBackground(c);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
}
}
}

View File

@@ -0,0 +1,168 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ScrollPaneConstants;
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.LinkType;
import com.neuronrobotics.sdk.namespace.bcs.pid.IPidControlNamespace;
import java.awt.FlowLayout;
import javax.swing.JList;
import java.awt.BorderLayout;
import net.miginfocom.swing.MigLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
public class AxisPanel extends JPanel {
private LinkConfiguration thisLink;
private JList list;
private JScrollPane scrollPane;
private JPanel viewPanel;
private JButton btnNewButton;
private JButton btnNewButton_1;
private SettingsListItem setLinkName;
private SettingsListItem setLinkType;
private SettingsListItem setHardwareIndex;
private SettingsListItem setHomingTicksPerSecond;
private SettingsListItem setIndexLatch;
private SettingsListItem setKP;
private SettingsListItem setKI;
private SettingsListItem setKD;
private SettingsListItem setLowerLimit;
private SettingsListItem setUpperLimit;
private SettingsListItem setLowerVelocity;
private SettingsListItem setUpperVelocity;
private SettingsListItem setLinkIndex;
private SettingsListItem setScale;
public AxisPanel(LinkConfiguration _thisLink){
setLayout(new BorderLayout(0, 0));
add(getScrollPane());
thisLink = _thisLink;
//getScrollPane().add(new SettingsListItem());
viewPanel.add(setLinkName = new SettingsListItem("Link Name", thisLink.getName()), "cell 0 0");
FlowLayout flowLayout = (FlowLayout) setLinkName.getLayout();
flowLayout.setAlignment(FlowLayout.LEFT);
viewPanel.add(setLinkType = new SettingsListItem("Link Type", thisLink.getTypeEnum().getName()), "cell 0 1");
FlowLayout flowLayout_1 = (FlowLayout) setLinkType.getLayout();
flowLayout_1.setAlignment(FlowLayout.LEFT);
viewPanel.add(setHardwareIndex = new SettingsListItem("Hardware Index", thisLink.getHardwareIndex()), "cell 0 2");
FlowLayout flowLayout_2 = (FlowLayout) setHardwareIndex.getLayout();
flowLayout_2.setAlignment(FlowLayout.LEFT);
viewPanel.add(setHomingTicksPerSecond = new SettingsListItem("Homing Ticks per Second", thisLink.getHomingTicksPerSecond()), "cell 0 3");
FlowLayout flowLayout_3 = (FlowLayout) setHomingTicksPerSecond.getLayout();
flowLayout_3.setAlignment(FlowLayout.LEFT);
viewPanel.add(setIndexLatch = new SettingsListItem("Index Latch",thisLink.getIndexLatch()), "cell 0 4");
FlowLayout flowLayout_4 = (FlowLayout) setIndexLatch.getLayout();
flowLayout_4.setAlignment(FlowLayout.LEFT);
viewPanel.add(setKP = new SettingsListItem("KP",thisLink.getKP()), "cell 0 5");
FlowLayout flowLayout_5 = (FlowLayout) setKP.getLayout();
flowLayout_5.setAlignment(FlowLayout.LEFT);
viewPanel.add(setKI = new SettingsListItem("KI", thisLink.getKI()), "cell 0 6");
FlowLayout flowLayout_6 = (FlowLayout) setKI.getLayout();
flowLayout_6.setAlignment(FlowLayout.LEFT);
viewPanel.add(setKD = new SettingsListItem("KD", thisLink.getKD()), "cell 0 7");
FlowLayout flowLayout_7 = (FlowLayout) setKD.getLayout();
flowLayout_7.setAlignment(FlowLayout.LEFT);
viewPanel.add(setLowerLimit = new SettingsListItem("Lower Limit", thisLink.getLowerLimit()), "cell 0 8");
FlowLayout flowLayout_8 = (FlowLayout) setLowerLimit.getLayout();
flowLayout_8.setAlignment(FlowLayout.LEFT);
viewPanel.add(setUpperLimit = new SettingsListItem("Upper Limit", thisLink.getUpperLimit()), "cell 0 9");
FlowLayout flowLayout_9 = (FlowLayout) setUpperLimit.getLayout();
flowLayout_9.setAlignment(FlowLayout.LEFT);
viewPanel.add(setLowerVelocity = new SettingsListItem("Lower Velocity", thisLink.getLowerVelocity()), "cell 0 10");
FlowLayout flowLayout_10 = (FlowLayout) setLowerVelocity.getLayout();
flowLayout_10.setAlignment(FlowLayout.LEFT);
viewPanel.add(setUpperVelocity = new SettingsListItem("Upper Velocity", thisLink.getUpperVelocity()), "cell 0 11");
FlowLayout flowLayout_11 = (FlowLayout) setUpperVelocity.getLayout();
flowLayout_11.setAlignment(FlowLayout.LEFT);
viewPanel.add(setLinkIndex = new SettingsListItem("Link Index",thisLink.getLinkIndex()), "cell 0 12");
FlowLayout flowLayout_12 = (FlowLayout) setLinkIndex.getLayout();
flowLayout_12.setAlignment(FlowLayout.LEFT);
viewPanel.add(setScale = new SettingsListItem("Scale" ,thisLink.getScale()), "cell 0 13");
FlowLayout flowLayout_13 = (FlowLayout) setScale.getLayout();
flowLayout_13.setAlignment(FlowLayout.LEFT);
//viewPanel.add(new SettingsListItem(), "cell 0 14");
//viewPanel.add(new SettingsListItem(), "cell 0 15");
//viewPanel.add(new SettingsListItem(), "cell 0 16");
//viewPanel.add(new SettingsListItem(), "cell 0 17");
}
public LinkConfiguration getLink(){
return thisLink;
}
private JList getList() {
if (list == null) {
list = new JList();
}
return list;
}
private void reloadSettings(){
setLinkName.loadValues("Link Name", thisLink.getName());
setLinkType.loadValues("Link Type", thisLink.getTypeEnum().getName());
setHardwareIndex.loadValues("Hardware Index", thisLink.getHardwareIndex());
setHomingTicksPerSecond.loadValues("Homing Ticks per Second", thisLink.getHomingTicksPerSecond());
setIndexLatch.loadValues("Index Latch",thisLink.getIndexLatch());
setKP.loadValues("KP",thisLink.getKP());
setKI.loadValues("KI", thisLink.getKI());
setKD.loadValues("KD", thisLink.getKD());
setLowerLimit.loadValues("Lower Limit", thisLink.getLowerLimit());
setUpperLimit.loadValues("Upper Limit", thisLink.getUpperLimit());
setLowerVelocity.loadValues("Lower Velocity", thisLink.getLowerVelocity());
setUpperVelocity.loadValues("Upper Velocity", thisLink.getUpperVelocity());
setLinkIndex.loadValues("Link Index",thisLink.getLinkIndex());
setScale.loadValues("Scale" ,thisLink.getScale());
}
public void writeSettings(){
thisLink.setName(setLinkName.getStringValue());
thisLink.setType(LinkType.fromString(setLinkType.getStringValue()));
thisLink.setHardwareIndex(setHardwareIndex.getIntValue());
thisLink.setHomingTicksPerSecond(setHomingTicksPerSecond.getIntValue());
thisLink.setIndexLatch(setIndexLatch.getIntValue());
thisLink.setKP(setKP.getDoubleValue());
thisLink.setKI(setKI.getDoubleValue());
thisLink.setKD(setKD.getDoubleValue());
thisLink.setLowerLimit(setLowerLimit.getIntValue());
thisLink.setUpperLimit(setUpperLimit.getIntValue());
thisLink.setLowerVelocity(setLowerVelocity.getDoubleValue());
thisLink.setUpperVelocity(setUpperVelocity.getDoubleValue());
thisLink.setLinkIndex(setLinkIndex.getIntValue());
thisLink.setScale(setScale.getDoubleValue());
reloadSettings();
}
private JScrollPane getScrollPane() {
if (scrollPane == null) {
scrollPane = new JScrollPane();
scrollPane.setViewportView(getViewPanel());
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
}
return scrollPane;
}
private JPanel getViewPanel() {
if (viewPanel == null) {
viewPanel = new JPanel();
viewPanel.setLayout(new MigLayout("", "[grow,fill]", "[][]"));
}
return viewPanel;
}
}

View File

@@ -0,0 +1,238 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout;
import com.neuronrobotics.replicator.driver.BowlerBoardDevice;
import com.neuronrobotics.replicator.driver.NRPrinter;
import com.neuronrobotics.replicator.driver.Slic3r;
import com.neuronrobotics.sdk.addons.kinematics.LinkConfiguration;
import com.neuronrobotics.sdk.addons.kinematics.LinkFactory;
import javax.swing.JList;
import javax.swing.JTextField;
import java.awt.BorderLayout;
//import com.sun.deploy.uitoolkit.impl.fx.Utils;
//import com.sun.deploy.uitoolkit.impl.fx.Utils;
public class DeviceConfigPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 12345L;
private NRPrinter printer;
File gCodes = null;
FileInputStream gCodeStream;
double currpos = 0;
long lastUpdate = 0;
public String fileName = "None";
private JPanel pnlAction;
private JButton btnReloadConfigs;
private JButton btnWriteConfigs;
private JTabbedPane tabPnlSettings;
private JScrollPane pnlSlic3rSetts;
private Slic3rMasterPanel slic3rSettingsPanel = new Slic3rMasterPanel();
private LocalSettingsPanel localSettingsPanel = new LocalSettingsPanel();
private JPanel axisConfigsPanel;
private JTabbedPane AxisTabs;
private ArrayList<AxisPanel> axisPanels = new ArrayList<>();
public DeviceConfigPanel() {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
initComponents();
}
});
}
public void setDevices(BowlerBoardDevice delt, NRPrinter printer) {
this.printer = printer;
}
private void initComponents() {
setLayout(new MigLayout("", "[grow]", "[][grow]"));
add(getPnlAction(), "cell 0 0,grow");
add(getTabPnlSettings(), "cell 0 1,grow");
}
public void updateSettings(){
printer.reloadSlic3rSettings();
slic3rSettingsPanel.setValue(0, new MachineSetting<Double>("NozzleDia" ,printer.getSlicer().getNozzle_diameter()));
slic3rSettingsPanel.setValue(1, new MachineSetting<Double>("PCenterX" ,printer.getSlicer().getPrintCenter()[0]));
slic3rSettingsPanel.setValue(2, new MachineSetting<Double>("PCenterY" ,printer.getSlicer().getPrintCenter()[1]));
slic3rSettingsPanel.setValue(3, new MachineSetting<Double>("FilaDia" ,printer.getSlicer().getFilimentDiameter()));
slic3rSettingsPanel.setValue(4, new MachineSetting<Double>("ExtMult" ,printer.getSlicer().getExtrusionMultiplier()));
slic3rSettingsPanel.setValue(5, new MachineSetting<Integer>("PTemp" , printer.getSlicer().getTempreture()));
slic3rSettingsPanel.setValue(6, new MachineSetting<Integer>("BTemp" , printer.getSlicer().getBedTempreture()));
slic3rSettingsPanel.setValue(7, new MachineSetting<Double>("LayerHeight" ,printer.getSlicer().getLayerHeight()));
slic3rSettingsPanel.setValue(8, new MachineSetting<Integer>("WallThickness" , printer.getSlicer().getWallThickness()));
slic3rSettingsPanel.setValue(9, new MachineSetting<Boolean>("UseSupport" ,printer.getSlicer().isUseSupportMaterial()));
slic3rSettingsPanel.setValue(10, new MachineSetting<Double>("RetractLength" ,printer.getSlicer().getRetractLength()));
slic3rSettingsPanel.setValue(11, new MachineSetting<Integer>("TravelSpd" ,printer.getSlicer().getTravilSpeed()));
slic3rSettingsPanel.setValue(12, new MachineSetting<Integer>("PeriSpd" ,printer.getSlicer().getPerimeterSpeed()));
slic3rSettingsPanel.setValue(13, new MachineSetting<Integer>("BridgeSpd" ,printer.getSlicer().getBridgeSpeed()));
slic3rSettingsPanel.setValue(14, new MachineSetting<Integer>("GapFillSpd" ,printer.getSlicer().getGapFillSpeed()));
slic3rSettingsPanel.setValue(15, new MachineSetting<Integer>("InfillSpd" ,printer.getSlicer().getInfillSpeed()));
slic3rSettingsPanel.setValue(16, new MachineSetting<Integer>("SupPeriSpdPcnt" ,printer.getSlicer().getSupportMaterialInterfaceSpeedPercent()));
slic3rSettingsPanel.setValue(17, new MachineSetting<Integer>("SmPeriSpdPcnt" ,printer.getSlicer().getSmallPerimeterSpeedPercent()));
slic3rSettingsPanel.setValue(18, new MachineSetting<Integer>("ExtPeriSpdPcnt" ,printer.getSlicer().getExternalPerimeterSpeedPercent()));
slic3rSettingsPanel.setValue(19, new MachineSetting<Integer>("SolidInfillSpdPcnt" ,printer.getSlicer().getSolidInfillSpeedPercent()));
slic3rSettingsPanel.setValue(20, new MachineSetting<Integer>("TopSolidInfillSpdPcnt" ,printer.getSlicer().getTopSolidInfillSpeedPercent()));
slic3rSettingsPanel.setValue(21, new MachineSetting<Integer>("SupportMatIntSpdPcnt" ,printer.getSlicer().getSupportMaterialSpeed()));
slic3rSettingsPanel.setValue(22, new MachineSetting<Integer>("FirstLayerSpdPcnt" ,printer.getSlicer().getFirstLayerSpeedPercent()));
System.out.println(printer.getLinkConfigurations().size());
getAxisTabs().removeAll();
axisPanels.clear();
for (LinkConfiguration lCfg : printer.getLinkConfigurations()) {
AxisPanel aPNL = new AxisPanel(lCfg);
axisPanels.add(aPNL);
getAxisTabs().addTab(lCfg.getName(), aPNL);
}
localSettingsPanel.reloadAllSettings();
}
public void writeSettings(){
slic3rSettingsPanel.checkNewSettings();
Slic3r newSettings = new Slic3r(
slic3rSettingsPanel.getDoubleValue(0),
new double[]{slic3rSettingsPanel.getDoubleValue(1),slic3rSettingsPanel.getDoubleValue(2)},
slic3rSettingsPanel.getDoubleValue(3),
slic3rSettingsPanel.getDoubleValue(4),
slic3rSettingsPanel.getIntegerValue(5),
slic3rSettingsPanel.getIntegerValue(6),
slic3rSettingsPanel.getDoubleValue(7),
slic3rSettingsPanel.getIntegerValue(8),
slic3rSettingsPanel.getBooleanValue(9),
slic3rSettingsPanel.getDoubleValue(10),
slic3rSettingsPanel.getIntegerValue(11),
slic3rSettingsPanel.getIntegerValue(12),
slic3rSettingsPanel.getIntegerValue(13),
slic3rSettingsPanel.getIntegerValue(14),
slic3rSettingsPanel.getIntegerValue(15),
slic3rSettingsPanel.getIntegerValue(16),
slic3rSettingsPanel.getIntegerValue(17),
slic3rSettingsPanel.getIntegerValue(18),
slic3rSettingsPanel.getIntegerValue(19),
slic3rSettingsPanel.getIntegerValue(20),
slic3rSettingsPanel.getIntegerValue(21),
slic3rSettingsPanel.getIntegerValue(22));
printer.getDeltaDevice().setSlic3rConfiguration(newSettings);
for (AxisPanel axisPanel : axisPanels) {
axisPanel.writeSettings();
printer.getDeltaDevice().setLinkConfiguration(axisPanels.indexOf(axisPanel), axisPanel.getLink());
}
}
private JPanel getPnlAction() {
if (pnlAction == null) {
pnlAction = new JPanel();
pnlAction.setLayout(new MigLayout("", "[][]", "[]"));
pnlAction.add(getBtnReloadConfigs(), "cell 0 0");
pnlAction.add(getBtnWriteConfigs(), "cell 1 0");
}
return pnlAction;
}
private JButton getBtnReloadConfigs() {
if (btnReloadConfigs == null) {
btnReloadConfigs = new JButton("Reload Configs");
btnReloadConfigs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
updateSettings();
}
});
}
return btnReloadConfigs;
}
private JButton getBtnWriteConfigs() {
if (btnWriteConfigs == null) {
btnWriteConfigs = new JButton("Write Configs");
btnWriteConfigs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
writeSettings();
}
});
}
return btnWriteConfigs;
}
private JTabbedPane getTabPnlSettings() {
if (tabPnlSettings == null) {
tabPnlSettings = new JTabbedPane(JTabbedPane.TOP);
tabPnlSettings.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent arg0) {
try {
updateSettings();
} catch (Exception e) {
}
}
});
tabPnlSettings.addTab(slic3rSettingsPanel.getPanelName(), null, slic3rSettingsPanel, null);
tabPnlSettings.addTab(localSettingsPanel.getPanelName(), null, localSettingsPanel, null);
tabPnlSettings.addTab("Axis Configs", null, getAxisConfigsPanel(), null);
}
return tabPnlSettings;
}
private JPanel getAxisConfigsPanel() {
if (axisConfigsPanel == null) {
axisConfigsPanel = new JPanel();
axisConfigsPanel.setLayout(new BorderLayout(0, 0));
axisConfigsPanel.add(getAxisTabs(), BorderLayout.CENTER);
}
return axisConfigsPanel;
}
private JTabbedPane getAxisTabs() {
if (AxisTabs == null) {
AxisTabs = new JTabbedPane(JTabbedPane.TOP);
}
return AxisTabs;
}
}

View File

@@ -0,0 +1,131 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javafx.stage.FileChooser.ExtensionFilter;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import com.neuronrobotics.nrconsole.util.FileSelectionFactory;
import com.neuronrobotics.nrconsole.util.PrefsLoader;
import com.neuronrobotics.nrconsole.util.Slic3rFilter;
public class LocalSettingsPanel extends SettingsPanel {
private JTextField tfSlic3rLocation;
private JButton btnChangeSlicr;
private JLabel lblCurrentLocationOf;
String slic3rPath;
PrefsLoader prefs = new PrefsLoader();
private JButton btnLoadDefaults;
/**
* Create the panel.
*/
public LocalSettingsPanel() {
initComponents();
}
@Override
public String getPanelName() {
return "Local Settings";
}
@Override
public void initComponents() {
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
.addComponent(getTfSlic3rLocation(), GroupLayout.DEFAULT_SIZE, 283, Short.MAX_VALUE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getBtnChangeSlicr()))
.addComponent(getBtnLoadDefaults(), Alignment.TRAILING)
.addComponent(getLblCurrentLocationOf()))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(getLblCurrentLocationOf())
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getTfSlic3rLocation(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getBtnChangeSlicr()))
.addPreferredGap(ComponentPlacement.RELATED, 212, Short.MAX_VALUE)
.addComponent(getBtnLoadDefaults())
.addContainerGap())
);
setLayout(groupLayout);
getTfSlic3rLocation().setText(prefs.getSlic3rLocation());
}
public void reloadAllSettings(){
getTfSlic3rLocation().setText(prefs.getSlic3rLocation());
}
private void changeSlic3rLocation(){
slic3rPath = FileSelectionFactory.GetFile(null, new ExtensionFilter("Slicer Executable","*")).getPath();
prefs.setSlic3rLocation(slic3rPath);
getTfSlic3rLocation().setText(prefs.getSlic3rLocation());
}
private JTextField getTfSlic3rLocation() {
if (tfSlic3rLocation == null) {
tfSlic3rLocation = new JTextField();
tfSlic3rLocation.setHorizontalAlignment(SwingConstants.LEFT);
tfSlic3rLocation.setEditable(false);
tfSlic3rLocation.setColumns(10);
}
return tfSlic3rLocation;
}
private JButton getBtnChangeSlicr() {
if (btnChangeSlicr == null) {
btnChangeSlicr = new JButton("Change Slic3r Location");
btnChangeSlicr.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
changeSlic3rLocation();
}
});
}
return btnChangeSlicr;
}
private JLabel getLblCurrentLocationOf() {
if (lblCurrentLocationOf == null) {
lblCurrentLocationOf = new JLabel("Current Location of slic3r-console.exe:");
}
return lblCurrentLocationOf;
}
private JButton getBtnLoadDefaults() {
if (btnLoadDefaults == null) {
btnLoadDefaults = new JButton("Load Defaults");
btnLoadDefaults.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
if (JOptionPane.showConfirmDialog(null, "This operation could be dangerous and break things.\n"
+ "You should restart NrConsole immediately after performing this action to avoid problems.", "This could be risky...", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION){
prefs.loadDefaults();
}
}
});
reloadAllSettings();
}
});
}
return btnLoadDefaults;
}
}

View File

@@ -0,0 +1,31 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
public class MachineSetting<V> {
private final String name;
private V value;
public MachineSetting(String _name,V v) {
name = _name;
value = v;
}
public MachineSetting(String _name) {
name = _name;
}
public String getName() {
return name;
}
public V getValue() {
return value;
}
public void setValue(V _value) {
value = _value;
}
public String toString() {
return "(" + name + ", " + value + ")";
}
}

View File

@@ -0,0 +1,54 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import javafx.embed.swing.SwingNode;
import javafx.scene.control.ScrollPane;
import com.neuronrobotics.bowlerstudio.tabs.AbstractBowlerStudioTab;
import com.neuronrobotics.replicator.driver.BowlerBoardDevice;
import com.neuronrobotics.replicator.driver.NRPrinter;
import com.neuronrobotics.sdk.common.BowlerAbstractDevice;
public class PrinterConiguration extends AbstractBowlerStudioTab{
private DeviceConfigPanel gui = new DeviceConfigPanel();
@Override
public void onTabClosing() {
// TODO Auto-generated method stub
}
@Override
public String[] getMyNameSpaces() {
return new String[]{"bcs.cartesian.*"};
}
@Override
public void initializeUI(BowlerAbstractDevice pm) {
NRPrinter printer = (NRPrinter)pm;
BowlerBoardDevice delt = printer.getDeltaDevice();
if (delt.isAvailable()){
gui.setDevices(delt,printer);
}
if (delt.isAvailable()){
gui.updateSettings();
}
SwingNode sn = new SwingNode();
sn.setContent(gui);
ScrollPane s1 = new ScrollPane();
s1.setContent(sn);
setContent(s1);
setText("Printer Config");
onTabReOpening();
}
@Override
public void onTabReOpening() {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,6 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
public interface SettingsChangeListener {
public void settingsChanged();
public void settingsRequest();
}

View File

@@ -0,0 +1,127 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import java.awt.List;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.beans.VetoableChangeListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Color;
import javax.swing.JFormattedTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.event.InputMethodListener;
import java.awt.event.InputMethodEvent;
public class SettingsListItem extends JPanel {
private JLabel lblNewLabel;
private JTextField txtSetVal;
private String labelTxt;
private String currentValue;
public SettingsListItem() {
add(getLblNewLabel());
add(getTxtSetVal());
}
public SettingsListItem(String _lblText, String _value) {
add(getLblNewLabel());
add(getTxtSetVal());
loadValues( _lblText, _value);
}
public SettingsListItem(String _lblText, int _value) {
add(getLblNewLabel());
add(getTxtSetVal());
loadValues( _lblText, _value);
}
public SettingsListItem(String _lblText, double _value) {
add(getLblNewLabel());
add(getTxtSetVal());
loadValues( _lblText, _value);
}
public void loadValues(String _lblTxt, String _value){
currentValue = _value;
labelTxt =_lblTxt;
getLblNewLabel().setText(_lblTxt);
getTxtSetVal().setText(_value);
}
public void loadValues(String _lblTxt, int _value){
currentValue = Integer.toString(_value);
labelTxt =_lblTxt;
getLblNewLabel().setText(_lblTxt);
getTxtSetVal().setText(Integer.toString(_value));
}
public void loadValues(String _lblTxt, double _value){
currentValue = Double.toString(_value);
labelTxt =_lblTxt;
getLblNewLabel().setText(_lblTxt);
getTxtSetVal().setText(Double.toString(_value));
}
private JLabel getLblNewLabel() {
if (lblNewLabel == null) {
lblNewLabel = new JLabel("New label");
}
return lblNewLabel;
}
public int getIntValue(){
try {
return Integer.valueOf(getTxtSetVal().getText());
} catch (Exception e) {
return 1;
}
}
public double getDoubleValue(){
try {
return Double.valueOf(getTxtSetVal().getText());
} catch (Exception e) {
return 1;
}
}
public String getStringValue(){
return getTxtSetVal().getText();
}
private JTextField getTxtSetVal() {
if (txtSetVal == null) {
txtSetVal = new JTextField();
txtSetVal.setText("Setting");
txtSetVal.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
if (txtSetVal.getText().equals(currentValue)){
txtSetVal.setBackground(Color.WHITE);
}
else{
txtSetVal.setBackground(Color.ORANGE);
}
}
});
txtSetVal.setColumns(10);
}
return txtSetVal;
}
}

View File

@@ -0,0 +1,139 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
public abstract class SettingsPanel extends JPanel {
private ArrayList<MachineSetting> settings = new ArrayList<>();
private List<SettingsChangeListener> listeners = new ArrayList<>();
public abstract String getPanelName();
public abstract void initComponents();
public void addListener(SettingsChangeListener toAdd) {
listeners.add(toAdd);
}
public void removeListeners() {
listeners.clear();
}
public void notifySettingsChanged(){
for (SettingsChangeListener ptl : listeners) {
ptl.settingsChanged();
}
}
public void notifySettingsRequest(){
for (SettingsChangeListener ptl : listeners) {
ptl.settingsRequest();
}
}
public void checkNewSettings(){
notifySettingsRequest();
}
public ArrayList<MachineSetting> getValues(){
return settings;
}
public void setValues(ArrayList<MachineSetting> values) {
settings = values;
notifySettingsChanged();
}
public boolean settingExists(String _name){
for (MachineSetting machineSetting : settings) {
if (machineSetting.getName() == _name){
return true;
}
}
return false;
}
public MachineSetting getSetting(String _name){
for (MachineSetting machineSetting : settings) {
if (machineSetting.getName() == _name){
return machineSetting;
}
}
return null;
}
public int numSettings(){
return settings.size();
}
public MachineSetting getSetting(int index){
return settings.get(index);
}
public void setValue(int index, MachineSetting item){
if (settings.size() <= index){
settings.add(index, item);
}
else{
settings.set(index, item);
}
notifySettingsChanged();
}
public Object getSetValue(String _name){
for (MachineSetting machineSetting : settings) {
if (machineSetting.getName() == _name){
return machineSetting.getValue();
}
}
return null;
}
public Object getSetValue(int index){
return settings.get(index).getValue();
}
public int getIntValue(String _name){
for (MachineSetting machineSetting : settings) {
if (machineSetting.getName() == _name){
return (Integer) machineSetting.getValue();
}
}
return -1;
}
public boolean getBooleanValue(String _name){
for (MachineSetting machineSetting : settings) {
if (machineSetting.getName() == _name){
return (Boolean) machineSetting.getValue();
}
}
return false;
}
public double getDoubleValue(String _name){
for (MachineSetting machineSetting : settings) {
if (machineSetting.getName() == _name){
return (Double) machineSetting.getValue();
}
}
return -1;
}
public double getDoubleValue(int index){
return (Double) settings.get(index).getValue();
}
public int getIntegerValue(int index){
return (Integer) settings.get(index).getValue();
}
public boolean getBooleanValue(int index){
return (Boolean) settings.get(index).getValue();
}
}

View File

@@ -0,0 +1,909 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import java.text.NumberFormat;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.LayoutStyle.ComponentPlacement;
public class Slic3rAll extends SettingsPanel implements SettingsChangeListener{
private JLabel lblNozzleDiameter;
private JLabel lblPrintCenter;
private JLabel lblFilamentDiameter;
private JLabel lblExtrusionMultiplier;
private JLabel lblPrintTemperature;
private JLabel lblBedTemperature;
private JLabel lblLayerHeight;
private JLabel lblWallThickness;
private JLabel lblUseSupportMaterial;
private JLabel lblRetractLength;
private JLabel lblTravelSpeed;
private JLabel lblPerimeterSpeed;
private JLabel lblBridgeSpeed;
private JLabel lblGapFillSpeed;
private JLabel lblInfillSpeed;
private JLabel lblSupportMaterialSpeed;
private JLabel lblSmallPerimeterSpeed;
private JLabel lblExternalPerimeterSpeed;
private JLabel lblSolidInfillSpeed;
private JLabel lblTopSolidInfill;
private JLabel lblSupportMaterialInterface;
private JLabel lblFirstLayerSpeed;
private JFormattedTextField tfNozzleDia;
private JLabel lblX;
private JFormattedTextField tfPrintCenterX;
private JLabel lblY;
private JFormattedTextField tfPrintCenterY;
private JFormattedTextField tfFilaDia;
private JFormattedTextField tfExtrusionMult;
private JFormattedTextField tfPTemp;
private JFormattedTextField tfBTemp;
private JFormattedTextField tfLayerHeight;
private JFormattedTextField tfWallThickness;
private JFormattedTextField tfRetractLength;
private JFormattedTextField tfTravelSpeed;
private JFormattedTextField tfPerimeterSpeed;
private JFormattedTextField tfBridgeSpeed;
private JFormattedTextField tfGapFillSpeed;
private JFormattedTextField tfInfillSpeed;
private JFormattedTextField tfSupportMaterialSpeed;
private JFormattedTextField tfSmallPerimeterSpeedPercent;
private JFormattedTextField tfExternalPerimeterSpeedPercent;
private JFormattedTextField tfSolidInfillSpeedPercent;
private JFormattedTextField tfTopSolidInfillSpeedPercent;
private JFormattedTextField tfSupportMaterialInterSpeedPercent;
private JFormattedTextField tfFirstLayerSpeedPercent;
private JLabel lblMm;
private JLabel lblMm_1;
private JLabel lblMm_2;
private JLabel lblMm_3;
private JLabel lblc;
private JLabel lblc_1;
private JLabel lblMm_4;
private JLabel lblMm_5;
private JLabel lblMm_6;
private JLabel lblMms;
private JLabel lblMms_1;
private JLabel lblMms_2;
private JLabel lblMms_3;
private JLabel lblMms_4;
private JLabel lblMms_5;
private JLabel label;
private JLabel label_1;
private JLabel label_2;
private JLabel label_3;
private JLabel label_4;
private JLabel label_5;
private Slic3rMasterPanel master;
public Slic3rAll(Slic3rMasterPanel _master) {
master = _master;
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
initComponents();
}
});
}
@Override
public String getPanelName() {
return "Slic3r Settings";
}
@Override
public void settingsChanged() {
if (master.numSettings() > 22){
tfNozzleDia.setValue(master.getSetting(0).getValue());
tfPrintCenterX.setValue(master.getSetting(1).getValue());
tfPrintCenterY.setValue(master.getSetting(2).getValue());
tfFilaDia.setValue(master.getSetting(3).getValue());
tfExtrusionMult.setValue(master.getSetting(4).getValue());
tfPTemp.setValue(master.getSetting(5).getValue());
tfBTemp.setValue(master.getSetting(6).getValue());
tfLayerHeight.setValue(master.getSetting(7).getValue());
tfWallThickness.setValue(master.getSetting(8).getValue());
//TODO Use Support Material?
tfRetractLength.setValue(master.getSetting(10).getValue());
tfTravelSpeed.setValue(master.getSetting(11).getValue());
tfPerimeterSpeed.setValue(master.getSetting(12).getValue());
tfBridgeSpeed.setValue(master.getSetting(13).getValue());
tfGapFillSpeed.setValue(master.getSetting(14).getValue());
tfInfillSpeed.setValue(master.getSetting(15).getValue());
tfSupportMaterialSpeed.setValue(master.getSetting(16).getValue());
tfSmallPerimeterSpeedPercent.setValue(master.getSetting(17).getValue());
tfExternalPerimeterSpeedPercent.setValue(master.getSetting(18).getValue());
tfSolidInfillSpeedPercent.setValue(master.getSetting(19).getValue());
tfTopSolidInfillSpeedPercent.setValue(master.getSetting(20).getValue());
tfSupportMaterialInterSpeedPercent.setValue(master.getSetting(21).getValue());
tfFirstLayerSpeedPercent.setValue(master.getSetting(22).getValue());
}
}
@Override
public void initComponents() {
GroupLayout groupLayout = new GroupLayout(this);
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblNozzleDiameter())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfNozzleDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblPrintCenter())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblX())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfPrintCenterX(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm_1())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblY())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfPrintCenterY(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm_2()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblFilamentDiameter())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfFilaDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm_3()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblExtrusionMultiplier())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfExtrusionMult(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblPrintTemperature())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfPTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblc()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblBedTemperature())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfBTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblc_1()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblLayerHeight())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfLayerHeight(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm_4()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblWallThickness())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfWallThickness(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm_5()))
.addComponent(getLblUseSupportMaterial())
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblRetractLength())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfRetractLength(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMm_6()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblTravelSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfTravelSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMms()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblPerimeterSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfPerimeterSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMms_1()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblInfillSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfInfillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMms_4()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblSupportMaterialSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfSupportMaterialSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMms_5()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblSmallPerimeterSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfSmallPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLabel()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblExternalPerimeterSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfExternalPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLabel_1()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblSolidInfillSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLabel_2()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblTopSolidInfill())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfTopSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLabel_3()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblSupportMaterialInterface())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfSupportMaterialInterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLabel_4()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getLblFirstLayerSpeed())
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getTfFirstLayerSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLabel_5()))
.addGroup(groupLayout.createSequentialGroup()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(getLblBridgeSpeed())
.addComponent(getLblGapFillSpeed()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getTfGapFillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMms_3()))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(getTfBridgeSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblMms_2())))))
.addContainerGap(140, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblNozzleDiameter())
.addComponent(getTfNozzleDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMm()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblPrintCenter())
.addComponent(getLblX())
.addComponent(getTfPrintCenterX(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblY())
.addComponent(getTfPrintCenterY(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMm_1())
.addComponent(getLblMm_2()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblFilamentDiameter())
.addComponent(getTfFilaDia(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMm_3()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblExtrusionMultiplier())
.addComponent(getTfExtrusionMult(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblPrintTemperature())
.addComponent(getTfPTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblc()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblBedTemperature())
.addComponent(getTfBTemp(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblc_1()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblLayerHeight())
.addComponent(getTfLayerHeight(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMm_4()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblWallThickness())
.addComponent(getTfWallThickness(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMm_5()))
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(getLblUseSupportMaterial())
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblRetractLength())
.addComponent(getTfRetractLength(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMm_6()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblTravelSpeed())
.addComponent(getTfTravelSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMms()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblPerimeterSpeed())
.addComponent(getTfPerimeterSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMms_1()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblBridgeSpeed())
.addComponent(getTfBridgeSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMms_2()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblGapFillSpeed())
.addComponent(getTfGapFillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMms_3()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblInfillSpeed())
.addComponent(getTfInfillSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMms_4()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblSupportMaterialSpeed())
.addComponent(getTfSupportMaterialSpeed(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLblMms_5()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblSmallPerimeterSpeed())
.addComponent(getTfSmallPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLabel()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblExternalPerimeterSpeed())
.addComponent(getTfExternalPerimeterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLabel_1()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblSolidInfillSpeed())
.addComponent(getTfSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLabel_2()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblTopSolidInfill())
.addComponent(getTfTopSolidInfillSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLabel_3()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblSupportMaterialInterface())
.addComponent(getTfSupportMaterialInterSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLabel_4()))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(getLblFirstLayerSpeed())
.addComponent(getTfFirstLayerSpeedPercent(), GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(getLabel_5()))
.addContainerGap(25, Short.MAX_VALUE))
);
setLayout(groupLayout);
this.addListener(this);
}
public NumberFormat getNumFormat(int numInts, int numDec){
NumberFormat x = NumberFormat.getNumberInstance();
x.setMaximumFractionDigits(numDec);
x.setMinimumFractionDigits(numDec);
x.setMaximumIntegerDigits(numInts);
x.setMinimumIntegerDigits(numInts);
return x;
}
private JLabel getLblNozzleDiameter() {
if (lblNozzleDiameter == null) {
lblNozzleDiameter = new JLabel("Nozzle Diameter");
}
return lblNozzleDiameter;
}
private JLabel getLblPrintCenter() {
if (lblPrintCenter == null) {
lblPrintCenter = new JLabel("Print Center");
}
return lblPrintCenter;
}
private JLabel getLblFilamentDiameter() {
if (lblFilamentDiameter == null) {
lblFilamentDiameter = new JLabel("Filament Diameter");
}
return lblFilamentDiameter;
}
private JLabel getLblExtrusionMultiplier() {
if (lblExtrusionMultiplier == null) {
lblExtrusionMultiplier = new JLabel("Extrusion Multiplier");
}
return lblExtrusionMultiplier;
}
private JLabel getLblPrintTemperature() {
if (lblPrintTemperature == null) {
lblPrintTemperature = new JLabel("Print Temperature");
}
return lblPrintTemperature;
}
private JLabel getLblBedTemperature() {
if (lblBedTemperature == null) {
lblBedTemperature = new JLabel("Bed Temperature");
}
return lblBedTemperature;
}
private JLabel getLblLayerHeight() {
if (lblLayerHeight == null) {
lblLayerHeight = new JLabel("Layer Height");
}
return lblLayerHeight;
}
private JLabel getLblWallThickness() {
if (lblWallThickness == null) {
lblWallThickness = new JLabel("Wall Thickness");
}
return lblWallThickness;
}
private JLabel getLblUseSupportMaterial() {
if (lblUseSupportMaterial == null) {
lblUseSupportMaterial = new JLabel("Use Support Material");
}
return lblUseSupportMaterial;
}
private JLabel getLblRetractLength() {
if (lblRetractLength == null) {
lblRetractLength = new JLabel("Retract Length");
}
return lblRetractLength;
}
private JLabel getLblTravelSpeed() {
if (lblTravelSpeed == null) {
lblTravelSpeed = new JLabel("Travel Speed");
}
return lblTravelSpeed;
}
private JLabel getLblPerimeterSpeed() {
if (lblPerimeterSpeed == null) {
lblPerimeterSpeed = new JLabel("Perimeter Speed");
}
return lblPerimeterSpeed;
}
private JLabel getLblBridgeSpeed() {
if (lblBridgeSpeed == null) {
lblBridgeSpeed = new JLabel("Bridge Speed");
}
return lblBridgeSpeed;
}
private JLabel getLblGapFillSpeed() {
if (lblGapFillSpeed == null) {
lblGapFillSpeed = new JLabel("Gap Fill Speed");
}
return lblGapFillSpeed;
}
private JLabel getLblInfillSpeed() {
if (lblInfillSpeed == null) {
lblInfillSpeed = new JLabel("Infill Speed");
}
return lblInfillSpeed;
}
private JLabel getLblSupportMaterialSpeed() {
if (lblSupportMaterialSpeed == null) {
lblSupportMaterialSpeed = new JLabel("Support Material Speed");
}
return lblSupportMaterialSpeed;
}
private JLabel getLblSmallPerimeterSpeed() {
if (lblSmallPerimeterSpeed == null) {
lblSmallPerimeterSpeed = new JLabel("Small Perimeter Speed Percent");
}
return lblSmallPerimeterSpeed;
}
private JLabel getLblExternalPerimeterSpeed() {
if (lblExternalPerimeterSpeed == null) {
lblExternalPerimeterSpeed = new JLabel("External Perimeter Speed Percent");
}
return lblExternalPerimeterSpeed;
}
private JLabel getLblSolidInfillSpeed() {
if (lblSolidInfillSpeed == null) {
lblSolidInfillSpeed = new JLabel("Solid Infill Speed Percent");
}
return lblSolidInfillSpeed;
}
private JLabel getLblTopSolidInfill() {
if (lblTopSolidInfill == null) {
lblTopSolidInfill = new JLabel("Top Solid Infill Speed Percent");
}
return lblTopSolidInfill;
}
private JLabel getLblSupportMaterialInterface() {
if (lblSupportMaterialInterface == null) {
lblSupportMaterialInterface = new JLabel("Support Material Interface Speed Percent");
}
return lblSupportMaterialInterface;
}
private JLabel getLblFirstLayerSpeed() {
if (lblFirstLayerSpeed == null) {
lblFirstLayerSpeed = new JLabel("First Layer Speed Percent");
}
return lblFirstLayerSpeed;
}
private JLabel getLblX() {
if (lblX == null) {
lblX = new JLabel("X:");
}
return lblX;
}
private JLabel getLblY() {
if (lblY == null) {
lblY = new JLabel("Y:");
}
return lblY;
}
private JFormattedTextField getTfNozzleDia() {
if (tfNozzleDia == null) {
tfNozzleDia = new JFormattedTextField(getNumFormat(2,3));
tfNozzleDia.setColumns(5);
}
return tfNozzleDia;
}
private JFormattedTextField getTfPrintCenterX() {
if (tfPrintCenterX == null) {
tfPrintCenterX = new JFormattedTextField(getNumFormat(3,0));
tfPrintCenterX.setColumns(5);
}
return tfPrintCenterX;
}
private JFormattedTextField getTfPrintCenterY() {
if (tfPrintCenterY == null) {
tfPrintCenterY = new JFormattedTextField(getNumFormat(3,0));
tfPrintCenterY.setColumns(5);
}
return tfPrintCenterY;
}
private JFormattedTextField getTfFilaDia() {
if (tfFilaDia == null) {
tfFilaDia = new JFormattedTextField(getNumFormat(2,2));
tfFilaDia.setColumns(5);
}
return tfFilaDia;
}
private JFormattedTextField getTfExtrusionMult() {
if (tfExtrusionMult == null) {
tfExtrusionMult = new JFormattedTextField(getNumFormat(2,4));
tfExtrusionMult.setColumns(5);
}
return tfExtrusionMult;
}
private JFormattedTextField getTfPTemp() {
if (tfPTemp == null) {
tfPTemp = new JFormattedTextField(getNumFormat(3,0));
tfPTemp.setColumns(5);
}
return tfPTemp;
}
private JFormattedTextField getTfBTemp() {
if (tfBTemp == null) {
tfBTemp = new JFormattedTextField(getNumFormat(3,0));
tfBTemp.setColumns(5);
}
return tfBTemp;
}
private JFormattedTextField getTfLayerHeight() {
if (tfLayerHeight == null) {
tfLayerHeight = new JFormattedTextField(getNumFormat(2,2));
tfLayerHeight.setColumns(5);
}
return tfLayerHeight;
}
private JFormattedTextField getTfWallThickness() {
if (tfWallThickness == null) {
tfWallThickness = new JFormattedTextField(getNumFormat(2,2));
tfWallThickness.setColumns(5);
}
return tfWallThickness;
}
private JFormattedTextField getTfRetractLength() {
if (tfRetractLength == null) {
tfRetractLength = new JFormattedTextField(getNumFormat(3,0));
tfRetractLength.setColumns(5);
}
return tfRetractLength;
}
private JFormattedTextField getTfTravelSpeed() {
if (tfTravelSpeed == null) {
tfTravelSpeed = new JFormattedTextField(getNumFormat(3,0));
tfTravelSpeed.setColumns(5);
}
return tfTravelSpeed;
}
private JFormattedTextField getTfPerimeterSpeed() {
if (tfPerimeterSpeed == null) {
tfPerimeterSpeed = new JFormattedTextField(getNumFormat(3,0));
tfPerimeterSpeed.setColumns(5);
}
return tfPerimeterSpeed;
}
private JFormattedTextField getTfBridgeSpeed() {
if (tfBridgeSpeed == null) {
tfBridgeSpeed = new JFormattedTextField(getNumFormat(3,0));
tfBridgeSpeed.setColumns(5);
}
return tfBridgeSpeed;
}
private JFormattedTextField getTfGapFillSpeed() {
if (tfGapFillSpeed == null) {
tfGapFillSpeed = new JFormattedTextField(getNumFormat(3,0));
tfGapFillSpeed.setColumns(5);
}
return tfGapFillSpeed;
}
private JFormattedTextField getTfInfillSpeed() {
if (tfInfillSpeed == null) {
tfInfillSpeed = new JFormattedTextField(getNumFormat(3,0));
tfInfillSpeed.setColumns(5);
}
return tfInfillSpeed;
}
private JFormattedTextField getTfSupportMaterialSpeed() {
if (tfSupportMaterialSpeed == null) {
tfSupportMaterialSpeed = new JFormattedTextField(getNumFormat(3,0));
tfSupportMaterialSpeed.setColumns(5);
}
return tfSupportMaterialSpeed;
}
private JFormattedTextField getTfSmallPerimeterSpeedPercent() {
if (tfSmallPerimeterSpeedPercent == null) {
tfSmallPerimeterSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
tfSmallPerimeterSpeedPercent.setColumns(5);
}
return tfSmallPerimeterSpeedPercent;
}
private JFormattedTextField getTfExternalPerimeterSpeedPercent() {
if (tfExternalPerimeterSpeedPercent == null) {
tfExternalPerimeterSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
tfExternalPerimeterSpeedPercent.setColumns(5);
}
return tfExternalPerimeterSpeedPercent;
}
private JFormattedTextField getTfSolidInfillSpeedPercent() {
if (tfSolidInfillSpeedPercent == null) {
tfSolidInfillSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
tfSolidInfillSpeedPercent.setColumns(5);
}
return tfSolidInfillSpeedPercent;
}
private JFormattedTextField getTfTopSolidInfillSpeedPercent() {
if (tfTopSolidInfillSpeedPercent == null) {
tfTopSolidInfillSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
tfTopSolidInfillSpeedPercent.setColumns(5);
}
return tfTopSolidInfillSpeedPercent;
}
private JFormattedTextField getTfSupportMaterialInterSpeedPercent() {
if (tfSupportMaterialInterSpeedPercent == null) {
tfSupportMaterialInterSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
tfSupportMaterialInterSpeedPercent.setColumns(5);
}
return tfSupportMaterialInterSpeedPercent;
}
private JFormattedTextField getTfFirstLayerSpeedPercent() {
if (tfFirstLayerSpeedPercent == null) {
tfFirstLayerSpeedPercent = new JFormattedTextField(getNumFormat(3,0));
tfFirstLayerSpeedPercent.setColumns(5);
}
return tfFirstLayerSpeedPercent;
}
private JLabel getLblMm() {
if (lblMm == null) {
lblMm = new JLabel("mm");
}
return lblMm;
}
private JLabel getLblMm_1() {
if (lblMm_1 == null) {
lblMm_1 = new JLabel("mm");
}
return lblMm_1;
}
private JLabel getLblMm_2() {
if (lblMm_2 == null) {
lblMm_2 = new JLabel("mm");
}
return lblMm_2;
}
private JLabel getLblMm_3() {
if (lblMm_3 == null) {
lblMm_3 = new JLabel("mm");
}
return lblMm_3;
}
private JLabel getLblc() {
if (lblc == null) {
lblc = new JLabel("\u00B0C");
}
return lblc;
}
private JLabel getLblc_1() {
if (lblc_1 == null) {
lblc_1 = new JLabel("\u00B0C");
}
return lblc_1;
}
private JLabel getLblMm_4() {
if (lblMm_4 == null) {
lblMm_4 = new JLabel("mm");
}
return lblMm_4;
}
private JLabel getLblMm_5() {
if (lblMm_5 == null) {
lblMm_5 = new JLabel("mm");
}
return lblMm_5;
}
private JLabel getLblMm_6() {
if (lblMm_6 == null) {
lblMm_6 = new JLabel("mm");
}
return lblMm_6;
}
private JLabel getLblMms() {
if (lblMms == null) {
lblMms = new JLabel("mm/s");
}
return lblMms;
}
private JLabel getLblMms_1() {
if (lblMms_1 == null) {
lblMms_1 = new JLabel("mm/s");
}
return lblMms_1;
}
private JLabel getLblMms_2() {
if (lblMms_2 == null) {
lblMms_2 = new JLabel("mm/s");
}
return lblMms_2;
}
private JLabel getLblMms_3() {
if (lblMms_3 == null) {
lblMms_3 = new JLabel("mm/s");
}
return lblMms_3;
}
private JLabel getLblMms_4() {
if (lblMms_4 == null) {
lblMms_4 = new JLabel("mm/s");
}
return lblMms_4;
}
private JLabel getLblMms_5() {
if (lblMms_5 == null) {
lblMms_5 = new JLabel("mm/s");
}
return lblMms_5;
}
private JLabel getLabel() {
if (label == null) {
label = new JLabel("%");
}
return label;
}
private JLabel getLabel_1() {
if (label_1 == null) {
label_1 = new JLabel("%");
}
return label_1;
}
private JLabel getLabel_2() {
if (label_2 == null) {
label_2 = new JLabel("%");
}
return label_2;
}
private JLabel getLabel_3() {
if (label_3 == null) {
label_3 = new JLabel("%");
}
return label_3;
}
private JLabel getLabel_4() {
if (label_4 == null) {
label_4 = new JLabel("%");
}
return label_4;
}
private JLabel getLabel_5() {
if (label_5 == null) {
label_5 = new JLabel("%");
}
return label_5;
}
@Override
public void settingsRequest() {
master.setValue(0, new MachineSetting<Double>("NozzleDia" ,(Double) tfNozzleDia.getValue()));
master.setValue(1, new MachineSetting<Double>("PCenterX" ,(Double) tfPrintCenterX.getValue()));
master.setValue(2, new MachineSetting<Double>("PCenterY" ,(Double) tfPrintCenterY.getValue()));
master.setValue(3, new MachineSetting<Double>("FilaDia" ,(Double) tfFilaDia.getValue()));
master.setValue(4, new MachineSetting<Double>("ExtMult" ,(Double) tfExtrusionMult.getValue()));
master.setValue(5, new MachineSetting<Integer>("PTemp" ,(Integer) tfPTemp.getValue()));
master.setValue(6, new MachineSetting<Integer>("BTemp" ,(Integer) tfBTemp.getValue()));
master.setValue(7, new MachineSetting<Double>("LayerHeight" ,(Double) tfLayerHeight.getValue()));
master.setValue(8, new MachineSetting<Integer>("WallThickness" ,(Integer) tfWallThickness.getValue()));
//master.setValue(9, new MachineSetting<Boolean>("UseSupport" ,(Boolean) tfRetractLength.getValue()));
master.setValue(10, new MachineSetting<Double>("RetractLength" ,(Double) tfRetractLength.getValue()));
master.setValue(11, new MachineSetting<Integer>("TravelSpd" ,(Integer) tfTravelSpeed.getValue()));
master.setValue(12, new MachineSetting<Integer>("PeriSpd" ,(Integer) tfPerimeterSpeed.getValue()));
master.setValue(13, new MachineSetting<Integer>("BridgeSpd" ,(Integer) tfBridgeSpeed.getValue()));
master.setValue(14, new MachineSetting<Integer>("GapFillSpd" ,(Integer) tfGapFillSpeed.getValue()));
master.setValue(15, new MachineSetting<Integer>("InfillSpd" ,(Integer) tfInfillSpeed.getValue()));
master.setValue(16, new MachineSetting<Integer>("SupportMatSpd" ,(Integer) tfSupportMaterialSpeed.getValue()));
master.setValue(17, new MachineSetting<Integer>("SmPeriSpdPcnt" ,(Integer) tfSmallPerimeterSpeedPercent.getValue()));
master.setValue(18, new MachineSetting<Integer>("ExtPeriSpdPcnt" ,(Integer) tfExternalPerimeterSpeedPercent.getValue()));
master.setValue(19, new MachineSetting<Integer>("SolidInfillSpdPcnt" ,(Integer) tfSolidInfillSpeedPercent.getValue()));
master.setValue(20, new MachineSetting<Integer>("TopSolidInfillSpdPcnt" ,(Integer) tfTopSolidInfillSpeedPercent.getValue()));
master.setValue(21, new MachineSetting<Integer>("SupportMatIntSpdPcnt" ,(Integer) tfSupportMaterialInterSpeedPercent.getValue()));
master.setValue(22, new MachineSetting<Integer>("FirstLayerSpdPcnt" ,(Integer) tfFirstLayerSpeedPercent.getValue()));
}
}

View File

@@ -0,0 +1,168 @@
package com.neuronrobotics.nrconsole.plugin.DeviceConfig;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import net.miginfocom.swing.MigLayout;
import com.neuronrobotics.nrconsole.util.PrefsLoader;
public class Slic3rMasterPanel extends SettingsPanel {
private JScrollPane scrollPane;
private JPanel panel;
private JRadioButton rdbtnShowAllSettings;
private JPanel panel_1;
PrefsLoader prefs = new PrefsLoader();
private Slic3rAll pnlAll = new Slic3rAll(this);
private Slic3rPrinter pnlPrinter = new Slic3rPrinter(this);
private Slic3rPrints pnlPrints = new Slic3rPrints(this);
private JRadioButton rdbtnShowOnlyPrinter;
private JRadioButton rdbtnShowOnlyPrint;
private final ButtonGroup buttonGroup = new ButtonGroup();
/**
* Create the panel.
*/
public Slic3rMasterPanel() {
initComponents();
}
private SettingsPanel whichPanel(){
if (rdbtnShowAllSettings.isSelected()){
removeListeners();
addListener(pnlAll);
notifySettingsChanged();
return pnlAll;
}
else if (rdbtnShowOnlyPrinter.isSelected()){
removeListeners();
addListener(pnlPrinter);
notifySettingsChanged();
return pnlPrinter;
}
else if(rdbtnShowOnlyPrint.isSelected()){
removeListeners();
addListener(pnlPrints);
notifySettingsChanged();
return pnlPrints;
}
removeListeners();
addListener(pnlAll);
notifySettingsChanged();
return pnlAll;
}
private void changePanels(){
scrollPane.setViewportView(whichPanel());
}
private JScrollPane getScrollPane() {
if (scrollPane == null) {
scrollPane = new JScrollPane();
scrollPane.setColumnHeaderView(getPanel());
}
return scrollPane;
}
private JPanel getPanel() {
if (panel == null) {
panel = new JPanel();
panel.add(getRdbtnShowOnlyPrinter());
panel.add(getRdbtnShowOnlyPrint());
panel.add(getRdbtnShowAllSettings());
}
return panel;
}
private JRadioButton getRdbtnShowAllSettings() {
if (rdbtnShowAllSettings == null) {
rdbtnShowAllSettings = new JRadioButton("Show All Settings");
rdbtnShowAllSettings.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (rdbtnShowAllSettings.isSelected()){
prefs.setSlic3rRDBTNLast(0);
}
changePanels();
}
});
buttonGroup.add(rdbtnShowAllSettings);
}
return rdbtnShowAllSettings;
}
@Override
public String getPanelName() {
return "Slic3r Settings";
}
@Override
public void initComponents() {
setLayout(new MigLayout("", "[grow]", "[grow]"));
add(getScrollPane(), "cell 0 0,grow");
switch (prefs.getSlic3rRDBTNLast()) {
case 0:
getRdbtnShowAllSettings().setSelected(true);
break;
case 1:
getRdbtnShowOnlyPrinter().setSelected(true);
break;
case 2:
getRdbtnShowOnlyPrint().setSelected(true);
break;
default:
getRdbtnShowAllSettings().setSelected(true);
break;
}
changePanels();
}
private JRadioButton getRdbtnShowOnlyPrinter() {
if (rdbtnShowOnlyPrinter == null) {
rdbtnShowOnlyPrinter = new JRadioButton("Show Only Printer Settings");
rdbtnShowOnlyPrinter.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (rdbtnShowOnlyPrinter.isSelected()){
prefs.setSlic3rRDBTNLast(1);
}
changePanels();
}
});
buttonGroup.add(rdbtnShowOnlyPrinter);
}
return rdbtnShowOnlyPrinter;
}
private JRadioButton getRdbtnShowOnlyPrint() {
if (rdbtnShowOnlyPrint == null) {
rdbtnShowOnlyPrint = new JRadioButton("Show Only Print Job Settings");
rdbtnShowOnlyPrint.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (rdbtnShowOnlyPrint.isSelected()){
prefs.setSlic3rRDBTNLast(2);
}
changePanels();
}
});
buttonGroup.add(rdbtnShowOnlyPrint);
}
return rdbtnShowOnlyPrint;
}
}

Some files were not shown because too many files have changed in this diff Show More