From 7ff372c033ae877bc4c0b8dd63382cbd69b9e858 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 08:47:57 -0400 Subject: [PATCH 01/14] Initial commit --- .gitignore | 12 ++++++++++++ README.md | 2 ++ 2 files changed, 14 insertions(+) create mode 100644 .gitignore create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32858aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/README.md b/README.md new file mode 100644 index 0000000..7af9f1f --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# crcl4java +Tools and Libraries for Java Developers using "Canonical Robot Command Language" (CRCL) From d142e1788f37f7b376ce5ba9afb62f50ca9a081c Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 09:15:54 -0400 Subject: [PATCH 02/14] move from crac repository --- .gitignore | 4 + README.md | 35 + crcl4java-base/README.txt | 37 + crcl4java-base/license-NIST.txt | 25 + crcl4java-base/nb-configuration.xml | 18 + crcl4java-base/nbactions.xml | 60 + crcl4java-base/pom.xml | 233 ++ .../main/resources/CRCLCommandInstance.xsd | 50 + .../src/main/resources/CRCLCommands.xsd | 1501 +++++++++ .../main/resources/CRCLProgramInstance.xsd | 64 + .../src/main/resources/CRCLStatus.xsd | 368 +++ .../src/main/resources/DataPrimitives.xsd | 201 ++ .../src/test/resources/main/initPose.csv | 2 + .../src/test/resources/main/programAll.xml | 262 ++ .../test/resources/main/programExample.xml | 731 +++++ crcl4java-utils/README.txt | 45 + crcl4java-utils/license-NIST.txt | 25 + crcl4java-utils/nb-configuration.xml | 18 + crcl4java-utils/nbactions.xml | 89 + crcl4java-utils/pom.xml | 353 ++ crcl4java-utils/run.bat | 16 + crcl4java-utils/run.sh | 16 + .../main/java/crcl/utils/AnnotatedPose.java | 85 + .../main/java/crcl/utils/CRCLPosemath.java | 685 ++++ .../src/main/java/crcl/utils/CRCLSocket.java | 1914 +++++++++++ .../java/crcl/utils/CRCLSocketExample.java | 108 + .../main/java/crcl/utils/CmdLineClient.java | 97 + .../java/crcl/utils/CmdLineSimServer.java | 74 + .../src/main/java/crcl/utils/DefaultMain.java | 103 + .../main/java/crcl/utils/GripperJFrame.form | 374 +++ .../main/java/crcl/utils/GripperJFrame.java | 735 +++++ .../main/java/crcl/utils/LauncherJFrame.form | 87 + .../main/java/crcl/utils/LauncherJFrame.java | 188 ++ .../java/crcl/utils/ListChooserJPanel.form | 82 + .../java/crcl/utils/ListChooserJPanel.java | 145 + .../crcl/utils/MultiLineStringJPanel.form | 80 + .../crcl/utils/MultiLineStringJPanel.java | 183 ++ .../main/java/crcl/utils/ObjTableJPanel.form | 277 ++ .../main/java/crcl/utils/ObjTableJPanel.java | 1783 +++++++++++ .../main/java/crcl/utils/OverHeadJPanel.java | 236 ++ .../main/java/crcl/utils/PendantClient.form | 1332 ++++++++ .../main/java/crcl/utils/PendantClient.java | 2841 +++++++++++++++++ .../java/crcl/utils/PendantClientInner.java | 1400 ++++++++ .../java/crcl/utils/PendantClientOuter.java | 54 + .../crcl/utils/PendantClientOuterStub.java | 206 ++ .../src/main/java/crcl/utils/PerfTest.java | 185 ++ .../java/crcl/utils/PoseToleranceChecker.java | 105 + .../main/java/crcl/utils/SideViewJPanel.java | 231 ++ .../main/java/crcl/utils/SimRobotEnum.java | 29 + .../src/main/java/crcl/utils/SimServer.form | 614 ++++ .../src/main/java/crcl/utils/SimServer.java | 1045 ++++++ .../main/java/crcl/utils/SimServerInner.java | 1797 +++++++++++ .../main/java/crcl/utils/SimServerOuter.java | 56 + .../java/crcl/utils/SimServerOuterStub.java | 218 ++ .../utils/SimulatedKinematicsPlausible.java | 320 ++ .../crcl/utils/SimulatedKinematicsSimple.java | 180 ++ .../main/java/crcl/utils/TestInstance.java | 105 + .../java/crcl/utils/XpathQueryJFrame.form | 125 + .../java/crcl/utils/XpathQueryJFrame.java | 305 ++ .../src/main/java/crcl/utils/XpathUtils.java | 133 + .../java/crcl/utils/CRCLPosemathTest.java | 978 ++++++ .../test/java/crcl/utils/CRCLSocketIT.java | 894 ++++++ .../test/java/crcl/utils/CRCLSocketTest.java | 439 +++ .../test/java/crcl/utils/CmdLineClientIT.java | 206 ++ .../SimulatedKinematicsPlausibleTest.java | 190 ++ .../utils/SimulatedKinematicsSimpleTest.java | 212 ++ .../src/test/resources/logging.properties | 7 + .../src/test/resources/main/initPose.csv | 2 + .../src/test/resources/main/programAll.xml | 262 ++ .../test/resources/main/programExample.xml | 731 +++++ pom.xml | 125 + 71 files changed, 26716 insertions(+) create mode 100644 crcl4java-base/README.txt create mode 100644 crcl4java-base/license-NIST.txt create mode 100644 crcl4java-base/nb-configuration.xml create mode 100644 crcl4java-base/nbactions.xml create mode 100644 crcl4java-base/pom.xml create mode 100644 crcl4java-base/src/main/resources/CRCLCommandInstance.xsd create mode 100644 crcl4java-base/src/main/resources/CRCLCommands.xsd create mode 100644 crcl4java-base/src/main/resources/CRCLProgramInstance.xsd create mode 100644 crcl4java-base/src/main/resources/CRCLStatus.xsd create mode 100644 crcl4java-base/src/main/resources/DataPrimitives.xsd create mode 100644 crcl4java-base/src/test/resources/main/initPose.csv create mode 100755 crcl4java-base/src/test/resources/main/programAll.xml create mode 100755 crcl4java-base/src/test/resources/main/programExample.xml create mode 100644 crcl4java-utils/README.txt create mode 100644 crcl4java-utils/license-NIST.txt create mode 100644 crcl4java-utils/nb-configuration.xml create mode 100644 crcl4java-utils/nbactions.xml create mode 100644 crcl4java-utils/pom.xml create mode 100644 crcl4java-utils/run.bat create mode 100755 crcl4java-utils/run.sh create mode 100644 crcl4java-utils/src/main/java/crcl/utils/AnnotatedPose.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/CRCLPosemath.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PendantClient.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PendantClient.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PerfTest.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/PoseToleranceChecker.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimRobotEnum.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimServer.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimServer.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimServerOuter.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimServerOuterStub.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsPlausible.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsSimple.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/TestInstance.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.form create mode 100644 crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java create mode 100644 crcl4java-utils/src/test/java/crcl/utils/CRCLPosemathTest.java create mode 100644 crcl4java-utils/src/test/java/crcl/utils/CRCLSocketIT.java create mode 100644 crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java create mode 100644 crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java create mode 100644 crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsPlausibleTest.java create mode 100644 crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsSimpleTest.java create mode 100644 crcl4java-utils/src/test/resources/logging.properties create mode 100644 crcl4java-utils/src/test/resources/main/initPose.csv create mode 100755 crcl4java-utils/src/test/resources/main/programAll.xml create mode 100755 crcl4java-utils/src/test/resources/main/programExample.xml create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore index 32858aa..60a9ef8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +/CRCLJavaBase/target/ +/crcl4java-base/target/ +/crcl4java-utils/target/ +/crcl4java-utils/nbproject/ \ No newline at end of file diff --git a/README.md b/README.md index 7af9f1f..6ef526a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,37 @@ # crcl4java Tools and Libraries for Java Developers using "Canonical Robot Command Language" (CRCL) + +The language called "Canonical Robot Command Language" (CRCL) provides generic command and status definitions that implement the functionality of typical industrial robots without being specific either to the language of a plan that is being executed or to the language used by a robot controller that executes CRCL commands. It can be used with offline planners that create output to be stored in CRCL files or online where CRCL is communicated in both directions via TCP. CRCL commands and status could also be exchanged over TCP between an operator interface and a robot controller or proxy for a robot controller. + +The programming language independent documentation and XML Schema files for +validation are stored in the main crcl repository: https://github.com/ros-industrial/crcl + +This repository contains Java libraries and tools related to CRCL. + + +Build +----- + + +To build one needs: + * JDK 1.8+ (http://www.oracle.com/technetwork/java/javase/downloads/index.html) and + * maven 3.0.5+ (https://maven.apache.org/download.cgi) + +Use the command: + + mvn package + +OR + + * An IDE bundled with both maven and a JDK such as Netbeans, IntelliJ, or Eclipse. + * Netbeans will open a maven project with File -> Open Project just like Netbeans generated Ant projects. + * IntelliJ and Eclipse both have options to import maven projects. + + +Contents +-------- + +The two subdirectories correspond to two artifacts. + + * crcl4java-base -- xjc autogenerated JAXB annotated classes corresponding to the CRCL schemas. + * crcl4java-utils -- class for sending and receiving CRCL classes over a TCP Socket, graphical user interfaces, Pose math conversions, robot simulation for testing. \ No newline at end of file diff --git a/crcl4java-base/README.txt b/crcl4java-base/README.txt new file mode 100644 index 0000000..a27a6ec --- /dev/null +++ b/crcl4java-base/README.txt @@ -0,0 +1,37 @@ +To Build: + +Download the latest JDK (at-least 1.8+) from http://www.oracle.com/technetwork/java/javase/downloads/index.html + +( getting the bundled Netbeans is recommended but not required) + +To build with netbeans simply open this directory as a project (File-> Open Project ...) and choose +(Run -> Build Project (CRCLJavaBase) ). + +To build on the command line: + +export JAVA_HOME=[path_to_jdk_1.8+] +sudo apt-get install maven +mvn clean install + +The schemas are now stored in this projects resources directory. + +To change the shemas use and force regeneration of sources: + +use -PnewSchema and -Dcrcl.schemaBaseUrl= to set the url of the new schema. + +eg. + +mvn clean install -PnewSchema -Dcrcl.schemaBaseUrl=https://raw.githubusercontent.com/ros-industrial/crcl/master/schemas/ + +OR + +mvn clean install -PnewSchema -Dcrcl.schemaBaseUrl=file:${HOME}/crac/xml/crcl/xmlSchemas + + + +This directory only produces a library jar file, +target/CRCLJavaBase-1.0-SNAPSHOT.jar, from +xjc automatically generated sources using the XML Schema files in +../xml/crcl/xmlSchemas. + +It is used by the main project CRCLJava. diff --git a/crcl4java-base/license-NIST.txt b/crcl4java-base/license-NIST.txt new file mode 100644 index 0000000..6049062 --- /dev/null +++ b/crcl4java-base/license-NIST.txt @@ -0,0 +1,25 @@ +<#if licenseFirst??> +${licenseFirst} + +${licensePrefix}This software is public domain software, however it is preferred +${licensePrefix}that the following disclaimers be attached. +${licensePrefix}Software Copywrite/Warranty Disclaimer +${licensePrefix} +${licensePrefix}This software was developed at the National Institute of Standards and +${licensePrefix}Technology by employees of the Federal Government in the course of their +${licensePrefix}official duties. Pursuant to title 17 Section 105 of the United States +${licensePrefix}Code this software is not subject to copyright protection and is in the +${licensePrefix}public domain. NIST Real-Time Control System software is an experimental +${licensePrefix}system. NIST assumes no responsibility whatsoever for its use by other +${licensePrefix}parties, and makes no guarantees, expressed or implied, about its +${licensePrefix}quality, reliability, or any other characteristic. We would appreciate +${licensePrefix}acknowledgement if the software is used. This software can be +${licensePrefix}redistributed and/or modified freely provided that any derivative works +${licensePrefix}bear some notice that they are derived from it, and any modified +${licensePrefix}versions bear some notice that they have been modified. +${licensePrefix} +${licensePrefix} See http://www.copyright.gov/title17/92chap1.html#105 +${licensePrefix} +<#if licenseLast??> +${licenseLast} + diff --git a/crcl4java-base/nb-configuration.xml b/crcl4java-base/nb-configuration.xml new file mode 100644 index 0000000..9723198 --- /dev/null +++ b/crcl4java-base/nb-configuration.xml @@ -0,0 +1,18 @@ + + + + + + ${project.basedir}/license-NIST.txt + + diff --git a/crcl4java-base/nbactions.xml b/crcl4java-base/nbactions.xml new file mode 100644 index 0000000..6a4a433 --- /dev/null +++ b/crcl4java-base/nbactions.xml @@ -0,0 +1,60 @@ + + + + run + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -classpath %classpath ${main.class} + java + + + + debug + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath ${main.class} + java + true + + + + CUSTOM-Verify + Verify + + verify + + + codecoverage + + + + CUSTOM-Clean and Package Only + Clean and Package Only + + clean + package + + + + CUSTOM-getNewSchema + getNewSchema + + org.apache.maven.plugins:maven-antrun-plugin:1.8:run + + + newSchema + + + diff --git a/crcl4java-base/pom.xml b/crcl4java-base/pom.xml new file mode 100644 index 0000000..9749eef --- /dev/null +++ b/crcl4java-base/pom.xml @@ -0,0 +1,233 @@ + + + 4.0.0 + com.github.wshackle + crcl4java-base + 1.0-SNAPSHOT + jar + + .. + com.github.wshackle + CRCLJavaParent + 1.0-SNAPSHOT + + + + junit + junit + 4.10 + test + + + + UTF-8 + 1.8 + 1.8 + UTF-8 + UTF-8 + https://raw.githubusercontent.com/ros-industrial/crcl/master/schemas/ + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + + -Xdiags:verbose + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.8 + + + maven-failsafe-plugin + 2.18.1 + + + + integration-test + verify + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + ${main.class} + + + + + + org.jvnet.jaxb2.maven2 + maven-jaxb2-plugin + 0.12.3 + + + + + generate + + + + + + + crcl.base + ${project.basedir}/src/main/resources/ + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-2 + + + set-additional-system-properties + + set-system-properties + + + + + + + javax.xml.accessExternalSchema + file,http + + + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + newSchema + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + download-files + initialize + + + + + + + + + + + + + + + run + + + + + + + + + doclint-java8-disable + + [1.8,) + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + -Xdoclint:none -quiet + + + + + + + crcl4java-base + \ No newline at end of file diff --git a/crcl4java-base/src/main/resources/CRCLCommandInstance.xsd b/crcl4java-base/src/main/resources/CRCLCommandInstance.xsd new file mode 100644 index 0000000..69c8a34 --- /dev/null +++ b/crcl4java-base/src/main/resources/CRCLCommandInstance.xsd @@ -0,0 +1,50 @@ + + + + + + + + This ontology models a single command written in the canonical robot + command language (CRCL). + + owlPrefix=crc + + + + + + The global CRCLCommandInstance element may be used as the root + element of a CRCL instance file containing a single CRCL + command. + + + + + + + + CRCLCommandInstanceType is derived from DataThingType. + An instance of CRCLCommandInstanceType has the following elements: + Name (inherited, optional) + CRCLCommand. + + CRCLCommandInstanceType contains a single CRCL command. + + + + + + + + + + + + diff --git a/crcl4java-base/src/main/resources/CRCLCommands.xsd b/crcl4java-base/src/main/resources/CRCLCommands.xsd new file mode 100644 index 0000000..3deb4e7 --- /dev/null +++ b/crcl4java-base/src/main/resources/CRCLCommands.xsd @@ -0,0 +1,1501 @@ + + + + + + + + This ontology models commands written in the canonical robot command + language (CRCL). CRCL is a low-level messaging language for telling a + robot what to do. CRCL commands are executed by a low-level device + controller. The usual source of CRCL commands is a plan/program + execution system. + + CRCL is intended for use with devices typically described as + industrial robots and for other positionable automated devices such + as automated guided vehicles (AGVs). An AGV with a robotic arm + attached may be regarded as a single robot responding to a single + stream of CRCL commands or as two robots responding to two separate + streams of CRCL commands. + + Although CRCL is not a programming language, the commands are in the + context of a session consisting of getting ready for activity, + performing activities, and becoming quiescent. CRCL commands may be + collected in files for testing purposes, but executing such files (by + giving the commands in the order they occur in the file) should not + be the normal operating mode of a robot. + + The robot model on which the CRCL commands are based has a controlled + point and orientation. The speed, and acceleration that are the + subject of CRCL commands apply to the controlled point. The positions + (Poses) that are the subject of CRCL commands apply to the controlled + point and orientation. The coordinate system for Poses in CRCL + commands is the coordinate system of the workstation in which the + robot is working. + + For a robot designed to use a single end effector, when the robot has + an end effector such as a gripper attached, the controlled point is a + point designated by the robot system designer that is fixed in the + coordinate system of the end effector. For most purposes, that point + should be near the place on the end effector where the end effector + performs its function (between the jaws of a gripper, for example). + The location of the coordinate system of the end effector with + respect to the mechanical components of the end effector must be set + by the robot system designer. CRCL commands are used to specify + orientation by describing where the Z and X axes of the end effector + coordinate system should point. + + Also for a robot designed to use a single end effector, when no end + effector is attached, the controlled point is a point designated by + the robot system designer that is fixed in the coordinate system of + the robot component (call it LastLink) to which an end effector may + be attached. The location of the coordinate system of LastLink with + respect to the mechanical components of LastLink must be set by the + robot system designer. CRCL commands may be used to specify + orientation of LastLink by describing where the Z and X axes of the + LastLink coordinate system should point. + + Attaching or detaching an end effector changes the controlled point. + + Where command arguments are in terms of units, the units are as set + by the most recent SetXXXUnits command. If no SetXXXUnits command for + a given unit type has been executed since the last InitCanonType + command was executed, the following default units apply: + length -- meter + angle -- radian + force -- newton + torque -- newtonMeter + + For an AGV without an end effector, the controlled point is a point + designated by the robot system designer that is fixed in the + coordinate system of the AGV. The location of the coordinate system + of the AGV with respect to the mechanical components of the AGV must + be set by the robot system designer. CRCL commands may be used to + specify orientation of the AGV by describing where the Z and X axes + of the AGV coordinate system should point. + + If any joint setting or joint status reporting is done, it is assumed + that the system sending canonical commands and the system executing + them both know the kinematics of the robot and have the same + numbering system for the joints, starting with 1. The two systems + also have the same understanding of where the zero point is and which + direction is positive for each joint. + + In order that this file may be translateable into OWL, all + complexTypes in this file include the (optional) Name element, + inherited from DataThingType. If an instance file has instances of + complex data without names, it will not be translateable into OWL. + + This file uses the term 'single axis rotation' (and similar terms + such as 'single axis rotational speed'). When referring to motion + from one pose to another. It is always possible to find a single axis + and an amount of rotation around that axis that moves from one + orientation to another. That rotation is what is meant by 'single + axis rotation'. + + A few abbreviations are used in names. They are + Accel = Acceleration + Trans = Translational + Rot = Rotational + + + owlPrefix=crcl + + + + + + ActuateJointsType is derived from MiddleCommandType. + An instance of ActuateJointsType has the following elements: + Name (inherited, optional) + CommandID (inherited) + ActuateJoint (multiple). + + Each joint may appear in at most one ActuateJoint element. If + a joint appears in no ActuateJoint element, its actuation should + be as previously set. + + + + + + + + + + + + + + + ActuateJointType is derived from DataThingType. + An instance of ActuateJointType has the following elements: + Name (inherited, optional) + JointNumber + JointPosition + JointDetails. + + JointPosition is the target position for the joint. JointDetails + provides either (1) the speed and acceleration to use in getting to + the position or (2)the force or torque and rate of change of force + or torque to use in getting to the position. + + + + + + + + + + + + + + + + + CloseToolChangerType is derived from MiddleCommandType. + An instance of CloseToolChangerType has the following elements: + Name (inherited, optional) + CommandID (inherited). + + After an instance of CloseToolChangerType is executed, it is + understood that if the tool changer was in position to acquire an + end effector, the end effector will be mounted on the robot. In + that case, the controlled point will change. + + + + + + + + + + + ConfigureJointReportsType is derived from MiddleCommandType. + An instance of ConfigureJointReportsType has the following elements: + Name (inherited, optional) + CommandID (inherited) + ResetAll + ConfigureJointReport (multiple). + + ConfigureJointReportsType is used to specify how the status of the + robot joints should be reported. The ConfigureJointReports command + may be used more than once during a session to change joint status + reporting. + + If ResetAll is set to true, an instance of + ConfigureJointReportsType resets the joint reporting of all + joints, and, in that case, if there is no ConfigureJointReport + element for a joint in the instance, the status of that joint + should not be reported. Thus, an instance of + ConfigureJointReportsType with ResetAll set to true and no + ConfigureJointReport elements turns off all joint reporting. + + If ResetAll is set to false, status reporting is changed for only + those joints given in a ConfigureJointReport element. Status + reporting for other joints remains the same. + + No joint may appear in more than one ConfigureJointReport element. + Joint numbers in ConfigureJointReport elements must be given in + increasing order. + + See the in-line documentation of CRCLStatus.xsd for further + information. + + + + + + + + + + + + + + + + ConfigureJointReportType is derived from DataThingType. + An instance of ConfigureJointReportType has the following elements: + Name (inherited, optional) + JointNumber + ReportPosition + ReportTorqueOrForce + ReportVelocity + + ConfigureJointReportType is used to specify whether and how status + reporting should be done for the joint identified by its joint + number. For each ReportXXX element, true means XXX data should be + reported and false means XXX data should not be reported. + + + + + + + + + + + + + + + + + + The abstract CRCLCommandType is derived from DataThingType. + An instance of CRCLCommandType has the following elements: + Name (inherited, optional) + CommandID. + + CRCLCommandType is an abstract type from which all other + CRCL commands are derived. + + + + + + + + + + + + + + + DwellType is derived from MiddleCommandType. + An instance of DwellType has the following elements: + Name (inherited, optional) + CommandID (inherited) + DwellTime. + + The DwellTime is an amount of time, in seconds, that the robot + should wait before executing the next command. + + + + + + + + + + + + + + + EndCanonType is derived from CRCLCommandType. + An instance of EndCanonType has the following elements: + Name (inherited, optional) + CommandID (inherited). + + An instance of EndCanonType is used to indicate that the robot + should not execute any further CRCL commands other than an + instance of InitCanonType until an InitCanonType command is + received. Other robot-specific actions may be taken in + preparation for shutting down. + + + + + + + + + + + GetStatusType is derived from MiddleCommandType. + An instance of GetStatusType has the following elements: + Name (inherited, optional) + CommandID (inherited). + + An instance of GetStatusType is used to indicate that the robot + should report status immediately. The joint status portion of + the status report must be as set by the most recent + ConfigureJointReports command. + + + + + + + + + + + InitCanonType is derived from CRCLCommandType. + An instance of InitCanonType has the following elements: + Name (inherited, optional) + CommandID (inherited). + + An instance of InitCanonType is used to indicate that the robot + should be prepared to execute further canonical robot commands. + When a robot is ready to execute commands, the first CRCL command + it should be sent is an instance of InitCanonType. Any CRCL + commands received before an instance of InitCanonType must not be + executed. Other robot-specific actions may be taken in preparation + for executing CRCL commands. + + + + + + + + + + + The abstract JointDetailsType is derived from DataThingType. + An instance of JointDetailsType has the following elements: + Name (inherited, optional) + . + + JointDetailsType is an abstract type used as the parent type of: + JointSpeedAccelType + JointForceTorqueType + + + + + + + + + + + JointForceTorqueType is derived from JointDetailsType. + An instance of JointForceTorqueType has the following elements: + Name (inherited, optional) + Setting (optional) + ChangeRate (optional). + + JointForceTorqueType specifies the force or torque and the rate of + change of force or torque for a joint. For a translational joint, + Setting is in current force units, and ChangeRate is in current + force units per second. For a rotational joint, Setting is in + current torque units, and ChangeRate is in current torque units per + second. + + + + + + + + + + + + + + + + JointSpeedAccelType is derived from JointDetailsType. + An instance of JointSpeedAccelType has the following elements: + Name (inherited, optional) + JointSpeed (optional) + JointAccel (optional). + + JointSpeedAccelType specifies the speed and acceleration for a + joint. For a rotational joint, the speed units are the current + angle units per second, and the acceleration units are the current + angle units per second per second. For a translational joint, the + speed units are the current length units per second, and the + acceleration units are the current length units per second per + second. + + + + + + + + + + + + + + + + MessageType is derived from MiddleCommandType. + An instance of MessageType has the following elements: + Name (inherited, optional) + CommandID (inherited) + Message. + + Message is a string that should be displayed by the robot + controller. + + + + + + + + + + + + + + + The abstract MiddleCommandType is derived from CRCLCommandType. + MiddleCommandType has the following elements: + Name (inherited, optional) + CommandID (inherited). + + MiddleCommandType is the abstract parent type of specific CRCL + command types. Only derived types of MiddleCommandType may be + instantiated. + + + + + + + + + + + MoveScrewType is derived from MiddleCommandType. + An instance of MoveScrewType has the following elements: + Name (inherited, optional) + CommandID (inherited) + StartPosition (optional) + AxisPoint (optional) + AxialDistanceFree (optional) + AxialDistanceScrew + Turn. + + This command is designed for attaching screws, nuts, and bolts. + It might also be used for drilling. + + The command is executed as follows. + + First, if the StartPosition exists, the controlled point and axis + are moved to the StartPosition along any convenient trajectory. + + Second, if the AxialDistanceFree exists and is not zero, the + controlled point is moved along the axis by the given + AxialDistanceFree. + + Third and finally, a screwing motion is made. If there is no + AxisPoint (or if an AxisPoint is given that is at the controlled + point), the gripper rotates around its axis through the angle given + by Turn at a constant rate while simultaneously translating along + the axis at a constant rate (the currently set speed) through the + AxialDistanceScrew so that the rotation and translation finish at + the same time. If there is an AxisPoint and it differs from the + location of the controlled point, the controlled point + simultaneously (1) rotates as above, (2) revolves around an axis + through the AxisPoint parallel to the controlled axis, and (3) + translates as above. That makes a helical motion of the controlled + point. The motion along the helix is done at the currently set + speed. + + A positive value of AxialDistanceFree or AxialDistanceScrew means + to move away from the end effector. A negative value means to move + toward the end effector. + + A positive value of Turn means to rotate (and possibly revolve) in + a counterclockwise sense as viewed from the positive Z axis of the + gripper (the region extending away from the gripper). + + The robot must reach the EndPosition within the tolerance + established (1) by the tolerance given for the pose in the + EndPosition, if there is a tolerance in the EndPosition, or if not + (2) by the most recently executed instance of + SetEndPoseToleranceType. The speed and acceleration to use are set + either in the EndPosition or by previously executed CRCL commands. + + In an instance file, the type of StartPosition may be either + PoseType or PoseAndSetType, which is derived from PoseType. + + + + + + + + + + + + + + + + + + + MoveThroughToType is derived from MiddleCommandType. + An instance of MoveThroughToType has the following elements: + Name (inherited, optional) + CommandID (inherited) + MoveStraight + Waypoint (multiple) + NumPositions. + + Each Waypoint before the last is a Pose that the robot should move + through. The last Waypoint is the Pose the robot should be in after + the command is fully executed. NumPositions is the number of + instances of the Waypoint element. The robot must pass each point + within the tolerance established (1) by the tolerance given for the + pose in the Waypoint, if there is a tolerance in the Waypoint, or + if not (2) by the most recently executed instance of + SetIntermediatePoseToleranceType (or by SetEndPoseToleranceType for + the final Waypoint). The speed and acceleration to use are set + either in the Waypoint or by previously executed CRCL commands. + + If the value of MoveStraight is true, the controlled point must be + moved in a straight line between Waypoints. If the value of + MoveStraight is false, the controlled point may be moved along any + convenient trajectory between Waypoints. In either case, there are + no restrictions on the values of XAxis and ZAxis between waypoints. + + The type of each Waypoint may be either PoseType or + PoseAndSetType, which is derived from PoseType. + + + + + + + + + + + + + + + + + MoveToType is derived from MiddleCommandType. + An instance of MoveToType has the following elements: + Name (inherited, optional) + CommandID (inherited) + MoveStraight + EndPosition. + + EndPosition is a Pose to which the robot will move. If the value of + MoveStraight is true, the controlled point must be moved in a + straight line. If the value of MoveStraight is false, the + controlled point may be moved along any convenient trajectory. + + The robot must reach the EndPosition within the tolerance + established (1) by the tolerance given for the pose in the + EndPosition, if there is a tolerance in the EndPosition, or if not + (2) by the most recently executed instance of + SetEndPoseToleranceType. The speed and acceleration to use are set + either in the EndPosition or by previously executed CRCL commands. + + The type of EndPosition may be either PoseType or + PoseAndSetType, which is derived from PoseType. + + + + + + + + + + + + + + + + OpenToolChangerType is derived from MiddleCommandType. + An instance of OpenToolChangerType has the following elements: + Name (inherited, optional) + CommandID (inherited). + + After an instance of OpenToolChangerType is executed, it is + understood that if a gripper was mounted on the robot, the + gripper is no longer mounted on the robot. In that case, + the controlled point will change. + + + + + + + + + + + ParameterSettingType is derived from DataThingType. + An instance of ParameterSettingType has the following elements: + Name (inherited, optional) + ParameterName + ParameterValue. + + ParameterSettingType is used to set values of parameters. The + ParameterName and ParameterValue are both strings. The + ParameterValue string may represent a data type known to the + receiving system. + + + + + + + + + + + + + + + + PoseAndSetType is derived from PoseType. + An instance of PoseAndSetType has the following elements: + Name (inherited, optional) + Point (inherited) + XAxis (inherited) + ZAxis (inherited) + Coordinated + TransSpeed (optional) + RotSpeed (optional) + TransAccel (optional) + RotAccel (optional) + Tolerance (optional). + + PoseAndSetType is used for waypoints of move commands. The + TransSpeed and TransAccel elements are the target translational + speed and acceleration for the controlled point as it moves to the + given pose. The RotSpeed and RotAccel elements are the target + rotational speed and acceleration for the single axis rotation + required to move from the initial pose to the target pose. The + Tolerance is the tolerance for the given pose. The TransSpeed, + TransAccel, RotSpeed, RotAccel, and Tolerance temporarily override + any set values. The set values apply again once the given pose is + reached. If the Coordinated element is set to true, translation and + rotation should finish simultaneously. If Coordinated is false, + either translation or rotation may finish first. + + + + + + + + + + + + + + + + + + + + + PoseToleranceType is derived from DataThingType. + An instance of PoseToleranceType has the following elements: + Name (inherited, optional) + XPointTolerance (optional) + YPointTolerance (optional) + ZPointTolerance (optional) + XAxisTolerance (optional) + ZAxisTolerance (optional). + + The XPointTolerance is the distance along the XAxis in current + length units within which the controlled point must come from the X + value of the point given in the pose with which the pose tolerance + is associated. The YPointTolerance and ZPointTolerance are similar. + The XAxisTolerance is the angle in current angle units within which + the XAxis must come from the given XAxis. The ZAxisTolerance is + similar. All five tolerances must be satisfied at the same instant. + + + + + + + + + + + + + + + + + + + RotAccelAbsoluteType is derived from RotAccelType. + An instance of RotAccelAbsoluteType has the following elements: + Name (inherited, optional) + Setting. + + Setting is a real number that represents the target single axis + rotational acceleration for the robot, in current angle units per + second per second. + + + + + + + + + + + + + + + RotAccelRelativeType is derived from RotAccelType. + An instance of RotAccelRelativeType has the following elements: + Name (inherited, optional) + Fraction. + + Fraction is a real number that represents the fraction of the + robot's maximum rotational acceleration that it should use. + + + + + + + + + + + + + + + The abstract RotAccelType is derived from DataThingType. + An instance of RotAccelType has the following + elements: + Name (inherited, optional) + . + + RotAccelType is an abstract type used as the parent type of: + RotAccelAbsoluteType + RotAccelRelativeType. + + + + + + + + + + + RotSpeedAbsoluteType is derived from RotSpeedType. + An instance of RotSpeedAbsoluteType has the following + elements: + Name (inherited, optional) + Setting. + + Setting is a real number that represents the target single axis + rotational speed for the robot, in current angle units per second. + + + + + + + + + + + + + + + RotSpeedRelativeType is derived from RotSpeedType. + An instance of RotSpeedRelativeType has the following elements: + Name (inherited, optional) + Fraction. + + Fraction is a real number that represents the fraction of the + robot's maximum rotational speed that it should use. + + + + + + + + + + + + + + + The abstract RotSpeedType is derived from DataThingType. + An instance of RotSpeedType has the following + elements: + Name (inherited, optional) + . + + RotSpeedType is an abstract type used as the parent type of: + RotSpeedAbsoluteType + RotSpeedRelativeType. + + + + + + + + + + + RunProgramType is derived from MiddleCommandType. + An instance of RunProgramType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + ProgramText. + + The RunProgramType is used to instruct the low level controller to + run a program written in a non-CRCL language that controller + understands. The ProgramText element gives the text of the program. + + + + + + + + + + + + + + + SetAngleUnits is derived from MiddleCommandType. + An instance of SetAngleUnits has the following elements: + Name (inherited, optional) + CommandID (inherited) + UnitName. + + UnitName is a string that can be only the literals 'radian' or + 'degree'. This tells the robot that all further commands + giving angle values will implicitly use the named unit. + + + + + + + + + + + + + + + SetEndEffectorParametersType is derived from MiddleCommandType. + An instance of SetEndEffectorParametersType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + ParameterSetting (multiple). + + SetEndEffectorParametersType is for setting parameters of end + effectors that have parameters. The meaning of the parameter + settings is not part of CRCL. It is expected that this command will + be used only to send parameter values that can be used by the end + effector currently in use. + + + + + + + + + + + + + + + SetEndEffectorType is derived from MiddleCommandType. + An instance of SetEndEffectorType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + Setting. + + SetEndEffectorType is for setting the effectivity of end effectors. + If an end effector has multiple control modes, the control mode + must be set using a SetEndEffectorParameters command, so that the + meaning of SetEndEffector commands is unambiguous. + + For end effectors that have a continuously variable setting, the + Setting means a fraction of maximum openness, force, torque, power, + etc. + + For end effectors that have only two choices (powered or unpowered, + open or closed, on or off), a positive Setting value means powered, + open, or on, while a zero Setting value means unpowered, closed, or + off. + + + + + + + + + + + + + + + SetEndPoseToleranceType is derived from MiddleCommandType. + An instance of SetEndPoseToleranceType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + Tolerance. + + The Tolerance element indicates to the robot the precision with + which it must reach its end location. + + + + + + + + + + + + + + + SetForceUnitsType is derived from MiddleCommandType. + An instance of SetForceUnitsType has the following elements: + Name (inherited, optional) + CommandID (inherited) + UnitName. + + UnitName is a string that can be only the literals 'newton', + 'pound', or 'ounce'. This tells the robot that all further commands + giving force values will implicitly use the named unit. + + + + + + + + + + + + + + + SetIntermediatePoseToleranceType is derived from MiddleCommandType. + An instance of SetIntermediatePoseToleranceType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + Tolerance. + + The Tolerance element indicates to the robot the precision with + which it must reach each intermediate waypoint. + + + + + + + + + + + + + + + SetLengthUnitsType is derived from MiddleCommandType. + An instance of SetLengthUnitsType has the following elements: + Name (inherited, optional) + CommandID (inherited) + UnitName. + + UnitName is a string that can be only the literals 'meter', + 'millimeter', or 'inch'. This tells the robot that all further + commands giving position or length values will implicitly use the + named unit. + + + + + + + + + + + + + + + SetMotionCoordinationType is derived from MiddleCommandType. + An instance of SetMotionCoordinationType has the following elements: + Name (inherited, optional) + CommandID (inherited) + Coordinated. + + Coordinated is a boolean. If the value is true, rotational and + translational motion must finish simultaneously in motion commands + (including each segment in a multiple segment motion command), + except as possibly temporarily overridden in the the motion + command. If the value is false, there is no such requirement. + + + + + + + + + + + + + + + SetRobotParametersType is derived from MiddleCommandType. + An instance of SetRobotParametersType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + ParameterSetting (multiple). + + SetRobotParametersType is for setting robot parameters that + cannot be set by any other CRCL command. The meaning of the + parameter settings is not part of CRCL. + + + + + + + + + + + + + + + SetRotAccelType is derived from MiddleCommandType. + An instance of SetRotAccelType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + RotAccel. + + RotAccel specifies the rotational acceleration that should + be used. + + + + + + + + + + + + + + + SetRotSpeedType is derived from MiddleCommandType. + An instance of SetRotSpeedType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + RotSpeed. + + RotSpeed specifies the rotational speed that should be used. + + + + + + + + + + + + + + + SetTorqueUnitsType is derived from MiddleCommandType. + An instance of SetTorqueUnitsType has the following elements: + Name (inherited, optional) + CommandID (inherited) + UnitName. + + UnitName is a string that can be only the literals 'newtonMeter' + or 'footPound'. This tells the robot that all further commands + giving torque values will implicitly use the named unit. + + + + + + + + + + + + + + + The SetTransAccelType is derived from MiddleCommandType. + An instance of SetTransAccelType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + TransAccel. + + TransAccel specifies the translational acceleration that should + be used. + + + + + + + + + + + + + + + SetTransSpeedType is derived from MiddleCommandType. + An instance of SetTransSpeedType has the following + elements: + Name (inherited, optional) + CommandID (inherited) + TransSpeed. + + TransSpeed specifies the translational speed that should be used. + + + + + + + + + + + + + + + The StopConditionEnumType enumerates types of commanded stops. Any + physical devices or built-in control methods of the robot + controller for stopping the robot are in addition to these + commanded stop types. + + Immediate means the robot's drives are deactivated immediately and + the brakes are applied. This may result in the controlled point + being off the commanded path when the robot stops. + + Fast means the robot and any external axes are brought to a fast, + controlled stop. The drives are deactivated after one second, and + the brakes are applied. The controlled point must be kept on the + on the commanded path as the robot stops. + + Normal means the robot and any external drives are stopped using + a normal braking ramp. The drives are not deactivated, and the + brakes are not applied. The controlled point must be kept on the + on the commanded path as the robot stops. + + + + + + + + + + + + + StopMotionType is derived from MiddleCommandType. + An instance of StopMotionType has the following elements: + Name (inherited, optional) + CommandID (inherited) + StopCondition. + + StopCondition is an enumerated value indicating how the stop + should occur. + + + + + + + + + + + + + + + TransAccelAbsoluteType is derived from TransAccelType. + An instance of TransAccelAbsoluteType has the following + elements: + Name (inherited, optional) + Setting. + + Setting is a real number that represents the target + translational acceleration for the controlled point, in + current length units per second per second. + + + + + + + + + + + + + + + TransAccelRelativeType is derived from TransAccelType. + An instance of TransAccelRelativeType has the following + elements: + Name (inherited, optional) + Fraction. + + Fraction is a real number that represents the fraction of the + robot's maximum translational acceleration that it should use. + + + + + + + + + + + + + + + The abstract TransAccelType is derived from DataThingType. + An instance of TransAccelType has the following + elements: + Name (inherited, optional) + . + + TransAccelType is an abstract type used as the parent type of: + TransAccelAbsoluteType + TransAccelRelativeType. + + + + + + + + + + + TransSpeedAbsoluteType is derived from TransSpeedType. + An instance of TransSpeedAbsoluteType has the following + elements: + Name (inherited, optional) + Setting. + + Setting is a real number that represents the target speed for the + controlled point, in current length units per second. + + + + + + + + + + + + + + + TransSpeedRelativeType is derived from TransSpeedType. + An instance of TransSpeedRelativeType has the following elements: + Name (inherited, optional) + Fraction. + + Fraction is a real number that represents the fraction of the + robot's maximum translational speed that it should use. + + + + + + + + + + + + + + + The abstract TransSpeedType is derived from DataThingType. + An instance of TransSpeedType has the following + elements: + Name (inherited, optional) + . + + TransSpeedType is and abstract type used as the parent type of: + TransSpeedAbsoluteType + TransSpeedRelativeType. + + + + + + + + diff --git a/crcl4java-base/src/main/resources/CRCLProgramInstance.xsd b/crcl4java-base/src/main/resources/CRCLProgramInstance.xsd new file mode 100644 index 0000000..18b5664 --- /dev/null +++ b/crcl4java-base/src/main/resources/CRCLProgramInstance.xsd @@ -0,0 +1,64 @@ + + + + + + + + This ontology models a program written in the canonical robot + command language (CRCL). + + owlPrefix=crp + + + + + + The global CRCLProgram element may be used as the root element of + a CRCL instance file containing an entire CRCL program. + + + + + + + + CRCLProgramType is derived from DataThingType. + An instance of CRCLProgramType has the following elements: + Name (inherited, optional) + InitCanon + MiddleCommand (optional, multiple) + EndCanon. + + CRCLProgramType defines a CRCL program as a sequence of CRCL + commands. The CRCL commands in an instance of CRCLProgramType + must be executed in the order given. Using a CRCL program is + intended for testing and demos, not normal operation. + + A CRCL program must start with an InitCanon command and end + with an EndCanon command. It may have zero to many middle + commands between the InitCanon and the EndCanon. + + + + + + + + + + + + + + diff --git a/crcl4java-base/src/main/resources/CRCLStatus.xsd b/crcl4java-base/src/main/resources/CRCLStatus.xsd new file mode 100644 index 0000000..1ce5686 --- /dev/null +++ b/crcl4java-base/src/main/resources/CRCLStatus.xsd @@ -0,0 +1,368 @@ + + + + + + + + + Root element + + + + + + + This ontology models a status message from a low-level robot + controller to a controller sending commands to the low-level + controller. The messages are designed to work with the canonical + robot command language (CRCL). + + If any joint status reporting is done, it is assumed that the system + sending canonical commands and the system executing them both know + the kinematics of the robot and have the same numbering system for + the joints, starting with 1. The two systems also have the same + understanding of where the zero point is and which direction is + positive for each joint. + + Status items for joints must be configured using a + ConfigureJointReports command. + For each joint for which anything is to be reported, + ConfigureJointReports specifies: + - whether joint position should be reported + - whether joint torque or force should be reported + - whether joint velocity should be reported + + During a CRCL session, until a ConfigureJointReports command has + been executed that sets the reporting status for a joint, no joint + status should be reported for that joint. The ConfigureJointReports + command may be used more than once during a session to change joint + status reporting. + + The units used in a status report are the following, where linear + units are set by a SetLinearUnits command, and angular units are set + by a SetAngularUnits command. + distance - linear units + angle - angular units + linear speed - linear units per second + angular speed - angular units per second + linear acceleration - linear units per second per second + angular acceleration - angular units per second per second + force - as set by a SetForceUnits command + torque - as set by a SetTorqueUnits command + + If reporting a joint status requires a unit, the units are as + set by the most recent SetXXXUnits command. If no SetXXXUnits + command for a given unit type has been executed since the last + InitCanonType command was executed, the following default units + apply: + length -- meter + angle -- radian + force -- newton + torque -- newtonMeter + + In order that this file may be translateable into OWL, all + complexTypes in this file include the (optional) Name element, + inherited from DataThingType. If an instance file has instances of + complex data without names, it will not be translateable into OWL. + + See the in-line documentation of ConfigureJointReportsType in + CRCL.xsd for further information. + + owlPrefix=stat + + + + + + CommandStateEnumType enumerates the command states that may be used + to describe command status. + + Done means that the most recent command is done. + + Error means that the most recent command resulted in an error + of some sort. + + Working means that the most recent command is being executed, + and no error has occurred so far, but execution of the command + is not yet done. + + + + + + + + + + + + + CommandStatusType is derived from DataThingType. + An instance of CommandStatusType has the following elements: + Name (inherited, optional) + CommandID + StatusID + CommandState. + + The CommandStatusType relates the execution status of the + currently executing command (or the most recently executed + command, if there is no current command). + CommandID echoes the command id from the received command to + which the status message applies + StatusID is an ID associated with this particular status + message. + The combination of StatusID and CommandID must be unique + within a session. + + + + + + + + + + + + + + + + + CRCLStatusType is derived from DataThingType. + An instance of CRCLStatusType has the following elements: + Name (inherited, optional) + CommandStatus + JointStatuses (optional) + Pose (optional) + GripperStatus (optional). + + Status is returned periodically by the controller. + + See notes at the beginning of this file regarding configuring + CRCL status messages. + + GripperStatus should not be reported when there is no gripper + and should be reported when there is a gripper. + + The coordinate system in which the Pose is reported is always + workstation coordinates. + + If CRCL status is being reported on separate channels for both + a robot and a gripper, the status reported on the robot + channel should include a Pose, while the status reported on the + gripper channel should not include a Pose. + + + + + + + + + + + + + + + + + + The abstract GripperStatusType is derived from DataThingType. + An instance of GripperStatusType has the following elements: + Name (inherited, optional) + GripperName. + + GripperStatusType is an abstract type from which more specialized + types of gripper status are derived. + + + + + + + + + + + + + + + JointStatusesType is derived from DataThingType. + An instance of JointStatusesType has the following elements: + Name (inherited, optional) + JointStatus (multiple). + + Each JointStatus element gives the status of one joint. No + joint may be reported more than once in an instance of + JointStatusesType. See notes at the beginning of this file + regarding configuring joint status. + + + + + + + + + + + + + + + JointStatusType is derived from DataThingType. + JointStatusType reports the status of one joint. + An instance of JointStatusType has the following elements: + Name (inherited, optional) + JointNumber + JointPosition (optional) + JointTorqueOrForce (optional) + JointVelocity (optional). + + + + + + + + + + + + + + + + + + + ParallelGripperStatusType is derived from GripperStatusType. + An instance of ParallelGripperStatusType has the following elements: + Name (inherited, optional) + GripperName (inherited) + Separation. + + ParallelGripperStatusType gives gripper status for a parallel + jaw gripper. The Separation element gives the distance between + the jaws in length units. + + + + + + + + + + + + + + + ThreeFingerGripperStatusType is derived from GripperStatusType. + An instance of ThreeFingerGripperStatusType has the following + elements: + Name (inherited, optional) + GripperName (inherited) + Finger1Position (optional) + Finger2Position (optional) + Finger3Position (optional) + Finger1Force (optional) + Finger2Force (optional) + Finger3Force (optional). + + ThreeFingerGripperStatusType gives gripper status for a three + finger gripper. The fingers are assumed to be non-articulated. + Finger position is 0.0 at fully closed and 1.0 at fully open and + linear in either angle or distance for rotating fingers or + sliding fingers, respectively. All elements are optional, but + typically all three positions will be used if any one of + them is used, and similarly for the three forces. + + Force units are as set by the most recent SetForceUnits command. + The system sending CRCL commands and the system executing them + must agree on which fingers are Finger1, Finger2,and Finger3. + + + + + + + + + + + + + + + + + + + + VacuumGripperStatusType is derived from GripperStatusType. + An instance of VacuumGripperStatusType has the following elements: + Name (inherited, optional) + GripperName (inherited) + IsPowered. + + VacuumGripperStatusType gives gripper status for a vacuum + gripper. The IsPowered element is true if a vacuum is being + applied and is false if not. + + + + + + + + + + + + diff --git a/crcl4java-base/src/main/resources/DataPrimitives.xsd b/crcl4java-base/src/main/resources/DataPrimitives.xsd new file mode 100644 index 0000000..eb6b38e --- /dev/null +++ b/crcl4java-base/src/main/resources/DataPrimitives.xsd @@ -0,0 +1,201 @@ + + + + + + + This ontology models primitive types useful for building + information models for automated manufacturing. + + + In order that models using this file may be translateable into + OWL, all complexTypes in this file include the Name element. This + is done by putting the Name element in the top-level data type, + DataThingType and having all other complexTypes be descended + directly or indirectly from DataThingType. + + In order that models using this file are not required to assign + a name to each complex data instance, the Name element of + DataThingType is optional. If an instance file has instances of + complex data without names, it will not be translateable into + OWL. + + owlPrefix=prim + + + + + + AngleUnitEnumType enumerates angle units. This might be used, + for example, in a command that sets angle units. + + + + + + + + + + + + An instance of DataThingType has the following elements: + Name (optional) + . + + DataThingType is an abstract type from which more specific types + of data thing are derived. That includes all complex data + types such as VectorType, PoseType, etc. + + + + + + + + + + + ForceUnitEnumType enumerates force units. This might be used, + for example, in a command that sets force units. + + + + + + + + + + + + + FractionType is a number between zero and 1 representing a fraction. + + + + + + + + + + + + LengthUnitEnumType enumerates length units. This might be used, + for example, in a command that sets length units. + + + + + + + + + + + + + PointType is derived from DataThingType. + An instance of PointType has the following elements: + Name (inherited, optional) + X + Y + Z. + + X, Y, and Z are the Cartesian coordinates of the Point. + + + + + + + + + + + + + + + + + PoseType is derived from DataThingType. + An instance of PoseType has the following elements: + Name (inherited, optional) + Point + XAxis + ZAxis. + + The Point locates the origin of a coordinate system. The XAxis and + ZAxis give the orientation of the coordinate system. The data for + the Point, the ZAxis and the XAxis are expressed relative to another + coordinate system. + + + + + + + + + + + + + + + + + TorqueUnitEnumType enumerates torque units. This might be used, + for example in a command that sets torque units. + + + + + + + + + + + + VectorType is derived from DataThingType. + An instance of VectorType has the following elements: + Name (inherited, optional) + I + J + K. + + I, J, and K represent the usual i, j, and k components of a 3D + vector. + + + + + + + + + + + + + + diff --git a/crcl4java-base/src/test/resources/main/initPose.csv b/crcl4java-base/src/test/resources/main/initPose.csv new file mode 100644 index 0000000..a323f26 --- /dev/null +++ b/crcl4java-base/src/test/resources/main/initPose.csv @@ -0,0 +1,2 @@ +x,y,z,roll,pitch,yaw +8.2,1.0,0.5,180.0,0.0,0.0 \ No newline at end of file diff --git a/crcl4java-base/src/test/resources/main/programAll.xml b/crcl4java-base/src/test/resources/main/programAll.xml new file mode 100755 index 0000000..ace2409 --- /dev/null +++ b/crcl4java-base/src/test/resources/main/programAll.xml @@ -0,0 +1,262 @@ + + + + + start + 1 + + + 2 + + 1 + 3.8 + + 3.7 + 11 + + + + 3 + 3.8 + + 7 + 13.0 + + + + + 3 + + + 4 + true + + 1 + true + false + false + + + 3 + true + true + false + + + + 5 + 2.5 + + + 6 + + + 7 + Hi Mom + + + + 8 + + 8.25 1 0.5 + + 6.10 + -3.14 + + + 9 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + true + + 0.9 + + + 0.5 + + + 0.005 + 0.01 + 0.015 + 1.0 + + + 2 + + + 12 + true + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 13 + + + 14 + GH$%kkk457 xxx 65 + + + 15 + degree + + + 16 + + rhabdaciousness + on + + + fluoxity + 33 + + + + 17 + 1.0 + + + 18 + + 0.005 + 0.01 + 0.015 + 1.0 + 1.0 + + + + 19 + ounce + + + 20 + + 0.1 + 0.05 + 0.06 + 1.0 + 1.0 + + + + 21 + meter + + + 22 + true + + + 23 + + empathy + 3.2 + + + air pressure + 701 + + + + 24 + + 4.08 + + + + 25 + + 0.77 + + + + 26 + + 6.28 + + + + 27 + + 0.55 + + + + 28 + newtonMeter + + + 29 + + 9.80 + + + + 30 + + 0.75 + + + + 31 + + 5.0 + + + + 32 + + 0.85 + + + + 33 + Normal + + + 34 + + diff --git a/crcl4java-base/src/test/resources/main/programExample.xml b/crcl4java-base/src/test/resources/main/programExample.xml new file mode 100755 index 0000000..4b0a65e --- /dev/null +++ b/crcl4java-base/src/test/resources/main/programExample.xml @@ -0,0 +1,731 @@ + + + + 1 + + + 2 + meter + + + 3 + + 1.0 + + + + 4 + + 0.80 + + + + 5 + + 0.002 + 0.002 + 0.002 + + + + 6 + + 0.01 + 0.01 + 0.01 + + + + 7 + 0 + + + 8 + false + + + 1.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 1.5 1 0.0001 + + + 1 0 0 + + + 0 0 -1 + + + 2 + + + 9 + 1 + + + 10 + false + + + 1.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 0.5001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 11 + 0 + + + 12 + false + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.4 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 13 + + + 14 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 15 + + + 16 + false + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 1.1 1.8 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 1.1 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 17 + 1 + + + 18 + false + + + 5.659 1.1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 1.07 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 19 + 0 + + + 20 + false + + + 3.86 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 0.9 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 0.9 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 21 + 1 + + + 22 + false + + + 5.659 0.9 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 0.93 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 23 + 0 + + + 24 + false + + + 3.86 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 6.42 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 6.42 1 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 25 + 1 + + + 26 + false + + + 6.42 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 0.93 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 27 + 0 + + + 28 + false + + + 4.14 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 7.61 1.02 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 7.61 1.02 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 29 + 1 + + + 30 + false + + + 7.61 1.02 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 1.07 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 31 + 0 + + + 32 + false + + + 4.14 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 0.475 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 33 + + + 34 + false + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 35 + + + 36 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 0.5001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 37 + 1 + + + 38 + false + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 2.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 2.5 1 0.0001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 39 + 0 + + + 40 + false + + + 2.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 0.5 0 2 + + + 1 0 0 + + + 0 0 -1 + + + 2 + + + 41 + + diff --git a/crcl4java-utils/README.txt b/crcl4java-utils/README.txt new file mode 100644 index 0000000..fc351b0 --- /dev/null +++ b/crcl4java-utils/README.txt @@ -0,0 +1,45 @@ +To Build: + +Download the latest JDK (at-least 1.8+) from http://www.oracle.com/technetwork/java/javase/downloads/index.html + +( getting the bundled Netbeans is recommended but not required) + +To build with netbeans simply open this directory as a project (File-> Open Project ...) and choose +(Run -> Build Project (CRCLJava) ). + +To build on the command line: + +export JAVA_HOME=[path_to_jdk_1.8+] +sudo apt-get install maven +mvn clean package + +To run graphical launcher: + +[path_to_jdk_1.8+]/bin/java -jar target/CRCLJava-1.0-SNAPSHOT-jar-with-dependencies.jar + +or use the convenience scripts run.sh or run.bat + +./run.sh + +or on Windows + +run.bat + + +For example to run the server in the background on port 5004 + +./run.sh --mode CmdLineServer --port 5004 & + +or on Windows + +run.bat --mode CmdLineServer --port 5004 + +To have the client send a program one command at a time and check status: + +./run.sh --mode CmdLineClient --host localhost --port 5004 --program ../xml/crcl/xmlInstanceFiles/programExample.xml + +or on Windows + +run.bat --mode CmdLineClient --host localhost --port 5004 --program ..\xml\crcl\xmlInstanceFiles\programExample.xml + +The program shows two buttons to launch either the server or client (one could even launch multiple clients/servers) diff --git a/crcl4java-utils/license-NIST.txt b/crcl4java-utils/license-NIST.txt new file mode 100644 index 0000000..6049062 --- /dev/null +++ b/crcl4java-utils/license-NIST.txt @@ -0,0 +1,25 @@ +<#if licenseFirst??> +${licenseFirst} + +${licensePrefix}This software is public domain software, however it is preferred +${licensePrefix}that the following disclaimers be attached. +${licensePrefix}Software Copywrite/Warranty Disclaimer +${licensePrefix} +${licensePrefix}This software was developed at the National Institute of Standards and +${licensePrefix}Technology by employees of the Federal Government in the course of their +${licensePrefix}official duties. Pursuant to title 17 Section 105 of the United States +${licensePrefix}Code this software is not subject to copyright protection and is in the +${licensePrefix}public domain. NIST Real-Time Control System software is an experimental +${licensePrefix}system. NIST assumes no responsibility whatsoever for its use by other +${licensePrefix}parties, and makes no guarantees, expressed or implied, about its +${licensePrefix}quality, reliability, or any other characteristic. We would appreciate +${licensePrefix}acknowledgement if the software is used. This software can be +${licensePrefix}redistributed and/or modified freely provided that any derivative works +${licensePrefix}bear some notice that they are derived from it, and any modified +${licensePrefix}versions bear some notice that they have been modified. +${licensePrefix} +${licensePrefix} See http://www.copyright.gov/title17/92chap1.html#105 +${licensePrefix} +<#if licenseLast??> +${licenseLast} + diff --git a/crcl4java-utils/nb-configuration.xml b/crcl4java-utils/nb-configuration.xml new file mode 100644 index 0000000..9723198 --- /dev/null +++ b/crcl4java-utils/nb-configuration.xml @@ -0,0 +1,18 @@ + + + + + + ${project.basedir}/license-NIST.txt + + diff --git a/crcl4java-utils/nbactions.xml b/crcl4java-utils/nbactions.xml new file mode 100644 index 0000000..bdd210d --- /dev/null +++ b/crcl4java-utils/nbactions.xml @@ -0,0 +1,89 @@ + + + + run + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -classpath %classpath ${main.class} + java + + + + CUSTOM-runPerfTest + runPerfTest + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -classpath %classpath crcl.utils.PerfTest + java + + + + debug + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath ${main.class} + java + true + + + + CUSTOM-Verify + Verify + + verify + + + codecoverage + + + + CUSTOM-Clean and Package Only + Clean and Package Only + + clean + package + + + + profile + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -classpath %classpath ${main.class} + java + + + + CUSTOM-PerfTest + PerfTest + + exec:java + + + "crcl.utils.PerfTest" + + + diff --git a/crcl4java-utils/pom.xml b/crcl4java-utils/pom.xml new file mode 100644 index 0000000..ae100f0 --- /dev/null +++ b/crcl4java-utils/pom.xml @@ -0,0 +1,353 @@ + + + 4.0.0 + com.github.wshackle + crcl4java-utils + 1.0-SNAPSHOT + jar + + .. + com.github.wshackle + CRCLJavaParent + 1.0-SNAPSHOT + + + + com.github.wshackle + rcslib + 2015.05.04.02 + + + com.github.wshackle + poseList3DPlot + 1.0-SNAPSHOT + + + com.github.wshackle + CRCLJavaBase + 1.0-SNAPSHOT + + + junit + junit + 4.10 + test + + + org.apache.commons + commons-math3 + 3.5 + jar + + + commons-io + commons-io + 2.4 + jar + + + com.siemens.ct.exi + exificient + 0.9.4 + + + + 1.8 + 1.8 + crcl.utils.DefaultMain + UTF-8 + UTF-8 + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.8 + + + maven-failsafe-plugin + 2.18.1 + + + + integration-test + verify + + + + + + + src/test/resources/logging.properties + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + ${main.class} + + + + + + maven-assembly-plugin + 2.5.5 + + + + ${main.class} + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + codecoverage + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + + ${surefireArgLine} + + ${skip.unit.tests} + + + **/IT*.java + + + + src/test/resources/logging.properties + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.15 + + + + integration-tests + + integration-test + verify + + + + ${failsafeArgLine} + + ${skip.integration.tests} + + + src/test/resources/logging.properties + + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.4.201502262128 + + + + prepare-agent + + + + report + prepare-package + + report + + + + + pre-unit-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + surefireArgLine + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + ${project.reporting.outputDirectory}/jacoco-ut + + + + + pre-integration-test + pre-integration-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-it.exec + + failsafeArgLine + + + + + post-integration-test + post-integration-test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-it.exec + + ${project.reporting.outputDirectory}/jacoco-it + + + + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + crcl4java-utils + \ No newline at end of file diff --git a/crcl4java-utils/run.bat b/crcl4java-utils/run.bat new file mode 100644 index 0000000..ef77e6e --- /dev/null +++ b/crcl4java-utils/run.bat @@ -0,0 +1,16 @@ + + + +@REM set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_31\ +@REM set PATH=%JAVA_HOME%\bin;%PATH% +@REM set PATH=%PATH%;"C:\Program Files\NetBeans 8.0.2\java\maven\bin"; +@REM mvn package + + +@REM set OLDDIR=%CD% +SET mypath=%~dp0 +@REM cd %mypath% + +java -jar %mypath%/target/CRCLJava-1.0-SNAPSHOT-jar-with-dependencies.jar %* +@REM chdir /d %OLDDIR% +@REM restore current directory diff --git a/crcl4java-utils/run.sh b/crcl4java-utils/run.sh new file mode 100755 index 0000000..5356a49 --- /dev/null +++ b/crcl4java-utils/run.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +if test ! -f ./run.sh ; then + cd "${0%%run.sh}"; +fi + +if test "x" != "x${JAVA_HOME}" ; then + export PATH="${JAVA_HOME}/bin/:${PATH}"; +fi + +if test ! -f target/CRCLJava-1.0-SNAPSHOT-jar-with-dependencies.jar ; then + mvn -version || ( echo "Please install maven." && false) + mvn package +fi; + +java -jar target/CRCLJava-1.0-SNAPSHOT-jar-with-dependencies.jar $* diff --git a/crcl4java-utils/src/main/java/crcl/utils/AnnotatedPose.java b/crcl4java-utils/src/main/java/crcl/utils/AnnotatedPose.java new file mode 100644 index 0000000..6cbd82b --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/AnnotatedPose.java @@ -0,0 +1,85 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +import crcl.base.CRCLStatusType; +import java.math.BigInteger; +import rcs.posemath.PmCartesian; +import rcs.posemath.PmPose; +import rcs.posemath.PmQuaternion; + +/** + * + * @author Will Shackleford {@literal } + */ +public class AnnotatedPose extends PmPose { + + private final long time; + private final BigInteger cmdId; + private final String commandName; + private final CRCLStatusType status; + + /** + * + * @param time the value of time + * @param cmdId the value of cmdId + * @param commandName the value of commandName + * @param starttran the value of starttran + * @param startrot the value of startrot + * @param status the value of status + */ + public AnnotatedPose( + long time, BigInteger cmdId, String commandName, PmCartesian starttran, PmQuaternion startrot, CRCLStatusType status) { + super(starttran, startrot); + this.time = time; + this.cmdId = cmdId; + this.commandName = commandName; + this.status = status; + } + + public long getTime() { + return time; + } + + public BigInteger getCmdId() { + return cmdId; + } + + public String getCommandName() { + return commandName; + } + + public PmCartesian getTran() { + return tran; + } + + public PmQuaternion getRot() { + return rot; + } + + public CRCLStatusType getStatus() { + return status; + } + + + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLPosemath.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLPosemath.java new file mode 100644 index 0000000..84e36d6 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLPosemath.java @@ -0,0 +1,685 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + + +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.PoseType; +import crcl.base.VectorType; +import java.math.BigDecimal; +import org.apache.commons.math3.geometry.euclidean.threed.Rotation; +import rcs.posemath.PmCartesian; +import rcs.posemath.PmException; +import rcs.posemath.PmPose; +import rcs.posemath.PmRotationMatrix; +import rcs.posemath.PmRotationVector; +import rcs.posemath.PmRpy; +import rcs.posemath.Posemath; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; + +/** + * This class converts the types used in CRCL to and from the Posemath classes + * in rcslib and the Vector3D and Rotation classes of Apache commons-math. + * + * Note Posemath stores data in primitive double variables for faster + * computation but crcl generally uses BigDecimal for larger potential range and + * precision. Some range overflow or loss of precision could result. + * + * @author Will Shackleford{@literal } + */ +public class CRCLPosemath { + + private CRCLPosemath() { + // never to be called. + } + + /** + * Convert a CRCL VectorType to commons-math Vector3D + * + * @param vIn vector to convert + * @return commons-math representation of a Vector + */ + public static Vector3D toCommonsVector3D(VectorType vIn) { + return new Vector3D( + vIn.getI().doubleValue(), + vIn.getJ().doubleValue(), + vIn.getK().doubleValue()); + } + + /** + * Convert a CRCL VectorType to commons-math Vector3D + * + * @param ptIn point to convert + * @return commons-math representation of a Vector + */ + public static Vector3D toCommonsVector3D(PointType ptIn) { + return new Vector3D( + ptIn.getX().doubleValue(), + ptIn.getY().doubleValue(), + ptIn.getZ().doubleValue()); + } + + /** + * Take the translational component of a CRCL Pose and convert it to + * commons-math Vector3D + * + * @param poseIn pose to convert + * @return commons-math representation of a Vector + */ + public static Vector3D toCommonsVector3D(PoseType poseIn) { + return toCommonsVector3D(poseIn.getPoint()); + } + + /** + * Convert commons-math Vector3D to a CRCL Unit Vector without normalizing + * WARNING: may produce non-normalized vectors + * + * @param vIn commons-math vector to convert + * @param vOut optional location to store converted value in + * @return CRCL VectorType of the unit of input vector + */ + public static VectorType toCRCLVector(Vector3D vIn, VectorType vOut) { + if (vOut == null) { + vOut = new VectorType(); + } + try { + vOut.setI(BigDecimal.valueOf(vIn.getX())); + vOut.setJ(BigDecimal.valueOf(vIn.getY())); + vOut.setK(BigDecimal.valueOf(vIn.getZ())); + } catch (org.apache.commons.math3.exception.MathArithmeticException ex) { + // If the input vector had zero magnitude return magnitude vector. + } + return vOut; + } + + /** + * Convert commons-math Vector3D to a without normalizing CRCL Unit Vector + * WARNING: may produce non-normalized vectors + * + * @param vIn commons-math vector to convert + * @return CRCL VectorType of the unit of input vector + */ + public static VectorType toCRCLVector(Vector3D vIn) { + return toCRCLVector(vIn, new VectorType()); + } + + + /** + * Normalize and convert commons-math Vector3D to a CRCL Unit Vector + * + * @param vIn commons-math vector to convert + * @param vOut optional location to store converted value in + * @return CRCL VectorType of the unit of input vector + */ + public static VectorType toCRCLUnitVector(Vector3D vIn, VectorType vOut) { + if (vOut == null) { + vOut = new VectorType(); + } + try { + Vector3D vInUnit = vIn.normalize(); + vOut.setI(BigDecimal.valueOf(vInUnit.getX())); + vOut.setJ(BigDecimal.valueOf(vInUnit.getY())); + vOut.setK(BigDecimal.valueOf(vInUnit.getZ())); + } catch (org.apache.commons.math3.exception.MathArithmeticException ex) { + // If the input vector had zero magnitude return magnitude vector. + } + return vOut; + } + + /** + * Normalize and convert commons-math Vector3D to a CRCL Unit Vector + * + * @param vIn commons-math vector to convert + * @return CRCL VectorType of the unit of input vector + */ + public static VectorType toCRCLUnitVector(Vector3D vIn) { + return toCRCLUnitVector(vIn, new VectorType()); + } + + /** + * Take the rotation component of PoseLocationIn and convert to commons-math + * Rotation + * + * @param poseIn CRCL Pose to convert + * @return converted rotational component + */ + public static Rotation toCommonsRotation(PoseType poseIn) { + return new Rotation( + toCommonsVector3D(poseIn.getXAxis()), + toCommonsVector3D(poseIn.getZAxis()), + Vector3D.PLUS_I, + Vector3D.PLUS_K); + } + + /** + * Convert commons-math Vector3D to CRCL Point + * + * @param vIn commons-math vector to convert + * @param ptOut optional location to store new Point + * @return converted vector as CRCL PointType + */ + public static PointType toCRCLPoint(Vector3D vIn, PointType ptOut) { + if (null == ptOut) { + ptOut = new PointType(); + } + ptOut.setX(BigDecimal.valueOf(vIn.getX())); + ptOut.setY(BigDecimal.valueOf(vIn.getY())); + ptOut.setZ(BigDecimal.valueOf(vIn.getZ())); + return ptOut; + } + + /** + * Convert commons-math Vector3D to CRCL Point + * + * @param vIn commons-math vector to convert + * @return converted vector as CRCL PointType + */ + public static PointType toCRCLPoint(Vector3D vIn) { + return toCRCLPoint(vIn, new PointType()); + } + + /** + * Convert crcl.PointType to rcs.posemath.PmCartesian + * + * @param pt Point to be converted + * @return PmCartesian equivalent + */ + public static PmCartesian pointToPmCartesian(final PointType pt) { + return new PmCartesian( + pt.getX().doubleValue(), + pt.getY().doubleValue(), + pt.getZ().doubleValue()); + } + + public static PoseType identityPose() { + PoseType newPose = new PoseType(); + PointType pt = new PointType(); + pt.setX(BigDecimal.ZERO); + pt.setY(BigDecimal.ZERO); + pt.setZ(BigDecimal.ZERO); + newPose.setPoint(pt); + VectorType xAxis = new VectorType(); + xAxis.setI(BigDecimal.ONE); + xAxis.setJ(BigDecimal.ZERO); + xAxis.setK(BigDecimal.ZERO); + newPose.setXAxis(xAxis); + VectorType zAxis = new VectorType(); + zAxis.setI(BigDecimal.ZERO); + zAxis.setJ(BigDecimal.ZERO); + zAxis.setK(BigDecimal.ONE); + newPose.setZAxis(zAxis); + return newPose; + } + + public static String poseToString(PoseType pose) throws PmException { + PmRotationMatrix rmat = toPmRotationMatrix(pose); + PmCartesian cart = pointToPmCartesian(pose.getPoint()); + return String.format("{\n{%.3g,%.3g,%.3g,%.3g},\n{%.3g,%.3g,%.3g,%.3g},\n{%.3g,%.3g,%.3g,%.3g},\n{%.3g,%.3g,%.3g,%.3g}\n}", + rmat.x.x, rmat.x.y, rmat.x.z, cart.x, + rmat.y.x, rmat.y.y, rmat.y.z, cart.y, + rmat.z.x, rmat.z.y, rmat.z.z, cart.z, + 0.0, 0.0, 0.0, 1.0); + } + + public static PointType add(PointType p1, PointType p2) { + PointType sum = new PointType(); + sum.setX(p1.getX().add(p2.getX())); + sum.setY(p1.getY().add(p2.getY())); + sum.setZ(p1.getZ().add(p2.getZ())); + return sum; + } + + public static PointType subtract(PointType p1, PointType p2) { + PointType sum = new PointType(); + sum.setX(p1.getX().subtract(p2.getX())); + sum.setY(p1.getY().subtract(p2.getY())); + sum.setZ(p1.getZ().subtract(p2.getZ())); + return sum; + } + + public static PmPose toPmPose(PoseType p) throws PmException { + return new PmPose(pointToPmCartesian(p.getPoint()), + Posemath.toQuat(toPmRotationMatrix(p))); + } + + public static PointType multiply(final BigDecimal dist, final VectorType v) { + PointType out = new PointType(); + out.setX(v.getI().multiply(dist)); + out.setY(v.getJ().multiply(dist)); + out.setZ(v.getK().multiply(dist)); + return out; + } + + public static PointType multiply(double dist, VectorType v) { + return multiply(BigDecimal.valueOf(dist), v); + } + + public static PointType multiply(BigDecimal dist, PointType p) { + PointType out = new PointType(); + out.setX(p.getX().multiply(dist)); + out.setY(p.getY().multiply(dist)); + out.setZ(p.getZ().multiply(dist)); + return out; + } + + public static PointType multiply(double dist, PointType p) { + return multiply(BigDecimal.valueOf(dist), p); + } + + public static BigDecimal dot(VectorType v1, VectorType v2) { + return v1.getI().multiply(v2.getI()) + .add(v1.getJ().multiply(v2.getJ())) + .add(v1.getK().multiply(v2.getK())); + } + + public static BigDecimal dot(VectorType v1, PointType p2) { + return v1.getI().multiply(p2.getX()) + .add(v1.getJ().multiply(p2.getY())) + .add(v1.getK().multiply(p2.getZ())); + } + + /** + * Generate L2 norm of Vector + * WARNING: This function loses the BigDecimal precision and range in VectorType + * @param v1 vector to compute norm of + * @return norm of input vector + */ + public static double norm(VectorType v1) { + // FIXME(maybe?) It is difficult to take sqrt(BigDecimal) so + // I punted and just hope double precision is good enough. + double i = v1.getI().doubleValue(); + double j = v1.getJ().doubleValue(); + double k = v1.getK().doubleValue(); + return Math.sqrt(i*i + j*j + k*k); + } + + public static class ZeroNormException extends RuntimeException { + public ZeroNormException(String message) { + super(message); + } + } + + /** + * Normalize the vector so its L2 Norm is 1 + * WARNING: This function uses norm() + * which loses the BigDecimal precision and range in VectorType + * @param v vector to compute norm of + * @return normalized input vector + * @throws ZeroNormException if norm(v) less than Double.MIN_VALUE + */ + public static VectorType normalize(VectorType v) { + VectorType vout = new VectorType(); + double normv = norm(v); + if(normv < Double.MIN_VALUE) { + throw new ZeroNormException("Can't normalize vector with zero magnitude."); + } + BigDecimal normInv = BigDecimal.ONE.divide(BigDecimal.valueOf(norm(v))); + vout.setI(v.getI().multiply(normInv)); + vout.setJ(v.getJ().multiply(normInv)); + vout.setK(v.getK().multiply(normInv)); + return vout; + } + + /** + * Compute cross product of two Vectors + * WARNING: The output may not be normalized even if the input vectors are. + * @param v1 first vector + * @param v2 second vector + * @return cross product vector + */ + public static VectorType cross(VectorType v1, VectorType v2) { + VectorType vout = new VectorType(); +// vout.x = v1.y * v2.z - v1.z * v2.y; +// vout.y = v1.z * v2.x - v1.x * v2.z; +// vout.z = v1.x * v2.y - v1.y * v2.x; + vout.setI(v1.getJ().multiply(v2.getK()).subtract(v1.getK().multiply(v2.getJ()))); + vout.setJ(v1.getK().multiply(v2.getI()).subtract(v1.getI().multiply(v2.getK()))); + vout.setK(v1.getI().multiply(v2.getJ()).subtract(v1.getJ().multiply(v2.getI()))); + return vout; + } + + public static PoseType toPose(double mat[][]) { + if (null == mat || mat.length != 4 + || mat[0].length != 4 + || mat[1].length != 4 + || mat[2].length != 4 + || mat[3].length != 4) { + throw new IllegalArgumentException("toPose() matrix should be 4x4"); + } + PoseType newPose = new PoseType(); + PointType pt = new PointType(); + pt.setX(BigDecimal.valueOf(mat[0][3])); + pt.setY(BigDecimal.valueOf(mat[1][3])); + pt.setZ(BigDecimal.valueOf(mat[2][3])); + newPose.setPoint(pt); + VectorType xAxis = new VectorType(); + xAxis.setI(BigDecimal.valueOf(mat[0][0])); + xAxis.setJ(BigDecimal.valueOf(mat[0][1])); + xAxis.setK(BigDecimal.valueOf(mat[0][2])); + newPose.setXAxis(xAxis); + VectorType zAxis = new VectorType(); + zAxis.setI(BigDecimal.valueOf(mat[2][0])); + zAxis.setJ(BigDecimal.valueOf(mat[2][1])); + zAxis.setK(BigDecimal.valueOf(mat[2][2])); + newPose.setZAxis(zAxis); + return newPose; + } + + public static double[][] toHomMat(PoseType poseIn) { + double mat[][] = new double[][]{ + {1.0, 0.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0}, + {0.0, 0.0, 1.0, 0.0}, + {0.0, 0.0, 0.0, 1.0} + }; + PointType pt = poseIn.getPoint(); + mat[0][3] = pt.getX().doubleValue(); + mat[1][3] = pt.getY().doubleValue(); + mat[2][3] = pt.getZ().doubleValue(); + VectorType xAxis = poseIn.getXAxis(); + mat[0][0] = xAxis.getI().doubleValue(); + mat[0][1] = xAxis.getJ().doubleValue(); + mat[0][2] = xAxis.getK().doubleValue(); + VectorType yAxis = cross(poseIn.getZAxis(), poseIn.getXAxis()); + mat[1][0] = yAxis.getI().doubleValue(); + mat[1][1] = yAxis.getJ().doubleValue(); + mat[1][2] = yAxis.getK().doubleValue(); + VectorType zAxis = poseIn.getZAxis(); + mat[2][0] = zAxis.getI().doubleValue(); + mat[2][1] = zAxis.getJ().doubleValue(); + mat[2][2] = zAxis.getK().doubleValue(); + return mat; + } + + public static PoseType invert(PoseType p) { + PoseType pOut = new PoseType(); + VectorType xAxisIn = p.getXAxis(); + VectorType zAxisIn = p.getZAxis(); + VectorType yAxisIn = cross(p.getZAxis(), p.getXAxis()); + VectorType xAxisOut = new VectorType(); + xAxisOut.setI(p.getXAxis().getI()); + xAxisOut.setJ(yAxisIn.getI()); + xAxisOut.setK(p.getZAxis().getI()); + pOut.setXAxis(xAxisOut); + VectorType zAxisOut = new VectorType(); + zAxisOut.setI(p.getXAxis().getK()); + zAxisOut.setJ(yAxisIn.getK()); + zAxisOut.setK(p.getZAxis().getK()); + pOut.setZAxis(zAxisOut); +// VectorType yAxisOut = cross(zAxisOut,xAxisOut); + + PointType pt = new PointType(); + pt.setX(dot(xAxisIn, p.getPoint()).negate()); + pt.setY(dot(yAxisIn, p.getPoint()).negate()); + pt.setZ(dot(zAxisIn, p.getPoint()).negate()); + pOut.setPoint(pt); + + return pOut; + } + + public static PoseType multiply(PoseType p1, PoseType p2) { + PoseType poseOut = new PoseType(); + VectorType yAxis1 = cross(p1.getZAxis(), p1.getXAxis()); + VectorType yAxis2 = cross(p2.getZAxis(), p2.getXAxis()); + VectorType xAxisOut = new VectorType(); + VectorType zAxisOut = new VectorType(); + PointType pt2 = p2.getPoint(); + PointType pt2rot = new PointType(); + pt2rot.setX(p1.getXAxis().getI().multiply(pt2.getX()) + .add(yAxis1.getI().multiply(pt2.getY())) + .add(p1.getZAxis().getI().multiply(pt2.getZ())) + ); + pt2rot.setY(p1.getXAxis().getJ().multiply(pt2.getX()) + .add(yAxis1.getJ().multiply(pt2.getY())) + .add(p1.getZAxis().getJ().multiply(pt2.getZ())) + ); + pt2rot.setZ(p1.getXAxis().getK().multiply(pt2.getX()) + .add(yAxis1.getK().multiply(pt2.getY())) + .add(p1.getZAxis().getK().multiply(pt2.getZ())) + ); + PointType pt = add(p1.getPoint(), pt2rot); + poseOut.setPoint(pt); +// xAxisOut.setI( +// p1.getXAxis().getI().multiply(p2.getXAxis().getI()) +// .add(p1.getXAxis().getJ().multiply(yAxis2.getI())) +// .add(p1.getXAxis().getK().multiply(p2.getZAxis().getI())) +// ); +// xAxisOut.setJ( +// p1.getXAxis().getI().multiply(p2.getXAxis().getJ()) +// .add(p1.getXAxis().getJ().multiply(yAxis2.getJ())) +// .add(p1.getXAxis().getK().multiply(p2.getZAxis().getJ())) +// ); +// xAxisOut.setK( +// p1.getXAxis().getI().multiply(p2.getXAxis().getK()) +// .add(p1.getXAxis().getJ().multiply(yAxis2.getK())) +// .add(p1.getXAxis().getK().multiply(p2.getZAxis().getK())) +// ); + xAxisOut.setI( + p1.getXAxis().getI().multiply(p2.getXAxis().getI()) + .add(yAxis1.getI().multiply(p2.getXAxis().getJ())) + .add(p1.getZAxis().getI().multiply(p2.getXAxis().getK())) + ); + xAxisOut.setJ( + p1.getXAxis().getJ().multiply(p2.getXAxis().getI()) + .add(yAxis1.getJ().multiply(p2.getXAxis().getJ())) + .add(p1.getZAxis().getJ().multiply(p2.getXAxis().getK())) + ); + xAxisOut.setK( + p1.getXAxis().getK().multiply(p2.getXAxis().getI()) + .add(yAxis1.getK().multiply(p2.getXAxis().getJ())) + .add(p1.getZAxis().getK().multiply(p2.getXAxis().getK())) + ); + + poseOut.setXAxis(xAxisOut); + zAxisOut.setI( + p1.getXAxis().getI().multiply(p2.getZAxis().getI()) + .add(yAxis1.getI().multiply(p2.getZAxis().getJ())) + .add(p1.getZAxis().getI().multiply(p2.getZAxis().getK())) + ); + zAxisOut.setJ( + p1.getXAxis().getJ().multiply(p2.getZAxis().getI()) + .add(yAxis1.getJ().multiply(p2.getZAxis().getJ())) + .add(p1.getZAxis().getJ().multiply(p2.getZAxis().getK())) + ); + zAxisOut.setK( + p1.getXAxis().getK().multiply(p2.getZAxis().getI()) + .add(yAxis1.getK().multiply(p2.getZAxis().getJ())) + .add(p1.getZAxis().getK().multiply(p2.getZAxis().getK())) + ); + poseOut.setZAxis(zAxisOut); + return poseOut; + } + + public static PoseType shift(final PoseType poseIn, final PointType pt) { + PoseType poseOut = new PoseType(); + PointType sum = add(poseIn.getPoint(), pt); + poseOut.setPoint(sum); + poseOut.setXAxis(poseIn.getXAxis()); + poseOut.setZAxis(poseIn.getZAxis()); + return poseOut; + } + + public static PoseType pointXAxisZAxisToPose(PointType pt, VectorType x, VectorType z) { + PoseType pose = new PoseType(); + pose.setPoint(pt); + pose.setXAxis(x); + pose.setZAxis(z); + return pose; + } + + /** + * Compute the cartesian distance between two points. + * + * @param pt1 first Point + * @param pt2 second Point + * @return distance between pt1 and pt2 + */ + public static double diffPoints(PointType pt1, PointType pt2) { + return pointToPmCartesian(pt1).distFrom(pointToPmCartesian(pt2)); + } + + /** + * Compute the cartesian distane between the translational components of two + * poses. Rotations are ignored. + * + * @param p1 first Pose + * @param p2 second Pose + * @return distance between p1 and p2 + */ + public static double diffPosesTran(PoseType p1, PoseType p2) { + return diffPoints(p1.getPoint(), p2.getPoint()); + } + + /** + * Convert the crcl.VectorType to a PmCartesian. crcl.VectorType is + * generally used as a unit vector for rotation. + * + * @param v Vector to convert + * @return PmCartesian equivalent of v + */ + public static PmCartesian vectorToPmCartesian(VectorType v) { + return new PmCartesian(v.getI().doubleValue(), + v.getJ().doubleValue(), + v.getK().doubleValue()); + } + + /** + * Combine a translation and rotation in a PoseType + * + * @param tran translational component of pose + * @param v rotational component of pose + * @param pose_in optional pose to be set instead of creating new Pose + * @return new Pose creating from combining inputs or pose_in if not null + * @throws PmException if rotation vector can not be converted to matrix + */ + static public PoseType toPoseType(PmCartesian tran, PmRotationVector v, PoseType pose_in) throws PmException { + PoseType pose = pose_in; + if (pose == null) { + pose = new PoseType(); + } + pose.setPoint(toPointType(tran)); + PmRotationMatrix mat = Posemath.toMat(v); + VectorType xVec = new VectorType(); + xVec.setI(BigDecimal.valueOf(mat.x.x)); + xVec.setJ(BigDecimal.valueOf(mat.x.y)); + xVec.setK(BigDecimal.valueOf(mat.x.z)); + pose.setXAxis(xVec); + VectorType zVec = new VectorType(); + zVec.setI(BigDecimal.valueOf(mat.z.x)); + zVec.setJ(BigDecimal.valueOf(mat.z.y)); + zVec.setK(BigDecimal.valueOf(mat.z.z)); + pose.setZAxis(zVec); + return pose; + } + + /** + * Combine a translation and rotation in a PoseType + * + * @param tran translational component of Pose + * @param v rotational component of Pose + * @return new Pose + * @throws PmException if rotation vector can not be converted to matrix + */ + static public PoseType toPoseType(PmCartesian tran, PmRotationVector v) throws PmException { + return toPoseType(tran, v, null); + } + + /** + * Extracts only the rotation part of a PoseType and converts it to + * a PmRotationMatrix + * + * @param p Pose to be converted + * @return Rotation matrix from rotational component of pose + * @throws PmException if rotation vectors are invalid + */ + public static PmRotationMatrix toPmRotationMatrix(PoseType p) throws PmException { + PmCartesian cx = vectorToPmCartesian(p.getXAxis()); + PmCartesian cz = vectorToPmCartesian(p.getZAxis()); + //PmCartesian cy = Posemath.cross(cz, cx); + PmCartesian cy = vectorToPmCartesian(cross(p.getZAxis(), p.getXAxis())); + return new PmRotationMatrix(cx, cy, cz); + } + + /** + * Extracts only the rotation part of a PoseType and converts it to + * a PmRotationMatrix + * + * @param p Pose to convert + * @return Rotation Vector from rotational component of pose. + * @throws PmException if rotation vectors are invalid + */ + public static PmRotationVector toPmRotationVector(final PoseType p) throws PmException { + return Posemath.toRot(toPmRotationMatrix(p)); + } + + /** + * Extracts only the rotation part of a PoseType and converts it to + * a roll-pitch-yaw + * + * @param p Pose to convert + * @return Roll-pitch-yaw taken from rotational component of Pose + * @throws PmException if rotation vectors are invalid + */ + public static PmRpy toPmRpy(PoseType p) throws PmException { + return Posemath.toRpy(toPmRotationMatrix(p)); + } + + /** + * Convenience function that computes the maximum of the absolute value of + * two arrays. The two arrays must be the same length. + * + * @param da first array of doubles + * @param da2 second array of doubles + * @return maximum difference between corresponding elements of two arrays + */ + public static double maxDiffDoubleArray(double da[], double da2[]) { + if (null == da || null == da2 || da.length != da2.length) { + throw new IllegalArgumentException("maxDiffDoubleArray expencs two double arrays of same size"); + } + double diff = 0.0; + for (int i = 0; i < da.length; i++) { + diff = Math.max(diff, Math.abs(da[i] - da2[i])); + } + return diff; + } + + public static double diffPosesRot(PoseType pose1, PoseType pose2) throws PmException { + PmRotationMatrix m1 = toPmRotationMatrix(pose1); + PmRotationMatrix m2 = toPmRotationMatrix(pose2); + PmRotationVector r = Posemath.toRot(m1.multiply(m2.inv())); + return r.s; + } + + /** + * Convert a PmCartesian to a crcl.PointType + * + * @param c Cartesian point to convert + * @return Point equivalent of input cartesian + */ + public static PointType toPointType(PmCartesian c) { + PointType pt = new PointType(); + pt.setX(BigDecimal.valueOf(c.x)); + pt.setY(BigDecimal.valueOf(c.y)); + pt.setZ(BigDecimal.valueOf(c.z)); + return pt; + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java new file mode 100644 index 0000000..ba46614 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java @@ -0,0 +1,1914 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import com.siemens.ct.exi.EXIFactory; +import com.siemens.ct.exi.GrammarFactory; +import com.siemens.ct.exi.api.sax.EXIResult; +import com.siemens.ct.exi.api.sax.EXISource; +import com.siemens.ct.exi.exceptions.EXIException; +import com.siemens.ct.exi.grammars.Grammars; +import com.siemens.ct.exi.helpers.DefaultEXIFactory; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLProgramType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStatusType; +import crcl.base.GetStatusType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.ObjectFactory; +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.VectorType; +import java.awt.Component; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.function.UnaryOperator; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/** + * + * @author Will Shackleford {@literal } + */ +public class CRCLSocket implements AutoCloseable { + + CRCLSocket() { + this(null); + } + + public static final int DEFAULT_PORT = 64444; + + public boolean isConnected() { + return null != sock && sock.isConnected(); + + } + + public int available() { + try { + if (sock == null || getBufferedInputStream() == null) { + return 0; + } + if (null != bufferedInputStream) { + return bufferedInputStream.available(); + } + return getBufferedInputStream().available(); + } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); + return 0; + } + } + + private static String addCRCLToStatePriv(String in) { + return in.replaceAll("Working", "CRCL_Working") + .replaceAll("Done", "CRCL_Done") + .replaceAll("Error", "CRCL_Error") + .replaceAll("Ready", "CRCL_Ready"); + } + + static final public UnaryOperator addCRCLToState = new UnaryOperator() { + + @Override + public String apply(String t) { + return addCRCLToStatePriv(t); + } + }; + + private static String removeCRCLFromStatePriv(String in) { + return in.replaceAll("CRCL_Working", "Working") + .replaceAll("CRCL_Done", "Done") + .replaceAll("CRCL_Error", "Error") + .replaceAll("CRCL_Ready", "Ready"); + } + + static final public UnaryOperator removeCRCLFromState = new UnaryOperator() { + + @Override + public String apply(String t) { + return removeCRCLFromStatePriv(t); + } + }; + + private UnaryOperator statusStringInputFilter = null; + + public int getLocalPort() { + if (null == this.sock) { + return -1; + } + return this.sock.getLocalPort(); + } + + public int getPort() { + if (null == this.sock) { + return -1; + } + return this.sock.getPort(); + } + + public InetAddress getInetAddress() { + if (null == this.sock) { + return null; + } + return this.sock.getInetAddress(); + } + + /** + * Get the value of statusStringInputFilter + * + * @return the value of statusStringInputFilter + */ + public UnaryOperator getStatusStringInputFilter() { + return statusStringInputFilter; + } + + /** + * Set the value of statusStringInputFilter + * + * @param statusStringInputFilter new value of statusStringInputFilter + */ + public void setStatusStringInputFilter(UnaryOperator statusStringInputFilter) { + this.statusStringInputFilter = statusStringInputFilter; + } + + private UnaryOperator statusStringOutputFilter = null; + + /** + * Get the value of statusStringOutputFilter + * + * @return the value of statusStringOutputFilter + */ + public UnaryOperator getStatusStringOutputFilter() { + return statusStringOutputFilter; + } + + /** + * Set the value of statusStringOutputFilter + * + * @param statusStringOutputFilter new value of statusStringOutputFilter + */ + public void setStatusStringOutputFilter(UnaryOperator statusStringOutputFilter) { + this.statusStringOutputFilter = statusStringOutputFilter; + } + + public static String statusHeader = "\n" + + ""; + + public static String cmdHeader = "\n" + + ""; + + public static String progHeader = "\n" + + ""; + + public static boolean DEFAULT_JAXB_FRAGMENT = true; + +// public static String DEFAULT_XML_HEADER_OVERRIDE +// = ""; +// private String xmlHeader = DEFAULT_XML_HEADER_OVERRIDE; + private boolean jaxbFragment = DEFAULT_JAXB_FRAGMENT; + +// public static String DEFAULT_STATUS_NO_NAMESPACE_JAXB_SCHEMA_LOCATION = "../xmlSchemas/CRCLStatus.xsd"; +// public static String DEFAULT_COMMAND_NO_NAMESPACE_JAXB_SCHEMA_LOCATION = ".../xmlSchemas/CRCLCommandInstance.xsd"; +// public static String DEFAULT_PROGRAM_NO_NAMESPACE_JAXB_SCHEMA_LOCATION = "../xmlSchemas/CRCLProgramInstance.xsd"; +// public static String DEFAULT_JAXB_SCHEMA_LOCATION = "http://www.w3.org/2001/XMLSchema-instance"; + /** + * Get the value of jaxbFragment + * + * @return the value of jaxbFragment + */ + public boolean isJaxbFragment() { + return jaxbFragment; + } + + /** + * Set the value of jaxbFragment + * + * @param jaxbFragment new value of jaxbFragment + */ + public void setJaxbFragment(boolean jaxbFragment) { + this.jaxbFragment = jaxbFragment; + } + + private final Socket sock; + + private String lastStatusString; + + /** + * Get the value of lastStatusString + * + * @return the value of lastStatusString + */ + public String getLastStatusString() { + return lastStatusString; + } + + private String lastCommandString; + private String lastProgramString; + + /** + * Get the value of lastCommandString + * + * @return the value of lastCommandString + */ + public synchronized String getLastCommandString() { + return lastCommandString; + } + + public static Schema defaultCmdSchema = null; + public static Schema defaultProgramSchema = null; + public static Schema defaultStatSchema = null; + + public static File commandXsdFile = null; + + private Schema cmdSchema = defaultCmdSchema; + private Schema programSchema = defaultProgramSchema; + + /** + * Get the value of cmdSchema + * + * @return the value of cmdSchema + */ + public Schema getProgramSchema() { + return programSchema; + } + + /** + * Set the value of cmdSchema + * + * @param programSchema new value of cmdSchema + */ + public void setProgramSchema(Schema programSchema) { + this.programSchema = programSchema; + this.m_prog.setSchema(programSchema); + this.u_prog.setSchema(programSchema); + } + + /** + * Get the value of cmdSchema + * + * @return the value of cmdSchema + */ + public Schema getCmdSchema() { + return cmdSchema; + } + + /** + * Set the value of cmdSchema + * + * @param cmdSchema new value of cmdSchema + */ + public void setCmdSchema(Schema cmdSchema) { + this.cmdSchema = cmdSchema; + m_cmd.setSchema(cmdSchema); + u_cmd.setSchema(cmdSchema); + } + + private Schema statSchema = defaultStatSchema; + + /** + * Get the value of statSchema + * + * @return the value of statSchema + */ + public Schema getStatSchema() { + return statSchema; + } + + /** + * Set the value of statSchema + * + * @param statSchema new value of statSchema + */ + public void setStatSchema(Schema statSchema) { + this.statSchema = statSchema; + m_stat.setSchema(statSchema); + u_stat.setSchema(statSchema); + } + + public CRCLSocket(Socket sock) { + Marshaller tmp_m_cmd = null; + Unmarshaller tmp_u_cmd = null; + Marshaller tmp_m_stat = null; + Unmarshaller tmp_u_stat = null; + Marshaller tmp_m_prog = null; + Unmarshaller tmp_u_prog = null; + try { + Supplier jc = () -> { + try { + JAXBContext jc2 = JAXBContext.newInstance("crcl.base"); + return jc2; + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return null; + }; + tmp_u_cmd = jc.get().createUnmarshaller(); + tmp_m_cmd = jc.get().createMarshaller(); +// tmp_m_cmd.setProperty(Marshaller.JAXB_FRAGMENT, jaxbFragment); +// tmp_m_cmd.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, DEFAULT_COMMAND_NO_NAMESPACE_JAXB_SCHEMA_LOCATION); +// tmp_m_cmd.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, DEFAULT_JAXB_SCHEMA_LOCATION); + if (null != defaultCmdSchema) { + tmp_u_cmd.setSchema(defaultCmdSchema); + tmp_m_cmd.setSchema(defaultCmdSchema); + } + tmp_u_stat = jc.get().createUnmarshaller(); + tmp_m_stat = jc.get().createMarshaller(); +// tmp_m_stat.setProperty(Marshaller.JAXB_FRAGMENT, jaxbFragment); +// tmp_m_stat.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, DEFAULT_STATUS_NO_NAMESPACE_JAXB_SCHEMA_LOCATION); +// tmp_m_stat.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, DEFAULT_JAXB_SCHEMA_LOCATION); + if (null != defaultStatSchema) { + tmp_u_stat.setSchema(defaultStatSchema); + tmp_m_stat.setSchema(defaultStatSchema); + } + tmp_u_prog = jc.get().createUnmarshaller(); + tmp_m_prog = jc.get().createMarshaller(); +// tmp_m_prog.setProperty(Marshaller.JAXB_FRAGMENT, jaxbFragment); +// tmp_m_prog.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, DEFAULT_PROGRAM_NO_NAMESPACE_JAXB_SCHEMA_LOCATION); +// tmp_m_prog.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, DEFAULT_JAXB_SCHEMA_LOCATION); + if (null != defaultProgramSchema) { + tmp_u_prog.setSchema(defaultProgramSchema); + tmp_m_prog.setSchema(defaultProgramSchema); + } + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + m_cmd = tmp_m_cmd; + u_cmd = tmp_u_cmd; + m_stat = tmp_m_stat; + u_stat = tmp_u_stat; + m_prog = tmp_m_prog; + u_prog = tmp_u_prog; + this.sock = sock; + } + private static final Logger LOGGER = Logger.getLogger(CRCLSocket.class.getName()); + + public CRCLSocket(String hostname, int port) throws IOException { + this(new Socket(hostname, port)); + } + + @Override + public synchronized void close() throws IOException { + sock.close(); + exiCommandInSaxSource = null; + if (null != bufferedInputStream) { + try { + bufferedInputStream.close(); + } catch (Exception e) { + } + bufferedInputStream = null; + } + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + this.close(); + } + + private final Marshaller m_cmd; + private final Unmarshaller u_cmd; + + private final Marshaller m_prog; + private final Unmarshaller u_prog; + + private final Marshaller m_stat; + private final Unmarshaller u_stat; + + static JointStatusType getJointStatus(CRCLStatusType _status, int i) { + BigInteger bi = BigInteger.valueOf(i); + return getJointStatus(_status, bi); + } + + static JointStatusType getJointStatus(CRCLStatusType _status, BigInteger bi) { + if (null == _status) { + return null; + } + JointStatusesType jsst = _status.getJointStatuses(); + if (null == jsst) { + return null; + } + List jsl = jsst.getJointStatus(); + for (JointStatusType js : jsl) { + if (js.getJointNumber().equals(bi)) { + return js; + } + } + return null; + } + + private String readInProgressString = ""; + + public String getReadInProgressString() { + return this.readInProgressString; + } + + public String readUntilEndTag(final String tag, final InputStream is) throws IOException { + byte ba1[] = new byte[1]; + String rips = ""; + final String endTagStartString = "' || !endTag_started) { + int bytes_read = is.read(ba1); + if (bytes_read != 1) { + Level lvl = rips.length() > 0 ? Level.SEVERE : Level.FINE; + final int brF = bytes_read; + final String ripsF = rips; + LOGGER.log(lvl, + () -> "CRCLSocket.readUntilEndTag(" + tag + "): read returned " + brF + " before end of tag was found. str = " + ripsF); + throw new SocketException("socket closed after read returned:" + bytes_read); + } + if (ba1[0] == 0) { + continue; + } + rips += new String(ba1); + if (ba1[0] == '>' && !endTag_started && insideStartTag) { + if (rips.endsWith("/>")) { + break; + } + insideStartTag = false; + } + this.readInProgressString = rips; + if (!startTag_found) { + while (rips.length() > 0 + && !rips.startsWith(startTag.substring(0, Math.min(rips.length(), startTag.length())))) { + skipped_str += rips.substring(0, 1); + rips = rips.substring(1); + this.readInProgressString = rips; + } + if (rips.startsWith(startTag)) { + startTag_found = true; + insideStartTag = true; + } + } else if (!endTag_started) { + endTag_started = rips.endsWith(endTagStartString); + } + } + str = rips; + rips = ""; + this.readInProgressString = rips; + } + final String threadName = Thread.currentThread().getName(); + final String skipped_str_f = skipped_str; + LOGGER.log(Level.FINER, + () -> "readUntilEndTag(" + tag + ") called with skipped_str=\"" + skipped_str_f + "\" from Thread: " + threadName); + return str; + } + + public CRCLCommandInstanceType stringToCommand(String str, boolean validate) throws JAXBException { + synchronized (u_cmd) { + this.lastCommandString = str; + u_cmd.setSchema(validate ? cmdSchema : null); + JAXBElement el = (JAXBElement) u_cmd.unmarshal(new StringReader(str)); + CRCLCommandInstanceType instance + = (CRCLCommandInstanceType) el.getValue(); + return instance; + } + } + + public CRCLCommandInstanceType readCommandFromStream(final InputStream is, boolean validate) throws JAXBException { + synchronized (u_cmd) { +// this.lastCommandString = str; + u_cmd.setSchema(validate ? cmdSchema : null); + JAXBElement el = (JAXBElement) u_cmd.unmarshal(is); + CRCLCommandInstanceType instance + = (CRCLCommandInstanceType) el.getValue(); + return instance; + } + } + + public CRCLProgramType stringToProgram(String str, boolean validate) throws JAXBException { + synchronized (u_prog) { + this.lastProgramString = str; + u_prog.setSchema(validate ? programSchema : null); + JAXBElement el = (JAXBElement) u_prog.unmarshal(new StringReader(str)); + CRCLProgramType prog + = (CRCLProgramType) el.getValue(); + return prog; + } + } + + public synchronized CRCLCommandInstanceType readCommand(boolean validate) throws JAXBException, IOException, EXIException { + final String threadName = Thread.currentThread().getName(); + final boolean EXI = this.isEXIEnabled(); +// LOGGER.log(Level.FINE, +// ()-> "readCommand() called with EXI = " + EXI+ " from Thread: "+ threadName); + if (this.isEXIEnabled()) { + if (!this.isPrefixEXISizeEnabled()) { + final CRCLCommandInstanceType c = this.readCommandFromEXIStream(getBufferedInputStream()); + final CRCLCommandType cc = c.getCRCLCommand(); + final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; + LOGGER.log(loglevel, + () -> "readCommand() returning " + cc + " ID=" + cc.getCommandID() + " called from Thread: " + threadName); + return c; + } else { + byte sizeba[] = new byte[4]; + int r1 = getBufferedInputStream().read(sizeba); +// LOGGER.log(Level.FINEST,() ->"readCommand: r1 = " + r1); +// LOGGER.log(Level.FINEST,() ->"readCommand: sizeba = " + Arrays.toString(sizeba)); + ByteBuffer bb = ByteBuffer.wrap(sizeba); + int size = bb.getInt(); +// LOGGER.log(Level.FINEST,() ->"readCommand: size = " + size); + byte ba[] = new byte[size]; + int r2 = getBufferedInputStream().read(ba); +// LOGGER.log(Level.FINEST,() ->"readCommand: r2 = " + r2); +// LOGGER.log(Level.FINEST,() ->"readCommand: ba.length = " + ba.length); +// LOGGER.log(Level.FINEST,() ->"readCommand: ba = " + Arrays.toString(ba)); + final CRCLCommandInstanceType c = exiToCommand(ba); + final CRCLCommandType cc = c.getCRCLCommand(); + final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; + LOGGER.log(loglevel, + () -> "readCommand() returning " + cc + + " ID=" + cc.getCommandID() + + " called from Thread: " + threadName); + return c; + } + } +// return readCommandFromStream(getBufferedInputStream(), validate); + final String str = this.readUntilEndTag("CRCLCommandInstance", getBufferedInputStream()); + if (null == str) { + return null; + } + CRCLCommandInstanceType cmd = stringToCommand(str, validate); + final CRCLCommandType cc = cmd.getCRCLCommand(); + final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; + LOGGER.log(loglevel, + () -> "readCommand() returning " + cc + " ID=" + cc.getCommandID() + "str=" + str + " called from Thread: " + threadName); + this.lastCommandString = str; + return cmd; + } + + public CRCLStatusType stringToStatus(String str, boolean validate) throws JAXBException { + synchronized (u_stat) { + if (this.statusStringInputFilter != null) { + str = this.statusStringInputFilter.apply(str); + } + lastStatusString = str; + u_stat.setSchema(validate ? statSchema : null); + JAXBElement el = (JAXBElement) u_stat.unmarshal(new StringReader(str)); + CRCLStatusType instance + = (CRCLStatusType) el.getValue(); + return instance; + } + } + + public CRCLStatusType readStatusFromStream(final InputStream is, boolean validate) throws JAXBException { + synchronized (u_stat) { +// if (this.statusStringInputFilter != null) { +// str = this.statusStringInputFilter.apply(str); +// } +// lastStatusString = str; + u_stat.setSchema(validate ? statSchema : null); + JAXBElement el = (JAXBElement) u_stat.unmarshal(is); + CRCLStatusType instance + = (CRCLStatusType) el.getValue(); + return instance; + } + } + + private boolean EXIEnabled = Boolean.valueOf(System.getProperty("crcl.EXIEnabled", "false")); + + /** + * Get the value of EXIEnabled + * + * @return the value of EXIEnabled + */ + public boolean isEXIEnabled() { + return EXIEnabled; + } + + private boolean prefixEXISizeEnabled = Boolean.valueOf(System.getProperty("crcl.prefixEXISizeEnabled", "false")); + + /** + * Get the value of prefixEXISizeEnabled + * + * @return the value of prefixEXISizeEnabled + */ + public boolean isPrefixEXISizeEnabled() { + return prefixEXISizeEnabled; + } + + /** + * Set the value of prefixEXISizeEnabled + * + * @param prefixEXISizeEnabled new value of prefixEXISizeEnabled + */ + public void setPrefixEXISizeEnabled(boolean prefixEXISizeEnabled) { + this.prefixEXISizeEnabled = prefixEXISizeEnabled; + } + + private EXIFactory exiStatusFactory = null; + + private EXIFactory getExiStatusFactory() throws EXIException, IOException { + if (null != exiStatusFactory) { + return exiStatusFactory; + } + copySchemaResources(); + exiStatusFactory = DefaultEXIFactory.newInstance(); + GrammarFactory grammarFactory = GrammarFactory.newInstance(); + Grammars g = grammarFactory.createGrammars(crclSchemaDirFile.getCanonicalPath() + File.separator + "CRCLStatus.xsd"); + exiStatusFactory.setGrammars(g); + return exiStatusFactory; + } + + private EXIFactory exiCommandFactory = null; + + private EXIFactory getExiCommandFactory() throws EXIException, IOException { + if (null != exiCommandFactory) { + return exiCommandFactory; + } + copySchemaResources(); + exiCommandFactory = DefaultEXIFactory.newInstance(); + GrammarFactory grammarFactory = GrammarFactory.newInstance(); + Grammars g = grammarFactory.createGrammars(crclSchemaDirFile.getCanonicalPath() + File.separator + "CRCLCommandInstance.xsd"); + exiCommandFactory.setGrammars(g); + return exiCommandFactory; + } + + /** + * Set the value of EXIEnabled + * + * @param EXIEnabled new value of EXIEnabled + * @throws com.siemens.ct.exi.exceptions.EXIException internal EXI lib fault + */ + public void setEXIEnabled(boolean EXIEnabled) throws EXIException { + this.EXIEnabled = EXIEnabled; + if (!EXIEnabled) { + exiStatusFactory = null; + exiCommandFactory = null; + } + } + +// protected void encode(ContentHandler ch) throws SAXException, IOException { +// XMLReader xmlReader = XMLReaderFactory.createXMLReader(); +// xmlReader.setContentHandler(ch); +// +// // parse xml file +// xmlReader.parse(new InputSource(xmlLocation)); +// } +// +// protected void decode(XMLReader exiReader, String exiLocation) +// throws SAXException, IOException, TransformerException { +// +// TransformerFactory tf = TransformerFactory.newInstance(); +// Transformer transformer = tf.newTransformer(); +// +// InputStream exiIS = new FileInputStream(exiLocation); +// SAXSource exiSource = new SAXSource(new InputSource(exiIS)); +// exiSource.setXMLReader(exiReader); +// +// OutputStream os = new FileOutputStream(exiLocation + XML_EXTENSION); +// transformer.transform(exiSource, new StreamResult(os)); +// os.close(); +// } + public byte[] statusToEXI(CRCLStatusType status) throws JAXBException, IOException, EXIException { + final String threadName = Thread.currentThread().getName(); + try (ByteArrayOutputStream exiOS = new ByteArrayOutputStream()) { + writeEXIStatusToStream(exiOS, status); + return exiOS.toByteArray(); + } catch (Exception ex) { + final String xmlS = this.statusToString(status, true); + LOGGER.log(Level.SEVERE, + "CRCLStatus.statusToEXIFirst() Exception Thread=" + threadName + ", status=" + statToDebugString(status) + ",xmlS=" + xmlS, + ex); + final Level origLevel = LOGGER.getLevel(); + final Logger xmlInternalLogger = Logger.getLogger("com.sun.xml.internal.bind"); + final Level origXmlInternalLogLevel = xmlInternalLogger.getLevel(); + try (ByteArrayOutputStream exiOS = new ByteArrayOutputStream()) { + writeEXIStatusToStream(exiOS, status); + final byte ba[] = exiOS.toByteArray(); + LOGGER.log(Level.SEVERE, + "writeEXIStatusTOStream succeeded on second try. ba=" + ba); + return ba; + } finally { + xmlInternalLogger.setLevel(origXmlInternalLogLevel); + LOGGER.setLevel(origLevel); + } + } + } + + public byte[] commandToEXI(CRCLCommandInstanceType cmd) throws JAXBException, IOException, EXIException { + try (ByteArrayOutputStream exiOS = new ByteArrayOutputStream()) { + writeEXICommandToStream(exiOS, cmd); + return exiOS.toByteArray(); + } + } + + private static String vectorToDebugString(final VectorType v) { + return v == null ? "null" : v.toString() + " { " + + "I=" + v.getI() + "," + + "J=" + v.getJ() + "," + + "K=" + v.getK() + " } "; + } + + private static String pointToDebugString(final PointType p) { + return p == null ? "null" : p.toString() + " { " + + "X=" + p.getX() + "," + + "Y=" + p.getY() + "," + + "Z=" + p.getZ() + " } "; + } + + private static String poseToDebugString(final PoseType p) { + return p == null ? "null" : p.toString() + " { " + + "Point=" + pointToDebugString(p.getPoint()) + "," + + "XAxis=" + vectorToDebugString(p.getXAxis()) + "," + + "ZAxis=" + vectorToDebugString(p.getZAxis()) + " } "; + } + + private static String commandStatToDebugString(final CommandStatusType c) { + return c == null ? "null" : c.toString() + " { " + + "CommandId=" + c.getCommandID() + "," + + "CommandState=" + c.getCommandState() + "," + + "StatusId=" + c.getStatusID() + " } "; + } + + private static String jointStatusToDebugString(final JointStatusType j) { + return j == null ? "null" : j.toString() + " { " + + "JointNumber=" + j.getJointNumber() + "," + + "Position=" + j.getJointPosition() + "," + + "Velocity=" + j.getJointVelocity() + "," + + "TorqueOrForce=" + j.getJointTorqueOrForce() + + " } "; + } + + private static String jointStatusListToDebugString(final List l) { + return l == null ? "null" : l.toString() + " { " + + l.stream() + .map(CRCLSocket::jointStatusToDebugString) + .collect(Collectors.joining(",")) + " } "; + } + + private static String jointStatusesToDebugString(final JointStatusesType j) { + return j == null ? "null" : j.toString() + " { " + + "JointStatus=" + jointStatusListToDebugString(j.getJointStatus()) + " } "; + } + + public static String statToDebugString(final CRCLStatusType stat) { + return stat == null ? "null" : stat.toString() + " { " + + "CommandStatus=" + commandStatToDebugString(stat.getCommandStatus()) + "," + + "Pose=" + poseToDebugString(stat.getPose()) + "," + + "JointStatuses=" + jointStatusesToDebugString(stat.getJointStatuses()) + " } "; + } + + /** + * + * @param outStream the value of outStream + * @param status status to write + * @throws IOException network failure + * @throws JAXBException JAXB failure + * @throws EXIException EXI lib failure + */ + public void writeEXIStatusToStream( + final java.io.OutputStream outStream, + CRCLStatusType status) + throws IOException, JAXBException, EXIException { + final EXIResult exiResult = new EXIResult(getExiStatusFactory()); + exiResult.setOutputStream(outStream); + final ContentHandler handler = exiResult.getHandler(); + JAXBElement jaxb_status + = objectFactory.createCRCLStatus(status); + final String threadName = Thread.currentThread().getName(); + synchronized (m_stat) { +// try { + m_stat.marshal(jaxb_status, handler); +// } catch (Throwable t) { +// LOGGER.log(Level.SEVERE, +// "First Exception Thread=" + threadName + ", jaxb_status=" + jaxb_status + ", status=" + statToDebugString(status), +// t); +// final Level origLevel = LOGGER.getLevel(); +// final Logger xmlInternalLogger = Logger.getLogger("com.sun.xml.internal.bind"); +// final Level origXmlInternalLogLevel = xmlInternalLogger.getLevel(); +// try { +// final EXIResult exiResultNew = new EXIResult(getExiStatusFactory()); +// exiResultNew.setOutputStream(outStream); +// final ContentHandler handlerNew = exiResultNew.getHandler(); +// JAXBElement jaxb_statusNew +// = objectFactory.createCRCLStatus(status); +// xmlInternalLogger.setLevel(Level.ALL); +// LOGGER.setLevel(Level.ALL); +// m_stat.marshal(jaxb_statusNew, handlerNew); +// LOGGER.log(Level.SEVERE, "Data marshalled on second attempt."); +// } catch (Exception ex2) { +// LOGGER.log(Level.SEVERE, +// "Second Exception Thread=" + threadName, +// ex2); +// } finally { +// LOGGER.setLevel(origLevel); +// xmlInternalLogger.setLevel(origXmlInternalLogLevel); +// } +// } + } + } + + /** + * Write an EXI Command to a stream + * + * @param outStream the value of outStream + * @param cmdInstance command to send + * @throws IOException network failure + * @throws JAXBException JAXB failure + * @throws EXIException EXI lib failure + */ + public void writeEXICommandToStream( + final java.io.OutputStream outStream, + CRCLCommandInstanceType cmdInstance) + throws IOException, JAXBException, EXIException { + final EXIResult exiResult = new EXIResult(getExiCommandFactory()); + outStream.flush(); + exiResult.setOutputStream(outStream); + final ContentHandler handler = exiResult.getHandler(); + JAXBElement jaxb_cmd_instance + = objectFactory.createCRCLCommandInstance(cmdInstance); + final String threadName = Thread.currentThread().getName(); + synchronized (m_cmd) { + try { + m_cmd.marshal(jaxb_cmd_instance, handler); + outStream.flush(); + } catch (NullPointerException nullPointerException) { + LOGGER.log(Level.SEVERE, + "First NPE Thread=" + threadName, nullPointerException); + try { + m_cmd.marshal(jaxb_cmd_instance, handler); + } catch (NullPointerException nullPointerException2) { + LOGGER.log(Level.SEVERE, + "Second NPE Thread=" + threadName, + nullPointerException); + } + } + } + } + + public CRCLStatusType exiToStatus(byte exi[]) throws EXIException, JAXBException, IOException { + try (final InputStream inputStream = new ByteArrayInputStream(exi)) { + return readStatusFromEXIStream(inputStream); + } + } + + public CRCLCommandInstanceType exiToCommand(byte exi[]) + throws EXIException, JAXBException, IOException { + try (final InputStream inputStream = new ByteArrayInputStream(exi)) { + return readCommandFromEXIStream(inputStream); + } + } + +// private SAXSource getStatusSAXSource() throws IOException, EXIException { +// if(null != statusSAXSource) { +// return statusSAXSource; +// } +// EXISource exiSource = new EXISource(getExiStatusFactory()); +// XMLReader xmlReader = exiSource.getXMLReader(); +// InputSource inputSource = new InputSource(getBufferedInputStream()); +// statusSAXSource = new SAXSource(xmlReader, new InputSource(getBufferedInputStream())); +// return statusSAXSource; +// } + public CRCLStatusType readStatusFromEXIStream(final InputStream inputStream) + throws EXIException, JAXBException, IOException { +// EXISource exiSource = new EXISource(getExiStatusFactory()); +// XMLReader xmlReader = exiSource.getXMLReader(); + synchronized (inputStream) { + return readStatusFromSaxSource(getExiStatusInSaxSource(inputStream)); + } + } + + public CRCLStatusType readStatusFromSaxSource(SAXSource saxSource) throws JAXBException { + synchronized (u_stat) { + JAXBElement el + = u_stat.unmarshal(saxSource, CRCLStatusType.class); + return el.getValue(); + } + } + + private BufferedInputStream bufferedInputStream; + + private BufferedInputStream getBufferedInputStream() { + if (null != bufferedInputStream) { + return bufferedInputStream; + } + if (null != sock) { + try { + bufferedInputStream = new BufferedInputStream(sock.getInputStream()); + } catch (IOException ex) { + Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); + } + } + return bufferedInputStream; + } + + private SAXSource exiCommandInSaxSource = null; + + private SAXSource getExiCommandInSaxSource(final InputStream is) throws EXIException, IOException { + + if (null != exiCommandInSaxSource && exiCommandInSaxSource.getInputSource().getByteStream() == is) { + return exiCommandInSaxSource; + } + EXISource exiSource = new EXISource(getExiCommandFactory()); + XMLReader xmlReader = exiSource.getXMLReader(); +// byte notused_ba[] = new byte[1]; +// InputStream proxyInputStream = new ByteArrayInputStream(notused_ba) { +// +// int count = 0; +// +// @Override +// public int read() { +// int ret = -1; +// try { +// ret = inputStream.read(); +// count++; +// byte b = (byte) ret; +// if (b > 127) { +// b -= 256; +// } +// final int retf = ret; +// final byte bf = b; +// LOGGER.log(Level.FINEST, () -> "read() returning : " + retf + ", count =" + count + ", b = " + bf); +// return ret; +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// return ret; +// } +// +// @Override +// public boolean markSupported() { +// boolean ret = inputStream.markSupported(); +// LOGGER.log(Level.FINEST, () -> "markSupported() returning " + ret); +// return ret; +// } +// +// @Override +// public synchronized void reset() { +// try { +// LOGGER.log(Level.FINEST, () -> "reset() called."); +// inputStream.reset(); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// } +// +// @Override +// public synchronized void mark(int readlimit) { +// LOGGER.log(Level.FINEST, () -> "mart(" + readlimit + ") called"); +// inputStream.mark(readlimit); +// } +// +// @Override +// public void close() throws IOException { +// LOGGER.log(Level.FINEST, () -> "close() called"); +// inputStream.close(); +// } +// +// @Override +// public int available() { +// int ret = -1; +// try { +// ret = inputStream.available(); +// final int retf = ret; +// LOGGER.log(Level.FINEST, () -> "available() returning " + retf); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// return ret; +// } +// +// @Override +// public long skip(long n) { +// long ret = -1; +// try { +// ret = inputStream.skip(n); +// final long retf =ret; +// LOGGER.log(Level.FINEST, () -> "skip(" + n + ") returning " + retf); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// return ret; +// } +// +// @Override +// public int read(byte[] b, int off, int len) { +// LOGGER.log(Level.FINEST, () -> "read(...," + off + "," + len + ") called."); +// int ret = -1; +// try { +// ret = inputStream.read(b, off, len); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// final int retf = ret; +// if (ret > 0) { +// final byte bf[] = b; +// LOGGER.log(Level.FINEST, () -> "b = " + Arrays.toString(Arrays.copyOf(bf, retf))); +// } +// LOGGER.log(Level.FINEST, () -> "read(...," + off + "," + len + ") returning " + retf); +// return ret; +// } +// +// @Override +// public int read(byte[] b) throws IOException { +// LOGGER.log(Level.FINEST, () -> "read(...,) called."); +// int ret = inputStream.read(b); +// final int retf = ret; +// if (ret > 0) { +// final byte bf[] = b; +// LOGGER.log(Level.FINEST, () -> "b = " + Arrays.toString(Arrays.copyOf(bf, retf))); +// } +// +// LOGGER.log(Level.FINEST, () -> "read(...) returning " + retf); +// return ret; +// } +// }; + exiCommandInSaxSource = new SAXSource(xmlReader, new InputSource(is)); + return exiCommandInSaxSource; + } + + private SAXSource exiStatusInSaxSource = null; + + private SAXSource getExiStatusInSaxSource(final InputStream is) throws EXIException, IOException { + + if (null != exiStatusInSaxSource && exiStatusInSaxSource.getInputSource().getByteStream() == is) { + return exiStatusInSaxSource; + } + EXISource exiSource = new EXISource(getExiStatusFactory()); + XMLReader xmlReader = exiSource.getXMLReader(); +// byte notused_ba[] = new byte[1]; +// InputStream proxyInputStream = new ByteArrayInputStream(notused_ba) { +// +// int count = 0; +// +// @Override +// public int read() { +// int ret = -1; +// try { +// ret = inputStream.read(); +// count++; +// byte b = (byte) ret; +// if (b > 127) { +// b -= 256; +// } +// final int retf = ret; +// final byte bf = b; +// LOGGER.log(Level.FINEST, () -> "read() returning : " + retf + ", count =" + count + ", b = " + bf); +// return ret; +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// return ret; +// } +// +// @Override +// public boolean markSupported() { +// boolean ret = inputStream.markSupported(); +// LOGGER.log(Level.FINEST, () -> "markSupported() returning " + ret); +// return ret; +// } +// +// @Override +// public synchronized void reset() { +// try { +// LOGGER.log(Level.FINEST, () -> "reset() called."); +// inputStream.reset(); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// } +// +// @Override +// public synchronized void mark(int readlimit) { +// LOGGER.log(Level.FINEST, () -> "mart(" + readlimit + ") called"); +// inputStream.mark(readlimit); +// } +// +// @Override +// public void close() throws IOException { +// LOGGER.log(Level.FINEST, () -> "close() called"); +// inputStream.close(); +// } +// +// @Override +// public int available() { +// int ret = -1; +// try { +// ret = inputStream.available(); +// final int retf = ret; +// LOGGER.log(Level.FINEST, () -> "available() returning " + retf); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// return ret; +// } +// +// @Override +// public long skip(long n) { +// long ret = -1; +// try { +// ret = inputStream.skip(n); +// final long retf =ret; +// LOGGER.log(Level.FINEST, () -> "skip(" + n + ") returning " + retf); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// return ret; +// } +// +// @Override +// public int read(byte[] b, int off, int len) { +// LOGGER.log(Level.FINEST, () -> "read(...," + off + "," + len + ") called."); +// int ret = -1; +// try { +// ret = inputStream.read(b, off, len); +// } catch (IOException ex) { +// Logger.getLogger(CRCLSocket.class.getName()).log(Level.SEVERE, null, ex); +// } +// final int retf = ret; +// if (ret > 0) { +// final byte bf[] = b; +// LOGGER.log(Level.FINEST, () -> "b = " + Arrays.toString(Arrays.copyOf(bf, retf))); +// } +// LOGGER.log(Level.FINEST, () -> "read(...," + off + "," + len + ") returning " + retf); +// return ret; +// } +// +// @Override +// public int read(byte[] b) throws IOException { +// LOGGER.log(Level.FINEST, () -> "read(...,) called."); +// int ret = inputStream.read(b); +// final int retf = ret; +// if (ret > 0) { +// final byte bf[] = b; +// LOGGER.log(Level.FINEST, () -> "b = " + Arrays.toString(Arrays.copyOf(bf, retf))); +// } +// +// LOGGER.log(Level.FINEST, () -> "read(...) returning " + retf); +// return ret; +// } +// }; + exiStatusInSaxSource = new SAXSource(xmlReader, new InputSource(is)); + return exiStatusInSaxSource; + } + + public CRCLCommandInstanceType readCommandFromEXIStream(final InputStream inputStream) + throws EXIException, JAXBException, IOException { + + synchronized (u_cmd) { + JAXBElement el + = u_cmd.unmarshal(getExiCommandInSaxSource(inputStream), CRCLCommandInstanceType.class); + return el.getValue(); + } + } + + public CRCLStatusType readStatus(boolean validate) + throws JAXBException, IOException, EXIException { + if (this.isEXIEnabled()) { + if (this.isPrefixEXISizeEnabled()) { + int size = 0; +// String str = ""; + byte sizeba[] = new byte[4]; +// LOGGER.log(Level.FINEST,() ->"readStatus: sizeba = " + Arrays.toString(sizeba)); + int r1 = getBufferedInputStream().read(sizeba); +// LOGGER.log(Level.FINEST,() ->"readStatus: r1 = " + r1); +// LOGGER.log(Level.FINEST,() ->"readStatus: sizeba = " + Arrays.toString(sizeba)); +// str += new String(sizeba); +// LOGGER.log(Level.FINEST,() ->"str = " + str); +// LOGGER.log(Level.FINEST,() ->"readStatus: sizeba as String = " + new String(sizeba)); + ByteBuffer bb = ByteBuffer.wrap(sizeba); + size = bb.getInt(); +// LOGGER.log(Level.FINEST,() ->"readStatus: size = " + size); + byte ba[] = new byte[size]; + int r2 = getBufferedInputStream().read(ba); +// LOGGER.log(Level.FINEST,() ->"r2 = " + r2); +// LOGGER.log(Level.FINEST,() ->"readStatus: ba.length = " + ba.length); +// LOGGER.log(Level.FINEST,() ->"readStatus: ba = " + Arrays.toString(ba)); + return exiToStatus(ba); + } else { + return this.readStatusFromEXIStream(getBufferedInputStream()); + } + } +// return readStatusFromStream(getBufferedInputStream(), validate); + this.lastStatusString = this.readUntilEndTag("CRCLStatus", getBufferedInputStream()); + if (null == this.lastStatusString) { + return null; + } + return stringToStatus(this.lastStatusString, validate); + } + + private final ObjectFactory objectFactory + = new ObjectFactory(); + + public String commandToString(CRCLCommandType cmd, boolean validate) { + try { + CRCLCommandInstanceType instance = new CRCLCommandInstanceType(); + instance.setCRCLCommand(cmd); + String str = removeHeader(this.commandToString(instance, validate)); + if (str.endsWith("")) { + str = str.substring(0, str.length() - "".length()); + } + return str; + } catch (Exception ex) { + } + return ""; + } + + public String commandToString(CRCLCommandInstanceType cmd, boolean validate) throws JAXBException { + JAXBElement jaxb_cmd + = objectFactory.createCRCLCommandInstance(cmd); + StringWriter sw = new StringWriter(); + String ret = null; + synchronized (m_cmd) { + m_cmd.setSchema(validate ? cmdSchema : null); + m_cmd.marshal(jaxb_cmd, sw); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + ret = cmdHeader + str; + } else { + ret = str; + } + } + this.lastCommandString = ret; + return ret; + } + + public String programToString(CRCLProgramType prog, boolean validate) throws JAXBException { + JAXBElement jaxb_prog + = objectFactory.createCRCLProgram(prog); + StringWriter sw = new StringWriter(); + synchronized (m_prog) { + m_prog.setSchema(validate ? programSchema : null); + m_prog.marshal(jaxb_prog, sw); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + this.lastProgramString = progHeader + str; + } else { + this.lastProgramString = str; + } + } + return this.lastProgramString; + } + + public String commandToPrettyString(CRCLCommandInstanceType cmd, boolean validate) throws JAXBException { + JAXBElement jaxb_cmd + = objectFactory.createCRCLCommandInstance(cmd); + StringWriter sw = new StringWriter(); + String ret = null; + synchronized (m_cmd) { + m_cmd.setSchema(validate ? cmdSchema : null); + m_cmd.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + m_cmd.marshal(jaxb_cmd, sw); + m_cmd.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + ret = cmdHeader + str; + } else { + ret = str; + } + } + this.lastCommandString = ret; + return ret; + } + + public String commandToPrettyDocString(CRCLCommandInstanceType cmd, boolean validate) throws JAXBException { + JAXBElement jaxb_cmd + = objectFactory.createCRCLCommandInstance(cmd); + StringWriter sw = new StringWriter(); + String ret = null; + synchronized (m_cmd) { + m_cmd.setSchema(validate ? cmdSchema : null); + m_cmd.setProperty(Marshaller.JAXB_FRAGMENT, false); + m_cmd.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + m_cmd.marshal(jaxb_cmd, sw); + m_cmd.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); + m_cmd.setProperty(Marshaller.JAXB_FRAGMENT, jaxbFragment); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + ret = cmdHeader + str; + } else { + ret = str; + } + } + this.lastCommandString = ret; + return ret; + } + + public String programToPrettyString(CRCLProgramType prog, boolean validate) throws JAXBException { + JAXBElement jaxb_prog + = objectFactory.createCRCLProgram(prog); + StringWriter sw = new StringWriter(); + synchronized (m_prog) { + m_prog.setSchema(validate ? programSchema : null); + m_prog.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + m_prog.marshal(jaxb_prog, sw); + m_prog.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + this.lastProgramString = progHeader + str; + } else { + this.lastProgramString = str; + } + } + return this.lastProgramString; + } + + public String programToPrettyDocString(CRCLProgramType prog, boolean validate) throws JAXBException { + JAXBElement jaxb_proj + = objectFactory.createCRCLProgram(prog); + StringWriter sw = new StringWriter(); + synchronized (m_prog) { + m_prog.setSchema(validate ? programSchema : null); + m_prog.setProperty(Marshaller.JAXB_FRAGMENT, false); + m_prog.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + m_prog.marshal(jaxb_proj, sw); + m_prog.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); + m_prog.setProperty(Marshaller.JAXB_FRAGMENT, jaxbFragment); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + this.lastProgramString = progHeader + str; + } else { + this.lastProgramString = str; + } + } + return this.lastProgramString; + } + + public synchronized void writeCommand(CRCLCommandInstanceType cmd, boolean validate) throws JAXBException, IOException, InterruptedException, EXIException { + final CRCLCommandType cc = cmd.getCRCLCommand(); + final boolean EXI = this.isEXIEnabled(); + final String threadName = Thread.currentThread().getName(); + final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; + LOGGER.log(loglevel, + () -> "writeCommand(" + cc + " ID=" + cc.getCommandID() + ") with EXI = " + EXI + " called from Thread: " + threadName); + if (this.isEXIEnabled()) { + if (!this.isPrefixEXISizeEnabled()) { + this.writeEXICommandToStream(sock.getOutputStream(), cmd); + } else { + final byte ba[] = this.commandToEXI(cmd); + LOGGER.log(loglevel, () -> "writeCommand() : ba = " + Arrays.toString(ba)); + ByteBuffer bb = ByteBuffer.allocate(ba.length + 4); + bb.putInt(ba.length); +// LOGGER.log(Level.FINEST,() ->"writeCommand: ba.length = " + ba.length); + bb.put(ba); + byte ba2[] = bb.array(); +// LOGGER.log(Level.FINEST,() ->"writeCommand: ba2.length = " + ba2.length); +// LOGGER.log(Level.FINEST,() ->"writeCommand: ba2 = " + Arrays.toString(ba2)); + this.sock.getOutputStream().write(ba2); + this.sock.getOutputStream().flush(); + } + return; + + } + final String str = commandToString(cmd, validate); + LOGGER.log(loglevel, + () -> "writeCommand(" + cc + " ID=" + cc.getCommandID() + ") with str = " + str + " called from Thread: " + threadName); + writeWithFill(str); + this.lastCommandString = str; + } + + static public boolean DEFAULT_APPEND_TRAILING_ZERO = false; + public boolean appendTrailingZero = DEFAULT_APPEND_TRAILING_ZERO; + + static public boolean DEFAULT_RANDOM_PACKETING = false; + public boolean randomPacketing = DEFAULT_RANDOM_PACKETING; + private Random random = null; + public int rand_seed = 12345; + + private void writePackets(OutputStream os, byte ba[]) throws IOException, InterruptedException { + if (!this.randomPacketing) { + os.write(ba); + } else { + if (null == random) { + random = new Random(rand_seed); + } + int bytes_written = 0; + while (bytes_written < ba.length) { + int bytes_to_write = random.nextInt(ba.length); + if (bytes_to_write >= ba.length - bytes_written) { + bytes_to_write = ba.length - bytes_written; + } + os.write(ba, bytes_written, bytes_to_write); + bytes_written += bytes_to_write; + if (bytes_written < ba.length) { + os.flush(); + Thread.sleep(random.nextInt(150)); + } + } + } + } +// static final byte fill[] = new byte[2000]; +// static final private byte zeroba[] = new byte[1]; + + public void writeWithFill(String str) throws IOException, InterruptedException { + OutputStream os = sock.getOutputStream(); +// String strout = "\n"+str; + synchronized (os) { + if (!appendTrailingZero) { + this.writePackets(os, str.getBytes()); + } else { + int len = str.length(); + byte bytesPlusOne[] = new byte[len + 1]; + System.arraycopy(str.getBytes(), 0, bytesPlusOne, 0, len); + this.writePackets(os, bytesPlusOne); + } +// os.write(zeroba); +// os.write(fill,len,fill.length -len-1); + os.flush(); + } + } + + public void writeProgram(CRCLProgramType prog, boolean validate) throws JAXBException, IOException, InterruptedException { + this.lastProgramString = programToString(prog, validate); + this.writeWithFill(this.lastProgramString); + } + + private String last_xml_version_header = null; + private String last_orig_first_tag = null; + + private boolean replaceHeader; + + /** + * Get the value of replaceHeader + * + * @return the value of replaceHeader + */ + public boolean isReplaceHeader() { + return replaceHeader; + } + + /** + * Set the value of replaceHeader + * + * @param replaceHeader new value of replaceHeader + */ + public void setReplaceHeader(boolean replaceHeader) { + this.replaceHeader = replaceHeader; + } + + public String statusToString(CRCLStatusType status, boolean validate) throws JAXBException { + JAXBElement jaxb_status + = objectFactory.createCRCLStatus(status); + StringWriter sw = new StringWriter(); + synchronized (m_stat) { + m_stat.setSchema(validate ? statSchema : null); + try { + m_stat.marshal(jaxb_status, sw); + } catch (Exception ex1) { + LOGGER.log(Level.SEVERE, + "First Exception validate=" + validate + " sw.toString() = " + sw.toString() + ",status=" + statToDebugString(status), + ex1); + sw = new StringWriter(); + try { + m_stat.setSchema(null); + m_stat.marshal(jaxb_status, sw); + } catch (Exception ex2) { + LOGGER.log(Level.SEVERE, "Second Exception", ex2); + return this.lastStatusString; + } + } + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + this.lastStatusString = statusHeader + str; + } else { + this.lastStatusString = str; + } + if (null != this.statusStringOutputFilter) { + this.lastStatusString = this.statusStringOutputFilter.apply(this.lastStatusString); + } + return this.lastStatusString; + } + } + + private String removeHeader(String str) { + int qgtindex = str.indexOf("?>"); + if (qgtindex > 0) { + last_xml_version_header = str.substring(0, qgtindex + 2); + str = str.substring(qgtindex + 2); + } + int gtindex = str.indexOf('>'); + if (gtindex > 0) { + last_orig_first_tag = str.substring(0, gtindex + 1); + str = str.substring(gtindex + 1); + } + return str; + } + + public String statusToPrettyString(CRCLStatusType status, boolean validate) throws JAXBException { + JAXBElement jaxb_status + = objectFactory.createCRCLStatus(status); + StringWriter sw = new StringWriter(); + synchronized (m_stat) { + m_stat.setSchema(validate ? statSchema : null); + m_stat.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + m_stat.marshal(jaxb_status, sw); + m_stat.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); + String str = sw.toString(); + if (replaceHeader) { + str = removeHeader(str); + this.lastStatusString = statusHeader + str; + } else { + this.lastStatusString = str; + } + if (null != this.statusStringOutputFilter) { + this.lastStatusString = this.statusStringOutputFilter.apply(this.lastStatusString); + } + return this.lastStatusString; + } + } + + private static final File crclSchemaDirFile; + + static { + File startFile = new File(System.getProperty("user.home")); + crclSchemaDirFile = new File(startFile, String.join(File.separator, "crclXmlSchemas")); + } + + public static File[] findSchemaFiles() { + copySchemaResources(); + if (crclSchemaDirFile.exists()) { + return crclSchemaDirFile.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) { + return pathname.getName().endsWith(".xsd"); + } + }); + } + return null; + } + + private static boolean resourcesCopied = false; + + private static void copySchemaResources() { + if (resourcesCopied) { + return; + } + crclSchemaDirFile.mkdirs(); + copyResourcesToFiles(crclSchemaDirFile, + "CRCLCommandInstance.xsd", + "CRCLCommands.xsd", + "CRCLProgramInstance.xsd", + "DataPrimitives.xsd", + "CRCLStatus.xsd"); + resourcesCopied = true; + } + + /** + * + * @param dirFile the value of dirFile + * @param names the value of names + */ + private static void copyResourcesToFiles(File dirFile, String... names) { + dirFile.mkdirs(); + ClassLoader classLoader = CRCLStatusType.class.getClassLoader(); + for (String name : names) { + try { + File f = new File(dirFile, name); + if (f.exists() && (f.lastModified() - System.currentTimeMillis()) < 60000) { + continue; + } + org.apache.commons.io.FileUtils.copyInputStreamToFile( + classLoader.getResourceAsStream(name), + f); + } catch (MalformedURLException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + + public static List reorderStatSchemaFiles(List fl) { + Collections.sort(fl, new Comparator() { + + @Override + public int compare(File o1, File o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + int statIndex = -1; + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i).getName().contains("Status")) { + statIndex = i; + break; + } + } + if (statIndex > 0 && statIndex < fl.size()) { + File f = fl.remove(statIndex); + fl.add(0, f); + } + return fl; + } + + public static File[] reorderStatSchemaFiles(File fa[]) { + if (null == fa || fa.length < 1) { + return fa; + } + List fl = new ArrayList<>(); + fl.addAll(Arrays.asList(fa)); + return reorderStatSchemaFiles(fl).toArray(fa); + } + + public static Schema filesToSchema(File fa[]) throws SAXException { + Source sources[] = new Source[fa.length]; + for (int i = 0; i < sources.length; i++) { + sources[i] = new StreamSource(fa[i]); + } + SchemaFactory schemaFactory = SchemaFactory + .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + return schemaFactory.newSchema(sources); + } + + public static File[] readStatSchemaFiles(File schemaListFile) { + if (schemaListFile.exists() && System.currentTimeMillis() - schemaListFile.lastModified() > 60000) { + schemaListFile.delete(); + saveStatSchemaFiles(schemaListFile, findSchemaFiles()); + } else if (!schemaListFile.exists()) { + saveStatSchemaFiles(schemaListFile, findSchemaFiles()); + } + if (!schemaListFile.exists()) { +// showMessage("Could not find CRCL Schema xsd files."); + return null; + } + try (BufferedReader br = new BufferedReader(new FileReader(schemaListFile))) { + String line = null; + List fl = new ArrayList<>(); + while (null != (line = br.readLine())) { + fl.add(new File(line.trim())); + } + fl = reorderStatSchemaFiles(fl); + return fl.toArray(new File[fl.size()]); + } catch (FileNotFoundException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return null; + } + + public static void saveProgramSchemaFiles(File schemaListFile, File fa[]) { + if (null == fa) { + return; + } + fa = reorderProgramSchemaFiles(fa); + try (PrintStream ps = new PrintStream(new FileOutputStream(schemaListFile))) { + for (int i = 0; i < fa.length; i++) { + ps.println(fa[i].getCanonicalPath()); + } + } catch (FileNotFoundException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public static void saveStatSchemaFiles(File schemaListFile, File fa[]) { + if (null == fa) { + return; + } + fa = reorderStatSchemaFiles(fa); + try (PrintStream ps = new PrintStream(new FileOutputStream(schemaListFile))) { + for (int i = 0; i < fa.length; i++) { + ps.println(fa[i].getCanonicalPath()); + } + } catch (FileNotFoundException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public static File[] reorderCommandSchemaFiles(File[] fa) { + if (null == fa || fa.length < 1) { + return fa; + } + List fl = new ArrayList<>(); + fl.addAll(Arrays.asList(fa)); + return reorderCommandSchemaFiles(fl).toArray(fa); + } + + public static List reorderCommandSchemaFiles(List fl) { + Collections.sort(fl, new Comparator() { + + @Override + public int compare(File o1, File o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + int cmdInstanceIndex = -1; + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i).getName().contains("CommandInstance")) { + cmdInstanceIndex = i; + break; + } + } + if (cmdInstanceIndex > 0 && cmdInstanceIndex < fl.size()) { + File f = fl.remove(cmdInstanceIndex); + CRCLSocket.commandXsdFile = f; + fl.add(0, f); + } + return fl; + } + + public static File[] reorderProgramSchemaFiles(File[] fa) { + List fl = new ArrayList<>(); + fl.addAll(Arrays.asList(fa)); + return reorderProgramSchemaFiles(fl).toArray(fa); + } + + public static List reorderProgramSchemaFiles(List fl) { + Collections.sort(fl, new Comparator() { + + @Override + public int compare(File o1, File o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + int cmdInstanceIndex = -1; + for (int i = 0; i < fl.size(); i++) { + if (fl.get(i).getName().contains("ProgramInstance")) { + cmdInstanceIndex = i; + break; + } + } + if (cmdInstanceIndex > 0 && cmdInstanceIndex < fl.size()) { + File f = fl.remove(cmdInstanceIndex); + CRCLSocket.commandXsdFile = f; + fl.add(0, f); + } + return fl; + } + + public static File[] readCmdSchemaFiles(File schemasListFile) { + if (schemasListFile.exists() && System.currentTimeMillis() - schemasListFile.lastModified() > 60000) { + schemasListFile.delete(); + saveCmdSchemaFiles(schemasListFile, findSchemaFiles()); + } else if (!schemasListFile.exists()) { + saveCmdSchemaFiles(schemasListFile, findSchemaFiles()); + } + if (!schemasListFile.exists()) { +// showMessage("Could not find CRCL Schema xsd files."); + return null; + } + try (BufferedReader br = new BufferedReader(new FileReader(schemasListFile))) { + String line = null; + List fl = new ArrayList<>(); + while (null != (line = br.readLine())) { + fl.add(new File(line.trim())); + } + fl = reorderCommandSchemaFiles(fl); + return fl.toArray(new File[fl.size()]); + } catch (FileNotFoundException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return null; + } + + public static File[] readProgramSchemaFiles(File schemasListFile) { + if (!schemasListFile.exists()) { + saveCmdSchemaFiles(schemasListFile, findSchemaFiles()); + return null; + } + if (!schemasListFile.exists()) { +// showMessage("Could not find CRCL Schema xsd files."); + return null; + } + try (BufferedReader br = new BufferedReader(new FileReader(schemasListFile))) { + String line = null; + List fl = new ArrayList<>(); + while (null != (line = br.readLine())) { + fl.add(new File(line.trim())); + } + fl = reorderCommandSchemaFiles(fl); + return fl.toArray(new File[fl.size()]); + } catch (FileNotFoundException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return null; + } + + public static void saveCmdSchemaFiles(File schemasListFile, File fa[]) { + if (null == fa) { + return; + } + try (PrintStream ps = new PrintStream(new FileOutputStream(schemasListFile))) { + for (int i = 0; i < fa.length; i++) { + ps.println(fa[i].getCanonicalPath()); + } + } catch (FileNotFoundException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public void writeStatus(CRCLStatusType status, boolean validate) + throws JAXBException, IOException, InterruptedException, EXIException { + if (this.isEXIEnabled()) { + if (this.isPrefixEXISizeEnabled()) { + byte ba[] = this.statusToEXI(status); +// LOGGER.log(Level.FINEST,() ->"writeStatus() : ba = " + Arrays.toString(ba)); + ByteBuffer bb = ByteBuffer.allocate(ba.length + 4); + bb.putInt(ba.length); +// LOGGER.log(Level.FINEST,() ->"writeStatus: ba.length = " + ba.length); + bb.put(ba); + byte ba2[] = bb.array(); +// LOGGER.log(Level.FINEST,() ->"writeStatus: ba2.length = " + ba2.length); +// LOGGER.log(Level.FINEST,() ->"writeStatus: ba2 = " + Arrays.toString(ba2)); + this.sock.getOutputStream().write(ba2); + this.sock.getOutputStream().flush(); + } else { + this.writeEXIStatusToStream(sock.getOutputStream(), status); + } + return; + } + this.lastStatusString = statusToString(status, validate); + this.writeWithFill(this.lastStatusString); + } + +// public OutputStream getOutputStream() throws IOException { +// return sock.getOutputStream(); +// } +// +// public InputStream getInputStream() throws IOException { +// return getBufferedInputStream(); +// } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java new file mode 100644 index 0000000..7f96399 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java @@ -0,0 +1,108 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStatusType; +import crcl.base.GetStatusType; +import crcl.base.InitCanonType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.MoveToType; +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.VectorType; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Will Shackleford{@literal } + */ +public class CRCLSocketExample { + public static void main(String[] args) { + try { + // Connect to the server + CRCLSocket s = new CRCLSocket("localhost",CRCLSocket.DEFAULT_PORT); + + // Create an instance to wrap all commands. + CRCLCommandInstanceType instance = new CRCLCommandInstanceType(); + + // Create and send init command. + InitCanonType init = new InitCanonType(); + init.setCommandID(BigInteger.valueOf(7)); + instance.setCRCLCommand(init); + s.writeCommand(instance,false); + + // Create and send MoveTo command. + MoveToType moveTo = new MoveToType(); + moveTo.setCommandID(BigInteger.valueOf(8)); + PoseType pose = new PoseType(); + PointType pt = new PointType(); + pt.setX(BigDecimal.valueOf(1.1)); + pt.setY(BigDecimal.valueOf(0.0)); + pt.setZ(BigDecimal.valueOf(0.1)); + pose.setPoint(pt); + VectorType xAxis = new VectorType(); + xAxis.setI(BigDecimal.ONE); + xAxis.setI(BigDecimal.ZERO); + xAxis.setI(BigDecimal.ZERO); + pose.setXAxis(xAxis); + VectorType zAxis = new VectorType(); + zAxis.setI(BigDecimal.ZERO); + zAxis.setI(BigDecimal.ZERO); + zAxis.setI(BigDecimal.ONE); + pose.setXAxis(zAxis); + moveTo.setEndPosition(pose); + moveTo.setMoveStraight(false); + s.writeCommand(instance,false); + + // Create and send getStatus request. + GetStatusType getStat = new GetStatusType(); + getStat.setCommandID(BigInteger.valueOf(9)); + instance.setCRCLCommand(getStat); + s.writeCommand(instance,false); + + // Read status from server + CRCLStatusType stat = s.readStatus(false); + + // Print out the status details. + CommandStatusType cmdStat = stat.getCommandStatus(); + BigInteger IDback = cmdStat.getCommandID(); + System.out.println("Status:"); + System.out.println("CommandID = " + IDback); + System.out.println("State = "+cmdStat.getCommandState()); + pt = stat.getPose().getPoint(); + System.out.println("pose = "+pt.getX()+","+pt.getY()+","+pt.getZ()); + JointStatusesType jst = stat.getJointStatuses(); + List l = jst.getJointStatus(); + System.out.println("Joints:"); + l.forEach(js -> System.out.println("Num="+js.getJointNumber()+" Pos="+js.getJointPosition())); + } catch (Exception ex) { + Logger.getLogger(CRCLSocketExample.class.getName()).log(Level.SEVERE, null, ex); + } + + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java b/crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java new file mode 100644 index 0000000..01c5bdd --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java @@ -0,0 +1,97 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathExpressionException; +import org.xml.sax.SAXException; +import rcs.posemath.PmException; +import rcs.posemath.PmPose; +import rcs.posemath.PmRpy; +import rcs.posemath.Posemath; + +/** + * + * @author Will Shackleford {@literal } + */ +public class CmdLineClient { + + public static boolean programSucceeded = false; + + public static void main(String[] args) { + try { + String poseFileName = null; + for (int i = 0; i < args.length - 1; i++) { + switch (args[i]) { + case "--waitForDoneDelay": + System.setProperty("PendantClient.waitForDoneDelay", args[i + 1]); + i++; + break; + + case "--poseFileName": + poseFileName = args[i + 1]; + i++; + break; + } + } + programSucceeded = false; + System.setProperty("crcjava.PendandClient.useReadStatusThreadSelected", "false"); + PendantClientOuterStub pendantClientOuterStub = new PendantClientOuterStub(); + PendantClientInner pendantClientInner = new PendantClientInner(pendantClientOuterStub); + final String programPropertyString = System.getProperty("crcljava.program"); + if (null != programPropertyString) { + pendantClientInner.openXmlProgramFile(new File(programPropertyString)); + programSucceeded = pendantClientInner.runProgram(pendantClientInner.getProgram()); + System.out.println("Program " + programPropertyString + " succeeded: " + programSucceeded); + } else { + System.err.println("No program specified"); + System.err.println("Use --program option to set a program to run."); + pendantClientInner.disconnect(); + System.exit(1); + } + if(null != poseFileName) { + try { + pendantClientInner.savePoseListToCsvFile(poseFileName); + } catch (PmException ex) { + Logger.getLogger(CmdLineClient.class.getName()).log(Level.SEVERE, null, ex); + } + } + pendantClientInner.disconnect(); + + } catch (ParserConfigurationException ex) { + Logger.getLogger(CmdLineClient.class.getName()).log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + Logger.getLogger(CmdLineClient.class.getName()).log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + Logger.getLogger(CmdLineClient.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(CmdLineClient.class.getName()).log(Level.SEVERE, null, ex); + } catch (SAXException ex) { + Logger.getLogger(CmdLineClient.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java b/crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java new file mode 100644 index 0000000..2b45080 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java @@ -0,0 +1,74 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + */ +package crcl.utils; + +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.parsers.ParserConfigurationException; +import rcs.posemath.Posemath; + +/** + * + * @author Will Shackleford {@literal } + */ +public class CmdLineSimServer { + + public static SimServerInner simServerInner = null; + + public static void main(String[] args) { + try { + double initPose[][] = null; + for (int i = 0; i < args.length - 1; i++) { + switch (args[i]) { + case "--delayMillis": + System.setProperty("SimServer.delayMillis", args[i + 1]); + i++; + break; + + case "--jointSpeedMax": + System.setProperty("SimServer.jointSpeedMax", args[i + 1]); + i++; + break; + + case "--maxTransSpeed": + System.setProperty("SimServer.maxTransSpeed", args[i + 1]); + i++; + break; + + case "--maxTransAccel": + System.setProperty("SimServer.maxTransAccel", args[i + 1]); + i++; + break; + + case "--initPose": + initPose = Posemath.csvToHomMats(args[i + 1], 0, 1, 2, 3, 4, 5); + break; + } + } + SimServerOuterStub simServerOuterStub = new SimServerOuterStub(); + simServerInner = new SimServerInner(simServerOuterStub); + if (null != initPose) { + simServerInner.simulatedTeleportToPose(CRCLPosemath.toPose(initPose)); + } + simServerInner.restartServer(); + } catch (ParserConfigurationException ex) { + Logger.getLogger(CmdLineSimServer.class.getName()).log(Level.SEVERE, null, ex); + } + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java b/crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java new file mode 100644 index 0000000..09c64b5 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java @@ -0,0 +1,103 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +/** + * + * @author Will Shackleford {@literal } + */ +public class DefaultMain { + + public static void main(String[] args) { + String mode = "Launcher"; + for (int i = 0; i < args.length; i++) { + if (i < args.length - 1) { + if (args[i].compareTo("--port") == 0 || args[i].compareTo("-p") == 0) { + try { + int porti = Integer.valueOf(args[i + 1]); + if(porti < 1) { + System.err.println("port ("+porti+") must be positive."); + } + System.setProperty("crcljava.port", Integer.toString(porti)); + } catch (NumberFormatException numberFormatException) { + System.err.println("port\"("+args[i+1]+"\" must be an integer"); + System.exit(i); + } + i++; + continue; + } else if (args[i].compareTo("--host") == 0 || args[i].compareTo("-h") == 0) { + System.setProperty("crcljava.host", args[i + 1]); + i++; + continue; + } else if (args[i].compareTo("--program") == 0) { + System.setProperty("crcljava.program", args[i + 1]); + i++; + continue; + } else if (args[i].compareTo("--mode") == 0 || args[i].compareTo("-m") == 0) { + mode = args[i + 1]; + i++; + continue; + } + } + if (args[i].startsWith("-")) { + System.err.println("Unrecognized argument : " + args[i]); + System.err.println("Options are:"); + System.err.println("\t--port\tSet main tcp port."); + System.err.println("\t--host\tSet tcp port used by client to connect."); + System.err.println("\t--program\tSet xml program file to be sent by client one command at a time."); + System.err.println("\t--mode\tSet mode to one of:" + +"\n\t\tLauncher,CmdLineClient,CmdLineServer,GraphicalServer,GraphicalClient"); + System.exit(1); + } + } + switch (mode) { + case "Launcher": + LauncherJFrame.main(args); + break; + + case "CmdLineClient": + CmdLineClient.main(args); + break; + + case "CmdLineServer": + CmdLineSimServer.main(args); + break; + + case "GraphicalServer": + SimServer.main(args); + break; + + case "GraphicalClient": + PendantClient.main(args); + break; + + default: + System.err.println("Unrecognized mode:"+mode); + System.err.println("Options are:"); + System.err.println("\t--port\tSet main tcp port."); + System.err.println("\t--host\tSet tcp port used by client to connect."); + System.err.println("\t--mode\tSet mode to one of:" + +"\n\t\tLauncher,CmdLineClient,CmdLineServer,GraphicalServer,GraphicalClient"); + System.exit(1); + } + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.form b/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.form new file mode 100644 index 0000000..33c3af2 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.form @@ -0,0 +1,374 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ diff --git a/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java b/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java new file mode 100644 index 0000000..809884e --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java @@ -0,0 +1,735 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStateEnumType; +import crcl.base.CommandStatusType; +import crcl.base.EndCanonType; +import crcl.base.GetStatusType; +import crcl.base.InitCanonType; +import crcl.base.ParallelGripperStatusType; +import crcl.base.ThreeFingerGripperStatusType; +import crcl.base.VacuumGripperStatusType; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBException; + +/** + * + * @author Will Shackleford {@literal } + */ +public class GripperJFrame extends javax.swing.JFrame { + + /** + * Creates new form GripperJFrame + */ + public GripperJFrame() { + initComponents(); + this.jTextFieldPort.setText(Integer.toString(this.port)); + this.jTextFieldCycleTime.setText(Integer.toString(this.delayMillis)); + this.restartServer(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel6 = new javax.swing.JPanel(); + jLabel5 = new javax.swing.JLabel(); + jTextFieldPort = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + jTextFieldCycleTime = new javax.swing.JTextField(); + jButtonReset = new javax.swing.JButton(); + jCheckBoxInitialized = new javax.swing.JCheckBox(); + jCheckBoxSendStatusWithoutRequest = new javax.swing.JCheckBox(); + jButtonRestartServer = new javax.swing.JButton(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanelThreeFinger = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTableThreeFinger = new javax.swing.JTable(); + jPanelVacuum = new javax.swing.JPanel(); + jCheckBoxVacuumPower = new javax.swing.JCheckBox(); + jPanelParallel = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jTextFieldParallelSeperation = new javax.swing.JTextField(); + jMenuBar1 = new javax.swing.JMenuBar(); + jMenu1 = new javax.swing.JMenu(); + jMenu2 = new javax.swing.JMenu(); + jMenuOptions = new javax.swing.JMenu(); + jCheckBoxMenuItemReplaceState = new javax.swing.JCheckBoxMenuItem(); + + FormListener formListener = new FormListener(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("Sim Gripper Server"); + + jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("Setup")); + + jLabel5.setText("Port: "); + + jTextFieldPort.setText("4005 "); + jTextFieldPort.addActionListener(formListener); + + jLabel6.setText("Cycle Time (ms): "); + + jTextFieldCycleTime.setText("1000"); + jTextFieldCycleTime.addActionListener(formListener); + + jButtonReset.setText("Reset"); + jButtonReset.addActionListener(formListener); + + jCheckBoxInitialized.setText("Initialized"); + + jCheckBoxSendStatusWithoutRequest.setText("Send Status Without Requests"); + + jButtonRestartServer.setText("Restart Server"); + jButtonRestartServer.addActionListener(formListener); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel6)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldCycleTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldPort, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jCheckBoxInitialized))) + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addGap(12, 12, 12) + .addComponent(jCheckBoxSendStatusWithoutRequest)) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jButtonReset) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonRestartServer)))) + .addGap(30, 30, 30)) + ); + + jPanel6Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jTextFieldCycleTime, jTextFieldPort}); + + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel5) + .addComponent(jTextFieldPort, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel6) + .addComponent(jTextFieldCycleTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonReset) + .addComponent(jButtonRestartServer)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxInitialized) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxSendStatusWithoutRequest)) + ); + + jPanelThreeFinger.setName("ThreeFinger"); // NOI18N + + jTableThreeFinger.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jTableThreeFinger.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + { new Integer(1), new Double(0.0), null}, + { new Integer(2), new Double(0.0), null}, + { new Integer(3), new Double(0.0), null} + }, + new String [] { + "Finger", "Position", "Force" + } + ) { + Class[] types = new Class [] { + java.lang.Integer.class, java.lang.Double.class, java.lang.Object.class + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + }); + jScrollPane1.setViewportView(jTableThreeFinger); + + javax.swing.GroupLayout jPanelThreeFingerLayout = new javax.swing.GroupLayout(jPanelThreeFinger); + jPanelThreeFinger.setLayout(jPanelThreeFingerLayout); + jPanelThreeFingerLayout.setHorizontalGroup( + jPanelThreeFingerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelThreeFingerLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 385, Short.MAX_VALUE) + .addContainerGap()) + ); + jPanelThreeFingerLayout.setVerticalGroup( + jPanelThreeFingerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelThreeFingerLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE) + .addContainerGap()) + ); + + jTabbedPane1.addTab("ThreeFinger", jPanelThreeFinger); + + jPanelVacuum.setName("Vacuum"); // NOI18N + + jCheckBoxVacuumPower.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jCheckBoxVacuumPower.setText("Power"); + + javax.swing.GroupLayout jPanelVacuumLayout = new javax.swing.GroupLayout(jPanelVacuum); + jPanelVacuum.setLayout(jPanelVacuumLayout); + jPanelVacuumLayout.setHorizontalGroup( + jPanelVacuumLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelVacuumLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jCheckBoxVacuumPower) + .addContainerGap(314, Short.MAX_VALUE)) + ); + jPanelVacuumLayout.setVerticalGroup( + jPanelVacuumLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelVacuumLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jCheckBoxVacuumPower) + .addContainerGap(118, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab("Vacuum", jPanelVacuum); + + jPanelParallel.setName("Parallel"); // NOI18N + + jLabel1.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jLabel1.setText("Seperation"); + + jTextFieldParallelSeperation.setText("0.0"); + + javax.swing.GroupLayout jPanelParallelLayout = new javax.swing.GroupLayout(jPanelParallel); + jPanelParallel.setLayout(jPanelParallelLayout); + jPanelParallelLayout.setHorizontalGroup( + jPanelParallelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelParallelLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextFieldParallelSeperation, javax.swing.GroupLayout.DEFAULT_SIZE, 277, Short.MAX_VALUE) + .addContainerGap()) + ); + jPanelParallelLayout.setVerticalGroup( + jPanelParallelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelParallelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelParallelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldParallelSeperation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1)) + .addContainerGap(114, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab("Parallel", jPanelParallel); + + jMenu1.setText("File"); + jMenuBar1.add(jMenu1); + + jMenu2.setText("Edit"); + jMenuBar1.add(jMenu2); + + jMenuOptions.setText("Options"); + + jCheckBoxMenuItemReplaceState.setText("Replace CRCL_Working,CRCL_Done with Working,Done ..."); + jMenuOptions.add(jCheckBoxMenuItemReplaceState); + + jMenuBar1.add(jMenuOptions); + + setJMenuBar(jMenuBar1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTabbedPane1)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1) + .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + ); + + pack(); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jTextFieldPort) { + GripperJFrame.this.jTextFieldPortActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldCycleTime) { + GripperJFrame.this.jTextFieldCycleTimeActionPerformed(evt); + } + else if (evt.getSource() == jButtonReset) { + GripperJFrame.this.jButtonResetActionPerformed(evt); + } + else if (evt.getSource() == jButtonRestartServer) { + GripperJFrame.this.jButtonRestartServerActionPerformed(evt); + } + } + }// //GEN-END:initComponents + + private void jTextFieldPortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldPortActionPerformed + this.setPort(Integer.valueOf(this.jTextFieldPort.getText())); + this.restartServer(); + }//GEN-LAST:event_jTextFieldPortActionPerformed + + private void jTextFieldCycleTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldCycleTimeActionPerformed + this.setDelayMillis(Integer.valueOf(this.jTextFieldCycleTime.getText())); + this.restartServer(); + }//GEN-LAST:event_jTextFieldCycleTimeActionPerformed + + private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResetActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jButtonResetActionPerformed + + private int port = 4005; + + /** + * Get the value of port + * + * @return the value of port + */ + public int getPort() { + return port; + } + + /** + * Set the value of port + * + * @param port new value of port + */ + public void setPort(int port) { + this.port = port; + } + + private int delayMillis = 1000; + + /** + * Get the value of delayMillis + * + * @return the value of delayMillis + */ + public int getDelayMillis() { + return delayMillis; + } + + /** + * Set the value of delayMillis + * + * @param delayMillis new value of delayMillis + */ + public void setDelayMillis(int delayMillis) { + this.delayMillis = delayMillis; + } + + private ServerSocket serverSocket = null; + private Thread acceptThread = null; + private Thread updateThread = null; + private List clients = null; + private List clientThreads = null; + private final java.util.concurrent.LinkedBlockingQueue cmdQueue + = new java.util.concurrent.LinkedBlockingQueue<>(); + private CRCLStatusType status = new CRCLStatusType(); + + private void close() { + if (null != clients) { + for (int i = 0; i < clients.size(); i++) { + CRCLSocket cs = clients.get(i); + try { + cs.close(); + } catch (IOException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + clients.clear(); + clients = null; + } + if (null != serverSocket) { + try { + serverSocket.close(); + } catch (IOException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + serverSocket = null; + } + if (null != acceptThread) { + acceptThread.interrupt(); + try { + acceptThread.join(100); + } catch (InterruptedException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + acceptThread = null; + } + if (null != updateThread) { + updateThread.interrupt(); + try { + updateThread.join(100); + } catch (InterruptedException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + updateThread = null; + } + if (null != cmdQueue) { + cmdQueue.clear(); + } + } + + private ThreeFingerGripperStatusType threeFingerGripperStatus = null; + private VacuumGripperStatusType vacuumGripperStatus = null; + private ParallelGripperStatusType parallelGripperStatus = null; + + private void checkCommandQueue() { + CRCLCommandType cmd = this.cmdQueue.poll(); + if (null != cmd) { + CommandStatusType cst = status.getCommandStatus(); + if (cst == null) { + cst = new CommandStatusType(); + } + cst.setCommandID(cmd.getCommandID()); + status.setCommandStatus(cst); + if(cmd instanceof InitCanonType) { + this.jCheckBoxInitialized.setSelected(true); + } else if(cmd instanceof EndCanonType) { + this.jCheckBoxInitialized.setSelected(false); + } + } + } + + private void updateStatus() { + this.prepStatus(); + CommandStatusType cst = status.getCommandStatus(); + BigInteger statusId = cst.getStatusID(); + if (null == statusId) { + statusId = BigInteger.ONE; + } + cst.setStatusID(statusId.add(BigInteger.ONE)); + switch (this.jTabbedPane1.getSelectedComponent().getName()) { + case "ThreeFinger": + if (null == this.threeFingerGripperStatus) { + this.threeFingerGripperStatus = new ThreeFingerGripperStatusType(); + } + this.status.setGripperStatus(threeFingerGripperStatus); + Double f1pos = (Double) this.jTableThreeFinger.getModel().getValueAt(0, 1); + threeFingerGripperStatus.setFinger1Position(BigDecimal.valueOf(f1pos)); + Double f2pos = (Double) this.jTableThreeFinger.getModel().getValueAt(1, 1); + threeFingerGripperStatus.setFinger2Position(BigDecimal.valueOf(f2pos)); + Double f3pos = (Double) this.jTableThreeFinger.getModel().getValueAt(2, 1); + threeFingerGripperStatus.setFinger3Position(BigDecimal.valueOf(f3pos)); + Object f1forceObj = this.jTableThreeFinger.getModel().getValueAt(0, 2); + if (null != f1forceObj) { + try { + double f1force = Double.valueOf(f1forceObj.toString()); + threeFingerGripperStatus.setFinger1Force(BigDecimal.valueOf(f1force)); + } catch (NumberFormatException numberFormatException) { + } + } + Object f2forceObj = this.jTableThreeFinger.getModel().getValueAt(1, 2); + if (null != f2forceObj) { + try { + double f2force = Double.valueOf(f2forceObj.toString()); + threeFingerGripperStatus.setFinger2Force(BigDecimal.valueOf(f2force)); + } catch (NumberFormatException numberFormatException) { + } + } + Object f3forceObj = this.jTableThreeFinger.getModel().getValueAt(2, 2); + if (null != f3forceObj) { + try { + double f3force = Double.valueOf(f3forceObj.toString()); + threeFingerGripperStatus.setFinger3Force(BigDecimal.valueOf(f3force)); + } catch (NumberFormatException numberFormatException) { + } + } + break; + + case "Vacuum": + if (null == this.vacuumGripperStatus) { + this.vacuumGripperStatus = new VacuumGripperStatusType(); + } + vacuumGripperStatus.setIsPowered(this.jCheckBoxVacuumPower.isSelected()); + this.status.setGripperStatus(vacuumGripperStatus); + break; + + case "Parallel": + if (null == this.parallelGripperStatus) { + this.parallelGripperStatus = new ParallelGripperStatusType(); + } + try { + double sep = Double.valueOf(this.jTextFieldParallelSeperation.getText()); + parallelGripperStatus.setSeparation(BigDecimal.valueOf(sep)); + + } catch (NumberFormatException numberFormatException) { + } + this.status.setGripperStatus(parallelGripperStatus); + break; + } + this.status.getGripperStatus().setGripperName(this.jTabbedPane1.getSelectedComponent().getName()); + + if (this.jCheckBoxSendStatusWithoutRequest.isSelected()) { + if (null != clients && clients.size() > 0) { + try { + CRCLSocket cs0 = clients.get(0); + if(jCheckBoxMenuItemReplaceState.isSelected()) { + cs0.setStatusStringOutputFilter(CRCLSocket.removeCRCLFromState); + } else { + cs0.setStatusStringOutputFilter(null); + } + String xmlS = cs0.statusToString(status, false); + for (int i = 0; i < clients.size(); i++) { + try { + CRCLSocket curClient = clients.get(i); + curClient.writeWithFill(xmlS); + } catch (IOException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + clients.remove(i); + } catch (InterruptedException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + } catch (JAXBException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + } + + private void prepStatus() { + CommandStatusType cst = status.getCommandStatus(); + if (cst == null) { + cst = new CommandStatusType(); + status.setCommandStatus(cst); + } + if (null == cst.getCommandID()) { + cst.setCommandID(BigInteger.ONE); + } + if (null == cst.getStatusID()) { + cst.setStatusID(BigInteger.ONE); + } + if (null == cst.getCommandState()) { + cst.setCommandState(CommandStateEnumType.DONE); + } + } + + private void acceptClient() throws IOException { + Socket s = serverSocket.accept(); + final CRCLSocket cs = new CRCLSocket(s); + if (null == clients) { + clients = new ArrayList<>(); + } + clients.add(cs); + Thread t = new Thread(new Runnable() { + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + try { + CRCLCommandInstanceType cmdInstance = cs.readCommand(false); + if(null == cmdInstance) { + continue; + } + CRCLCommandType cmd = cmdInstance.getCRCLCommand(); + if (cmd instanceof GetStatusType) { + prepStatus(); + if(jCheckBoxMenuItemReplaceState.isSelected()) { + cs.setStatusStringOutputFilter(CRCLSocket.removeCRCLFromState); + } + cs.writeStatus(status, false); + } else { + cmdQueue.put(cmd); + } + } catch (JAXBException | IOException | InterruptedException | EXIException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + }, "gripperClientThread" + clients.size()); + if (null == clientThreads) { + clientThreads = new ArrayList<>(); + } + clientThreads.add(t); + t.start(); + } + + private void restartServer() { + try { + this.close(); + + try { + int new_port = Integer.valueOf(this.jTextFieldPort.getText()); + this.setPort(new_port); + } catch (NumberFormatException numberFormatException) { + } + try { + int new_delay_millis = Integer.valueOf(this.jTextFieldCycleTime.getText()); + this.setDelayMillis(new_delay_millis); + } catch (NumberFormatException numberFormatException) { + } + this.serverSocket = new ServerSocket(this.port); + this.clients = new ArrayList<>(); + this.clientThreads = new ArrayList<>(); + acceptThread = new Thread(new Runnable() { + + @Override + public void run() { + try { + while (!Thread.currentThread().isInterrupted()) { + acceptClient(); + } + } catch (IOException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + + }, "gripperAcceptThread"); + acceptThread.start(); + updateThread = new Thread(new Runnable() { + + @Override + public void run() { + try { + while (!Thread.currentThread().isInterrupted()) { + Thread.sleep(delayMillis); + checkCommandQueue(); + updateStatus(); + } + } catch (InterruptedException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + }, "gripperUpdateThread"); + updateThread.start(); + } catch (IOException ex) { + Logger.getLogger(GripperJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + this.close(); + } + + + private void jButtonRestartServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRestartServerActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jButtonRestartServerActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(GripperJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(GripperJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(GripperJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(GripperJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new GripperJFrame().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonReset; + private javax.swing.JButton jButtonRestartServer; + private javax.swing.JCheckBox jCheckBoxInitialized; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemReplaceState; + private javax.swing.JCheckBox jCheckBoxSendStatusWithoutRequest; + private javax.swing.JCheckBox jCheckBoxVacuumPower; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JMenu jMenu1; + private javax.swing.JMenu jMenu2; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JMenu jMenuOptions; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanelParallel; + private javax.swing.JPanel jPanelThreeFinger; + private javax.swing.JPanel jPanelVacuum; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTable jTableThreeFinger; + private javax.swing.JTextField jTextFieldCycleTime; + private javax.swing.JTextField jTextFieldParallelSeperation; + private javax.swing.JTextField jTextFieldPort; + // End of variables declaration//GEN-END:variables +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.form b/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.form new file mode 100644 index 0000000..5174dc1 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.form @@ -0,0 +1,87 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java b/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java new file mode 100644 index 0000000..3d43178 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java @@ -0,0 +1,188 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +/** + * + * @author Will Shackleford{@literal } + */ +public class LauncherJFrame extends javax.swing.JFrame { + + /** + * Creates new form LauncherJFrame + */ + public LauncherJFrame() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButtonLaunchServer = new javax.swing.JButton(); + jButtonLaunchClient = new javax.swing.JButton(); + jButtonLaunchGripperServer = new javax.swing.JButton(); + + FormListener formListener = new FormListener(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("CRCL Launcher"); + + jButtonLaunchServer.setFont(new java.awt.Font("Cantarell", 0, 24)); // NOI18N + jButtonLaunchServer.setText("Launch Simulated CRCL Server "); + jButtonLaunchServer.addActionListener(formListener); + + jButtonLaunchClient.setFont(new java.awt.Font("Cantarell", 0, 24)); // NOI18N + jButtonLaunchClient.setText("Launch Pendant CRCL Client"); + jButtonLaunchClient.addActionListener(formListener); + + jButtonLaunchGripperServer.setFont(new java.awt.Font("Cantarell", 0, 24)); // NOI18N + jButtonLaunchGripperServer.setText("Launch Simulated Gripper Server "); + jButtonLaunchGripperServer.addActionListener(formListener); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jButtonLaunchGripperServer) + .addComponent(jButtonLaunchClient, javax.swing.GroupLayout.PREFERRED_SIZE, 408, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jButtonLaunchServer)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jButtonLaunchClient, jButtonLaunchGripperServer, jButtonLaunchServer}); + + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jButtonLaunchServer) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButtonLaunchGripperServer) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonLaunchClient) + .addContainerGap()) + ); + + pack(); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jButtonLaunchServer) { + LauncherJFrame.this.jButtonLaunchServerActionPerformed(evt); + } + else if (evt.getSource() == jButtonLaunchClient) { + LauncherJFrame.this.jButtonLaunchClientActionPerformed(evt); + } + else if (evt.getSource() == jButtonLaunchGripperServer) { + LauncherJFrame.this.jButtonLaunchGripperServerActionPerformed(evt); + } + } + }// //GEN-END:initComponents + + private void jButtonLaunchServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLaunchServerActionPerformed + new Thread(new Runnable() { + + @Override + public void run() { + SimServer.main(args); + } + },"serverMain").start(); + }//GEN-LAST:event_jButtonLaunchServerActionPerformed + + private void jButtonLaunchClientActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLaunchClientActionPerformed + new Thread(new Runnable() { + + @Override + public void run() { + PendantClient.main(args); + } + },"clientMain").start(); + }//GEN-LAST:event_jButtonLaunchClientActionPerformed + + private void jButtonLaunchGripperServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLaunchGripperServerActionPerformed + new Thread(new Runnable() { + + @Override + public void run() { + GripperJFrame.main(args); + } + },"gripperMain").start(); + }//GEN-LAST:event_jButtonLaunchGripperServerActionPerformed + + private static String args[]=null; + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(LauncherJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(LauncherJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(LauncherJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(LauncherJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + // + + LauncherJFrame.args = args; + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new LauncherJFrame().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonLaunchClient; + private javax.swing.JButton jButtonLaunchGripperServer; + private javax.swing.JButton jButtonLaunchServer; + // End of variables declaration//GEN-END:variables +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.form b/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.form new file mode 100644 index 0000000..234678c --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.form @@ -0,0 +1,82 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java b/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java new file mode 100644 index 0000000..c243671 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java @@ -0,0 +1,145 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +import java.awt.Frame; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JDialog; + +/** + * + * @author Will Shackleford {@literal } + */ +public class ListChooserJPanel extends javax.swing.JPanel { + + /** + * Creates new form ListChooserJPanel + */ + private ListChooserJPanel(JDialog _dialog, TT[] choices, TT defaultChoice) { + initComponents(); + this.dialog = _dialog; + this.defaultChoice = defaultChoice; + this.selectedChoice = defaultChoice; + this.choices = choices; + this.dialog.add(this); + this.jComboBox1.setModel(new DefaultComboBoxModel(choices)); + this.jComboBox1.setSelectedItem(defaultChoice); + this.dialog.pack(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jComboBox1 = new javax.swing.JComboBox(); + jButtonCancel = new javax.swing.JButton(); + jButtonOK = new javax.swing.JButton(); + + FormListener formListener = new FormListener(); + + jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + + jButtonCancel.setText("Cancel"); + jButtonCancel.addActionListener(formListener); + + jButtonOK.setText("OK"); + jButtonOK.addActionListener(formListener); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jComboBox1, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 253, Short.MAX_VALUE) + .addComponent(jButtonOK) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jButtonCancel))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonCancel) + .addComponent(jButtonOK)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jButtonCancel) { + ListChooserJPanel.this.jButtonCancelActionPerformed(evt); + } + else if (evt.getSource() == jButtonOK) { + ListChooserJPanel.this.jButtonOKActionPerformed(evt); + } + } + }// //GEN-END:initComponents + + private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed + this.selectedChoice = (TT) this.jComboBox1.getSelectedItem(); + this.dialog.setVisible(false); + }//GEN-LAST:event_jButtonOKActionPerformed + + private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed + this.selectedChoice = this.defaultChoice; + }//GEN-LAST:event_jButtonCancelActionPerformed + + private final JDialog dialog; + private final TT[] choices; + private final TT defaultChoice; + private TT selectedChoice; + + public TT getSelectedChoice() { + return selectedChoice; + } + + public static T Choose(Frame owner, String title, T[] choices, T defaultChoice ) { + JDialog dialog = new JDialog(owner, title,true); + ListChooserJPanel panel = new ListChooserJPanel(dialog,choices,defaultChoice); + dialog.setVisible(true); + return panel.getSelectedChoice(); + } + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonCancel; + private javax.swing.JButton jButtonOK; + private javax.swing.JComboBox jComboBox1; + // End of variables declaration//GEN-END:variables +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.form b/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.form new file mode 100644 index 0000000..d8f21e9 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.form @@ -0,0 +1,80 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java b/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java new file mode 100644 index 0000000..dad7c55 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java @@ -0,0 +1,183 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.awt.Frame; +import javax.swing.JDialog; + +/** + * + * @author Will Shackleford{@literal } + */ +public class MultiLineStringJPanel extends javax.swing.JPanel { + + /** + * Creates new form MultiLineStringJPanel + */ + public MultiLineStringJPanel() { + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButtonCancel = new javax.swing.JButton(); + jButtonOK = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextArea1 = new javax.swing.JTextArea(); + + FormListener formListener = new FormListener(); + + jButtonCancel.setText("Cancel"); + jButtonCancel.addActionListener(formListener); + + jButtonOK.setText("OK"); + jButtonOK.addActionListener(formListener); + + jTextArea1.setColumns(20); + jTextArea1.setLineWrap(true); + jTextArea1.setRows(5); + jScrollPane1.setViewportView(jTextArea1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, Short.MAX_VALUE) + .addComponent(jButtonOK) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonCancel)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 592, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 342, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonCancel) + .addComponent(jButtonOK)) + .addContainerGap()) + ); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jButtonCancel) { + MultiLineStringJPanel.this.jButtonCancelActionPerformed(evt); + } + else if (evt.getSource() == jButtonOK) { + MultiLineStringJPanel.this.jButtonOKActionPerformed(evt); + } + } + }// //GEN-END:initComponents + + private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed + this.cancelled = false; + this.dialog.setVisible(false); + }//GEN-LAST:event_jButtonOKActionPerformed + + private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed + this.cancelled = true; + this.dialog.setVisible(false); + }//GEN-LAST:event_jButtonCancelActionPerformed + + + private JDialog dialog = null; + private boolean cancelled = false; + + private static String editTextPrivate(JDialog _dialog, String init) { + MultiLineStringJPanel panel = new MultiLineStringJPanel(); + panel.jTextArea1.setText(init); + panel.jScrollPane1.getVerticalScrollBar().setValue(0); + panel.jTextArea1.setCaretPosition(0); + panel.dialog = _dialog; + _dialog.add(panel); + _dialog.pack(); + _dialog.setVisible(true); + if(panel.cancelled) { + return null; + } + return panel.jTextArea1.getText(); + } + + public static String editText(String init, Frame _owner, + String _title, + boolean _modal) { + JDialog dialog = new JDialog(_owner, _title, _modal); + return editTextPrivate(dialog, init); + } + + public static String editText(String init) { + JDialog dialog = new JDialog(); + dialog.setModal(true); + return editTextPrivate(dialog, init); + } + + + private static boolean showTextPrivate(JDialog _dialog, String init) { + MultiLineStringJPanel panel = new MultiLineStringJPanel(); + panel.jTextArea1.setText(init); +// panel.jTextArea1.setEditable(false); + panel.jScrollPane1.getVerticalScrollBar().setValue(0); + panel.jTextArea1.setCaretPosition(0); + panel.dialog = _dialog; + _dialog.add(panel); + _dialog.pack(); + _dialog.setVisible(true); + return !panel.cancelled; + } + + public static boolean showText(String init, Frame _owner, + String _title, + boolean _modal) { + JDialog dialog = new JDialog(_owner, _title, _modal); + return showTextPrivate(dialog, init); + } + + public static boolean showText(String init) { + JDialog dialog = new JDialog(); + dialog.setModal(true); + return showTextPrivate(dialog, init); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonCancel; + private javax.swing.JButton jButtonOK; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + // End of variables declaration//GEN-END:variables +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.form b/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.form new file mode 100644 index 0000000..84e10dc --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.form @@ -0,0 +1,277 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java b/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java new file mode 100644 index 0000000..79720a4 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java @@ -0,0 +1,1783 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.CRCLCommandType; +import crcl.base.CRCLStatusType; +import java.awt.Color; +import java.awt.Component; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.function.Predicate; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.DefaultCellEditor; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.xml.bind.JAXBException; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathExpressionException; +import org.xml.sax.SAXException; + +/** + * + * @author Will Shackleford{@literal } + */ +public class ObjTableJPanel extends javax.swing.JPanel { + + /** + * Creates new form CmdTableJPanel + */ + public ObjTableJPanel() { + initComponents(); + setupTableSelection(); + } + + private XpathUtils xpu = null; + private String defaultDocumentation = null; + + private void setupTableSelection() { + + ListSelectionModel cellSelectionModel = this.jTable1.getSelectionModel(); + cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + cellSelectionModel.addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(ListSelectionEvent e) { + try { + jButtonNew.setEnabled(false); + jButtonDelete.setEnabled(false); + jButtonAddToList.setEnabled(false); + jButtonRemoveFromList.setEnabled(false); + jButtonEditMultiLineText.setEnabled(false); + int row = jTable1.getSelectedRow(); + DefaultTableModel tm = (DefaultTableModel) jTable1.getModel(); + if (row < 0 || row > tm.getRowCount()) { + return; + } + String type = (String) tm.getValueAt(row, 0); + String name = (String) tm.getValueAt(row, 1); + String typenoparams = removeTypeParams(type); + Class clss = null; + if (typenoparams.equals("boolean")) { + clss = boolean.class; + } else { + clss = Class.forName(typenoparams); + } + String documentation = null; + String doctype = typenoparams; + Object cur_obj = getObject(name); + if (null != cur_obj) { + doctype = cur_obj.getClass().getCanonicalName(); + } + int pindex = doctype.lastIndexOf('.'); + if (pindex > 0) { + doctype = doctype.substring(pindex + 1); + } + if (null != xpu) { + try { + documentation = xpu.getDocumentation(doctype); + } catch (SAXException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (ParserConfigurationException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + if (null != documentation) { + jTextPane1.setText(documentation); + } else if (null != defaultDocumentation) { + jTextPane1.setText(defaultDocumentation); + } + jTextPane1.setCaretPosition(0); + jScrollPaneDocumentation.getVerticalScrollBar().setValue(0); + } + if (name.equals("this") || row == 0) { + return; + } + if (isList(getParentObject(name).getClass())) { + jButtonRemoveFromList.setEnabled(true); + return; + } + if (isCompound(clss)) { + jButtonNew.setEnabled(true); + if (null != getObject(name)) { + jButtonDelete.setEnabled(true); + } + return; + } + if (isList(clss)) { + jButtonAddToList.setEnabled(true); + return; + } + if (clss.equals(String.class)) { + jButtonEditMultiLineText.setEnabled(true); + } + } catch (ClassNotFoundException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (InvocationTargetException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + }); + } + + private final Map editorMap = new HashMap<>(); + private final Map rendererMap = new HashMap<>(); + private final Map colorMap = new HashMap<>(); + private final Set noneditableSet = new HashSet<>(); + + private JTable createJTable() { + return new JTable() { + + @Override + public Component prepareRenderer( + TableCellRenderer renderer, int row, int column) { + Component c = super.prepareRenderer(renderer, row, column); + if (this.getSelectedRow() == row) { + return c; + } + Color color = colorMap.get(row); + if (color != null) { + c.setBackground(color); + } + return c; + } + + @Override + public TableCellEditor getCellEditor(int row, int column) { + if (column == 2 && editorMap.containsKey(row)) { + return editorMap.get(row); + } + return super.getCellEditor(row, column); + } + + @Override + public TableCellRenderer getCellRenderer(int row, int column) { + if (column == 2 && rendererMap.containsKey(row)) { + return rendererMap.get(row); + } + return super.getCellRenderer(row, column); + } + + @Override + public boolean isCellEditable(int row, int column) { + boolean returnvar = false; + returnvar = super.isCellEditable(row, column); + if (returnvar && column == 2 && noneditableSet.contains(row)) { + return false; + } + return returnvar; + } + + }; + } + + private class NewDeletePanel extends JPanel { + + private final JButton jButtonNew = new JButton("New"); + private final JButton jButtonDelete = new JButton("Delete"); + + public NewDeletePanel() { + super(); + +// this.setPreferredSize(new Dimension(400,400)); +// this.setSize(new Dimension(400,400)); +// this.setMinimumSize(new Dimension(400,400)); + jButtonNew.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + setNewTableItem(); + } + }); + jButtonDelete.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + //setNewTableItem(); + System.err.println("FIXME: implement delete"); + } + }); + this.add(jButtonNew); + this.add(jButtonDelete); + } + }; + + Map pnlMap = new HashMap<>(); + +// private class MyTableModel extends DefaultTableModel { +// +// final private DefaultTableModel orig; +// +// public MyTableModel(final DefaultTableModel _orig) { +// super(); +// this.orig = _orig; +// } +// +// +// @Override +// public boolean isCellEditable(int row, int column) { +// return column != 2 && null == pnlMap.get(row); +// } +// +// @Override +// public int getRowCount() { +// if(null == orig) { +// return 0; +// } +// return orig.getRowCount(); +// } +// +// @Override +// public int getColumnCount() { +// if(null == orig) { +// return 3; +// } +// return orig.getColumnCount(); +// } +// +// @Override +// public String getColumnName(int columnIndex) { +// return orig.getColumnName(columnIndex); +// } +// +// @Override +// public Class getColumnClass(int columnIndex) { +// return orig.getColumnClass(columnIndex); +// } +// +// @Override +// public Object getValueAt(int rowIndex, int columnIndex) { +// return orig.getValueAt(rowIndex, columnIndex); +// } +// +// @Override +// public void setValueAt(Object aValue, int rowIndex, int columnIndex) { +// orig.setValueAt(aValue, rowIndex, columnIndex); +// } +// +// @Override +// public void addTableModelListener(TableModelListener l) { +// orig.addTableModelListener(l); +// } +// +// @Override +// public void removeTableModelListener(TableModelListener l) { +// orig.removeTableModelListener(l); +// } +// +// }; + private class MyTableCellRenderer extends DefaultTableCellRenderer { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + Component returnvar = null; + if (column == 2) { + try { + DefaultTableModel tm = (DefaultTableModel) table.getModel(); + String type = (String) tm.getValueAt(row, 0); + String typenoparams = removeTypeParams(type); + Class clss = Class.forName(typenoparams); + pnlMap.remove(row); + if (isCompound(clss)) { + NewDeletePanel pnl = new NewDeletePanel(); + pnlMap.put(row, pnl); + int rheight = table.getRowHeight(row); + table.setRowHeight(row, Math.max(rheight, pnl.getPreferredSize().height)); + return pnl; + } +// if (isList(clss)) { +// jButtonAddToList.setEnabled(true); +// } + } catch (ClassNotFoundException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + returnvar = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + return returnvar; + } + }; + +// private class MyTableCellEditor implements TableCellEditor { +// +// private final JButton jButtonNew = new JButton("New"); +// private final JButton jButtonDelete = new JButton("Delete"); +// private final JTextField jtf = new JTextField(); +// +// public MyTableCellEditor() { +// jButtonNew.addActionListener(new ActionListener() { +// +// @Override +// public void actionPerformed(ActionEvent e) { +// System.out.println("e = " + e); +// } +// }); +// } +// +// @Override +// public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { +// if (column == 2) { +// NewDeletePanel ndp = pnlMap.get(row); +// if (null != ndp) { +// return jButtonNew; +// } +// } +// return jtf; +// } +// +// @Override +// public Object getCellEditorValue() { +// return jtf.getText(); +// } +// +// @Override +// public boolean isCellEditable(EventObject anEvent) { +// // TODO: implement this function +// return (boolean) false; +// } +// +// @Override +// public boolean shouldSelectCell(EventObject anEvent) { +// // TODO: implement this function +// return (boolean) false; +// } +// +// @Override +// public boolean stopCellEditing() { +// // TODO: implement this function +// return (boolean) false; +// } +// +// @Override +// public void cancelCellEditing() { +// } +// +// @Override +// public void addCellEditorListener(CellEditorListener l) { +// } +// +// @Override +// public void removeCellEditorListener(CellEditorListener l) { +// } +// +// }; + + private static String removeTypeParams(String type) { + String typenoparams = type; + int ltindex = typenoparams.indexOf("<"); + if (ltindex > 0) { + typenoparams = typenoparams.substring(0, ltindex); + } + return typenoparams; + } + + private static String getTypeParams(String type) { + String params = ""; + int ltindex = type.indexOf("<"); + int gtindex = type.indexOf(">"); + if (gtindex > 0 && ltindex > 0) { + params = type.substring(ltindex + 1, gtindex); + } + return params; + } + + private static boolean isList(Class clss) { + return List.class.isAssignableFrom(clss); + } + + private static boolean isCompound(Class clss) { + if (clss.isPrimitive()) { + return false; + } +// System.out.println("List.class.isAssignableFrom(ArrayList.class) = "+ List.class.isAssignableFrom(ArrayList.class)); +// System.out.println("ArrayList.class.isAssignableFrom(List.class) = "+ ArrayList.class.isAssignableFrom(List.class)); + if (List.class.isAssignableFrom(clss)) { + return false; + } + if (String.class.isAssignableFrom(clss)) { + return false; + } + if (java.lang.Boolean.class.isAssignableFrom(clss)) { + return false; + } + if (java.lang.Float.class.isAssignableFrom(clss)) { + return false; + } + if (java.lang.Double.class.isAssignableFrom(clss)) { + return false; + } + if (java.lang.Short.class.isAssignableFrom(clss)) { + return false; + } + if (java.lang.Integer.class.isAssignableFrom(clss)) { + return false; + } + if (java.lang.Long.class.isAssignableFrom(clss)) { + return false; + } + if (java.math.BigDecimal.class.isAssignableFrom(clss)) { + return false; + } + if (java.math.BigInteger.class.isAssignableFrom(clss)) { + return false; + } + if (clss.isEnum()) { + return false; + } + if (null == classes) { + classes = getClasses(); + } + List availClasses = getAssignableClasses(clss, classes); + return availClasses.size() > 0; + } + + private T obj; + + /** + * Get the value of obj + * + * @return the value of obj + */ + public T getObj() { + return obj; + } + + private void updateObjFromTable() { + DefaultTableModel tm = (DefaultTableModel) this.jTable1.getModel(); + final int row_count = tm.getRowCount(); + Class clss = obj.getClass(); + for (int i = 0; i < row_count; i++) { + try { + String type = (String) tm.getValueAt(i, 0); + String name = (String) tm.getValueAt(i, 1); + Object o = tm.getValueAt(i, 2); + this.setObjectForName(type, name, o); + + } catch (SecurityException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + final private Color myBlue = new Color(150, 150, 255); + + private Object getDefaultForClass(Class clss) throws InstantiationException, IllegalAccessException { + if (String.class.isAssignableFrom(clss)) { + return ""; + } + if (java.math.BigDecimal.class.isAssignableFrom(clss)) { + return BigDecimal.ZERO; + } + if (java.math.BigInteger.class.isAssignableFrom(clss)) { + return BigInteger.ONE; + } + if (Boolean.class.isAssignableFrom(clss)) { + return Boolean.FALSE; + } + if (Double.class.isAssignableFrom(clss)) { + return Double.valueOf(0.0); + } + if (Float.class.isAssignableFrom(clss)) { + return Float.valueOf(0.0f); + } + if (Short.class.isAssignableFrom(clss)) { + return Short.valueOf((short) 0); + } + if (Integer.class.isAssignableFrom(clss)) { + return Integer.valueOf(0); + } + if (Long.class.isAssignableFrom(clss)) { + return Long.valueOf(0); + } + if (clss.isEnum()) { + return clss.getEnumConstants()[0]; + } + return clss.newInstance(); + } + + private Field getField(Class clss, String name) { + Field f = null; + if (clss == null) { + return null; + } + try { + f = clss.getField(name); + } catch (Exception ex) { + } + if (null != f) { + return f; + } + try { + f = clss.getDeclaredField(name); + } catch (Exception ex) { + } + if (null != f) { + return f; + } + return getField(clss.getSuperclass(), name); + } + + private void addObjectToTable(String name_prefix, + DefaultTableModel tm, Object o, Class clss) { + Class oclss = clss; + if (null != o) { + oclss = o.getClass(); + } + if (null != defaultDocumentation) { + jTextPane1.setText(defaultDocumentation); + jTextPane1.setCaretPosition(0); + jScrollPaneDocumentation.getVerticalScrollBar().setValue(0); + } + + Method ma[] = oclss.getMethods(); + SortedSet names = new TreeSet<>(); + Map map = new HashMap<>(); + for (Method m : ma) { +// try { +// if (m.getName().startsWith("set") && m.getParameterCount() == 1) { +// String mname = m.getName().substring(3); +// names.add(mname); +// map.put(mname, m); +// } +// } catch (Exception e) { +// } + try { + if (m.getName().startsWith("get") && m.getParameterCount() == 0) { + String mname = m.getName().substring(3); + if (mname.equals("Class")) { + continue; + } + names.add(mname); + map.put(mname, m); + } + } catch (Exception e) { + } + try { + if (m.getName().startsWith("is") && m.getParameterCount() == 0) { + String mname = m.getName().substring(2); + if (mname.equals("Class")) { + continue; + } + names.add(mname); + map.put(mname, m); + } + } catch (Exception e) { + } + } + for (String name : names) { + try { + Method m = map.get(name); + Class mclss = null; + if (m.getParameterCount() == 1) { + mclss = m.getParameterTypes()[0]; + } else { + mclss = m.getReturnType(); + } + Method mget = null; + try { + mget = oclss.getMethod("get" + name); + + } catch (NoSuchMethodException noSuchMethodException) { + } catch (SecurityException securityException) { + } + try { + mget = clss.getMethod("is" + name); + + } catch (NoSuchMethodException noSuchMethodException) { + } catch (SecurityException securityException) { + } + Object mo = null; + if (null != o && null != mget) { + try { + mo = mget.invoke(o); + } catch (IllegalAccessException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (InvocationTargetException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + Method subma[] = mclss.getMethods(); + int numsetters = 0; + for (Method subm : subma) { + if (subm.getName().startsWith("set") && subm.getParameterCount() == 1) { + numsetters++; + } + } + String type = mclss.getCanonicalName(); + String list_item_type = null; + if (List.class.isAssignableFrom(mclss) && null != mget) { + try { + ParameterizedType prt = (ParameterizedType) mget.getGenericReturnType(); + list_item_type = prt.getActualTypeArguments()[0].getTypeName(); + type += "<" + list_item_type + ">"; + } catch (Exception e) { + } +// Class moclss = mo.getClass(); +// Method moa[] = moclss.getMethods(); +// for (Method mom : moa) { +// System.out.println("mom = " + mom); +//// Method moget = moclss.getMethod("get", int.class); +// try { +// Type tret = mom.getGenericReturnType(); +// System.out.println("tret = " + tret); +// Type[] params = mom.getGenericParameterTypes(); +// ParameterizedType firstParam = (ParameterizedType) params[0]; +// System.out.println("firstParam = " + firstParam); +// Type[] paramsOfFirstGeneric = firstParam.getActualTypeArguments(); +// System.out.println("paramsOfFirstGeneric = " + Arrays.toString(paramsOfFirstGeneric)); +// System.out.println("paramsOfFirstGeneric[0] = " + paramsOfFirstGeneric[0]); +// +// } catch (Exception e) { +// } +// } +// System.out.println("moget = " + moget); +// Class mogetret = moget.getReturnType(); +// System.out.println("mogetret = " + mogetret); + } +// type += "<"+mogetret.getCanonicalName()+">"; + this.colorMap.put(tm.getRowCount(), Color.LIGHT_GRAY); + if (mclss.isEnum()) { + JComboBox comboBox = new JComboBox(); + for (Object oc : mclss.getEnumConstants()) { + comboBox.addItem(oc); + } + this.editorMap.put(tm.getRowCount(), new DefaultCellEditor(comboBox)); +// this.colorMap.put(tm.getRowCount(), Color.pink); + } + if (mclss.equals(boolean.class)) { + if (mo == null) { + mo = Boolean.FALSE; + } else { + mo = Boolean.valueOf((boolean) mo); + } + final JCheckBox jc = new JCheckBox("false"); + jc.setBackground(Color.LIGHT_GRAY); + jc.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (jc.isSelected()) { + jc.setText("true"); + } else { + jc.setText("false"); + } + } + }); + this.rendererMap.put(tm.getRowCount(), new DefaultTableCellRenderer() { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + return jc; + } + }); + this.editorMap.put(tm.getRowCount(), new DefaultCellEditor(jc) { + + @Override + public Object getCellEditorValue() { + if (jc.isSelected()) { + return Boolean.TRUE; + } + return Boolean.FALSE; + } + + }); + + } + String fieldName = name.substring(0, 1).toLowerCase() + name.substring(1); + if (null == mo) { + Field field = this.getField(clss, fieldName); + if (null != field) { + Annotation annotations[] = field.getDeclaredAnnotations(); + for (Annotation a : annotations) { + if (XmlElement.class.isAssignableFrom(a.annotationType())) { + XmlElement xe = (XmlElement) a; + if (xe.required()) { + try { + mo = this.getDefaultForClass(mclss); + if (null != mo) { + Method mset = oclss.getMethod("set" + name, mclss); + mset.invoke(o, mo); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + } + } + } + Object oa[] = new Object[]{type, name_prefix + name, mo}; + tm.addRow(oa); + if (isCompound(mclss)) { + this.noneditableSet.add(tm.getRowCount() - 1); + } + if (mclss.equals(String.class) && mo != null + && mo.toString().contains("\n")) { + final JTextArea jta = new JTextArea(); + this.noneditableSet.add(tm.getRowCount() - 1); + this.rendererMap.put(tm.getRowCount() - 1, new DefaultTableCellRenderer() { + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + jta.setText(value.toString()); + table.setRowHeight(row, Math.max(table.getRowHeight(row), jta.getPreferredSize().height)); + return jta; + } + }); +// this.editorMap.put(tm.getRowCount()-1, new TableCellEditor() { +// +// @Override +// public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { +// jta.setText(value.toString()); +// table.setRowHeight(row, Math.max(table.getRowHeight(row),jta.getPreferredSize().height)); +// return jta; +// } +// +// @Override +// public Object getCellEditorValue() { +// return jta.getText(); +// } +// +// @Override +// public boolean isCellEditable(EventObject anEvent) { +// return jta.isEditable(); +// } +// +// @Override +// public boolean shouldSelectCell(EventObject anEvent) { +// return true; +// } +// +// @Override +// public boolean stopCellEditing() { +// if(null != listeners) { +// ChangeEvent changeEvent = new ChangeEvent(this); +// Iterator celit = listeners.iterator(); +// while(celit.hasNext()) { +// CellEditorListener l = celit.next(); +// l.editingStopped(changeEvent); +// } +// } +// return true; +// } +// +// @Override +// public void cancelCellEditing() { +// if(null != listeners) { +// ChangeEvent changeEvent = new ChangeEvent(this); +// Iterator celit = listeners.iterator(); +// while(celit.hasNext()) { +// CellEditorListener l = celit.next(); +// l.editingStopped(changeEvent); +// } +// } +//// jta.setEditable(false); +// } +// +// private List listeners = null; +// +// @Override +// public void addCellEditorListener(CellEditorListener l) { +// if(listeners == null) { +// listeners = new ArrayList<>(); +// } +// listeners.add(l); +// } +// +// @Override +// public void removeCellEditorListener(CellEditorListener l) { +// if(null != listeners) { +// listeners.remove(l); +// } +// } +// }); +// + } + if (List.class.isAssignableFrom(mclss) && null != mget && null != mo) { + this.noneditableSet.add(tm.getRowCount() - 1); + this.colorMap.put(tm.getRowCount() - 1, Color.green.brighter()); + List l = (List) mo; + Class lclss = Object.class; + try { + ParameterizedType prt = (ParameterizedType) mget.getGenericReturnType(); + lclss = Class.forName(prt.getActualTypeArguments()[0].getTypeName()); + } catch (Exception e) { + } + for (int i = 0; i < l.size(); i++) { + Object lo = l.get(i); + if (null != lo) { + String item_name = name_prefix + name + ".get(" + i + ")"; + oa = new Object[]{list_item_type, item_name, lo}; + this.colorMap.put(tm.getRowCount(), Color.yellow); + tm.addRow(oa); + addObjectToTable(item_name + ".", tm, lo, lclss); + } + } + } else if (numsetters > 0 && mo != null + && !mclss.equals(java.math.BigDecimal.class) + && !mclss.equals(java.math.BigInteger.class)) { + this.noneditableSet.add(tm.getRowCount() - 1); + this.colorMap.put(tm.getRowCount() - 1, myBlue); + addObjectToTable(name_prefix + name + ".", tm, mo, mclss); + } + } catch (SecurityException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + /** + * Set the value of obj + * + * @param obj new value of obj + */ + public void setObj(T obj) { + this.obj = obj; + updateTableFromObject(); + } + + private void updateTableFromObject() { + DefaultTableModel tm = (DefaultTableModel) this.jTable1.getModel(); + tm.setRowCount(0); + Class clss = obj.getClass(); + rendererMap.clear(); + editorMap.clear(); + colorMap.clear(); + noneditableSet.clear(); + Object oa[] = new Object[]{obj.getClass().getCanonicalName(), "this", obj}; + tm.addRow(oa); + colorMap.put(0, myBlue); + addObjectToTable("", tm, obj, clss); + } + + private JDialog dialog = null; + private boolean cancelled = false; + private Predicate isValid = null; + + private static T editObjectPriv(JDialog _dialog, T _obj, XpathUtils xpu, java.util.function.Predicate isValid) { + ObjTableJPanel panel = new ObjTableJPanel(); + panel.dialog = _dialog; + panel.setObj(_obj); + panel.isValid = isValid; + String clssname = _obj.getClass().getCanonicalName(); + int pindex = clssname.lastIndexOf('.'); + if (pindex > 0) { + clssname = clssname.substring(pindex + 1); + } + if (null != xpu) { + String documentation = null; + try { + documentation = xpu.getDocumentation(clssname); + } catch (SAXException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (ParserConfigurationException ex) { + Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } + panel.xpu = xpu; + if (null != documentation) { + panel.jTextPane1.setText(documentation); + panel.defaultDocumentation = documentation; + } + } + panel.jTextPane1.setCaretPosition(0); + panel.jScrollPaneDocumentation.getVerticalScrollBar().setValue(0); + _dialog.add(panel); + _dialog.pack(); + _dialog.setVisible(true); + if (panel.cancelled) { + return null; + } + return panel.getObj(); + } + + public static T editObject(T _obj, Frame _owner, String _title, boolean _modal, XpathUtils xpu, java.util.function.Predicate isValid) { + JDialog dialog = new JDialog(_owner, _obj.getClass().getCanonicalName() + ":" + _title, _modal); + return editObjectPriv(dialog, _obj, xpu, isValid); + } + + public static T editObject(T _obj, XpathUtils xpu, java.util.function.Predicate isValid) { + JDialog dialog = new JDialog(); + dialog.setTitle(_obj.getClass().getCanonicalName()); + dialog.setModal(true); + return editObjectPriv(dialog, _obj, xpu, isValid); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jButtonCancel = new javax.swing.JButton(); + jButtonOK = new javax.swing.JButton(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTable1 = createJTable(); + jButtonNew = new javax.swing.JButton(); + jButtonAddToList = new javax.swing.JButton(); + jButtonRemoveFromList = new javax.swing.JButton(); + jButtonDelete = new javax.swing.JButton(); + jButtonEditMultiLineText = new javax.swing.JButton(); + jPanel1 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + jPanel2 = new javax.swing.JPanel(); + jScrollPaneDocumentation = new javax.swing.JScrollPane(); + jTextPane1 = new javax.swing.JTextPane(); + + FormListener formListener = new FormListener(); + + jButtonCancel.setText("Cancel"); + jButtonCancel.addActionListener(formListener); + + jButtonOK.setText("OK"); + jButtonOK.addActionListener(formListener); + + jTable1.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null}, + {null, null, null}, + {null, null, null} + }, + new String [] { + "Type", "Name", "Value" + } + ) { + Class[] types = new Class [] { + java.lang.String.class, java.lang.String.class, java.lang.Object.class + }; + boolean[] canEdit = new boolean [] { + false, false, true + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jScrollPane2.setViewportView(jTable1); + + jButtonNew.setText("New"); + jButtonNew.setEnabled(false); + jButtonNew.addActionListener(formListener); + + jButtonAddToList.setText("Add To List"); + jButtonAddToList.setEnabled(false); + jButtonAddToList.addActionListener(formListener); + + jButtonRemoveFromList.setText("Remove From List"); + jButtonRemoveFromList.setEnabled(false); + jButtonRemoveFromList.addActionListener(formListener); + + jButtonDelete.setText("Delete"); + jButtonDelete.setEnabled(false); + jButtonDelete.addActionListener(formListener); + + jButtonEditMultiLineText.setText("Edit Multi-line Text"); + jButtonEditMultiLineText.setEnabled(false); + jButtonEditMultiLineText.addActionListener(formListener); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Color Code")); + + jLabel1.setBackground(new java.awt.Color(150, 150, 255)); + jLabel1.setText("Compound Type"); + jLabel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + jLabel1.setOpaque(true); + + jLabel2.setBackground(new java.awt.Color(0, 255, 0)); + jLabel2.setText("List"); + jLabel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + jLabel2.setOpaque(true); + + jLabel3.setBackground(new java.awt.Color(255, 255, 0)); + jLabel3.setText("List Item"); + jLabel3.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); + jLabel3.setOpaque(true); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel3) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jLabel2) + .addComponent(jLabel3)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Documentation")); + + jTextPane1.setEditable(false); + jScrollPaneDocumentation.setViewportView(jTextPane1); + + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); + jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPaneDocumentation) + .addContainerGap()) + ); + jPanel2Layout.setVerticalGroup( + jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPaneDocumentation, javax.swing.GroupLayout.DEFAULT_SIZE, 170, Short.MAX_VALUE) + .addContainerGap()) + ); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jButtonNew) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonDelete) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonAddToList) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonRemoveFromList) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonEditMultiLineText) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 200, Short.MAX_VALUE) + .addComponent(jButtonOK) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonCancel))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonCancel) + .addComponent(jButtonOK) + .addComponent(jButtonNew) + .addComponent(jButtonAddToList) + .addComponent(jButtonRemoveFromList) + .addComponent(jButtonDelete) + .addComponent(jButtonEditMultiLineText)) + .addContainerGap()) + ); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jButtonCancel) { + ObjTableJPanel.this.jButtonCancelActionPerformed(evt); + } + else if (evt.getSource() == jButtonOK) { + ObjTableJPanel.this.jButtonOKActionPerformed(evt); + } + else if (evt.getSource() == jButtonNew) { + ObjTableJPanel.this.jButtonNewActionPerformed(evt); + } + else if (evt.getSource() == jButtonAddToList) { + ObjTableJPanel.this.jButtonAddToListActionPerformed(evt); + } + else if (evt.getSource() == jButtonRemoveFromList) { + ObjTableJPanel.this.jButtonRemoveFromListActionPerformed(evt); + } + else if (evt.getSource() == jButtonDelete) { + ObjTableJPanel.this.jButtonDeleteActionPerformed(evt); + } + else if (evt.getSource() == jButtonEditMultiLineText) { + ObjTableJPanel.this.jButtonEditMultiLineTextActionPerformed(evt); + } + } + }// //GEN-END:initComponents + + private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed + this.cancelled = true; + this.dialog.setVisible(false); + }//GEN-LAST:event_jButtonCancelActionPerformed + + private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOKActionPerformed + this.cancelled = false; + this.updateObjFromTable(); + if (null != this.isValid) { + if (!this.isValid.test(this.obj)) { + return; + } + } + this.dialog.setVisible(false); + }//GEN-LAST:event_jButtonOKActionPerformed + + static private List classes = null; + + static private List addClasses(String prefix, File dir, List classes) { + File fa[] = dir.listFiles(); + if(fa == null) { + return classes; + } + for (File f : fa) { + if (f.isDirectory()) { + classes = addClasses(prefix + f.getName() + ".", f, classes); + } else if (f.getName().endsWith(".class")) { + String clssNameToLookup = ""; + try { + String name = f.getName(); + name = name.substring(0, name.length() - 6); + if (name.indexOf("$") >= 0) { + continue; + } + clssNameToLookup = prefix + name; + Class clss = Class.forName(clssNameToLookup); + if (!Modifier.isAbstract(clss.getModifiers()) + && !clss.isSynthetic() + && !clss.isAnonymousClass() + && !clss.isMemberClass()) { + classes.add(clss); + } + } catch (Exception ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, "clssNameToLookup="+clssNameToLookup); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + } + return classes; + } + + static public List getClasses() { + String name = ""; + File jar = null; + List classes = new ArrayList<>(); + try { + for (String classpathEntry : System.getProperty("java.class.path").split(System.getProperty("path.separator"))) { +// System.out.println("classpathEntry = " + classpathEntry); + if (classpathEntry.endsWith(".jar") + && !classpathEntry.contains("xerces") + && !classpathEntry.contains("exificient")) { + JarInputStream is = null; + try { + jar = new File(classpathEntry); + is = new JarInputStream(new FileInputStream(jar)); + JarEntry entry; + while ((entry = is.getNextJarEntry()) != null) { + if (entry.getName().endsWith(".class")) { + name = entry.getName(); + name = name.substring(0, name.length() - 6); + name = name.replaceAll("/", "."); + if (name.indexOf("$") >= 0) { + continue; + } + Class clss; + try { + clss = Class.forName(name); + if (!Modifier.isAbstract(clss.getModifiers()) + && !clss.isSynthetic() + && !clss.isAnonymousClass() + && !clss.isMemberClass()) { + classes.add(clss); + + } + } catch (ClassNotFoundException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + + } + } + } catch (IOException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } finally { + try { + if(null != is) { + is.close(); + } + } catch (IOException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + } else { + File dir = new File(classpathEntry); + classes = addClasses("", dir, classes); + } + } + } catch (Throwable t) { + System.err.println("name = "+ name); + System.err.println("jar = "+jar); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, t); + } +// classes.add(javax.xml.datatype.XMLGregorianCalendar.class); +// classes.add(javax.xml.datatype.Duration.class); + return classes; + } + + private Object getObject(String name) throws IllegalAccessException, InvocationTargetException { + int pindex = name.lastIndexOf("."); + String endname = name; + if (pindex > 0) { + endname = name.substring(pindex + 1); + } + if (name.equals("this")) { + return obj; + } + return getObject(getParentObject(name), endname); + } + + private Object getObject(Object pobj, String name) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + if (pobj instanceof List) { + List l = (List) pobj; + String indexString = name.substring(name.lastIndexOf("(") + 1, name.lastIndexOf(")")); + return l.get(Integer.valueOf(indexString)); + } + Method mget = null; + try { + mget = pobj.getClass().getMethod("get" + name); + + } catch (NoSuchMethodException ex) { +// Logger.getLogger(ObjTableJPanel.class +// .getName()).log(Level.SEVERE, null, ex); + } + try { + if (null == mget) { + mget = pobj.getClass().getMethod("is" + name); + } + } catch (NoSuchMethodException ex) { +// Logger.getLogger(ObjTableJPanel.class +// .getName()).log(Level.SEVERE, null, ex); + } + if (mget == null) { + System.err.println("Method to get object for " + name + " does not exist"); + return null; + } + pobj = mget.invoke(pobj); + return pobj; + } + + private Object getParentObject(String name) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Object pobj = this.obj; + String pnames[] = name.split("[.]"); + for (int i = 0; i < pnames.length - 1; i++) { + pobj = getObject(pobj, pnames[i]); + if (pobj == null) { + System.err.println("Parent object for " + pnames[i] + " of " + name + "does not exist"); + return null; + } + } + return pobj; + } + + private Class stringToClass(String type) throws ClassNotFoundException { + if (type.equals("boolean")) { + return boolean.class; + } + if (type.equals("int")) { + return int.class; + } + if (type.equals("short")) { + return short.class; + } + if (type.equals("long")) { + return long.class; + } + if (type.equals("float")) { + return float.class; + } + if (type.equals("double")) { + return double.class; + } + return Class.forName(type); + } + + private Object convertToType(Class tclass, String name, Object o) throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { + if (tclass.equals(boolean.class)) { + return Boolean.valueOf(o.toString()); + } + if (tclass.equals(int.class)) { + return Integer.valueOf(o.toString()); + } + if (tclass.equals(short.class)) { + return Short.valueOf(o.toString()); + } + if (tclass.equals(long.class)) { + return Long.valueOf(o.toString()); + } + if (tclass.equals(float.class)) { + return Float.valueOf(o.toString()); + } + if (tclass.equals(double.class)) { + return Double.valueOf(o.toString()); + } + Object tobj = o; + if (null != o && !tclass.isAssignableFrom(o.getClass())) { + String ostring = o.toString(); + Method valueOf = null; + + try { + valueOf = tclass.getMethod("valueOf", String.class); + } catch (NoSuchMethodException ex) { +// Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); + } catch (SecurityException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + if (null != valueOf) { + tobj = valueOf.invoke(null, new Object[]{ostring}); + } else { + Constructor constructor = null; + + try { + constructor = tclass.getConstructor(String.class); + } catch (NoSuchMethodException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (SecurityException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + tobj = constructor.newInstance(ostring); + } + } + return tobj; + } + + private void setObjectForName(String type, String name, Object o) { + try { + if (type.startsWith("java.util.List")) { + return; + } + if (name.endsWith(")")) { + return; + } + Object orig_obj = this.getObject(name); + if (null != orig_obj && orig_obj.equals(o)) { + return; + } + if (null == orig_obj && null == o) { + return; + } + Class tclass = this.stringToClass(type); + Object tobj = this.convertToType(tclass, name, o); + Object pobj = this.getParentObject(name); + if (pobj instanceof List) { + return; + } + String endname = name; + int pindex = name.lastIndexOf("."); + if (pindex > 0) { + endname = endname.substring(pindex + 1); + } + Method mset = null; + try { + mset = pobj.getClass().getMethod("set" + endname, tclass); + + } catch (NoSuchMethodException ex) { +// System.err.println("endname =" + endname); +// Logger.getLogger(ObjTableJPanel.class +// .getName()).log(Level.SEVERE, null, ex); + } + if (mset == null) { + System.err.println("Method to set " + name + " does not exist"); + return; + } + mset.invoke(pobj, new Object[]{tobj}); +// System.out.println("pobj = " + pobj); +// System.out.println("tobj = " + tobj); + + } catch (SecurityException ex) { + System.err.println("Error in setObjectForName(" + type + "," + name + ", " + o + ")"); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + System.err.println("Error in setObjectForName(" + type + "," + name + ", " + o + ")"); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + System.err.println("Error in setObjectForName(" + type + "," + name + ", " + o + ")"); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InvocationTargetException ex) { + System.err.println("Error in setObjectForName(" + type + "," + name + ", " + o + ")"); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (ClassNotFoundException ex) { + System.err.println("Error in setObjectForName(" + type + "," + name + ", " + o + ")"); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + System.err.println("Error in setObjectForName(" + type + "," + name + ", " + o + ")"); + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + + private void addObjectToList(String type, String name, Object o) { + try { + Class tclass = this.stringToClass(type); + Object tobj = this.convertToType(tclass, name, o); + Object pobj = this.getParentObject(name); + String endname = name; + int pindex = name.lastIndexOf("."); + if (pindex > 0) { + endname = endname.substring(pindex + 1); + } + List l = (List) getObject(pobj, endname); + l.add(tobj); + } catch (SecurityException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InvocationTargetException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (ClassNotFoundException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + + private void removeObjectFromList(String name) { + try { + List l = (List) this.getParentObject(name); + int index1 = name.lastIndexOf(".get("); + int index2 = name.lastIndexOf(")"); + String indexString = name.substring(index1 + 5, index2); + int index = Integer.valueOf(indexString); + l.remove(index); + } catch (SecurityException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalArgumentException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InvocationTargetException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + + private void deleteTableItem() { + try { + int row = jTable1.getSelectedRow(); + DefaultTableModel tm = (DefaultTableModel) jTable1.getModel(); + if (row < 0 || row > tm.getRowCount()) { + jButtonNew.setEnabled(false); + jButtonDelete.setEnabled(false); + return; + } + String type = (String) tm.getValueAt(row, 0); + String name = (String) tm.getValueAt(row, 1); + this.updateTableFromObject(); +// clss.getClassLoader(). + + } catch (Exception ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + + private void setNewTableItem() { + try { + int row = jTable1.getSelectedRow(); + DefaultTableModel tm = (DefaultTableModel) jTable1.getModel(); + if (row < 0 || row > tm.getRowCount()) { + jButtonNew.setEnabled(false); + return; + } + String type = (String) tm.getValueAt(row, 0); + String name = (String) tm.getValueAt(row, 1); + Class clss = this.stringToClass(type); + if (null == classes) { + classes = getClasses(); + } + List availClasses = getAssignableClasses(clss, classes); + Class ca[] = availClasses.toArray(new Class[availClasses.size()]); + int selected = JOptionPane.showOptionDialog(this.dialog, + "Select class of new " + clss.getCanonicalName(), + name + " = new " + clss.getCanonicalName(), + JOptionPane.DEFAULT_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + ca, + null); +// System.out.println("ca[selected] = " + ca[selected]); + this.updateObjFromTable(); + Object newo = null; +// if(javax.xml.datatype.XMLGregorianCalendar.class.isAssignableFrom(ca[selected])) { +// try { +// newo = javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar(); +// } catch (DatatypeConfigurationException ex) { +// Logger.getLogger(ObjTableJPanel.class.getName()).log(Level.SEVERE, null, ex); +// } +// } else { + newo = ca[selected].newInstance(); +// } + this.setObjectForName(type, name, newo); + this.updateTableFromObject(); +// clss.getClassLoader(). + + } catch (ClassNotFoundException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + + private void jButtonNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonNewActionPerformed + this.setNewTableItem(); + }//GEN-LAST:event_jButtonNewActionPerformed + + private void jButtonAddToListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddToListActionPerformed + try { + int row = jTable1.getSelectedRow(); + DefaultTableModel tm = (DefaultTableModel) jTable1.getModel(); + if (row < 0 || row > tm.getRowCount()) { + jButtonNew.setEnabled(false); + return; + } + String type = (String) tm.getValueAt(row, 0); + String name = (String) tm.getValueAt(row, 1); + String typeparams = getTypeParams(type); + Class clss = Class.forName(typeparams); + if (null == classes) { + classes = getClasses(); + } + List availClasses = getAssignableClasses(clss, classes); + Class ca[] = availClasses.toArray(new Class[availClasses.size()]); + int selected = JOptionPane.showOptionDialog(this.dialog, + "Select class of new " + clss.getCanonicalName(), + name + " = new " + clss.getCanonicalName(), + JOptionPane.DEFAULT_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + ca, + null); +// System.out.println("ca[selected] = " + ca[selected]); + Object newo = ca[selected].newInstance(); + this.updateObjFromTable(); + this.addObjectToList(typeparams, name, newo); + this.updateTableFromObject(); +// clss.getClassLoader(). + + } catch (ClassNotFoundException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jButtonAddToListActionPerformed + + private void jButtonRemoveFromListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRemoveFromListActionPerformed + try { + int row = jTable1.getSelectedRow(); + DefaultTableModel tm = (DefaultTableModel) jTable1.getModel(); + if (row < 0 || row > tm.getRowCount()) { + jButtonNew.setEnabled(false); + return; + } + String name = (String) tm.getValueAt(row, 1); + this.updateObjFromTable(); + this.removeObjectFromList(name); + this.updateTableFromObject(); +// clss.getClassLoader(). + + } catch (Exception ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jButtonRemoveFromListActionPerformed + + private void jButtonDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeleteActionPerformed + this.deleteTableItem(); + }//GEN-LAST:event_jButtonDeleteActionPerformed + + private void jButtonEditMultiLineTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEditMultiLineTextActionPerformed + + int row = this.jTable1.getSelectedRow(); + if (row < 0 || row >= this.jTable1.getRowCount()) { + this.jButtonEditMultiLineText.setEnabled(false); + return; + } + String type = this.jTable1.getValueAt(row, 0).toString(); + String name = this.jTable1.getValueAt(row, 1).toString(); + Object oIn = this.jTable1.getValueAt(row, 2); + String textIn = oIn == null ? "" : oIn.toString(); + String out = MultiLineStringJPanel.editText(textIn, null, name + ":" + type, true); + if (null != out) { + this.setObjectForName(type, name, out); + this.updateTableFromObject(); + } + }//GEN-LAST:event_jButtonEditMultiLineTextActionPerformed + + public static List getAssignableClasses(Class baseClss, List classes) { + List assignableClasses = new ArrayList<>(); + for (Class clss : classes) { + if (baseClss.isAssignableFrom(clss)) { + assignableClasses.add(clss); + } + } + return assignableClasses; + } + + public static void main(String[] args) { + try { + classes = getClasses(); + System.out.println("classes = " + classes); + List cmdClasses = getAssignableClasses(CRCLCommandType.class, classes); + System.out.println( + "cmdClasses = " + cmdClasses); + CRCLStatusType o = ObjTableJPanel.editObject(new CRCLStatusType(), null, null); + CRCLSocket s = new CRCLSocket(null); + String xmls = s.statusToString(o, false); + System.out.println( + "xmls = " + xmls); + System.exit( + 0); + } catch (JAXBException ex) { + Logger.getLogger(ObjTableJPanel.class + .getName()).log(Level.SEVERE, null, ex); + } + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonAddToList; + private javax.swing.JButton jButtonCancel; + private javax.swing.JButton jButtonDelete; + private javax.swing.JButton jButtonEditMultiLineText; + private javax.swing.JButton jButtonNew; + private javax.swing.JButton jButtonOK; + private javax.swing.JButton jButtonRemoveFromList; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JScrollPane jScrollPaneDocumentation; + private javax.swing.JTable jTable1; + private javax.swing.JTextPane jTextPane1; + // End of variables declaration//GEN-END:variables +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java b/crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java new file mode 100644 index 0000000..6113c4d --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java @@ -0,0 +1,236 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Arc2D; +import java.awt.geom.Rectangle2D; +import javax.swing.JPanel; + +/** + * + * @author Will Shackleford {@literal } + */ +public class OverHeadJPanel extends JPanel { + + private SimRobotEnum robotType = SimRobotEnum.SIMPLE; + + /** + * Get the value of robotType + * + * @return the value of robotType + */ + public SimRobotEnum getRobotType() { + return robotType; + } + + /** + * Set the value of robotType + * + * @param robotType new value of robotType + */ + public void setRobotType(SimRobotEnum robotType) { + this.robotType = robotType; + this.repaint(); + } + + private double[] jointvals; + + /** + * Get the value of jointvals + * + * @return the value of jointvals + */ + public double[] getJointvals() { + return jointvals; + } + + /** + * Set the value of jointvals + * + * @param jointvals new value of jointvals + */ + public void setJointvals(double[] jointvals) { + this.jointvals = jointvals; + } + + private double[] seglengths = SimulatedKinematicsPlausible.DEFAULT_SEGLENGTHS; + + /** + * Set the value of seglengths + * + * @param seglengths new value of seglengths + */ + public void setSeglengths(double[] seglengths) { + this.seglengths = seglengths; + if(null == seglengths || seglengths.length < 1) { + return; + } + l0rect.width = seglengths[0]; + if(seglengths.length < 2) { + return; + } + l1rect.width = seglengths[1]; + if(seglengths.length < 3) { + return; + } + l2rect.width = seglengths[2]; + if(seglengths.length < 4) { + return; + } + l3rect.width = seglengths[3]; + if(seglengths.length < 5) { + return; + } + l4rect.height = seglengths[4]; + if(seglengths.length < 6) { + return; + } + l5rect.width = seglengths[5]; + } + + Arc2D.Double j1circle = new Arc2D.Double(-10.0, -10.0 // x,y + , 20, 20 // w,h + , 0, 360, Arc2D.CHORD); + + Arc2D.Double j2circle = new Arc2D.Double(-6, -6.0 // x,y + , 12, 12 // w,h + , 0, 360, Arc2D.CHORD); + + Rectangle2D.Double jrect = new Rectangle2D.Double(0.0, -5.0, 10.0, 10.0); + + Rectangle2D.Double l0rect = new Rectangle2D.Double(0.0, -5.0, seglengths[0], 10.0); + Rectangle2D.Double l1rect = new Rectangle2D.Double(0.0, -5.0, seglengths[1], 10.0); + Rectangle2D.Double l2rect = new Rectangle2D.Double(0.0, -5.0, seglengths[2], 10.0); + Rectangle2D.Double l3rect = new Rectangle2D.Double(0.0, -5.0, seglengths[3], 10.0); + Rectangle2D.Double l4rect = new Rectangle2D.Double(0.0, -10.0, 5.0, seglengths[4]); + Rectangle2D.Double l5rect = new Rectangle2D.Double(0.0, -0.5, seglengths[5], 1.0); + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + try { + Graphics2D g2d = (Graphics2D) g; + Dimension d = this.getSize(); + g2d.translate(d.width / 2.0, d.height / 2.0); + switch (robotType) { + case PLAUSIBLE: + if (paintPlausibleRobot(d, g2d)) { + return; + } + break; + + case SIMPLE: + if (paintSimpleRobot(d, g2d)) { + return; + } + break; + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private double maxSimpleJv0 = 0; + + private boolean paintSimpleRobot(Dimension d, Graphics2D g2d) { + if(null == jointvals || jointvals.length < SimulatedKinematicsSimple.NUM_JOINTS) { + return true; + } + maxSimpleJv0 = Math.max(maxSimpleJv0, jointvals[0]); + double sfactor = Math.min(d.width / 2.0, d.height / 2.0) / (Math.abs(maxSimpleJv0) + SimulatedKinematicsSimple.DEFAULT_SEGLENGTHS[0]); + g2d.scale(sfactor, -1.0 * sfactor); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + l0rect.width = Math.cos(Math.toRadians(jointvals[2])) * jointvals[0]; + g2d.rotate(Math.toRadians(jointvals[1])); + g2d.setColor(Color.yellow); + g2d.fill(l0rect); + g2d.translate(l0rect.width, 0.0); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + l1rect.width = Math.cos(Math.toRadians(jointvals[4])) * SimulatedKinematicsSimple.DEFAULT_SEGLENGTHS[0]; + g2d.rotate(Math.toRadians(jointvals[5] - jointvals[2])); + g2d.setColor(Color.yellow); + g2d.fill(l1rect); + return false; + } + + private boolean paintPlausibleRobot(Dimension d, Graphics2D g2d) { + double sfactor = Math.min(d.width / 2.0, d.height / 2.0) / (seglengths[0] + seglengths[1] + seglengths[2] + seglengths[3]); + g2d.scale(sfactor, -1.0 * sfactor); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + if (null == jointvals) { + return true; + } + g2d.rotate(Math.toRadians(jointvals[0])); + g2d.setColor(Color.yellow); + double angle = jointvals[1]; + l0rect.width = seglengths[0] * Math.cos(Math.toRadians(angle)); + g2d.fill(l0rect); + g2d.translate(l0rect.width, 0.0); + g2d.setColor(Color.yellow); + angle += jointvals[2]; + l1rect.width = seglengths[1] * Math.cos(Math.toRadians(angle)); + if (l1rect.width <= 0) { + return true; + } + g2d.fill(l1rect); + g2d.setColor(Color.gray); + g2d.fill(jrect); + g2d.translate(l1rect.width, 0.0); + angle += jointvals[3]; + l2rect.width = seglengths[2] * Math.cos(Math.toRadians(angle)); + if (l2rect.width <= 0) { + return true; + } + g2d.setColor(Color.yellow); + g2d.fill(l2rect); + g2d.setColor(Color.gray); + g2d.fill(jrect); + g2d.translate(l2rect.width, 0.0); + l3rect.width = seglengths[3] * Math.cos(Math.toRadians(angle)); + if (l3rect.width <= 0) { + return true; + } + g2d.rotate(Math.toRadians(jointvals[4])); + g2d.setColor(Color.yellow); + g2d.fill(l3rect); + g2d.setColor(Color.gray); + g2d.fill(j2circle); + g2d.translate(l3rect.width, 0.0); + g2d.setColor(Color.BLACK); + l4rect.height = seglengths[3] * Math.abs(Math.sin(Math.toRadians(jointvals[5]))); + l4rect.y = -0.5 * l5rect.height; + g2d.fill(l4rect); + g2d.translate(0.0, l5rect.height / 2.0); + g2d.fill(l5rect); + g2d.translate(0.0, -l5rect.height); + g2d.fill(l5rect); + return false; + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClient.form b/crcl4java-utils/src/main/java/crcl/utils/PendantClient.form new file mode 100644 index 0000000..d18315c --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClient.form @@ -0,0 +1,1332 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClient.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClient.java new file mode 100644 index 0000000..234382d --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClient.java @@ -0,0 +1,2841 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.ActuateJointType; +import crcl.base.ActuateJointsType; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLProgramType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStateEnumType; +import crcl.base.CommandStatusType; +import crcl.base.EndCanonType; +import crcl.base.InitCanonType; +import crcl.base.JointSpeedAccelType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.MiddleCommandType; +import crcl.base.MoveToType; +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.PoseType; +import crcl.base.VectorType; +import static crcl.utils.ObjTableJPanel.getAssignableClasses; +import diagapplet.plotter.PlotData; +import diagapplet.plotter.plotterJFrame; +import java.awt.Color; +import java.awt.Desktop; +import java.awt.GraphicsConfiguration; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JTable; +import javax.swing.JViewport; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.table.DefaultTableModel; +import javax.xml.bind.JAXBException; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathExpressionException; +import org.xml.sax.SAXException; +import rcs.posemath.PmException; +import rcs.posemath.PmRotationMatrix; +import rcs.posemath.PmRotationVector; +import rcs.posemath.PmRpy; +import rcs.posemath.Posemath; + + + +/** + * + * @author Will Shackleford{@literal } + */ +public class PendantClient extends javax.swing.JFrame implements PendantClientOuter { + + public PendantClient(GraphicsConfiguration gc) throws ParserConfigurationException { + super(gc); + this.internal = new PendantClientInner(this); + init(); + } + + public PendantClient(String title) throws ParserConfigurationException { + super(title); + this.internal = new PendantClientInner(this); + init(); + setTitle(title); + } + + /** + * Creates new form PendantClient + * @throws javax.xml.parsers.ParserConfigurationException when javax.xml.parsers.DocumentBuilderFactory fails in XpathUtils + */ + public PendantClient() throws ParserConfigurationException { + super(); + this.internal = new PendantClientInner(this); + init(); + } + + private void init() { + initComponents(); + addCommandsMenu(); + + String portPropertyString = System.getProperty("crcljava.port"); + if(null != portPropertyString) { + this.jTextFieldPort.setText(portPropertyString); + } + String hostPropertyString = System.getProperty("crcljava.host"); + if(null != hostPropertyString) { + this.jTextFieldHost.setText(hostPropertyString); + } + internal.setStatSchema(CRCLSocket.readStatSchemaFiles(PendantClient.statSchemasFile)); + internal.setCmdSchema(CRCLSocket.readCmdSchemaFiles(PendantClient.cmdSchemasFile)); + internal.setProgramSchema(CRCLSocket.readProgramSchemaFiles(PendantClient.programSchemasFile)); + readRecentCommandFiles(); + readRecentPrograms(); + this.jTextFieldJointJogIncrement.setText(Double.toString(internal.getJogIncrement())); + final String programPropertyString = System.getProperty("crcljava.program"); + if(null != programPropertyString) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + try { + openXmlProgramFile(new File(programPropertyString)); + } catch (ParserConfigurationException | JAXBException | XPathExpressionException | IOException | SAXException ex) { + showMessage(ex); + LOGGER.log(Level.SEVERE, null, ex); + } + } + }); + } + } + + private void readRecentCommandFiles() { + File fMainDir = new File(System.getProperty("user.home"), recent_files_dir); + if (!fMainDir.exists()) { + return; + } + File fa[] = fMainDir.listFiles(new java.io.FileFilter() { + + @Override + public boolean accept(File pathname) { + return pathname.isDirectory() && pathname.canRead(); + } + }); + if (null == fa || fa.length < 1) { + return; + } + Arrays.sort(fa, new Comparator() { + + @Override + public int compare(File o1, File o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + for (File fSubDir : fa) { + JMenu jm = new JMenu(fSubDir.getName()); + this.jMenuCommandRecent.add(jm); + File sub_fa[] = fSubDir.listFiles(new java.io.FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".xml"); + } + }); + Arrays.sort(sub_fa, new Comparator() { + + @Override + public int compare(File o1, File o2) { + return Long.compare(o1.lastModified(), o2.lastModified()); + } + }); + for (int i = 0; i < sub_fa.length && i < 3; i++) { + File xmlFile = sub_fa[i]; + JMenuItem jmi = new JMenuItem(xmlFile.getName()); + jmi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + try { + openXmlInstanceFile(xmlFile); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (XPathExpressionException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } + } + }); + jm.add(jmi); + } + } + + } + public static final Logger LOGGER = Logger.getLogger(PendantClient.class.getName()); + + public void openXmlProgramFile(File f) throws ParserConfigurationException, JAXBException, XPathExpressionException, IOException, SAXException { + internal.openXmlProgramFile(f); + } + + public void saveXmlProgramFile(File f) throws ParserConfigurationException, JAXBException, XPathExpressionException, IOException, SAXException { + internal.saveXmlProgramFile(f); + } + + @Override + public boolean isRecordPoseSelected() { + return this.jCheckBoxMenuItemRecordPoseList.isSelected(); + } + + + @Override + public void finishOpenXmlProgramFile(File f, CRCLProgramType program) { + try { + showProgram(program); + internal.setProgram(program); + this.saveRecentProgram(f); + this.jTabbedPane1.setSelectedComponent(this.jPanelProgram); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + private String getFirstLine(File f) throws IOException { + try (BufferedReader br = new BufferedReader(new FileReader(f))) { + return br.readLine(); + } + } + + private Set getRecentPrograms() { + File fMainDir = new File(System.getProperty("user.home"), recent_programs_dir); + Set pathSet = new TreeSet(); + if (!fMainDir.exists()) { + return pathSet; + } + File fa[] = fMainDir.listFiles(new java.io.FileFilter() { + + @Override + public boolean accept(File pathname) { + return !pathname.isDirectory() && pathname.canRead(); + } + }); + if (null == fa || fa.length < 1) { + return pathSet; + } + Arrays.sort(fa, new Comparator() { + + @Override + public int compare(File o1, File o2) { + return o1.getName().compareTo(o2.getName()); + } + }); + this.jMenuRecentProgram.removeAll(); + for (File f : fa) { + try { + String path = getFirstLine(f).trim(); + File fprog = new File(path); + if (!fprog.exists() || !fprog.canRead() || fprog.isDirectory()) { + f.delete(); + continue; + } + final String fprogCanon = fprog.getCanonicalPath(); + if (pathSet.contains(fprogCanon)) { + continue; + } + pathSet.add(fprogCanon); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + return pathSet; + } + + private void readRecentPrograms() { + Set pathSet = this.getRecentPrograms(); + for (final String fprogCanon : pathSet) { + try { + JMenuItem jmi = new JMenuItem(fprogCanon); + jmi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + try { + openXmlProgramFile(new File(fprogCanon)); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + }); + this.jMenuRecentProgram.add(jmi); + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + + private void addCommandsMenu() { + try { + List allClasses = ObjTableJPanel.getClasses(); + List cmdClasses = ObjTableJPanel.getAssignableClasses(CRCLCommandType.class, + allClasses); + Collections.sort(cmdClasses, new Comparator() { + + @Override + public int compare(Class o1, Class o2) { + return o1.getCanonicalName().compareTo(o2.getCanonicalName()); + } + }); + for (final Class c : cmdClasses) { + JMenuItem jmi = new JMenuItem(c.getCanonicalName()); + jmi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + try { + CRCLCommandType cmd = (CRCLCommandType) c.newInstance(); + cmd + = (CRCLCommandType) ObjTableJPanel.editObject(cmd, + internal.getXpu(), PendantClient.this.internal.getCheckCommandValidPredicate()); + internal.incAndSendCommand(cmd); + saveRecentCommand(cmd); + } catch (InstantiationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + }); + this.jMenuCmds.add(jmi); + } + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, null, e); + } + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + jLabel3 = new javax.swing.JLabel(); + jTextFieldStatCmdID = new javax.swing.JTextField(); + jScrollPane2 = new javax.swing.JScrollPane(); + jTableJoints = new javax.swing.JTable(); + jLabel6 = new javax.swing.JLabel(); + jTextFieldStatus = new javax.swing.JTextField(); + jScrollPane3 = new javax.swing.JScrollPane(); + jTablePose = new javax.swing.JTable(); + jTextFieldStatusID = new javax.swing.JTextField(); + jLabel10 = new javax.swing.JLabel(); + jPanel3 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextAreaErrors = new javax.swing.JTextArea(); + jPanel5 = new javax.swing.JPanel(); + jTextFieldPort = new javax.swing.JTextField(); + jButtonConnect = new javax.swing.JButton(); + jButtonDisconnect = new javax.swing.JButton(); + jButtonEnd = new javax.swing.JButton(); + jButtonInit = new javax.swing.JButton(); + jLabel1 = new javax.swing.JLabel(); + jTextFieldHost = new javax.swing.JTextField(); + jLabel2 = new javax.swing.JLabel(); + jCheckBoxPoll = new javax.swing.JCheckBox(); + jTextFieldPollTime = new javax.swing.JTextField(); + jLabel4 = new javax.swing.JLabel(); + jPanel6 = new javax.swing.JPanel(); + jTabbedPane1 = new javax.swing.JTabbedPane(); + jPanelJogging = new javax.swing.JPanel(); + jComboBox1 = new javax.swing.JComboBox(); + jPanelJogMinus = new javax.swing.JPanel(); + jLabelJogMinus = new javax.swing.JLabel(); + jPanelJogPlus = new javax.swing.JPanel(); + jLabelJogPlus = new javax.swing.JLabel(); + jComboBoxXYZRPY = new javax.swing.JComboBox(); + jPanelJogPlus1 = new javax.swing.JPanel(); + jLabelJogPlus1 = new javax.swing.JLabel(); + jPanelJogMinus1 = new javax.swing.JPanel(); + jLabelJogMinus1 = new javax.swing.JLabel(); + jLabel5 = new javax.swing.JLabel(); + jLabel7 = new javax.swing.JLabel(); + jLabel8 = new javax.swing.JLabel(); + jTextFieldJointJogIncrement = new javax.swing.JTextField(); + jTextFieldXYZJogIncrement = new javax.swing.JTextField(); + jTextFieldRPYJogIncrement = new javax.swing.JTextField(); + jLabel9 = new javax.swing.JLabel(); + jTextFieldJogTime = new javax.swing.JTextField(); + jPanelMoveTo = new javax.swing.JPanel(); + jButtonMoveTo = new javax.swing.JButton(); + jScrollPane4 = new javax.swing.JScrollPane(); + jTableMoveToPose = new javax.swing.JTable(); + jCheckBoxStraight = new javax.swing.JCheckBox(); + jButtonMoveToCurrent = new javax.swing.JButton(); + jPanelProgram = new javax.swing.JPanel(); + jScrollPaneProgram = new javax.swing.JScrollPane(); + jTableProgram = new javax.swing.JTable(); + jButtonProgramPause = new javax.swing.JButton(); + jButtonProgramAbort = new javax.swing.JButton(); + jButtonEditProgramItem = new javax.swing.JButton(); + jButtonDeletProgramItem = new javax.swing.JButton(); + jButtonAddProgramItem = new javax.swing.JButton(); + jButtonProgramRun = new javax.swing.JButton(); + jButtonResume = new javax.swing.JButton(); + jButtonPlotProgramItem = new javax.swing.JButton(); + jMenuBarReplaceCommandState = new javax.swing.JMenuBar(); + jMenu1 = new javax.swing.JMenu(); + jMenuItemOpenXmlCommandInstance = new javax.swing.JMenuItem(); + jMenuCommandRecent = new javax.swing.JMenu(); + jMenuItemOpenXmlProgram = new javax.swing.JMenuItem(); + jMenuRecentProgram = new javax.swing.JMenu(); + jMenuItemSaveProgramAs = new javax.swing.JMenuItem(); + jMenuItemSavePoseList = new javax.swing.JMenuItem(); + jMenuItemExit = new javax.swing.JMenuItem(); + jMenu2 = new javax.swing.JMenu(); + jMenuTools = new javax.swing.JMenu(); + jMenuItemXPathQuery = new javax.swing.JMenuItem(); + jCheckBoxMenuItemPlotXYZ = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemJoints = new javax.swing.JCheckBoxMenuItem(); + jMenuItemRunTest = new javax.swing.JMenuItem(); + jCheckBoxMenuItemRecordPoseList = new javax.swing.JCheckBoxMenuItem(); + jMenuItemPoseList3DPlot = new javax.swing.JMenuItem(); + jMenuItemOpenStatusLog = new javax.swing.JMenuItem(); + jMenuCmds = new javax.swing.JMenu(); + jMenuXmlSchemas = new javax.swing.JMenu(); + jMenuItemSetSchemaFiles = new javax.swing.JMenuItem(); + jCheckBoxMenuItemValidateXml = new javax.swing.JCheckBoxMenuItem(); + jMenuOptions = new javax.swing.JMenu(); + jCheckBoxMenuItemReplaceState = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemDebugWaitForDone = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemDebugSendCommand = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemDebugReadStatus = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemUseEXI = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemUseReadStatusThread = new javax.swing.JCheckBoxMenuItem(); + + FormListener formListener = new FormListener(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("CRCL Pendant Client"); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Status")); + + jLabel3.setText("Command ID:"); + + jTextFieldStatCmdID.setEditable(false); + jTextFieldStatCmdID.setText("0"); + + jTableJoints.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + { new Integer(1), null, null, null}, + { new Integer(2), null, null, null}, + { new Integer(3), null, null, null}, + { new Integer(4), null, null, null}, + { new Integer(5), null, null, null}, + { new Integer(6), null, null, null} + }, + new String [] { + "Joint", "Position", "Velocity", "TorqueOrForce" + } + ) { + Class[] types = new Class [] { + java.lang.Integer.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class + }; + boolean[] canEdit = new boolean [] { + false, false, false, false + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jScrollPane2.setViewportView(jTableJoints); + + jLabel6.setText("Status : "); + + jTablePose.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {"X", null}, + {"Y", null}, + {"Z", null}, + {"XI", null}, + {"XJ", null}, + {"XK", null}, + {"ZI", null}, + {"ZJ", null}, + {"Zk", null}, + {"Roll", null}, + {"Pitch", null}, + {"Yaw", null} + }, + new String [] { + "Pose Axis", "Position" + } + ) { + Class[] types = new Class [] { + java.lang.String.class, java.lang.Double.class + }; + boolean[] canEdit = new boolean [] { + false, false + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jScrollPane3.setViewportView(jTablePose); + + jTextFieldStatusID.setText("0"); + + jLabel10.setText("Status ID:"); + + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); + jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 276, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel3) + .addComponent(jLabel6) + .addComponent(jLabel10)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jTextFieldStatCmdID, javax.swing.GroupLayout.DEFAULT_SIZE, 165, Short.MAX_VALUE) + .addComponent(jTextFieldStatus) + .addComponent(jTextFieldStatusID)))) + .addGap(0, 9, Short.MAX_VALUE)))) + ); + jPanel1Layout.setVerticalGroup( + jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(jTextFieldStatCmdID, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel6) + .addComponent(jTextFieldStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldStatusID, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10)) + .addGap(18, 18, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Errors")); + + jTextAreaErrors.setColumns(20); + jTextAreaErrors.setLineWrap(true); + jTextAreaErrors.setRows(5); + jScrollPane1.setViewportView(jTextAreaErrors); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 121, Short.MAX_VALUE) + ); + + jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createTitledBorder("Connection"))); + + jTextFieldPort.setText("64444"); + + jButtonConnect.setText("Connect"); + jButtonConnect.addActionListener(formListener); + + jButtonDisconnect.setText("Disconnect "); + jButtonDisconnect.setEnabled(false); + jButtonDisconnect.addActionListener(formListener); + + jButtonEnd.setText("End"); + jButtonEnd.setEnabled(false); + jButtonEnd.addActionListener(formListener); + + jButtonInit.setText("Init"); + jButtonInit.setEnabled(false); + jButtonInit.addActionListener(formListener); + + jLabel1.setText("Host: "); + + jTextFieldHost.setText("localhost"); + + jLabel2.setText("Port:"); + + jCheckBoxPoll.setSelected(true); + jCheckBoxPoll.setText("Poll"); + jCheckBoxPoll.addActionListener(formListener); + + jTextFieldPollTime.setText("200"); + jTextFieldPollTime.addActionListener(formListener); + + jLabel4.setText("Poll interval(ms):"); + + javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); + jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addComponent(jButtonInit) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonEnd)) + .addGroup(jPanel5Layout.createSequentialGroup() + .addComponent(jButtonConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonDisconnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxPoll)) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel4) + .addComponent(jLabel1)) + .addGap(18, 18, 18) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jTextFieldHost, javax.swing.GroupLayout.DEFAULT_SIZE, 187, Short.MAX_VALUE) + .addComponent(jTextFieldPort) + .addComponent(jTextFieldPollTime)))) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanel5Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jButtonConnect, jButtonDisconnect}); + + jPanel5Layout.setVerticalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jTextFieldHost, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel2) + .addComponent(jTextFieldPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldPollTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel4)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 40, Short.MAX_VALUE) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonConnect) + .addComponent(jButtonDisconnect) + .addComponent(jCheckBoxPoll)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonInit) + .addComponent(jButtonEnd)) + .addContainerGap()) + ); + + jPanel6.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + + jTabbedPane1.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED)); + jTabbedPane1.setName(""); // NOI18N + + jPanelJogging.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + jPanelJogging.setName("Jogging"); // NOI18N + + jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Joint 1", "Joint 2", "Joint 3", "Joint 4", "Joint 5", "Joint 6" })); + + jPanelJogMinus.setBackground(new java.awt.Color(255, 255, 255)); + jPanelJogMinus.setBorder(new javax.swing.border.MatteBorder(null)); + jPanelJogMinus.addMouseListener(formListener); + + jLabelJogMinus.setBackground(new java.awt.Color(255, 255, 255)); + jLabelJogMinus.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jLabelJogMinus.setText("Jog -"); + jLabelJogMinus.addMouseListener(formListener); + + javax.swing.GroupLayout jPanelJogMinusLayout = new javax.swing.GroupLayout(jPanelJogMinus); + jPanelJogMinus.setLayout(jPanelJogMinusLayout); + jPanelJogMinusLayout.setHorizontalGroup( + jPanelJogMinusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogMinusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogMinus) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanelJogMinusLayout.setVerticalGroup( + jPanelJogMinusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogMinusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogMinus, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanelJogPlus.setBackground(new java.awt.Color(255, 255, 255)); + jPanelJogPlus.setBorder(new javax.swing.border.MatteBorder(null)); + + jLabelJogPlus.setBackground(new java.awt.Color(255, 255, 255)); + jLabelJogPlus.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jLabelJogPlus.setText("Jog +"); + jLabelJogPlus.addMouseListener(formListener); + + javax.swing.GroupLayout jPanelJogPlusLayout = new javax.swing.GroupLayout(jPanelJogPlus); + jPanelJogPlus.setLayout(jPanelJogPlusLayout); + jPanelJogPlusLayout.setHorizontalGroup( + jPanelJogPlusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogPlusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogPlus) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanelJogPlusLayout.setVerticalGroup( + jPanelJogPlusLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogPlusLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogPlus, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jComboBoxXYZRPY.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "X", "Y", "Z", "Roll", "Pitch", "Yaw", " " })); + + jPanelJogPlus1.setBackground(new java.awt.Color(255, 255, 255)); + jPanelJogPlus1.setBorder(new javax.swing.border.MatteBorder(null)); + + jLabelJogPlus1.setBackground(new java.awt.Color(255, 255, 255)); + jLabelJogPlus1.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jLabelJogPlus1.setText("Jog +"); + jLabelJogPlus1.addMouseListener(formListener); + + javax.swing.GroupLayout jPanelJogPlus1Layout = new javax.swing.GroupLayout(jPanelJogPlus1); + jPanelJogPlus1.setLayout(jPanelJogPlus1Layout); + jPanelJogPlus1Layout.setHorizontalGroup( + jPanelJogPlus1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogPlus1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogPlus1) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanelJogPlus1Layout.setVerticalGroup( + jPanelJogPlus1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogPlus1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogPlus1, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanelJogMinus1.setBackground(new java.awt.Color(255, 255, 255)); + jPanelJogMinus1.setBorder(new javax.swing.border.MatteBorder(null)); + jPanelJogMinus1.addMouseListener(formListener); + + jLabelJogMinus1.setBackground(new java.awt.Color(255, 255, 255)); + jLabelJogMinus1.setFont(new java.awt.Font("Cantarell", 0, 18)); // NOI18N + jLabelJogMinus1.setText("Jog -"); + jLabelJogMinus1.addMouseListener(formListener); + + javax.swing.GroupLayout jPanelJogMinus1Layout = new javax.swing.GroupLayout(jPanelJogMinus1); + jPanelJogMinus1.setLayout(jPanelJogMinus1Layout); + jPanelJogMinus1Layout.setHorizontalGroup( + jPanelJogMinus1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogMinus1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogMinus1) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanelJogMinus1Layout.setVerticalGroup( + jPanelJogMinus1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJogMinus1Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabelJogMinus1, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jLabel5.setText("Joint Jog Increment: "); + + jLabel7.setText("XYZ Jog Increment:"); + + jLabel8.setText("RPY Jog Increment:"); + + jTextFieldJointJogIncrement.setText("3.0"); + jTextFieldJointJogIncrement.addActionListener(formListener); + + jTextFieldXYZJogIncrement.setText("3.0"); + jTextFieldXYZJogIncrement.addActionListener(formListener); + + jTextFieldRPYJogIncrement.setText("3.0"); + jTextFieldRPYJogIncrement.addActionListener(formListener); + + jLabel9.setText("Jog Time Period (ms) :"); + + jTextFieldJogTime.setText("200"); + jTextFieldJogTime.addActionListener(formListener); + + javax.swing.GroupLayout jPanelJoggingLayout = new javax.swing.GroupLayout(jPanelJogging); + jPanelJogging.setLayout(jPanelJoggingLayout); + jPanelJoggingLayout.setHorizontalGroup( + jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJoggingLayout.createSequentialGroup() + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJoggingLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel7) + .addComponent(jLabel9) + .addComponent(jLabel8)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldJogTime, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldRPYJogIncrement, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldXYZJogIncrement, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldJointJogIncrement, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanelJoggingLayout.createSequentialGroup() + .addGap(12, 12, 12) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJoggingLayout.createSequentialGroup() + .addComponent(jComboBoxXYZRPY, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanelJogMinus1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanelJogPlus1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanelJoggingLayout.createSequentialGroup() + .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanelJogMinus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanelJogPlus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))) + .addGap(0, 0, Short.MAX_VALUE)) + ); + + jPanelJoggingLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jTextFieldJogTime, jTextFieldJointJogIncrement, jTextFieldRPYJogIncrement, jTextFieldXYZJogIncrement}); + + jPanelJoggingLayout.setVerticalGroup( + jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelJoggingLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jPanelJogMinus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboBox1) + .addComponent(jPanelJogPlus, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jPanelJogMinus1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboBoxXYZRPY) + .addComponent(jPanelJogPlus1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(jTextFieldJointJogIncrement, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(6, 6, 6) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel7) + .addComponent(jTextFieldXYZJogIncrement, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(12, 12, 12) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldRPYJogIncrement, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelJoggingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9) + .addComponent(jTextFieldJogTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab("Jog", jPanelJogging); + + jPanelMoveTo.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1)); + jPanelMoveTo.setName("MoveTo"); // NOI18N + + jButtonMoveTo.setText("MoveTo"); + jButtonMoveTo.addActionListener(formListener); + + jTableMoveToPose.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {"X", null}, + {"Y", null}, + {"Z", null}, + {"XI", new Double(1.0)}, + {"XJ", new Double(0.0)}, + {"XK", new Double(0.0)}, + {"ZI", new Double(0.0)}, + {"ZJ", new Double(0.0)}, + {"ZJ", new Double(1.0)} + }, + new String [] { + "Pose Axis", "Position" + } + ) { + Class[] types = new Class [] { + java.lang.String.class, java.lang.Double.class + }; + boolean[] canEdit = new boolean [] { + false, true + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jScrollPane4.setViewportView(jTableMoveToPose); + + jCheckBoxStraight.setText("Straight"); + + jButtonMoveToCurrent.setText("Current"); + jButtonMoveToCurrent.addActionListener(formListener); + + javax.swing.GroupLayout jPanelMoveToLayout = new javax.swing.GroupLayout(jPanelMoveTo); + jPanelMoveTo.setLayout(jPanelMoveToLayout); + jPanelMoveToLayout.setHorizontalGroup( + jPanelMoveToLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelMoveToLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelMoveToLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelMoveToLayout.createSequentialGroup() + .addComponent(jButtonMoveTo) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxStraight) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonMoveToCurrent)) + .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 286, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanelMoveToLayout.setVerticalGroup( + jPanelMoveToLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelMoveToLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelMoveToLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonMoveTo) + .addComponent(jCheckBoxStraight) + .addComponent(jButtonMoveToCurrent)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 191, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jTabbedPane1.addTab("MoveTo", jPanelMoveTo); + + jTableProgram.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + { new Long(1), "InitCanonType", new Long(-1), new Double(0.0)}, + { new Long(2), "EndCanonType", new Long(-1), null} + }, + new String [] { + "ID", "Type", "Time To Execute(ms)", "Distance Moved" + } + ) { + Class[] types = new Class [] { + java.lang.Long.class, java.lang.String.class, java.lang.Long.class, java.lang.Double.class + }; + boolean[] canEdit = new boolean [] { + false, false, false, false + }; + + public Class getColumnClass(int columnIndex) { + return types [columnIndex]; + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + jTableProgram.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + jScrollPaneProgram.setViewportView(jTableProgram); + + jButtonProgramPause.setText("Pause"); + jButtonProgramPause.setEnabled(false); + jButtonProgramPause.addActionListener(formListener); + + jButtonProgramAbort.setText("Abort"); + jButtonProgramAbort.addActionListener(formListener); + + jButtonEditProgramItem.setText("Edit Item"); + jButtonEditProgramItem.addActionListener(formListener); + + jButtonDeletProgramItem.setText("Delete Item"); + jButtonDeletProgramItem.addActionListener(formListener); + + jButtonAddProgramItem.setText("Add Item"); + jButtonAddProgramItem.addActionListener(formListener); + + jButtonProgramRun.setText("Run From Start"); + jButtonProgramRun.addActionListener(formListener); + + jButtonResume.setText("Resume"); + jButtonResume.setEnabled(false); + jButtonResume.addActionListener(formListener); + + jButtonPlotProgramItem.setText("Plot"); + jButtonPlotProgramItem.addActionListener(formListener); + + javax.swing.GroupLayout jPanelProgramLayout = new javax.swing.GroupLayout(jPanelProgram); + jPanelProgram.setLayout(jPanelProgramLayout); + jPanelProgramLayout.setHorizontalGroup( + jPanelProgramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelProgramLayout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanelProgramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPaneProgram, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(jPanelProgramLayout.createSequentialGroup() + .addComponent(jButtonProgramPause) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonResume) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonProgramAbort) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonProgramRun)) + .addGroup(jPanelProgramLayout.createSequentialGroup() + .addComponent(jButtonEditProgramItem) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonDeletProgramItem) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonAddProgramItem) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonPlotProgramItem))) + .addContainerGap()) + ); + jPanelProgramLayout.setVerticalGroup( + jPanelProgramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanelProgramLayout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPaneProgram, javax.swing.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelProgramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonProgramPause) + .addComponent(jButtonProgramAbort) + .addComponent(jButtonProgramRun) + .addComponent(jButtonResume)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanelProgramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonEditProgramItem) + .addComponent(jButtonDeletProgramItem) + .addComponent(jButtonAddProgramItem) + .addComponent(jButtonPlotProgramItem)) + .addContainerGap()) + ); + + jTabbedPane1.addTab("Program", jPanelProgram); + + javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6); + jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel6Layout.createSequentialGroup() + .addComponent(jTabbedPane1) + .addGap(1, 1, 1)) + ); + jPanel6Layout.setVerticalGroup( + jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + ); + + jMenu1.setText("File"); + + jMenuItemOpenXmlCommandInstance.setText("Open CRCL XML Command Instance File ... "); + jMenuItemOpenXmlCommandInstance.addActionListener(formListener); + jMenu1.add(jMenuItemOpenXmlCommandInstance); + + jMenuCommandRecent.setText("Recent CRCL XML Command Instance Files"); + jMenu1.add(jMenuCommandRecent); + + jMenuItemOpenXmlProgram.setText("Open CRCL XML Program File ..."); + jMenuItemOpenXmlProgram.addActionListener(formListener); + jMenu1.add(jMenuItemOpenXmlProgram); + + jMenuRecentProgram.setText("Recent CRCL XML Program File ..."); + jMenu1.add(jMenuRecentProgram); + + jMenuItemSaveProgramAs.setText("Save Program As ..."); + jMenuItemSaveProgramAs.addActionListener(formListener); + jMenu1.add(jMenuItemSaveProgramAs); + + jMenuItemSavePoseList.setText("Save Pose List ..."); + jMenuItemSavePoseList.addActionListener(formListener); + jMenu1.add(jMenuItemSavePoseList); + + jMenuItemExit.setText("Exit"); + jMenuItemExit.addActionListener(formListener); + jMenu1.add(jMenuItemExit); + + jMenuBarReplaceCommandState.add(jMenu1); + + jMenu2.setText("Edit"); + jMenuBarReplaceCommandState.add(jMenu2); + + jMenuTools.setText(" Tools "); + + jMenuItemXPathQuery.setText("XPath Status Query ... "); + jMenuItemXPathQuery.addActionListener(formListener); + jMenuTools.add(jMenuItemXPathQuery); + + jCheckBoxMenuItemPlotXYZ.setText("2D Plot XYZ vs Time ..."); + jCheckBoxMenuItemPlotXYZ.addActionListener(formListener); + jMenuTools.add(jCheckBoxMenuItemPlotXYZ); + + jCheckBoxMenuItemJoints.setText("Plot Joints"); + jCheckBoxMenuItemJoints.addActionListener(formListener); + jMenuTools.add(jCheckBoxMenuItemJoints); + + jMenuItemRunTest.setText("Run Test"); + jMenuItemRunTest.addActionListener(formListener); + jMenuTools.add(jMenuItemRunTest); + + jCheckBoxMenuItemRecordPoseList.setSelected(true); + jCheckBoxMenuItemRecordPoseList.setText("Record Pose List"); + jMenuTools.add(jCheckBoxMenuItemRecordPoseList); + + jMenuItemPoseList3DPlot.setText("3D Pose List Plot ..."); + jMenuItemPoseList3DPlot.addActionListener(formListener); + jMenuTools.add(jMenuItemPoseList3DPlot); + + jMenuItemOpenStatusLog.setText("Open Status Log ..."); + jMenuItemOpenStatusLog.addActionListener(formListener); + jMenuTools.add(jMenuItemOpenStatusLog); + + jMenuBarReplaceCommandState.add(jMenuTools); + + jMenuCmds.setText("Commands"); + jMenuBarReplaceCommandState.add(jMenuCmds); + + jMenuXmlSchemas.setText("XML Schemas"); + + jMenuItemSetSchemaFiles.setText("Set XML Schema Files ... "); + jMenuItemSetSchemaFiles.addActionListener(formListener); + jMenuXmlSchemas.add(jMenuItemSetSchemaFiles); + + jCheckBoxMenuItemValidateXml.setSelected(true); + jCheckBoxMenuItemValidateXml.setText("Validate using Schemas"); + jMenuXmlSchemas.add(jCheckBoxMenuItemValidateXml); + + jMenuBarReplaceCommandState.add(jMenuXmlSchemas); + + jMenuOptions.setText("Options"); + + jCheckBoxMenuItemReplaceState.setText("Replace Ready,Done,.. with CRCL_Ready,CRCL_DONE ..."); + jMenuOptions.add(jCheckBoxMenuItemReplaceState); + + jCheckBoxMenuItemDebugWaitForDone.setText("Debug waitForDone()"); + jMenuOptions.add(jCheckBoxMenuItemDebugWaitForDone); + + jCheckBoxMenuItemDebugSendCommand.setText("Debug sendCommand()"); + jMenuOptions.add(jCheckBoxMenuItemDebugSendCommand); + + jCheckBoxMenuItemDebugReadStatus.setText("Debug readStatus() "); + jMenuOptions.add(jCheckBoxMenuItemDebugReadStatus); + + jCheckBoxMenuItemUseEXI.setText("USE EXI (Efficient XML Interchange)"); + jCheckBoxMenuItemUseEXI.addActionListener(formListener); + jMenuOptions.add(jCheckBoxMenuItemUseEXI); + + jCheckBoxMenuItemUseReadStatusThread.setText("Use seperate read status thread."); + jCheckBoxMenuItemUseReadStatusThread.addActionListener(formListener); + jMenuOptions.add(jCheckBoxMenuItemUseReadStatusThread); + + jMenuBarReplaceCommandState.add(jMenuOptions); + + setJMenuBar(jMenuBarReplaceCommandState); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGap(6, 6, 6)) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, 0)) + ); + + pack(); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener, java.awt.event.MouseListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jButtonConnect) { + PendantClient.this.jButtonConnectActionPerformed(evt); + } + else if (evt.getSource() == jButtonDisconnect) { + PendantClient.this.jButtonDisconnectActionPerformed(evt); + } + else if (evt.getSource() == jButtonEnd) { + PendantClient.this.jButtonEndActionPerformed(evt); + } + else if (evt.getSource() == jButtonInit) { + PendantClient.this.jButtonInitActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxPoll) { + PendantClient.this.jCheckBoxPollActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldPollTime) { + PendantClient.this.jTextFieldPollTimeActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldJointJogIncrement) { + PendantClient.this.jTextFieldJointJogIncrementActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldXYZJogIncrement) { + PendantClient.this.jTextFieldXYZJogIncrementActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldRPYJogIncrement) { + PendantClient.this.jTextFieldRPYJogIncrementActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldJogTime) { + PendantClient.this.jTextFieldJogTimeActionPerformed(evt); + } + else if (evt.getSource() == jButtonMoveTo) { + PendantClient.this.jButtonMoveToActionPerformed(evt); + } + else if (evt.getSource() == jButtonMoveToCurrent) { + PendantClient.this.jButtonMoveToCurrentActionPerformed(evt); + } + else if (evt.getSource() == jButtonProgramPause) { + PendantClient.this.jButtonProgramPauseActionPerformed(evt); + } + else if (evt.getSource() == jButtonProgramAbort) { + PendantClient.this.jButtonProgramAbortActionPerformed(evt); + } + else if (evt.getSource() == jButtonEditProgramItem) { + PendantClient.this.jButtonEditProgramItemActionPerformed(evt); + } + else if (evt.getSource() == jButtonDeletProgramItem) { + PendantClient.this.jButtonDeletProgramItemActionPerformed(evt); + } + else if (evt.getSource() == jButtonAddProgramItem) { + PendantClient.this.jButtonAddProgramItemActionPerformed(evt); + } + else if (evt.getSource() == jButtonProgramRun) { + PendantClient.this.jButtonProgramRunActionPerformed(evt); + } + else if (evt.getSource() == jButtonResume) { + PendantClient.this.jButtonResumeActionPerformed(evt); + } + else if (evt.getSource() == jButtonPlotProgramItem) { + PendantClient.this.jButtonPlotProgramItemActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemOpenXmlCommandInstance) { + PendantClient.this.jMenuItemOpenXmlCommandInstanceActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemOpenXmlProgram) { + PendantClient.this.jMenuItemOpenXmlProgramActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemSaveProgramAs) { + PendantClient.this.jMenuItemSaveProgramAsActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemSavePoseList) { + PendantClient.this.jMenuItemSavePoseListActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemExit) { + PendantClient.this.jMenuItemExitActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemXPathQuery) { + PendantClient.this.jMenuItemXPathQueryActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxMenuItemPlotXYZ) { + PendantClient.this.jCheckBoxMenuItemPlotXYZActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxMenuItemJoints) { + PendantClient.this.jCheckBoxMenuItemJointsActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemRunTest) { + PendantClient.this.jMenuItemRunTestActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemPoseList3DPlot) { + PendantClient.this.jMenuItemPoseList3DPlotActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemOpenStatusLog) { + PendantClient.this.jMenuItemOpenStatusLogActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemSetSchemaFiles) { + PendantClient.this.jMenuItemSetSchemaFilesActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxMenuItemUseEXI) { + PendantClient.this.jCheckBoxMenuItemUseEXIActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxMenuItemUseReadStatusThread) { + PendantClient.this.jCheckBoxMenuItemUseReadStatusThreadActionPerformed(evt); + } + } + + public void mouseClicked(java.awt.event.MouseEvent evt) { + } + + public void mouseEntered(java.awt.event.MouseEvent evt) { + } + + public void mouseExited(java.awt.event.MouseEvent evt) { + if (evt.getSource() == jLabelJogMinus) { + PendantClient.this.jLabelJogMinusMouseExited(evt); + } + else if (evt.getSource() == jLabelJogPlus) { + PendantClient.this.jLabelJogPlusMouseExited(evt); + } + else if (evt.getSource() == jLabelJogPlus1) { + PendantClient.this.jLabelJogPlus1MouseExited(evt); + } + else if (evt.getSource() == jLabelJogMinus1) { + PendantClient.this.jLabelJogMinus1MouseExited(evt); + } + } + + public void mousePressed(java.awt.event.MouseEvent evt) { + if (evt.getSource() == jPanelJogMinus) { + PendantClient.this.jPanelJogMinusMousePressed(evt); + } + else if (evt.getSource() == jLabelJogMinus) { + PendantClient.this.jLabelJogMinusMousePressed(evt); + } + else if (evt.getSource() == jLabelJogPlus) { + PendantClient.this.jLabelJogPlusMousePressed(evt); + } + else if (evt.getSource() == jLabelJogPlus1) { + PendantClient.this.jLabelJogPlus1MousePressed(evt); + } + else if (evt.getSource() == jPanelJogMinus1) { + PendantClient.this.jPanelJogMinus1MousePressed(evt); + } + else if (evt.getSource() == jLabelJogMinus1) { + PendantClient.this.jLabelJogMinus1MousePressed(evt); + } + } + + public void mouseReleased(java.awt.event.MouseEvent evt) { + if (evt.getSource() == jLabelJogMinus) { + PendantClient.this.jLabelJogMinusMouseReleased(evt); + } + else if (evt.getSource() == jLabelJogPlus) { + PendantClient.this.jLabelJogPlusMouseReleased(evt); + } + else if (evt.getSource() == jLabelJogPlus1) { + PendantClient.this.jLabelJogPlus1MouseReleased(evt); + } + else if (evt.getSource() == jLabelJogMinus1) { + PendantClient.this.jLabelJogMinus1MouseReleased(evt); + } + } + }// //GEN-END:initComponents + + private final static File statSchemasFile = new File(System.getProperty("user.home"), + ".crcljava_pendantclient_stat_schemas.txt"); + + private final static File cmdSchemasFile = new File(System.getProperty("user.home"), + ".crcljava_pendantclient_cmd_schemas.txt"); + + private final static File programSchemasFile = new File(System.getProperty("user.home"), + ".crcljava_pendantclient_cmd_schemas.txt"); + + private boolean showing_message = false; + private volatile long last_message_show_time = 0; + + public void showMessage(final String s) { + if (showDebugMessage(s)) { + return; + } + + if (showing_message) { + return; + } + showing_message = true; + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + long t = System.currentTimeMillis(); + if (t - last_message_show_time > 5000) { + last_message_show_time = System.currentTimeMillis(); + MultiLineStringJPanel.showText(s, PendantClient.this, "Message from Client", true); + } + last_message_show_time = System.currentTimeMillis(); + showing_message = false; + } + }); + } + + @Override + public boolean showDebugMessage(final String s) { + final String sWithThread = "Thread:" + Thread.currentThread().getName()+" "+s; + LOGGER.log(Level.FINE, sWithThread); + if (!this.isVisible()) { + return true; + } + java.awt.EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + jTextAreaErrors.setText(jTextAreaErrors.getText() + "\n" + sWithThread); + } + }); + return false; + } + + + public void showMessage(Throwable t) { + this.showMessage(t.toString()); + } + + double last_t_pos_logged = 0; + + final Map last_joints = new HashMap<>(); + + private boolean jointsChanged(List jsl) { + if (jsl.size() != last_joints.values().size()) { + return true; + } + for (JointStatusType jst : jsl) { + BigDecimal D = last_joints.get(jst.getJointNumber()); + if (null == D) { + return true; + } + if (!D.equals(jst.getJointPosition())) { + return true; + } + } + return false; + } + + private void copyJointPositions(List jsl) { + this.last_joints.clear(); + for (JointStatusType jst : jsl) { + this.last_joints.put(jst.getJointNumber(), jst.getJointPosition()); + } + } + + public void setStatus(CRCLStatusType _status) { + internal.setStatus(_status); + } + + public void checkXmlQuery(CRCLSocket crclSocket) { + if (null != this.xqJFrame && this.xqJFrame.isUpdateAutomaticallySelected()) { + String q = this.xqJFrame.getQuery(); + if (q != null && q.length() > 0) { + xqJFrame.runQuery(q, crclSocket.getLastStatusString()); + } + } + } + + public void finishConnect() { + this.jButtonConnect.setEnabled(false); + this.jButtonDisconnect.setEnabled(true); + this.jButtonEnd.setEnabled(true); + this.jButtonInit.setEnabled(true); + if (this.jCheckBoxPoll.isSelected()) { + this.startPollTimer(); + } + } + + @Override + public void finishSetStatus() { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + PendantClient.this.finishSetStatusPriv(); + } + }); + } + + private void finishSetStatusPriv() { + if (null != internal.getStatus() && null != internal.getStatus().getCommandStatus()) { + CommandStatusType ccst = internal.getStatus().getCommandStatus(); + if (null != ccst) { + if (null != ccst.getCommandID()) { + this.jTextFieldStatCmdID.setText(ccst.getCommandID().toString()); + } + if (null != ccst.getCommandState()) { + this.jTextFieldStatus.setText(ccst.getCommandState().toString()); + } + this.jTextFieldStatusID.setText(ccst.getStatusID().toString()); + } + JointStatusesType jsst = internal.getStatus().getJointStatuses(); + if (jsst != null) { + List jsl = jsst.getJointStatus(); + boolean joints_changed = this.jointsChanged(jsl); + if (joints_changed) { + this.copyJointPositions(jsl); + DefaultTableModel tm = (DefaultTableModel) this.jTableJoints.getModel(); + double t = System.currentTimeMillis(); + tm.setRowCount(jsl.size()); + for (JointStatusType js : jsl) { + int jn = js.getJointNumber().intValue(); + if (null != js.getJointVelocity()) { + tm.setValueAt(js.getJointVelocity().doubleValue(), jn - 1, 2); + } + if (null != js.getJointTorqueOrForce()) { + tm.setValueAt(js.getJointTorqueOrForce().doubleValue(), jn - 1, 3); + } + if (null == js.getJointPosition()) { +// tm.setValueAt(Double.NaN, jn-1,1); + continue; + } + + double pos = js.getJointPosition().doubleValue(); + tm.setValueAt(jn, jn - 1, 0); + tm.setValueAt(pos, jn - 1, 1); + if (this.jCheckBoxMenuItemJoints.isSelected()) { + if (null == this.jointsPlotter) { + jointsPlotter = new plotterJFrame(); + jointsPlotter.setTitle("JOINTS"); + jointsPlotter.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + jointsPlotter.setVisible(true); + } + String pname = "joint[" + jn + "]"; + PlotData pd = this.jointsPlotter.getPlotByName(pname); + if (null == pd) { + pd = new PlotData(); + pd.name = pname; + this.jointsPlotter.AddPlot(pd, pname); + } + this.jointsPlotter.AddPointToPlot(pd, t, pos, rootPaneCheckingEnabled); + if (pd.get_num_points() < 100) { + this.jointsPlotter.FitToGraph(); + } + } + } + if (null != this.jointsPlotter) { + this.jointsPlotter.ScrollRight(); + } + } + } + PoseType p = internal.getStatus().getPose(); + if (null != p) { + updatePoseTable(p, this.jTablePose); + PointType pt = p.getPoint(); + if (this.jCheckBoxMenuItemPlotXYZ.isSelected()) { + if (null == xyzPlotter) { + xyzPlotter = new plotterJFrame(); + xyzPlotter.setTitle("XYZ"); + xyzPlotter.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + xyzPlotter.setVisible(true); + } + double t = (double) System.currentTimeMillis(); +// XMLGregorianCalendar xgc = p.getTimestamp(); +// if (null != xgc) { +// double old_t = t; +// t = (double) xgc.toGregorianCalendar().getTime().getTime(); +// } + if (t > this.last_t_pos_logged) { + PlotData xpd = xyzPlotter.getPlotByName("x"); + if (null == xpd) { + xpd = new PlotData(); + xpd.name = "x"; + xyzPlotter.AddPlot(xpd, "x"); + } + double x = pt.getX().doubleValue(); + xyzPlotter.AddPointToPlot(xpd, t, x, true); + PlotData ypd = xyzPlotter.getPlotByName("y"); + if (null == ypd) { + ypd = new PlotData(); + ypd.name = "y"; + xyzPlotter.AddPlot(xpd, "y"); + } + double y = pt.getY().doubleValue(); + xyzPlotter.AddPointToPlot(ypd, t, y, true); + PlotData zpd = xyzPlotter.getPlotByName("z"); + if (null == zpd) { + zpd = new PlotData(); + zpd.name = "x"; + xyzPlotter.AddPlot(zpd, "z"); + } + double z = pt.getZ().doubleValue(); + xyzPlotter.AddPointToPlot(zpd, t, z, true); + if (xpd.get_num_points() < 100) { + xyzPlotter.FitToGraph(); + } + xyzPlotter.ScrollRight(); + xyzPlotter.repaint(); + this.last_t_pos_logged = t; + } + } + + } + } + } + + private void updatePoseTable(PoseType p, JTable jTable) { + try { + DefaultTableModel tm = (DefaultTableModel) jTable.getModel(); + PointType pt = p.getPoint(); + if (null != pt) { + tm.setValueAt(pt.getX().doubleValue(), 0, 1); + tm.setValueAt(pt.getY().doubleValue(), 1, 1); + tm.setValueAt(pt.getZ().doubleValue(), 2, 1); + } + VectorType xv = p.getXAxis(); + if (null != xv) { + tm.setValueAt(xv.getI().doubleValue(), 3, 1); + tm.setValueAt(xv.getJ().doubleValue(), 4, 1); + tm.setValueAt(xv.getK().doubleValue(), 5, 1); + } + VectorType zv = p.getZAxis(); + if (null != zv) { + tm.setValueAt(zv.getI().doubleValue(), 6, 1); + tm.setValueAt(zv.getJ().doubleValue(), 7, 1); + tm.setValueAt(zv.getK().doubleValue(), 8, 1); + } + PmRpy rpy = CRCLPosemath.toPmRpy(p); + tm.setValueAt(Math.toDegrees(rpy.r), 9, 1); + tm.setValueAt(Math.toDegrees(rpy.p), 10, 1); + tm.setValueAt(Math.toDegrees(rpy.y), 11, 1); + } catch (PmException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + private void disconnect() { + internal.disconnect(); + } + + public void finishDisconnect() { + this.jButtonConnect.setEnabled(true); + this.jButtonDisconnect.setEnabled(false); + this.jButtonEnd.setEnabled(false); + this.jButtonInit.setEnabled(false); + this.stopPollTimer(); + } + + private final PendantClientInner internal; + + public boolean isConnected() { + return internal.isConnected(); + } + + public void connect(String _host, int _port) { + internal.connect(_host, _port); + } + + private void jButtonConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonConnectActionPerformed + this.connect(this.jTextFieldHost.getText(), Integer.valueOf(this.jTextFieldPort.getText())); + }//GEN-LAST:event_jButtonConnectActionPerformed + + private void jButtonDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDisconnectActionPerformed + this.disconnect(); + }//GEN-LAST:event_jButtonDisconnectActionPerformed + + private void jButtonInitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonInitActionPerformed + InitCanonType init = new InitCanonType(); + internal.incAndSendCommand(init); + }//GEN-LAST:event_jButtonInitActionPerformed + + + private void jButtonEndActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEndActionPerformed + EndCanonType end = new EndCanonType(); + internal.incAndSendCommand(end); + }//GEN-LAST:event_jButtonEndActionPerformed + + private void jPanelJogMinusMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelJogMinusMousePressed +// ActuateJointsType jog = new ActuateJointsType(); +// cmdId = cmdId.shift(BigInteger.ONE); +// jog.setCommandID(cmdId); +// ActuateJointType joint = new ActuateJointType(); +// List l = jog.getActuateJoint(); +// if(l == null) { +// l = new ArrayList<>(); +// } +// l.shift(joint); +// joint.setActuate(true); +// +// this.cmd_instance.setCRCLCommand(jog); +// this.sendCommand(); + }//GEN-LAST:event_jPanelJogMinusMousePressed + + private void jMenuItemExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemExitActionPerformed + System.exit(0); + }//GEN-LAST:event_jMenuItemExitActionPerformed + +// JointControlModeEnumType jcme = null; +// +// private void setJointControlModes(JointControlModeEnumType _jcme) { +// if (this.jcme != _jcme) { +// SetJointControlModesType setjcm = new SetJointControlModesType(); +// List ljcm = setjcm.getJointControlMode(); +// JointStatusesType jsst = internal.getStatus().getJointStatuses(); +// if (jsst != null) { +// List jsl = jsst.getJointStatus(); +// for (JointStatusType js : jsl) { +// JointControlModeType jcm = new JointControlModeType(); +// jcm.setMode(_jcme); +// jcm.setJointNumber(js.getJointNumber()); +// ljcm.shift(jcm); +// } +// } +// cmdId = cmdId.shift(BigInteger.ONE); +// setjcm.setCommandID(cmdId); +// this.cmd_instance.setCRCLCommand(setjcm); +// this.sendCommand(); +// this.jcme = _jcme; +// } +// } + javax.swing.Timer jog_timer = null; + + private void jogStart(final double increment) { + if (null == internal.getCRCLSocket() + || null == internal.getStatus()) { + showMessage("Can not send command when not connected."); + return; + } +// this.setJointControlModes(JointControlModeEnumType.POSITION); + final int index = this.jComboBox1.getSelectedIndex() + 1; + if (null != jog_timer) { + jog_timer.stop(); + jog_timer = null; + } + jog_timer = new javax.swing.Timer(internal.getJogInterval(), new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + try { + final JointStatusType js = CRCLSocket.getJointStatus(internal.getStatus(), index); + if (null == js) { + showMessage("Can't jog without joint position internal.getStatus() for joint " + index); + return; + } + if (internal.getStatus().getCommandStatus().getCommandState() == CommandStateEnumType.ERROR) { + jogStop(); + } + ActuateJointsType ajst = new ActuateJointsType(); + List ajl = ajst.getActuateJoint(); + ActuateJointType aj = new ActuateJointType(); + aj.setJointNumber(js.getJointNumber()); + aj.setJointPosition(js.getJointPosition().add(BigDecimal.valueOf(increment))); + JointSpeedAccelType jsa = new JointSpeedAccelType(); + aj.setJointDetails(jsa); + ajl.add(aj); + internal.incAndSendCommand(ajst); + } catch (Exception ex) { + ex.printStackTrace(); + jogStop(); + } + } + }); + jog_timer.start(); + } + + private double rpyJogIncrement = 3.0; + + /** + * Get the value of rpyJogIncrement + * + * @return the value of rpyJogIncrement + */ + public double getRpyJogIncrement() { + return rpyJogIncrement; + } + + /** + * Set the value of rpyJogIncrement + * + * @param rpyJogIncrement new value of rpyJogIncrement + */ + public void setRpyJogIncrement(double rpyJogIncrement) { + this.rpyJogIncrement = rpyJogIncrement; + } + + private void jogWorldStart(double sign) { + if (null == internal.getStatus() + || null == internal.getStatus()) { + showMessage("Can not send command when not connected."); + return; + } +// this.setJointControlModes(JointControlModeEnumType.POSITION); + final String axis = (String) this.jComboBoxXYZRPY.getSelectedItem(); + double tmpinc = 1.0; + sign = Math.signum(sign); + switch (axis) { + case "X": + case "Y": + case "Z": + tmpinc = internal.getXyzJogIncrement() * sign; + break; + + case "Roll": + case "Pitch": + case "Yaw": + tmpinc = Math.toRadians(this.rpyJogIncrement) * sign; + break; + } + final BigDecimal axisIncrement = BigDecimal.valueOf(tmpinc); + final double inc = tmpinc; + if (null != jog_timer) { + jog_timer.stop(); + jog_timer = null; + } + jog_timer = new javax.swing.Timer(internal.getJogInterval(), new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + try { + if (internal.getStatus().getCommandStatus().getCommandState() == CommandStateEnumType.ERROR) { + jogStop(); + } + MoveToType moveToType = new MoveToType(); + PoseType endPos = new PoseType(); + endPos.setPoint(new PointType()); + endPos.setXAxis(new VectorType()); + endPos.setZAxis(new VectorType()); + moveToType.setEndPosition(endPos); + moveToType.getEndPosition().getPoint().setX(internal.getStatus().getPose().getPoint().getX()); + moveToType.getEndPosition().getPoint().setY(internal.getStatus().getPose().getPoint().getY()); + moveToType.getEndPosition().getPoint().setZ(internal.getStatus().getPose().getPoint().getZ()); + moveToType.getEndPosition().getXAxis().setI(internal.getStatus().getPose().getXAxis().getI()); + moveToType.getEndPosition().getXAxis().setJ(internal.getStatus().getPose().getXAxis().getJ()); + moveToType.getEndPosition().getXAxis().setK(internal.getStatus().getPose().getXAxis().getK()); + moveToType.getEndPosition().getZAxis().setI(internal.getStatus().getPose().getZAxis().getI()); + moveToType.getEndPosition().getZAxis().setJ(internal.getStatus().getPose().getZAxis().getJ()); + moveToType.getEndPosition().getZAxis().setK(internal.getStatus().getPose().getZAxis().getK()); + switch (axis) { + case "X": + moveToType.getEndPosition().getPoint().setX(internal.getStatus().getPose().getPoint().getX().add(axisIncrement)); + break; + + case "Y": + moveToType.getEndPosition().getPoint().setY(internal.getStatus().getPose().getPoint().getY().add(axisIncrement)); + break; + + case "Z": + moveToType.getEndPosition().getPoint().setZ(internal.getStatus().getPose().getPoint().getZ().add(axisIncrement)); + break; + + case "Roll": + incrementRoll(moveToType, inc); + break; + + case "Pitch": + incrementPitch(moveToType, inc); + break; + + case "Yaw": + incrementYaw(moveToType, inc); + break; + + } + internal.incAndSendCommand(moveToType); + } catch (Exception ex) { + ex.printStackTrace(); + jogStop(); + } + } + + private void incrementYaw(MoveToType moveToType, final double inc) throws PmException { + PmRotationMatrix pm = CRCLPosemath.toPmRotationMatrix(internal.getStatus().getPose()); + PmRpy rpy = Posemath.toRpy(pm); + rpy.y += inc; + PmRotationVector pm2 = Posemath.toRot(rpy); + PoseType nextPose = CRCLPosemath.toPoseType( + CRCLPosemath.pointToPmCartesian(internal.getStatus().getPose().getPoint()), + pm2); + moveToType.setEndPosition(nextPose); + } + + private void incrementPitch(MoveToType moveToType, final double inc) throws PmException { + PmRotationMatrix pm = CRCLPosemath.toPmRotationMatrix(internal.getStatus().getPose()); + PmRpy rpy = Posemath.toRpy(pm); + rpy.p += inc; + PmRotationVector pm2 = Posemath.toRot(rpy); + PoseType nextPose = CRCLPosemath.toPoseType( + CRCLPosemath.pointToPmCartesian(internal.getStatus().getPose().getPoint()), + pm2); + moveToType.setEndPosition(nextPose); + } + + private void incrementRoll(MoveToType moveToType, final double inc) throws PmException { + PmRotationMatrix pm = CRCLPosemath.toPmRotationMatrix(internal.getStatus().getPose()); + PmRpy rpy = Posemath.toRpy(pm); + rpy.r += inc; + PmRotationVector pm2 = Posemath.toRot(rpy); + PoseType nextPose = CRCLPosemath.toPoseType( + CRCLPosemath.pointToPmCartesian(internal.getStatus().getPose().getPoint()), + pm2); + moveToType.setEndPosition(nextPose); + } + }); + jog_timer.start(); + } + + private void jogStop() { + if (null != jog_timer) { + jog_timer.stop(); + jog_timer = null; + } + } + + public void checkPollSelected() { + if (this.jCheckBoxPoll.isSelected()) { + this.startPollTimer(); + } + } + + private void commonJogStop() { + this.jogStop(); + this.jLabelJogMinus.setBackground(Color.WHITE); + this.jLabelJogMinus.setForeground(Color.BLACK); + this.jPanelJogMinus.setBackground(Color.WHITE); + this.jLabelJogMinus.repaint(); + this.jPanelJogMinus.repaint(); + this.jLabelJogMinus1.setBackground(Color.WHITE); + this.jLabelJogMinus1.setForeground(Color.BLACK); + this.jPanelJogMinus1.setBackground(Color.WHITE); + this.jLabelJogMinus1.repaint(); + this.jPanelJogMinus1.repaint(); + this.jLabelJogPlus.setBackground(Color.WHITE); + this.jLabelJogPlus.setForeground(Color.BLACK); + this.jPanelJogPlus.setBackground(Color.WHITE); + this.jLabelJogPlus.repaint(); + this.jPanelJogPlus.repaint(); + this.jLabelJogPlus1.setBackground(Color.WHITE); + this.jLabelJogPlus1.setForeground(Color.BLACK); + this.jPanelJogPlus1.setBackground(Color.WHITE); + this.jLabelJogPlus1.repaint(); + this.jPanelJogPlus1.repaint(); + } + + private void jLabelJogMinusMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogMinusMousePressed + this.jogStart(-1.0 * internal.getJogIncrement()); + this.jLabelJogMinus.setBackground(Color.BLACK); + this.jLabelJogMinus.setForeground(Color.WHITE); + this.jPanelJogMinus.setBackground(Color.BLACK); + this.jLabelJogMinus.repaint(); + this.jPanelJogMinus.repaint(); + }//GEN-LAST:event_jLabelJogMinusMousePressed + + private void jLabelJogMinusMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogMinusMouseReleased + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogMinusMouseReleased + + private void jLabelJogMinusMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogMinusMouseExited + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogMinusMouseExited + + private void jLabelJogPlusMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogPlusMousePressed + this.jogStart(+1.0 * internal.getJogIncrement()); + this.jLabelJogPlus.setBackground(Color.BLACK); + this.jLabelJogPlus.setForeground(Color.WHITE); + this.jPanelJogPlus.setBackground(Color.BLACK); + this.jLabelJogPlus.repaint(); + this.jPanelJogPlus.repaint(); + }//GEN-LAST:event_jLabelJogPlusMousePressed + + private void jLabelJogPlusMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogPlusMouseReleased + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogPlusMouseReleased + + private void jLabelJogPlusMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogPlusMouseExited + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogPlusMouseExited + + private XpathQueryJFrame xqJFrame = null; + private void jMenuItemXPathQueryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemXPathQueryActionPerformed + if (null == xqJFrame) { + try { + xqJFrame = new XpathQueryJFrame(); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + xqJFrame.setVisible(true); + }//GEN-LAST:event_jMenuItemXPathQueryActionPerformed + + private void jButtonMoveToActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonMoveToActionPerformed + MoveToType moveto = new MoveToType(); + PoseType p = new PoseType(); + DefaultTableModel tm = (DefaultTableModel) this.jTableMoveToPose.getModel(); + PointType pt = new PointType(); + pt.setX(BigDecimal.valueOf((Double) tm.getValueAt(0, 1))); + pt.setY(BigDecimal.valueOf((Double) tm.getValueAt(1, 1))); + pt.setZ(BigDecimal.valueOf((Double) tm.getValueAt(2, 1))); + VectorType xv = new VectorType(); + xv.setI(BigDecimal.valueOf((Double) tm.getValueAt(3, 1))); + xv.setJ(BigDecimal.valueOf((Double) tm.getValueAt(4, 1))); + xv.setK(BigDecimal.valueOf((Double) tm.getValueAt(5, 1))); + VectorType zv = new VectorType(); + zv.setI(BigDecimal.valueOf((Double) tm.getValueAt(6, 1))); + zv.setJ(BigDecimal.valueOf((Double) tm.getValueAt(7, 1))); + zv.setK(BigDecimal.valueOf((Double) tm.getValueAt(8, 1))); + p.setPoint(pt); + p.setXAxis(xv); + p.setZAxis(zv); + moveto.setEndPosition(p); + moveto.setMoveStraight(this.jCheckBoxStraight.isSelected()); + internal.incAndSendCommand(moveto); + }//GEN-LAST:event_jButtonMoveToActionPerformed + + diagapplet.plotter.plotterJFrame xyzPlotter = null; + + diagapplet.plotter.plotterJFrame jointsPlotter = null; + + private void jMenuItemSetSchemaFilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSetSchemaFilesActionPerformed + JFileChooser jFileChooser = new JFileChooser(); + javax.swing.filechooser.FileFilter[] ffa = jFileChooser.getChoosableFileFilters(); + for (javax.swing.filechooser.FileFilter ff : ffa) { + jFileChooser.removeChoosableFileFilter(ff); + } + jFileChooser.addChoosableFileFilter(new FileNameExtensionFilter("XML Schema file", "xsd")); + jFileChooser.setMultiSelectionEnabled(true); + int result = jFileChooser.showOpenDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + File fa[] = jFileChooser.getSelectedFiles(); + internal.setCmdSchema(fa); + CRCLSocket.saveCmdSchemaFiles(PendantClient.cmdSchemasFile, fa); + internal.setStatSchema(fa); + CRCLSocket.saveStatSchemaFiles(PendantClient.statSchemasFile, fa); + internal.setProgramSchema(fa); + CRCLSocket.saveProgramSchemaFiles(PendantClient.programSchemasFile, fa); + } + }//GEN-LAST:event_jMenuItemSetSchemaFilesActionPerformed + + private void jCheckBoxMenuItemJointsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemJointsActionPerformed + if (this.jCheckBoxMenuItemJoints.isSelected()) { + jointsPlotter = new plotterJFrame(); + jointsPlotter.setTitle("JOINTS"); + jointsPlotter.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + jointsPlotter.setVisible(true); + } + }//GEN-LAST:event_jCheckBoxMenuItemJointsActionPerformed + + private void jCheckBoxMenuItemPlotXYZActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemPlotXYZActionPerformed + if (this.jCheckBoxMenuItemPlotXYZ.isSelected()) { + xyzPlotter = new plotterJFrame(); + xyzPlotter.setTitle("XYZ"); + xyzPlotter.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + xyzPlotter.setVisible(true); + } + }//GEN-LAST:event_jCheckBoxMenuItemPlotXYZActionPerformed + + private void jButtonMoveToCurrentActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonMoveToCurrentActionPerformed + this.updatePoseTable(internal.getStatus().getPose(), this.jTableMoveToPose); + }//GEN-LAST:event_jButtonMoveToCurrentActionPerformed + + private static final String recent_files_dir = ".crcl_pendant_client_recent_files"; + + private void saveRecentCommandInstance(CRCLCommandInstanceType cmd) throws JAXBException, IOException { + CRCLSocket tmpcs = internal.getTempCRCLSocket(); + String s = tmpcs.commandToPrettyDocString(cmd, true); + File fDir = new File(System.getProperty("user.home"), recent_files_dir); + fDir.mkdirs(); + String name = cmd.getCRCLCommand().getClass().getSimpleName(); + int pindex = name.lastIndexOf('.'); + if (pindex > 0 && pindex < name.length()) { + name = name.substring(pindex + 1); + } + File fDir2 = new File(fDir, name); + fDir2.mkdirs(); + Date dNow = new Date(); + SimpleDateFormat ft + = new SimpleDateFormat("yyyy-MM-dd_hh_mm_ss_a_zzz_"); + String date_string = ft.format(dNow); + File f = File.createTempFile(date_string, ".xml", fDir2); + try (FileWriter fw = new FileWriter(f)) { + fw.write(s); + } + } + + private static final String recent_programs_dir = ".crcl_pendant_client_recent_programs"; + + private void saveRecentProgram(File fprog) throws JAXBException, IOException { + Set pathSet = this.getRecentPrograms(); + if (pathSet.contains(fprog.getCanonicalPath())) { + return; + } + File fDir = new File(System.getProperty("user.home"), recent_programs_dir); + fDir.mkdirs(); + String name = fprog.getName(); + if (null == name) { + name = "untitled"; + } + Date dNow = new Date(); + SimpleDateFormat ft + = new SimpleDateFormat("yyyy-MM-dd_hh_mm_ss_a_zzz_"); + String date_string = ft.format(dNow); + File flink = File.createTempFile(name + "_" + date_string, ".txt", fDir); + try (FileWriter fw = new FileWriter(flink)) { + fw.write(fprog.getCanonicalPath()); + } + } + + private void saveRecentCommand(CRCLCommandType cmd) throws JAXBException, IOException { + CRCLCommandInstanceType instanceForSave = new CRCLCommandInstanceType(); + instanceForSave.setCRCLCommand(cmd); + this.saveRecentCommandInstance(instanceForSave); + } + + private void browseOpenCommandXml() { + JFileChooser chooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter( + "XML Instance Files", "xml"); + chooser.setFileFilter(filter); + int returnVal = chooser.showOpenDialog(this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + try { + File f = chooser.getSelectedFile(); + openXmlInstanceFile(f); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + } + } + } + + private void browseOpenProgramXml() { + JFileChooser chooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter( + "XML Program Files", "xml"); + chooser.setFileFilter(filter); + int returnVal = chooser.showOpenDialog(this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + try { + File f = chooser.getSelectedFile(); + openXmlProgramFile(f); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + } + } + } + + @Override + public CRCLProgramType editProgram(CRCLProgramType program) { + internal.getXpu().setSchemaFiles(internal.getProgramSchemaFiles()); + program = ObjTableJPanel.editObject(program, internal.getXpu(), + internal.getCheckProgramValidPredicate()); + return program; + } + + private void openXmlInstanceFile(File f) throws ParserConfigurationException, JAXBException, XPathExpressionException, IOException, SAXException { + String s = internal.getXpu().queryXml(f, "/"); + CRCLCommandInstanceType cmdInstance + = internal.getCRCLSocket().stringToCommand(s, this.jCheckBoxMenuItemValidateXml.isSelected()); + CRCLCommandType cmd = cmdInstance.getCRCLCommand(); + cmd = ObjTableJPanel.editObject(cmd, internal.getXpu(), + internal.getCheckCommandValidPredicate()); + internal.incAndSendCommand(cmd); + this.saveRecentCommand(cmd); + } + + private String tableCommandType(CRCLCommandType cmd) { + String clssName = cmd.getClass().getSimpleName(); + String prefix = "crcl.base."; + if (clssName.startsWith(prefix)) { + return clssName.substring(prefix.length()); + } + return clssName; + } + + public void showProgram(CRCLProgramType program) { + DefaultTableModel dtm = (DefaultTableModel) this.jTableProgram.getModel(); + BigInteger maxCmdId = BigInteger.ONE; + InitCanonType init = program.getInitCanon(); + List middleCommands = program.getMiddleCommand(); + dtm.setRowCount(2 + middleCommands.size()); + if (init.getCommandID() == null) { + init.setCommandID(maxCmdId); + } else { + maxCmdId = maxCmdId.max(init.getCommandID()); + } + dtm.setValueAt(init.getCommandID().longValue(), 0, 0); + dtm.setValueAt(tableCommandType(init), 0, 1); + dtm.setValueAt(-1, 0, 2); + dtm.setValueAt(0.0, 0, 2); + for (int i = 0; i < middleCommands.size(); i++) { + MiddleCommandType middleCommand = middleCommands.get(i); + if (null == middleCommand) { + showDebugMessage("middleCommands contains null at " + i); + continue; + } + maxCmdId = maxCmdId.add(BigInteger.ONE); + if (middleCommand.getCommandID() == null || middleCommand.getCommandID().compareTo(maxCmdId) < 0) { + middleCommand.setCommandID(maxCmdId); + } + maxCmdId = maxCmdId.max(middleCommand.getCommandID()); + dtm.setValueAt(middleCommand.getCommandID().longValue(), i + 1, 0); + dtm.setValueAt(tableCommandType(middleCommand), i + 1, 1); + dtm.setValueAt(-1, i + 1, 2); + dtm.setValueAt(0.0, i + 1, 3); + } + EndCanonType endCommand = program.getEndCanon(); + maxCmdId = maxCmdId.add(BigInteger.ONE); + if (endCommand.getCommandID() == null || endCommand.getCommandID().compareTo(maxCmdId) < 0) { + endCommand.setCommandID(maxCmdId); + } + dtm.setValueAt(endCommand.getCommandID().longValue(), 1 + middleCommands.size(), 0); + dtm.setValueAt(tableCommandType(endCommand), 1 + middleCommands.size(), 1); + dtm.setValueAt(-1, 1 + middleCommands.size(), 2); + dtm.setValueAt(0.0, 1 + middleCommands.size(), 3); + } + private void jMenuItemOpenXmlCommandInstanceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOpenXmlCommandInstanceActionPerformed + this.browseOpenCommandXml(); + }//GEN-LAST:event_jMenuItemOpenXmlCommandInstanceActionPerformed + + private void jMenuItemOpenXmlProgramActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOpenXmlProgramActionPerformed + this.browseOpenProgramXml(); + }//GEN-LAST:event_jMenuItemOpenXmlProgramActionPerformed + + javax.swing.Timer pollTimer = null; + + private void startPollTimer() { + pollTimer = new javax.swing.Timer(internal.getPoll_ms(), new ActionListener() { + + private boolean toggler =false; + + @Override + public void actionPerformed(ActionEvent e) { + + if(!toggler) { + internal.requestStatus(); + if(!isUseReadStatusThreadSelected()) { + toggler = true; + } + } else { + if(!isUseReadStatusThreadSelected()) { + internal.readStatus(); + } + toggler = false; + } + } + }); + pollTimer.start(); + } + + @Override + public void stopPollTimer() { + if (pollTimer != null) { + pollTimer.stop(); + pollTimer = null; + } + } + + private void jCheckBoxPollActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxPollActionPerformed + this.stopPollTimer(); + if (this.jCheckBoxPoll.isSelected() && null != internal.getCRCLSocket()) { + this.startPollTimer(); + } + }//GEN-LAST:event_jCheckBoxPollActionPerformed + + private void jTextFieldPollTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldPollTimeActionPerformed + int new_poll_ms = Integer.valueOf(this.jTextFieldPollTime.getText()); + internal.setPoll_ms(new_poll_ms); + this.stopPollTimer(); + if (this.jCheckBoxPoll.isSelected()) { + this.startPollTimer(); + } + }//GEN-LAST:event_jTextFieldPollTimeActionPerformed + + private void jLabelJogPlus1MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogPlus1MousePressed + this.jogWorldStart(+1.0); + this.jLabelJogPlus1.setBackground(Color.BLACK); + this.jLabelJogPlus1.setForeground(Color.WHITE); + this.jPanelJogPlus1.setBackground(Color.BLACK); + this.jLabelJogPlus1.repaint(); + this.jPanelJogPlus1.repaint(); + }//GEN-LAST:event_jLabelJogPlus1MousePressed + + private void jLabelJogPlus1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogPlus1MouseReleased + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogPlus1MouseReleased + + private void jLabelJogPlus1MouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogPlus1MouseExited + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogPlus1MouseExited + + private void jLabelJogMinus1MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogMinus1MousePressed + this.jogWorldStart(-1.0); + this.jLabelJogMinus1.setBackground(Color.BLACK); + this.jLabelJogMinus1.setForeground(Color.WHITE); + this.jPanelJogMinus1.setBackground(Color.BLACK); + this.jLabelJogMinus1.repaint(); + this.jPanelJogMinus1.repaint(); + }//GEN-LAST:event_jLabelJogMinus1MousePressed + + private void jLabelJogMinus1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogMinus1MouseReleased + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogMinus1MouseReleased + + private void jLabelJogMinus1MouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLabelJogMinus1MouseExited + this.commonJogStop(); + }//GEN-LAST:event_jLabelJogMinus1MouseExited + + private void jPanelJogMinus1MousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelJogMinus1MousePressed + this.jogWorldStart(-1.0); + this.jLabelJogMinus1.setBackground(Color.BLACK); + this.jLabelJogMinus1.setForeground(Color.WHITE); + this.jPanelJogMinus1.setBackground(Color.BLACK); + this.jLabelJogMinus1.repaint(); + this.jPanelJogMinus1.repaint(); + }//GEN-LAST:event_jPanelJogMinus1MousePressed + + private void jTextFieldJointJogIncrementActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldJointJogIncrementActionPerformed + internal.setJogIncrement(Double.valueOf(this.jTextFieldJointJogIncrement.getText())); + }//GEN-LAST:event_jTextFieldJointJogIncrementActionPerformed + + private void jTextFieldXYZJogIncrementActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldXYZJogIncrementActionPerformed + internal.setXyzJogIncrement(Double.valueOf(this.jTextFieldXYZJogIncrement.getText())); + }//GEN-LAST:event_jTextFieldXYZJogIncrementActionPerformed + + private void jTextFieldRPYJogIncrementActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldRPYJogIncrementActionPerformed + this.setRpyJogIncrement(Double.valueOf(this.jTextFieldRPYJogIncrement.getText())); + }//GEN-LAST:event_jTextFieldRPYJogIncrementActionPerformed + + private void jTextFieldJogTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldJogTimeActionPerformed + internal.setJogIncrement(Double.valueOf(this.jTextFieldJogTime.getText())); + }//GEN-LAST:event_jTextFieldJogTimeActionPerformed + + private void jMenuItemRunTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemRunTestActionPerformed + internal.startRunTestThread(); + }//GEN-LAST:event_jMenuItemRunTestActionPerformed + + private void clearProgramTimesDistances() { + DefaultTableModel dtm = (DefaultTableModel) this.jTableProgram.getModel(); + for (int i = 0; i < dtm.getRowCount(); i++) { + dtm.setValueAt(-1, i, 2); + dtm.setValueAt(0.0, i, 3); + } + } + + private void jButtonProgramRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonProgramRunActionPerformed + this.clearProgramTimesDistances(); + internal.startRunProgramThread(); + this.jButtonResume.setEnabled(internal.isPaused()); + this.jButtonProgramPause.setEnabled(internal.isRunningProgram()); + }//GEN-LAST:event_jButtonProgramRunActionPerformed + + private void jButtonResumeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResumeActionPerformed + internal.unpause(); + this.jButtonResume.setEnabled(internal.isPaused()); + this.jButtonProgramPause.setEnabled(internal.isRunningProgram()); + }//GEN-LAST:event_jButtonResumeActionPerformed + + private void jButtonProgramPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonProgramPauseActionPerformed + internal.pause(); + this.jButtonResume.setEnabled(internal.isPaused()); + this.jButtonProgramPause.setEnabled(internal.isRunningProgram()); + }//GEN-LAST:event_jButtonProgramPauseActionPerformed + + private void jButtonProgramAbortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonProgramAbortActionPerformed + internal.abort(); + }//GEN-LAST:event_jButtonProgramAbortActionPerformed + + private void jButtonDeletProgramItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeletProgramItemActionPerformed + int index = this.jTableProgram.getSelectedRow(); + if (index > 0 && index < this.jTableProgram.getRowCount() - 1) { + internal.getProgram().getMiddleCommand().remove(index - 1); + this.showProgram(internal.getProgram()); + this.showCurrentProgramLine(index); + } + }//GEN-LAST:event_jButtonDeletProgramItemActionPerformed + + private void jButtonEditProgramItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEditProgramItemActionPerformed + int index = this.jTableProgram.getSelectedRow(); + if (index > 0 && index < this.jTableProgram.getRowCount() - 1) { + MiddleCommandType cmdOrig = internal.getProgram().getMiddleCommand().get(index - 1); + MiddleCommandType cmdEdited + = (MiddleCommandType) ObjTableJPanel.editObject(cmdOrig, + internal.getXpu(), PendantClient.this.internal.getCheckCommandValidPredicate()); + if (null == cmdEdited) { + showDebugMessage("Edit Program Item cancelled. cmdEdited == null"); + return; + } + internal.getProgram().getMiddleCommand().set(index - 1, cmdEdited); + this.showProgram(internal.getProgram()); + this.showCurrentProgramLine(index); + } + }//GEN-LAST:event_jButtonEditProgramItemActionPerformed + + private void jButtonAddProgramItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddProgramItemActionPerformed + int index = this.jTableProgram.getSelectedRow(); + if (index > 0 && index < this.jTableProgram.getRowCount() - 1) { + try { + Class clss = MiddleCommandType.class; + List availClasses = getAssignableClasses(clss, + ObjTableJPanel.getClasses()); + Class ca[] = availClasses.toArray(new Class[availClasses.size()]); +// int selected = JOptionPane.showOptionDialog(this, +// "Select class of new " + clss.getCanonicalName(), +// "new " + clss.getCanonicalName(), +// JOptionPane.DEFAULT_OPTION, +// JOptionPane.QUESTION_MESSAGE, +// null, +// ca, +// null); +// if(selected < 0 || selected >= ca.length) { +// showDebugMessage("Add Program Item cancelled. invalid class index = "+selected); +// return; +// } + Class selectedClss = ListChooserJPanel.Choose(this, "Type of new Item", ca, null); + if (selectedClss == null) { + showDebugMessage("Add Program Item cancelled. selectedClss == null"); + return; + } + MiddleCommandType cmdOrig = (MiddleCommandType) selectedClss.newInstance(); + MiddleCommandType cmdEdited + = (MiddleCommandType) ObjTableJPanel.editObject(cmdOrig, + internal.getXpu(), PendantClient.this.internal.getCheckCommandValidPredicate()); + if (null == cmdEdited) { + showDebugMessage("Add Program Item cancelled. cmdEdited == null"); + return; + } + internal.getProgram().getMiddleCommand().add(index - 1, cmdEdited); + this.showProgram(internal.getProgram()); + this.showCurrentProgramLine(index); + } catch (InstantiationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (IllegalAccessException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } + } + }//GEN-LAST:event_jButtonAddProgramItemActionPerformed + + private void jMenuItemSaveProgramAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSaveProgramAsActionPerformed + JFileChooser chooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter( + "XML Program Files", "xml"); + chooser.setFileFilter(filter); + int returnVal = chooser.showSaveDialog(this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + try { + File f = chooser.getSelectedFile(); + saveXmlProgramFile(f); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (XPathExpressionException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + } + } + }//GEN-LAST:event_jMenuItemSaveProgramAsActionPerformed + + private void jMenuItemSavePoseListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSavePoseListActionPerformed + JFileChooser chooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter( + "Comma-Separated-Values", "csv"); + chooser.setFileFilter(filter); + int returnVal = chooser.showSaveDialog(this); + if(returnVal == JFileChooser.APPROVE_OPTION) { + try { + this.internal.savePoseListToCsvFile(chooser.getSelectedFile().getAbsolutePath()); + } catch (IOException ex) { + Logger.getLogger(PendantClient.class.getName()).log(Level.SEVERE, null, ex); + } catch (PmException ex) { + Logger.getLogger(PendantClient.class.getName()).log(Level.SEVERE, null, ex); + } + } + }//GEN-LAST:event_jMenuItemSavePoseListActionPerformed + + private void jMenuItemPoseList3DPlotActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPoseList3DPlotActionPerformed + try { +// File tmpFile = File.createTempFile("poseList", ".csv"); +// this.internal.savePoseListToCsvFile(tmpFile.getAbsolutePath()); + com.github.wshackle.poselist3dplot.MainJFrame.showPoseList(this.internal.getPoseList()); + } catch (Exception ex) { + Logger.getLogger(PendantClient.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jMenuItemPoseList3DPlotActionPerformed + + private void jMenuItemOpenStatusLogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOpenStatusLogActionPerformed + try { + File tmpFile = File.createTempFile("poseList", ".csv"); + this.internal.savePoseListToCsvFile(tmpFile.getAbsolutePath()); + Desktop.getDesktop().open(tmpFile); + } catch (IOException ex) { + Logger.getLogger(PendantClient.class.getName()).log(Level.SEVERE, null, ex); + } catch (PmException ex) { + Logger.getLogger(PendantClient.class.getName()).log(Level.SEVERE, null, ex); + } + }//GEN-LAST:event_jMenuItemOpenStatusLogActionPerformed + + private void jButtonPlotProgramItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPlotProgramItemActionPerformed + final int index = this.jTableProgram.getSelectedRow(); + if (index > 0 && index < this.jTableProgram.getRowCount() - 1) { + MiddleCommandType cmdOrig = internal.getProgram().getMiddleCommand().get(index - 1); + BigInteger id = cmdOrig.getCommandID(); + final List l = + this.internal + .getPoseList() + .stream() + .filter(x -> x.getCmdId().compareTo(id) == 0) + .collect(Collectors.toList()); + com.github.wshackle.poselist3dplot.MainJFrame + .showPoseList(l); + } + }//GEN-LAST:event_jButtonPlotProgramItemActionPerformed + + private void jCheckBoxMenuItemUseEXIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemUseEXIActionPerformed + if(this.isConnected()) { + this.disconnect(); + this.connect(this.jTextFieldHost.getText(), Integer.valueOf(this.jTextFieldPort.getText())); + } + }//GEN-LAST:event_jCheckBoxMenuItemUseEXIActionPerformed + + private void jCheckBoxMenuItemUseReadStatusThreadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemUseReadStatusThreadActionPerformed + if(this.jCheckBoxMenuItemDebugReadStatus.isSelected()) { + internal.startStatusReaderThread(); + } else { + internal.stopStatusReaderThread(); + } + }//GEN-LAST:event_jCheckBoxMenuItemUseReadStatusThreadActionPerformed + + private static void scrollToVisible(JTable table, int rowIndex, int vColIndex) { + if (!(table.getParent() instanceof JViewport)) { + return; + } + JViewport viewport = (JViewport) table.getParent(); + Rectangle rect = table.getCellRect(rowIndex, vColIndex, true); + Point pt = viewport.getViewPosition(); + rect.setLocation(rect.x - pt.x, rect.y - pt.y); + viewport.scrollRectToVisible(rect); + } + + private void finishShowCurrentProgramLine(final int line) { + jTableProgram.clearSelection(); + jTableProgram.getSelectionModel().setSelectionInterval(line, line); + scrollToVisible(jTableProgram, line, 0); + jTableProgram.repaint(); + jPanelProgram.revalidate(); + jPanelProgram.repaint(); + } + + @Override + public void showCurrentProgramLine(final int line) { + if (line >= this.jTableProgram.getRowCount() || line < 0) { + return; + } + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + finishShowCurrentProgramLine(line); + } + }); + } + + @Override + public boolean isEXISelected() { + return this.jCheckBoxMenuItemUseEXI.isSelected(); + } + + @Override + public boolean isUseReadStatusThreadSelected() { + return this.jCheckBoxMenuItemUseReadStatusThread.isSelected(); + } + + + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } + // + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + try { + new PendantClient().setVisible(true); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + }); + } + + @Override + public boolean validateXmlSelected() { + return this.jCheckBoxMenuItemValidateXml.isSelected(); + + } + + @Override + public boolean replaceStateSelected() { + return this.jCheckBoxMenuItemReplaceState.isSelected(); + } + + @Override + public String getHost() { + return this.jTextFieldHost.getText(); + } + + @Override + public int getPort() { + return Integer.valueOf(this.jTextFieldPort.getText()); + } + + @Override + public boolean isDebugWaitForDoneSelected() { + return this.jCheckBoxMenuItemDebugWaitForDone.isSelected(); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonAddProgramItem; + private javax.swing.JButton jButtonConnect; + private javax.swing.JButton jButtonDeletProgramItem; + private javax.swing.JButton jButtonDisconnect; + private javax.swing.JButton jButtonEditProgramItem; + private javax.swing.JButton jButtonEnd; + private javax.swing.JButton jButtonInit; + private javax.swing.JButton jButtonMoveTo; + private javax.swing.JButton jButtonMoveToCurrent; + private javax.swing.JButton jButtonPlotProgramItem; + private javax.swing.JButton jButtonProgramAbort; + private javax.swing.JButton jButtonProgramPause; + private javax.swing.JButton jButtonProgramRun; + private javax.swing.JButton jButtonResume; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemDebugReadStatus; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemDebugSendCommand; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemDebugWaitForDone; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemJoints; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemPlotXYZ; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemRecordPoseList; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemReplaceState; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemUseEXI; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemUseReadStatusThread; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemValidateXml; + private javax.swing.JCheckBox jCheckBoxPoll; + private javax.swing.JCheckBox jCheckBoxStraight; + private javax.swing.JComboBox jComboBox1; + private javax.swing.JComboBox jComboBoxXYZRPY; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel10; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JLabel jLabelJogMinus; + private javax.swing.JLabel jLabelJogMinus1; + private javax.swing.JLabel jLabelJogPlus; + private javax.swing.JLabel jLabelJogPlus1; + private javax.swing.JMenu jMenu1; + private javax.swing.JMenu jMenu2; + private javax.swing.JMenuBar jMenuBarReplaceCommandState; + private javax.swing.JMenu jMenuCmds; + private javax.swing.JMenu jMenuCommandRecent; + private javax.swing.JMenuItem jMenuItemExit; + private javax.swing.JMenuItem jMenuItemOpenStatusLog; + private javax.swing.JMenuItem jMenuItemOpenXmlCommandInstance; + private javax.swing.JMenuItem jMenuItemOpenXmlProgram; + private javax.swing.JMenuItem jMenuItemPoseList3DPlot; + private javax.swing.JMenuItem jMenuItemRunTest; + private javax.swing.JMenuItem jMenuItemSavePoseList; + private javax.swing.JMenuItem jMenuItemSaveProgramAs; + private javax.swing.JMenuItem jMenuItemSetSchemaFiles; + private javax.swing.JMenuItem jMenuItemXPathQuery; + private javax.swing.JMenu jMenuOptions; + private javax.swing.JMenu jMenuRecentProgram; + private javax.swing.JMenu jMenuTools; + private javax.swing.JMenu jMenuXmlSchemas; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel5; + private javax.swing.JPanel jPanel6; + private javax.swing.JPanel jPanelJogMinus; + private javax.swing.JPanel jPanelJogMinus1; + private javax.swing.JPanel jPanelJogPlus; + private javax.swing.JPanel jPanelJogPlus1; + private javax.swing.JPanel jPanelJogging; + private javax.swing.JPanel jPanelMoveTo; + private javax.swing.JPanel jPanelProgram; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JScrollPane jScrollPane3; + private javax.swing.JScrollPane jScrollPane4; + private javax.swing.JScrollPane jScrollPaneProgram; + private javax.swing.JTabbedPane jTabbedPane1; + private javax.swing.JTable jTableJoints; + private javax.swing.JTable jTableMoveToPose; + private javax.swing.JTable jTablePose; + private javax.swing.JTable jTableProgram; + private javax.swing.JTextArea jTextAreaErrors; + private javax.swing.JTextField jTextFieldHost; + private javax.swing.JTextField jTextFieldJogTime; + private javax.swing.JTextField jTextFieldJointJogIncrement; + private javax.swing.JTextField jTextFieldPollTime; + private javax.swing.JTextField jTextFieldPort; + private javax.swing.JTextField jTextFieldRPYJogIncrement; + private javax.swing.JTextField jTextFieldStatCmdID; + private javax.swing.JTextField jTextFieldStatus; + private javax.swing.JTextField jTextFieldStatusID; + private javax.swing.JTextField jTextFieldXYZJogIncrement; + // End of variables declaration//GEN-END:variables + + @Override + public boolean isDebugSendCommandSelected() { + return this.jCheckBoxMenuItemDebugSendCommand.isSelected(); + } + + @Override + public boolean isDebugReadStatusSelected() { + return this.jCheckBoxMenuItemDebugReadStatus.isSelected(); + } + + + + @Override + public void showLastProgramLineExecTimeMillisDists(long millis, double dist) { + DefaultTableModel dtm = (DefaultTableModel) this.jTableProgram.getModel(); + final int row = this.jTableProgram.getSelectedRow(); + if(row >= 0 && row < dtm.getRowCount()) { + dtm.setValueAt(millis, row, 2); + dtm.setValueAt(dist, row, 3); + } + } + + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java new file mode 100644 index 0000000..459d09b --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java @@ -0,0 +1,1400 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.ActuateJointType; +import crcl.base.ActuateJointsType; +import crcl.base.AngleUnitEnumType; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLProgramType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStateEnumType; +import crcl.base.DwellType; +import crcl.base.EndCanonType; +import crcl.base.GetStatusType; +import crcl.base.InitCanonType; +import crcl.base.JointSpeedAccelType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.MiddleCommandType; +import crcl.base.MoveScrewType; +import crcl.base.MoveThroughToType; +import crcl.base.MoveToType; +import crcl.base.PoseType; +import crcl.base.PoseToleranceType; +import crcl.base.SetAngleUnitsType; +import crcl.base.SetEndPoseToleranceType; +import crcl.base.SetIntermediatePoseToleranceType; +import crcl.base.StopConditionEnumType; +import crcl.base.StopMotionType; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPathExpressionException; +import org.xml.sax.SAXException; +import rcs.posemath.PmCartesian; +import rcs.posemath.PmException; +import rcs.posemath.PmPose; +import rcs.posemath.PmRpy; +import rcs.posemath.Posemath; + +/** + * + * @author Will Shackleford {@literal } + */ +public class PendantClientInner { + + private Thread runTestProgramThread = null; + + private CRCLStatusType status; + private CRCLSocket crclSocket = null; + + private final PendantClientOuter outer; + private double jogIncrement = 3.0; + + private CRCLProgramType program; + + private PoseToleranceType expectedEndPoseTolerance = new PoseToleranceType(); + + /** + * Get the value of expectedEndPoseTolerance + * + * @return the value of expectedEndPoseTolerance + */ + public PoseToleranceType getExpectedEndPoseTolerance() { + return expectedEndPoseTolerance; + } + + /** + * Set the value of expectedEndPoseTolerance + * + * @param expectedEndPoseTolerance new value of expectedEndPoseTolerance + */ + public void setExpectedEndPoseTolerance(PoseToleranceType expectedEndPoseTolerance) { + this.expectedEndPoseTolerance = expectedEndPoseTolerance; + } + + private PoseToleranceType expectedIntermediatePoseTolerance; + + /** + * Get the value of expectedIntermediatePoseTolerance + * + * @return the value of expectedIntermediatePoseTolerance + */ + public PoseToleranceType getExpectedIntermediatePoseTolerance() { + return expectedIntermediatePoseTolerance; + } + + /** + * Set the value of expectedIntermediatePoseTolerance + * + * @param expectedIntermediatePoseToleranceType new value of + * expectedIntermediatePoseTolerance + */ + public void setExpectedIntermediatePoseTolerance(PoseToleranceType expectedIntermediatePoseToleranceType) { + this.expectedIntermediatePoseTolerance = expectedIntermediatePoseToleranceType; + } + + /** + * Get the value of program + * + * @return the value of program + */ + public CRCLProgramType getProgram() { + return program; + } + + /** + * Set the value of program + * + * @param program new value of program + */ + public void setProgram(CRCLProgramType program) { + this.program = program; + } + + public CRCLSocket getCRCLSocket() { + return this.crclSocket; + } + + public PendantClientInner(PendantClientOuter outer) throws ParserConfigurationException { + this.outer = outer; + this.xpu = new XpathUtils(); + this.expectedEndPoseTolerance = new PoseToleranceType(); + this.expectedEndPoseTolerance.setXAxisTolerance(BIG_DECIMAL_FIVE_DEGREES_IN_RADIANS); + this.expectedEndPoseTolerance.setZAxisTolerance(BIG_DECIMAL_FIVE_DEGREES_IN_RADIANS); + this.expectedEndPoseTolerance.setXPointTolerance(BIG_DECIMAL_POINT_01); + this.expectedEndPoseTolerance.setYPointTolerance(BIG_DECIMAL_POINT_01); + this.expectedEndPoseTolerance.setZPointTolerance(BIG_DECIMAL_POINT_01); + + this.expectedIntermediatePoseTolerance = new PoseToleranceType(); + this.expectedIntermediatePoseTolerance.setXAxisTolerance(BIG_DECIMAL_FIVE_DEGREES_IN_RADIANS); + this.expectedIntermediatePoseTolerance.setZAxisTolerance(BIG_DECIMAL_FIVE_DEGREES_IN_RADIANS); + this.expectedIntermediatePoseTolerance.setXPointTolerance(BIG_DECIMAL_POINT_01); + this.expectedIntermediatePoseTolerance.setYPointTolerance(BIG_DECIMAL_POINT_01); + this.expectedIntermediatePoseTolerance.setZPointTolerance(BIG_DECIMAL_POINT_01); + } + public static final BigDecimal BIG_DECIMAL_POINT_01 = new BigDecimal("0.01"); + public static final BigDecimal BIG_DECIMAL_FIVE_DEGREES_IN_RADIANS = BigDecimal.valueOf(Math.PI / 36); + + private volatile int close_test_count = 0; + + public void closeTestProgramThread() { + close_test_count++; + if (null != runTestProgramThread) { + if (runTestProgramThread.equals(Thread.currentThread())) { + return; + } + this.runTestProgramThread.interrupt(); + try { + this.runTestProgramThread.join(100); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + this.runTestProgramThread = null; + } + } + public static final Logger LOGGER = Logger.getLogger(PendantClientInner.class.getName()); + + public boolean isDone(BigInteger minCmdId) { + return this.status != null + && this.status.getCommandStatus() != null + && this.status.getCommandStatus().getCommandID() != null + && this.status.getCommandStatus().getCommandID().compareTo(minCmdId) >= 0 + && this.status.getCommandStatus().getCommandState() != CommandStateEnumType.WORKING; + } + + int request_status_count = 0; + public boolean requestStatus() { +// try { +// Thread.sleep(100); +// } catch (InterruptedException ex) { +// Logger.getLogger(PendantClientInner.class.getName()).log(Level.SEVERE, null, ex); +// } + request_status_count++; + LOGGER.log(Level.FINEST,() -> "PendantClientInner.requestStatus() : request_status_count="+request_status_count); + boolean result = false; + synchronized (this) { + if (null == cmdId) { + cmdId = BigInteger.ONE; + } + getStatusMsg.setCommandID(cmdId); + result = this.sendCommand(getStatusMsg); + } + LOGGER.log(Level.FINEST, () -> "PendantClientInner.requestStatus() : returning from RequestStatus() "+ request_status_count); + return result; + } + + private final GetStatusType getStatusMsg = new GetStatusType(); + private int jogInterval = 200; + + private double xyzJogIncrement = 3.0; + private int poll_ms = jogInterval; + + private BigInteger cmdId = BigInteger.ONE; + + private void showMessage(String s) { + outer.showMessage(s); + } + + private void showDebugMessage(String s) { + outer.showDebugMessage(s); + } + + private void showMessage(Throwable t) { + outer.showMessage(t); + } + + private final XpathUtils xpu; + + public XpathUtils getXpu() { + return this.xpu; + } + + private CRCLSocket checkerCRCLSocket = null; + private CRCLCommandInstanceType checkerCommandInstance = null; + + private final Predicate checkProgramValidPredicate + = this::checkProgramValid; + + public Predicate getCheckProgramValidPredicate() { + return checkProgramValidPredicate; + } + + public Predicate getCheckCommandValidPredicate() { + return checkCommandValidPredicate; + } + + public boolean checkProgramValid(CRCLProgramType prog) { + try { + + if (null == checkerCRCLSocket) { + checkerCRCLSocket = new CRCLSocket(); + } + if (null == checkerCommandInstance) { + checkerCommandInstance = new CRCLCommandInstanceType(); + } + String s = checkerCRCLSocket.programToPrettyString(prog, true); + return MultiLineStringJPanel.showText(s); + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } + return false; + } + + private final Predicate checkCommandValidPredicate + = this::checkCommandValid; + + public CRCLSocket getTempCRCLSocket() { + CRCLSocket tmpcs = checkerCRCLSocket; + if (tmpcs == null) { + if (null == checkerCRCLSocket) { + checkerCRCLSocket = new CRCLSocket(); + } + tmpcs = this.checkerCRCLSocket; + } + return tmpcs; + } + + public boolean checkCommandValid(CRCLCommandType cmdObj) { + try { + + if (null == checkerCRCLSocket) { + checkerCRCLSocket = new CRCLSocket(); + } + if (null == checkerCommandInstance) { + checkerCommandInstance = new CRCLCommandInstanceType(); + } + checkerCommandInstance.setCRCLCommand(cmdObj); + String s = checkerCRCLSocket.commandToPrettyString(checkerCommandInstance, true); + if (cmdObj instanceof MoveThroughToType) { + MoveThroughToType mtt = (MoveThroughToType) cmdObj; + int num_positions = mtt.getNumPositions().intValue(); + if (num_positions < 2) { + throw new RuntimeException("MoveThroughToType : NumPositions must be at-least 2 but was " + num_positions); + } + int wpts_length = mtt.getWaypoint().size(); + if (wpts_length != num_positions) { + throw new RuntimeException("MoveThroughToType : NumPositions must equal number of waypoints but NumPostions=" + num_positions + + " but number of waypoints = " + wpts_length); + } + } + return MultiLineStringJPanel.showText(s); + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } + return false; + } + + private File[] cmdSchemaFiles = null; + private File[] programSchemaFiles = null; + + public synchronized void setStatSchema(File[] fa) { + try { + fa = CRCLSocket.reorderStatSchemaFiles(fa); + CRCLSocket.defaultStatSchema = CRCLSocket.filesToSchema(fa); + if (null != this.crclSocket) { + this.crclSocket.setStatSchema(CRCLSocket.defaultStatSchema); + } + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + +// public String getDocumentation(String name) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { +// return xpu.queryXml(cmdSchemaFiles, "/schema/complexType[@name=\""+name+"\"]/annotation/documentation/text()"); +// } + public synchronized void setCmdSchema(File[] fa) { + try { + fa = CRCLSocket.reorderCommandSchemaFiles(fa); + CRCLSocket.defaultCmdSchema = CRCLSocket.filesToSchema(fa); + if (null != this.crclSocket) { + this.crclSocket.setCmdSchema(CRCLSocket.defaultCmdSchema); + } + cmdSchemaFiles = fa; + this.xpu.setSchemaFiles(cmdSchemaFiles); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public synchronized void setProgramSchema(File[] fa) { + try { + fa = CRCLSocket.reorderProgramSchemaFiles(fa); + CRCLSocket.defaultProgramSchema = CRCLSocket.filesToSchema(fa); + if (null != this.crclSocket) { + this.crclSocket.setProgramSchema(CRCLSocket.defaultProgramSchema); + } + programSchemaFiles = fa; +// xpu.setSchemaFiles(cmdSchemaFiles); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public File[] getCmdSchemaFiles() { + return cmdSchemaFiles; + } + + public File[] getProgramSchemaFiles() { + return programSchemaFiles; + } + + public void openXmlProgramFile(File f) throws ParserConfigurationException, JAXBException, XPathExpressionException, IOException, SAXException { + String s = this.xpu.queryXml(f, "/"); + CRCLSocket cs = checkerCRCLSocket; + if (null == cs) { + if (null == checkerCRCLSocket) { + checkerCRCLSocket = new CRCLSocket(); + } + cs = checkerCRCLSocket; + } + CRCLProgramType program + = cs.stringToProgram(s, outer.validateXmlSelected()); + + if (null == program.getName() || program.getName().length() < 1) { + String fname = f.getName(); + if (fname.endsWith(".xml")) { + fname = fname.substring(0, fname.length() - 4); + } + program.setName(fname); + } + this.setProgram(program); + outer.finishOpenXmlProgramFile(f, program); +// cmdId = cmdId.add(BigInteger.ONE); +// cmd.setCommandID(cmdId); +// this.sendCommand(cmd); +// this.saveRecentCommand(cmd); + } + + public void saveXmlProgramFile(File f) throws ParserConfigurationException, JAXBException, XPathExpressionException, IOException, SAXException { + CRCLSocket cs = checkerCRCLSocket; + if (null == cs) { + if (null == checkerCRCLSocket) { + checkerCRCLSocket = new CRCLSocket(); + } + cs = checkerCRCLSocket; + } + if (null == program.getName() || program.getName().length() < 1) { + String fname = f.getName(); + if (fname.endsWith(".xml")) { + fname = fname.substring(0, fname.length() - 4); + } + program.setName(fname); + } + String str + = cs.programToPrettyString(program, outer.validateXmlSelected()); + try (PrintWriter pw = new PrintWriter(new FileWriter(f))) { + pw.println(str); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } + } + + private CRCLCommandType lastCommandSent = null; + private CRCLCommandType prevLastCommandSent = null; + + private synchronized boolean sendCommandPrivate(CRCLCommandType cmd) { + try { + if (null == crclSocket) { + showMessage("Can not send command when not connected."); + return false; + } + CRCLCommandInstanceType cmdInstance + = new CRCLCommandInstanceType(); + cmdInstance.setCRCLCommand(cmd); + if (!(cmdInstance.getCRCLCommand() instanceof GetStatusType)) { + prevLastCommandSent = lastCommandSent; + lastCommandSent = cmdInstance.getCRCLCommand(); + } + crclSocket.writeCommand(cmdInstance, outer.validateXmlSelected()); + return true; + } catch (JAXBException | IOException | EXIException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return false; + } + + private synchronized void incCommandID(CRCLCommandType cmd) { + if (null == cmdId) { + cmdId = BigInteger.ZERO; + } + if (null != cmd.getCommandID() + && cmd.getCommandID().compareTo(cmdId) > 0) { + cmdId = cmd.getCommandID(); + } + if (null != status + && null != status.getCommandStatus() + && null != status.getCommandStatus().getCommandID() + && status.getCommandStatus().getCommandID().compareTo(cmdId) > 0) { + cmdId = status.getCommandStatus().getCommandID(); + } + cmdId = cmdId.add(BigInteger.ONE); + cmd.setCommandID(cmdId); + } + + public boolean incAndSendCommand(CRCLCommandType cmd) { + this.incCommandID(cmd); + return sendCommand(cmd); + } + + public synchronized boolean sendCommand(CRCLCommandType cmd) { + if (null == cmd) { + throw new IllegalArgumentException("cmd can not be null"); + } + if (null == this.crclSocket) { + throw new IllegalStateException("crclSocket must not be null."); + } + if (!(cmd instanceof GetStatusType) && outer.isDebugSendCommandSelected()) { + showDebugMessage("PendantClientInner.sendCommand() : cmd = " + cmdString(cmd)); + } + if (cmd instanceof SetAngleUnitsType) { + SetAngleUnitsType setAngle = (SetAngleUnitsType) cmd; + this.setAngleType(setAngle.getUnitName()); + } else if (cmd instanceof SetEndPoseToleranceType) { + SetEndPoseToleranceType endPoseTol = (SetEndPoseToleranceType) cmd; + this.setExpectedEndPoseTolerance(endPoseTol.getTolerance()); + } else if (cmd instanceof SetIntermediatePoseToleranceType) { + SetIntermediatePoseToleranceType intermediatePoseTol = (SetIntermediatePoseToleranceType) cmd; + this.setExpectedIntermediatePoseTolerance(intermediatePoseTol.getTolerance()); + } + boolean ret = this.sendCommandPrivate(cmd); + if (!(cmd instanceof GetStatusType) && outer.isDebugSendCommandSelected()) { + showDebugMessage("PendantClientInner.sendCommand() : ret = " + ret); + } + return ret; + } + + public void abort() { + this.closeTestProgramThread(); + unpause(); + stopMotion(StopConditionEnumType.FAST); + } + + /** + * + * @param stopType the value of stopType + */ + public void stopMotion(StopConditionEnumType stopType) { + StopMotionType stop = new StopMotionType(); + stop.setStopCondition(stopType); + this.incAndSendCommand(stop); + } + + /** + * + * @param minCmdId the value of minCmdId + * @param timeoutMilliSeconds the value of timeoutMilliSeconds + * @return the boolean + * @throws InterruptedException when Thread interrupted + */ + public boolean waitForDone(BigInteger minCmdId, long timeoutMilliSeconds) + throws InterruptedException { + + boolean returnDone = false; + try { + if (outer.isDebugWaitForDoneSelected()) { + showDebugStatus(); + } + long start = System.currentTimeMillis(); + long timeDiff = System.currentTimeMillis() - start; + int old_pause_count = this.pause_count; + final long fullTimeout = timeoutMilliSeconds + + ((waitForDoneDelay > 0) ? 2 * waitForDoneDelay : 0); + while (!Thread.currentThread().isInterrupted() + && !isDone(minCmdId) + && timeDiff < fullTimeout) { + if (outer.isDebugWaitForDoneSelected()) { + showDebugStatus(); + showDebugMessage("PendantClient waitForDone(" + minCmdId + ") timeDiff = " + timeDiff + " / " + timeoutMilliSeconds + " = " + ((double) timeDiff) / timeoutMilliSeconds); + } + if (waitForDoneDelay > 0) { + Thread.sleep(waitForDoneDelay); + } + if (!requestStatus()) { + return false; + } + if (null == readerThread) { + readStatus(); + } + if (this.pause_count != old_pause_count || this.paused) { + return false; + } + if (this.pause_count != old_pause_count || this.paused) { + return false; + } + timeDiff = System.currentTimeMillis() - start; + } + if (outer.isDebugWaitForDoneSelected()) { + showDebugMessage("PendantClient waitForDone(" + minCmdId + ") returning"); + showDebugStatus(); + showDebugMessage("PendantClient timeDiff = " + timeDiff + " / " + timeoutMilliSeconds + " = " + ((double) timeDiff) / timeoutMilliSeconds); + if (timeDiff >= timeoutMilliSeconds) { + showMessage("Timed out waiting for DONE."); + } + } + returnDone = !Thread.currentThread().isInterrupted() + && isDone(minCmdId); + } catch (NullPointerException ex) { + // Ugly hack hoping to catch strange debugging problem. + LOGGER.log(Level.SEVERE, null, ex); + } + return returnDone; + } + + private static long getLongProperty(String propName, long defaultLong) { + return Long.valueOf(System.getProperty(propName, Long.toString(defaultLong))); + } + + private long waitForDoneDelay = getLongProperty("PendantClient.waitForDoneDelay", 200); + + public long getWaitForDoneDelay() { + return waitForDoneDelay; + } + + public void setWaitForDoneDelay(long waitForDoneDelay) { + this.waitForDoneDelay = waitForDoneDelay; + } + + private void showDebugStatus() { + if (null == this.status) { + showDebugMessage("PendantClient this.status == null"); + } else { + if (null == this.status.getCommandStatus()) { + showDebugMessage("PendantClient this.status.getCommandStatus() == null"); + } else { + showDebugMessage("PendantClient this.status.getCommandStatus().getCommandID() =" + + this.status.getCommandStatus().getCommandID()); + showDebugMessage("PendantClient this.status.getCommandStatus().getCommandState() =" + + this.status.getCommandStatus().getCommandState()); + } + } + } + + Thread readerThread = null; + + /** + * Set the value of status + * + * @param status new value of status + */ + public void setStatus(CRCLStatusType status) { + this.status = status; + outer.finishSetStatus(); + } + + public CRCLStatusType getStatus() { + return this.status; + } + + private List poseList = null; + + public List getPoseList() { + return poseList; + } + + public static interface TrySupplier { + + public T tryGet() throws Throwable; + + }; + + public static Optional tryGet(TrySupplier ts) { + try { + return Optional.of(ts.tryGet()); + } catch (Throwable ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return Optional.empty(); + } + + public static Optional getJointStatus(CRCLStatusType status, BigInteger id) { + return Optional.ofNullable(status) + .map((x) -> x.getJointStatuses()) + .filter((x) -> x != null) + .map((x) -> x.getJointStatus()) + .flatMap((x) -> x.stream().filter((x2) -> x2.getJointNumber().compareTo(id) == 0).findAny()); + } + + public static Stream getJointValues(CRCLStatusType status, + Collection ids) { + return ids.stream() + .map((x) -> getJointStatus(status, x)) + .flatMap((x) -> x.map(Stream::of).orElseGet(Stream::empty)); + } + + public static String getJointString(CRCLStatusType status, + Function mapper, + Collection ids) { + return getJointValues(status, ids) + .map(mapper) + .collect(Collectors.joining(",")); + } + + public void savePoseListToCsvFile(String poseFileName) throws IOException, PmException { + if (null == poseFileName + || this.getPoseList() == null + || this.getPoseList().isEmpty()) { + return; + } + List jss + = this.getPoseList() + .stream() + .map((x) -> x.getStatus()) + .filter((x) -> x != null) + .map((x) -> x.getJointStatuses()) + .filter((x) -> x != null) + .collect(Collectors.toList()); + final Set jointIds = new TreeSet<>(); + jss.stream() + .flatMap((x) -> x.getJointStatus().stream()) + .forEach((x) -> jointIds.add(x.getJointNumber())); + Optional exampleJss = jss.stream().findAny(); + Optional exampleJs + = exampleJss + .map((x) -> x.getJointStatus()) + .map((x) -> x.stream().findAny()) + .orElse(Optional.empty()); + final boolean havePos + = exampleJs + .map((x) -> x.getJointPosition() != null) + .orElse(false); + final boolean haveVel + = exampleJs + .map((x) -> x.getJointVelocity() != null) + .orElse(false); + final boolean haveForce + = exampleJs + .map((x) -> x.getJointTorqueOrForce() != null) + .orElse(false); + + final PmRpy rpyZero = new PmRpy(); + try (PrintWriter pw = new PrintWriter(new FileWriter(poseFileName))) { + String headers = "time,cmdId,cmdName,x,y,z,roll,pitch,yaw," + + (havePos ? jointIds.stream().map((x) -> "Joint" + x + "Pos").collect(Collectors.joining(",")) : "") + + (haveVel ? jointIds.stream().map((x) -> "Joint" + x + "Vel").collect(Collectors.joining(",")) : "") + + (haveForce ? jointIds.stream().map((x) -> "Joint" + x + "Force").collect(Collectors.joining(",")) : ""); + pw.println(headers); + this.getPoseList() + .stream() + .map((pose) -> { + PmRpy rpy = tryGet(() -> Posemath.toRpy(pose.rot)).orElse(rpyZero); + Stream stream = Stream.builder() + .add(pose.getTime()) + .add(pose.getCmdId()) + .add(pose.getCommandName()) + .add(pose.tran.x) + .add(pose.tran.y) + .add(pose.tran.z) + .add(Math.toDegrees(rpy.r)) + .add(Math.toDegrees(rpy.p)) + .add(Math.toDegrees(rpy.y)) + .build(); + if (havePos) { + stream = Stream.concat(stream, getJointValues(status, jointIds) + .map((x) -> x.getJointPosition()) + ); + } + if (haveVel) { + stream = Stream.concat(stream, getJointValues(status, jointIds) + .map((x) -> x.getJointVelocity()) + ); + } + if (haveForce) { + stream = Stream.concat(stream, getJointValues(status, jointIds) + .map((x) -> x.getJointTorqueOrForce()) + ); + } + return stream + .map((x) -> x.toString()) + .collect(Collectors.joining(",")); + }) + .forEach((s) -> pw.println(s)); + } + } + + public void readStatus() { + try { + if (outer.replaceStateSelected()) { + crclSocket.setStatusStringInputFilter(CRCLSocket.addCRCLToState); + } else { + crclSocket.setStatusStringInputFilter(null); + } + final CRCLStatusType curStatus + = crclSocket.readStatus(outer.validateXmlSelected()); + if (outer.isDebugReadStatusSelected()) { + //outer.showDebugMessage("curStatus = "+curStatus); + String statString = crclSocket.getLastStatusString(); + outer.showDebugMessage("crclSocket.getLastStatusString() = " + statString); + if (null != curStatus + && (null == statString || statString.length() < 1)) { + outer.showDebugMessage("crclSocket.statusToString(curStatus,false)=" + + crclSocket.statusToString(curStatus, false)); + } + } + if (curStatus == null) { + return; + } + outer.checkXmlQuery(crclSocket); + if (outer.isRecordPoseSelected() + && null != curStatus.getPose()) { + if (null == poseList) { + poseList = new ArrayList<>(); + } + PmPose pmPose = CRCLPosemath.toPmPose(curStatus.getPose()); + BigInteger cmdId2 + = Optional.ofNullable(status) + .map((x) -> x.getCommandStatus()) + .map((x) -> x.getCommandID()) + .orElse(cmdId); + AnnotatedPose annotatedPose + = new AnnotatedPose(System.currentTimeMillis(), + cmdId2, + cmdId.compareTo(cmdId2) <= 0 ? cmdNameString(lastCommandSent) : cmdNameString(prevLastCommandSent), + pmPose.tran, pmPose.rot, + status + ); + poseList.add(annotatedPose); + } + this.setStatus(curStatus); + + } catch (IOException | IllegalStateException ex) { + if (disconnecting) { + return; + } + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex); + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + try { + PendantClientInner.this.disconnect(); + } catch (Exception e) { + // ignore + } + } + }); + + } catch (JAXBException ex) { + if (disconnecting) { + return; + } + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex.toString() + "\n" + crclSocket.getLastStatusString() + "\n"); + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + try { + disconnect(); + } catch (Exception e) { + // ignore + } + } + }); + } catch (Exception ex) { + if (disconnecting) { + return; + } + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public boolean isConnected() { + return null != this.crclSocket && this.crclSocket.isConnected(); + } + + public synchronized void connect(String host, int port) { + try { + disconnect(); + disconnecting = false; + crclSocket = new CRCLSocket(host, port); + crclSocket.setEXIEnabled(outer.isEXISelected()); + startStatusReaderThread(); + outer.finishConnect(); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage("Can't connect to " + host + ":" + port + " -- " + ex.getMessage()); + } catch (EXIException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public void startStatusReaderThread() { + this.stopStatusReaderThread(); + if (outer.isUseReadStatusThreadSelected()) { + readerThread = new Thread(new Runnable() { + + @Override + public void run() { + final Thread t = Thread.currentThread(); + while (!t.isInterrupted() + && !stopStatusReaderFlag + && null != crclSocket + && crclSocket.isConnected()) { + PendantClientInner.this.readStatus(); + } + } + }, "PendantClientInner.statusReaderThread"); + readerThread.start(); + } + } + + private boolean disconnecting = false; + + public synchronized void disconnect() { + disconnecting = true; + if (null != crclSocket) { + try { + crclSocket.close(); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + crclSocket = null; + } + stopStatusReaderThread(); + if (null != runTestProgramThread && !runTestProgramThread.equals(Thread.currentThread())) { + this.closeTestProgramThread(); + } + outer.finishDisconnect(); + } + + private boolean stopStatusReaderFlag = false; + + public void stopStatusReaderThread() { + if (null != readerThread) { + try { + stopStatusReaderFlag = true; + readerThread.interrupt(); + readerThread.join(1500); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } finally { + readerThread = null; + stopStatusReaderFlag = false; + } + + } + } + + private BigDecimal jointTol = BigDecimal.valueOf(jogIncrement / 5.0); + + private boolean testCommandEffect(CRCLCommandType cmd, long cmdStartTime) { + if (cmd instanceof ActuateJointsType) { + return testAcutateJointsEffect((ActuateJointsType) cmd); + } + if (cmd instanceof MoveThroughToType) { + return testMoveThroughToEffect((MoveThroughToType) cmd); + } + if (cmd instanceof MoveToType) { + return testMoveToEffect((MoveToType) cmd); + } + if (cmd instanceof DwellType) { + return testDwellEffect((DwellType) cmd, cmdStartTime); + } + return true; + } + + private boolean testAcutateJointsEffect(ActuateJointsType ajst) { + List ajl = ajst.getActuateJoint(); + for (ActuateJointType aj : ajl) { + List jointListTest = status.getJointStatuses().getJointStatus(); + JointStatusType jointStatusTest = null; + for (int j = 0; j < jointListTest.size(); j++) { + JointStatusType jsj = jointListTest.get(j); + if (jsj.getJointNumber().compareTo(aj.getJointNumber()) == 0) { + jointStatusTest = jointListTest.get(j); + break; + } + } + if (null == jointStatusTest) { + showMessage("Test program failed : no jointStatus for " + aj.getJointNumber()); + return false; + } + BigDecimal jointDiff = jointStatusTest.getJointPosition().subtract(aj.getJointPosition()).abs(); + if (jointDiff.compareTo(jointTol) > 0) { + showMessage("Test program failed measured position differs from commanded position.\n" + + "JointNumber: " + aj.getJointNumber() + "\n" + + "Commanded :" + aj.getJointPosition() + "\n" + + "Status (Measured): " + jointStatusTest.getJointPosition() + "\n" + + "Diff: " + jointDiff); + return false; + } + } + return true; + } + + private AngleUnitEnumType angleType = AngleUnitEnumType.RADIAN; + + /** + * Get the value of angleType + * + * @return the value of angleType + */ + public AngleUnitEnumType getAngleType() { + return angleType; + } + + public void setAngleType(AngleUnitEnumType newAngleType) { + this.angleType = newAngleType; + } + + private boolean testMoveThroughToEffect(MoveThroughToType moveThroughTo) { + PoseType curPose = status.getPose(); + PoseType cmdPose = moveThroughTo.getWaypoint().get(moveThroughTo.getNumPositions().intValue() - 1); + return PoseToleranceChecker.isInTolerance(curPose, cmdPose, expectedEndPoseTolerance, angleType); + } + + private boolean testDwellEffect(DwellType dwell, long startTime) { + long elapsed = System.currentTimeMillis() - startTime; + long expected = (long) (dwell.getDwellTime().doubleValue() * 1000.0); + if (Math.abs(elapsed - expected) > 1500) { + outer.showMessage("Dwell expected to take " + expected + " ms but took " + elapsed + " ms."); + return false; + } + return true; + } + + private boolean testMoveToEffect(MoveToType moveTo) { + PoseType curPose = status.getPose(); + if (PoseToleranceChecker.containsNull(curPose)) { + outer.showMessage("MoveTo Failed current pose contains null."); + return false; + } + PoseType cmdPose = moveTo.getEndPosition(); + if (PoseToleranceChecker.containsNull(curPose)) { + outer.showMessage("MoveTo Failed cmdPose contains null."); + return false; + } + if (!PoseToleranceChecker.isInTolerance(curPose, cmdPose, expectedEndPoseTolerance, angleType)) { + outer.showMessage("MoveTo Failed : diference between curPose and cmdPose exceeds tolerance."); + return false; + } + return true; + } + + private volatile BlockingQueue pauseQueue = new ArrayBlockingQueue(1); + private volatile boolean paused = false; + private volatile int waiting_for_pause_queue = 0; + private volatile int pause_count = 0; + + public void pause() { + pause_count++; + pauseQueue.clear(); + paused = true; + stopMotion(StopConditionEnumType.NORMAL); + } + + public void waitForPause() throws InterruptedException { + while (paused) { + waiting_for_pause_queue++; + pauseQueue.take(); + waiting_for_pause_queue--; + } + } + + public void unpause() { + paused = false; + for (int i = 0; i < waiting_for_pause_queue + 1; i++) { + try { + pauseQueue.put(this); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + + long programCommandStartTime; + + public boolean runProgram(CRCLProgramType prog) { + final int start_close_test_count = this.close_test_count; + try { + if (null == this.crclSocket) { + this.connect(outer.getHost(), outer.getPort()); + } + outer.stopPollTimer(); + outer.showCurrentProgramLine(0); +// this.stopStatusReaderThread(); + cmdId = BigInteger.ZERO; + programCommandStartTime = System.currentTimeMillis(); + PmCartesian p0 = getPoseCart(); + + InitCanonType initCmd = prog.getInitCanon(); + if (!testCommand(initCmd)) { + return false; + } + long time_to_exec = System.currentTimeMillis() - programCommandStartTime; + PmCartesian p1 = getPoseCart(); + outer.showLastProgramLineExecTimeMillisDists(time_to_exec, p1.distFrom(p0)); + p0 = p1; + outer.showCurrentProgramLine(1); + List middleCommands = prog.getMiddleCommand(); + for (int i = 0; i < middleCommands.size(); i++) { + programCommandStartTime = System.currentTimeMillis(); + MiddleCommandType cmd = middleCommands.get(i); + if (!testCommand(cmd)) { + return false; + } + time_to_exec = System.currentTimeMillis() - programCommandStartTime; + p1 = getPoseCart(); + outer.showLastProgramLineExecTimeMillisDists(time_to_exec, p1.distFrom(p0)); + p0 = p1; + outer.showCurrentProgramLine(i + 2); + } + programCommandStartTime = System.currentTimeMillis(); + EndCanonType endCmd = prog.getEndCanon(); + if (!testCommand(endCmd)) { + return false; + } + time_to_exec = System.currentTimeMillis() - programCommandStartTime; + outer.showLastProgramLineExecTimeMillisDists(time_to_exec, 0); + outer.showCurrentProgramLine(middleCommands.size() + 2); + outer.showDebugMessage("testProgram() succeeded"); + return true; + } catch (InterruptedException ex) { + if (close_test_count <= start_close_test_count) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + return false; + } + + private PmCartesian getPoseCart() { + PmCartesian p0 + = Optional.ofNullable(status) + .map(x -> x.getPose()) + .filter(x -> x != null) + .map(x -> x.getPoint()) + .filter(x -> x != null) + .map(CRCLPosemath::pointToPmCartesian) + .orElse(new PmCartesian()); + return p0; + } + + public boolean isPaused() { + return this.paused; + } + + public boolean isRunningProgram() { + return !paused + && null != this.runTestProgramThread + && this.runTestProgramThread.isAlive(); + } + + /** + * Tests if an automatically generated set of commands appears to be + * correctly implemented by the server. + * + * @return false for failure or true for success + */ + public boolean runTest() { + try { + if (null == this.crclSocket) { + this.connect(outer.getHost(), outer.getPort()); + } + outer.stopPollTimer(); + InitCanonType initCmd = new InitCanonType(); + if (!testCommand(initCmd)) { + return false; + } + Thread.sleep(1000); + jointTol = BigDecimal.valueOf(jogIncrement / 5.0); + if (null != status.getJointStatuses()) { + List jointList = status.getJointStatuses().getJointStatus(); + for (int i = 0; i < jointList.size(); i++) { + JointStatusType js = jointList.get(i); + ActuateJointsType ajst = new ActuateJointsType(); + List ajl = ajst.getActuateJoint(); + ActuateJointType aj = new ActuateJointType(); + aj.setJointNumber(js.getJointNumber()); + BigDecimal origPosition = BigDecimal.valueOf(js.getJointPosition().doubleValue()); + aj.setJointPosition(js.getJointPosition().add(BigDecimal.valueOf(jogIncrement))); + JointSpeedAccelType jsa = new JointSpeedAccelType(); + aj.setJointDetails(jsa); + ajl.add(aj); + if (!testCommand(ajst)) { + return false; + } + Thread.sleep(2000); + ajst = new ActuateJointsType(); + ajl = ajst.getActuateJoint(); + aj = new ActuateJointType(); + aj.setJointNumber(js.getJointNumber()); + aj.setJointPosition(origPosition); + jsa = new JointSpeedAccelType(); + aj.setJointDetails(jsa); + ajl.add(aj); + if (!testCommand(ajst)) { + return false; + } + } + } + EndCanonType endCmd = new EndCanonType(); + if (!testCommand(endCmd)) { + return false; + } + showMessage("Test program ran successfully."); + return true; + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + return false; + } finally { + outer.checkPollSelected(); + } + } + + private String cmdNameString(CRCLCommandType cmd) { + if (null == cmd) { + return ""; + } + String cmdName = cmd.getClass().getSimpleName(); + final String prefix = "crcl.base."; + if (cmdName.startsWith(prefix)) { + return cmdName.substring(prefix.length()); + } + return cmdName; + } + + private String cmdString(CRCLCommandType cmd) { + String cmdName = cmdNameString(cmd); + return cmdName + " with ID = " + cmd.getCommandID() + ", \txml: " + this.getTempCRCLSocket().commandToString(cmd, false); + } + + public BigDecimal getJointPosition(BigInteger jointNumber) { + if (null == status || null == status.getJointStatuses()) { + return null; + } + List jsl = status.getJointStatuses().getJointStatus(); + if (null == jsl) { + return null; + } + for (JointStatusType js : jsl) { + if (js.getJointNumber().compareTo(jointNumber) == 0) { + return js.getJointPosition(); + } + } + return null; + } + + private long getTimeoutForAcuateJoints(ActuateJointsType ajst) { + List ajl = ajst.getActuateJoint(); + BigDecimal diff = BigDecimal.ZERO; + for (ActuateJointType aj : ajl) { + BigDecimal jp = getJointPosition(aj.getJointNumber()); + if (null != jp) { + diff = diff.max(jp.subtract(aj.getJointPosition()).abs()); + } + } + return 2000 + (long) (diff.doubleValue() * 1000.0); + } + + private long getTimeoutForMoveThroughTo(MoveThroughToType cmd) { + return 90000; + } + + private long getTimeoutForMoveTo(MoveToType cmd) { + return 90000; + } + + private long getTimeoutForMoveScrew(MoveScrewType cmd) { + return 90000; + } + + private long getTimeoutForDwell(DwellType cmd) { + return (long) (1500 + cmd.getDwellTime().doubleValue() * 1000); + } + + private long getTimeout(CRCLCommandType cmd) { + if (cmd instanceof ActuateJointsType) { + return getTimeoutForAcuateJoints((ActuateJointsType) cmd); + } + if (cmd instanceof MoveThroughToType) { + return getTimeoutForMoveThroughTo((MoveThroughToType) cmd); + } + if (cmd instanceof MoveToType) { + return getTimeoutForMoveTo((MoveToType) cmd); + } + if (cmd instanceof MoveScrewType) { + return getTimeoutForMoveScrew((MoveScrewType) cmd); + } + if (cmd instanceof DwellType) { + return getTimeoutForDwell((DwellType) cmd); + } + return 3000; + } + + /** + * + * @param cmd the value of command to test + * @param timeout the value of timeout + * @return false for failure or true for success + * @throws InterruptedException + */ + private boolean testCommand(CRCLCommandType cmd) throws InterruptedException { + final long timeout = getTimeout(cmd); + int pause_count_start = this.pause_count; + long testCommandStartTime = System.currentTimeMillis(); + do { + if (null == crclSocket) { + throw new IllegalStateException("crclSocket must not be null"); + } + if (cmd instanceof GetStatusType) { + showDebugMessage("Ignoring command GetStatusType inside a program."); + return true; + } + this.waitForPause(); + pause_count_start = this.pause_count; + if (!incAndSendCommand(cmd)) { + final String cmdString = cmdString(cmd); + if (pause_count_start != this.pause_count) { + continue; + } + showMessage("Can not send " + cmdString + "."); + return false; + } + final String cmdString = cmdString(cmd); + long sendCommandTime = System.currentTimeMillis(); + if (!waitForDone(cmd.getCommandID(), timeout)) { + if (pause_count_start != this.pause_count) { + continue; + } + long curTime = System.currentTimeMillis(); + showMessage("Test Progam failed waiting for DONE from " + cmdString + ".\n" + + "sendCommandTime=" + sendCommandTime + "\n" + + "curTime = " + curTime + "\n" + + "(curTime-sendCommandTime)=" + (curTime - sendCommandTime) + "\n" + + "timeout=" + timeout + "\n" + + "cmd.getCommandID() = " + cmd.getCommandID() + "\n" + + ((status == null || status.getCommandStatus() == null) + ? "status.getCommandStatus()=null\n" + : ("status.getCommandStatus().getCommandID()=" + status.getCommandStatus().getCommandID() + "\n" + + "status.getCommandStatus().getCommandState()=" + status.getCommandStatus().getCommandState() + "\n")) + ); + SimServerInner.printAllClientStates(System.err); + Thread.getAllStackTraces().entrySet().forEach((x) -> { + System.err.println("Thread:" + x.getKey().getName()); + Arrays.stream(x.getValue()).forEach((xx) -> { + System.err.println("\t" + xx); + }); + System.err.println(""); + }); + return false; + } + } while (pause_count_start != this.pause_count); + + return testCommandEffect(cmd, testCommandStartTime); + } + + public void startRunProgramThread() { + this.closeTestProgramThread(); + this.runTestProgramThread = new Thread(new Runnable() { + + @Override + public void run() { + runProgram(program); + } + + }, "PendantClientInner.runProgram"); + this.runTestProgramThread.start(); + } + + public void startRunTestThread() { + this.closeTestProgramThread(); + this.runTestProgramThread = new Thread(new Runnable() { + + @Override + public void run() { + runTest(); + } + + }, "PendantClientInner.runTest"); + this.runTestProgramThread.start(); + } + + public int getPoll_ms() { + return poll_ms; + } + + public void setPoll_ms(int poll_ms) { + this.poll_ms = poll_ms; + } + + public BigInteger getCmdId() { + return cmdId; + } + + public synchronized void setCmdId(BigInteger cmdId) { + this.cmdId = cmdId; + } + + public double getJogIncrement() { + return jogIncrement; + } + + public void setJogIncrement(double jogIncrement) { + this.jogIncrement = jogIncrement; + } + + public double getXyzJogIncrement() { + return xyzJogIncrement; + } + + public void setXyzJogIncrement(double xyzJogIncrement) { + this.xyzJogIncrement = xyzJogIncrement; + } + + public int getJogInterval() { + return jogInterval; + } + + public void setJogInterval(int jogInterval) { + this.jogInterval = jogInterval; + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java new file mode 100644 index 0000000..5837e45 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java @@ -0,0 +1,54 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.CRCLProgramType; +import java.io.File; + +/** + * + * @author Will Shackleford {@literal } + */ +public interface PendantClientOuter { + + public void showMessage(String s); + public void showMessage(Throwable t); + public boolean showDebugMessage(String s); + public boolean validateXmlSelected(); + public boolean replaceStateSelected(); + public String getHost(); + public int getPort(); + public void finishDisconnect(); + public void finishConnect(); + public void finishSetStatus(); + public void checkXmlQuery(CRCLSocket crclSocket); + public void stopPollTimer(); + public void checkPollSelected(); + public boolean isDebugWaitForDoneSelected(); + public boolean isDebugSendCommandSelected(); + public boolean isDebugReadStatusSelected(); + public void showCurrentProgramLine(int line); + public void showLastProgramLineExecTimeMillisDists(long millis, double dist); + public void finishOpenXmlProgramFile(File f, CRCLProgramType program); + public CRCLProgramType editProgram(CRCLProgramType program); + public boolean isRecordPoseSelected(); + public boolean isEXISelected(); + public boolean isUseReadStatusThreadSelected(); +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java new file mode 100644 index 0000000..9339977 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java @@ -0,0 +1,206 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + + +import crcl.base.CRCLProgramType; +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Will Shackleford {@literal } + */ +public class PendantClientOuterStub implements PendantClientOuter{ + + @Override + public void showMessage(String s) { + final String sWithThread = "Thread:" + Thread.currentThread().getName()+" "+s; + Logger.getLogger(this.getClass().getName()).log(Level.FINE, sWithThread); + } + + @Override + public void showMessage(Throwable t) { + Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, t.toString()); + } + + @Override + public boolean showDebugMessage(String s) { + showMessage(s); + return false; + } + + private final boolean validateXml; + + @Override + public boolean validateXmlSelected() { + return this.validateXml; + } + + private final boolean replaceState; + + @Override + public boolean replaceStateSelected() { + return this.replaceState; + } + + private final String host; + + @Override + public String getHost() { + return this.host; + } + + private final int port; + @Override + public int getPort() { + return this.port; + } + + @Override + public void finishDisconnect() { + } + + @Override + public void finishConnect() { + } + + @Override + public void finishSetStatus() { + } + + @Override + public void checkXmlQuery(CRCLSocket crclSocket) { + } + + @Override + public void stopPollTimer() { + } + + @Override + public void checkPollSelected() { + } + + private final boolean debugWaitForDone; + + @Override + public boolean isDebugWaitForDoneSelected() { + return this.debugWaitForDone; + } + + private final boolean debugSendCommand; + + @Override + public boolean isDebugSendCommandSelected() { + return this.debugSendCommand; + } + + private final boolean debugReadStatus; + + @Override + public boolean isDebugReadStatusSelected() { + return this.debugReadStatus; + } + + + @Override + public void showCurrentProgramLine(int line) { + } + + @Override + public void finishOpenXmlProgramFile(File f, CRCLProgramType program) { + } + + @Override + public CRCLProgramType editProgram(CRCLProgramType program) { + return program; + } + + @Override + public void showLastProgramLineExecTimeMillisDists(long millis, double dist) { + } + + private final boolean recordPose; + @Override + public boolean isRecordPoseSelected() { + return this.recordPose; + } + + private static boolean prop(String propName, boolean defaultVal) { + return Boolean.valueOf(System.getProperty(propName,Boolean.toString(defaultVal))); + } + + public PendantClientOuterStub() { + this( + prop("crcjava.PendandClient.validateXML",false),// validateXML + prop("crcjava.PendandClient.replaceState",false),// validateXML + System.getProperty("crcljava.host","localhost"), //host + Integer.valueOf(System.getProperty("crcljava.port", + Integer.toString(CRCLSocket.DEFAULT_PORT))), //port + prop("crcjava.PendandClient.debugWaitForDone",false),// debugWaitForDone + prop("crcjava.PendandClient.debugSendCommand",false),// debugSendCommand + prop("crcjava.PendandClient.debugReadStatus",false),// debugReadStatus + prop("crcjava.PendandClient.recordPose",false),// recordPose + prop("crcjava.PendandClient.exiSelected",false),// exiSelected + prop("crcjava.PendandClient.useReadStatusThreadSelected",true)// exiSelected + ); + } + + public PendantClientOuterStub + ( + boolean validateXml, + boolean replaceState, + String host, + int port, + boolean debugWaitForDone, + boolean debugSendCommand, + boolean debugReadStatus, + boolean recordPose, + boolean exiSelected, + boolean useReadStatusThreadSelected) { + this.validateXml = validateXml; + this.replaceState = replaceState; + this.host = host; + this.port = port; + this.debugWaitForDone = debugWaitForDone; + this.debugSendCommand = debugSendCommand; + this.debugReadStatus = debugReadStatus; + this.recordPose = recordPose; + this.exiSelected = exiSelected; + this.useReadStatusThreadSelected = useReadStatusThreadSelected; + } + + + private final boolean exiSelected; + + @Override + public boolean isEXISelected() { + return this.exiSelected; + } + + private final boolean useReadStatusThreadSelected; + + @Override + public boolean isUseReadStatusThreadSelected() { + return this.useReadStatusThreadSelected; + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java b/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java new file mode 100644 index 0000000..84b2de0 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java @@ -0,0 +1,185 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStateEnumType; +import crcl.base.CommandStatusType; +import crcl.base.GetStatusType; +import crcl.base.GripperStatusType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.VacuumGripperStatusType; +import crcl.base.VectorType; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBException; + +/** + * + * @author Will Shackleford {@literal } + */ +public class PerfTest { + + private static CRCLStatusType createStatus() { + CRCLStatusType stat = new CRCLStatusType(); + CommandStatusType cst = new CommandStatusType(); + cst.setCommandID(BigInteger.ONE); + cst.setStatusID(BigInteger.ONE); + cst.setCommandState(CommandStateEnumType.WORKING); + stat.setCommandStatus(cst); + PoseType pose = new PoseType(); + PointType pt = new PointType(); + pt.setX(BigDecimal.ZERO); + pt.setY(BigDecimal.ONE); + pt.setZ(BigDecimal.TEN); + pose.setPoint(pt); + VectorType xAxis = new VectorType(); + xAxis.setI(BigDecimal.ONE); + xAxis.setJ(BigDecimal.ZERO); + xAxis.setK(BigDecimal.ZERO); + pose.setXAxis(xAxis); + VectorType zAxis = new VectorType(); + zAxis.setI(BigDecimal.ZERO); + zAxis.setJ(BigDecimal.ZERO); + zAxis.setK(BigDecimal.ONE); + pose.setZAxis(zAxis); + stat.setPose(pose); + GripperStatusType gst = new VacuumGripperStatusType(); + stat.setGripperStatus(gst); + JointStatusesType jst = new JointStatusesType(); + jst.getJointStatus().add(new JointStatusType()); + stat.setJointStatuses(jst); + return stat; + } + + public static void main(String[] args) { + runPerfTest(true); + runPerfTest(false); + } + + public static void runPerfTest(final boolean enableEXI) throws RuntimeException { + try { + CRCLSocket csTst = new CRCLSocket(); + csTst.setReplaceHeader(true); + CRCLStatusType stat0 = createStatus(); + String xmlS = csTst.statusToString(stat0, false); + System.out.println("Starting runPerfTest("+enableEXI+") ..."); + System.out.println("enableEXI = " + enableEXI); + System.out.println("xmlS = " + xmlS); + System.out.println("xmlS.length() = " + xmlS.length()); + byte ba[] = csTst.statusToEXI(stat0); + System.out.println("ba.length = " + ba.length); + System.out.println("ba = " + Arrays.toString(ba)); + ExecutorService exServ = Executors.newWorkStealingPool(); + try (ServerSocket ss = new ServerSocket(44004)) { + System.out.println("ss.getLocalPort() = " + ss.getLocalPort()); + exServ.execute(() -> { + while (!Thread.currentThread().isInterrupted() && !exServ.isShutdown()) { + try { + Socket s = ss.accept(); + final CRCLSocket cs = new CRCLSocket(s); + cs.setEXIEnabled(enableEXI); + final CRCLStatusType status = createStatus(); + exServ.execute(() -> { + try { + while (!Thread.currentThread().isInterrupted() && !exServ.isShutdown()) { + CRCLCommandInstanceType cmdInstance = cs.readCommand(false); + CRCLCommandType cmd = cmdInstance.getCRCLCommand(); +// System.out.println("cmd.getCommandID() = " + cmd.getCommandID()); + status.getCommandStatus().setCommandID(cmd.getCommandID()); + status.getCommandStatus().setStatusID(status.getCommandStatus().getStatusID().add(BigInteger.ONE)); + cs.writeStatus(status, false); + } + } catch (JAXBException | IOException | EXIException | InterruptedException ex) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } finally { + try { + cs.close(); + } catch (IOException ex) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + }); + } catch (IOException | EXIException ex) { + if(null != ss && !ss.isClosed()) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + }); + CRCLSocket cs = new CRCLSocket("localhost", ss.getLocalPort()); + cs.setEXIEnabled(enableEXI); + CRCLCommandInstanceType cmdInstance = new CRCLCommandInstanceType(); + GetStatusType getStatus = new GetStatusType(); + getStatus.setCommandID(BigInteger.ONE); + cmdInstance.setCRCLCommand(getStatus); + long start = System.currentTimeMillis(); + final long repeats = 10000; + long diff_max = 0; + for (int i = 0; i < repeats; i++) { + long t1 = System.currentTimeMillis(); + getStatus.setCommandID(getStatus.getCommandID().add(BigInteger.ONE)); +// System.out.println("getStatus.getCommandID() = " + getStatus.getCommandID()); + cs.writeCommand(cmdInstance, false); + CRCLStatusType stat = cs.readStatus(false); +// System.out.println("stat.getCommandStatus().getCommandID() = " + stat.getCommandStatus().getCommandID()); + if(stat.getCommandStatus().getCommandID().compareTo(getStatus.getCommandID()) != 0) { + throw new RuntimeException("Command ID doesn't match : " + +stat.getCommandStatus().getCommandID()+ " != "+ getStatus.getCommandID()); + } + long t2 = System.currentTimeMillis(); + long diff = t2 - t1; + if(diff > diff_max) { + diff_max = diff; + } + } + long end = System.currentTimeMillis(); + System.out.println("(end-start) = " + (end-start) + " ms"); + System.out.println("Average time = " + ((double)(end-start))/repeats + " ms"); + System.out.println("Max time = " + diff_max + " ms"); + exServ.shutdown(); + exServ.awaitTermination(5, TimeUnit.SECONDS); + exServ.shutdownNow(); + } + } catch (IOException | JAXBException | InterruptedException | EXIException ex) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } finally { + System.out.println("End of runPerfTest("+enableEXI+")"); + System.out.println(""); + } + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PoseToleranceChecker.java b/crcl4java-utils/src/main/java/crcl/utils/PoseToleranceChecker.java new file mode 100644 index 0000000..2a4903f --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/PoseToleranceChecker.java @@ -0,0 +1,105 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + + +import crcl.base.AngleUnitEnumType; +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.PoseToleranceType; +import crcl.base.VectorType; +import java.math.BigDecimal; + +/** + * + * @author Will Shackleford {@literal } + */ +public class PoseToleranceChecker { + + private PoseToleranceChecker() { + // Can't call me + } + + + static public boolean containsNull(PointType pt) { + return pt == null + || pt.getX() == null + || pt.getY() == null + || pt.getZ() == null; + } + + static public boolean containsNull(VectorType vec) { + return vec == null + || vec.getI() == null + || vec.getJ() == null + || vec.getK() == null; + } + + + static public boolean containsNull(PoseType pose) { + return pose == null + || containsNull(pose.getPoint()) + || containsNull(pose.getXAxis()) + || containsNull(pose.getZAxis()); + } + + static public boolean containsNull(PoseToleranceType tol) { + return tol == null + || tol.getXPointTolerance() == null + || tol.getYPointTolerance() == null + || tol.getZPointTolerance() == null + || tol.getXAxisTolerance() == null + || tol.getZAxisTolerance() == null; + } + + + static public boolean isInTolerance(BigDecimal v1, BigDecimal v2, BigDecimal tol) { + return v1.subtract(v2).abs().compareTo(tol) <= 0; + } + + static public boolean isInTolerance(final PointType pt1, final PointType pt2, final PoseToleranceType tol) { + return + isInTolerance(pt1.getX(),pt2.getX(),tol.getXPointTolerance()) + && isInTolerance(pt1.getY(),pt2.getY(),tol.getYPointTolerance()) + && isInTolerance(pt1.getZ(),pt2.getZ(),tol.getZPointTolerance()); + } + + static public boolean isInTolerance(VectorType v1, VectorType v2, BigDecimal tol, AngleUnitEnumType angleType) { + if(null == tol) { + return true; + } + BigDecimal dot = CRCLPosemath.dot(v1, v2); + if(angleType == AngleUnitEnumType.DEGREE) { + return dot.doubleValue() > Math.cos(Math.toRadians(tol.doubleValue())); + } + return dot.doubleValue() > Math.cos(tol.doubleValue()); + } + + static public boolean isInTolerance(final PoseType pose1, final PoseType pose2, + final PoseToleranceType tol, final AngleUnitEnumType angleType) { + return isInTolerance(pose1.getPoint(),pose2.getPoint(),tol) + && isInTolerance(pose1.getXAxis(),pose2.getXAxis(),tol.getXAxisTolerance(),angleType) + && isInTolerance(pose1.getZAxis(),pose2.getZAxis(),tol.getZAxisTolerance(),angleType); + } + + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java b/crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java new file mode 100644 index 0000000..1d4cbaa --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java @@ -0,0 +1,231 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.Arc2D; +import java.awt.geom.Rectangle2D; +import javax.swing.JPanel; + +/** + * + * @author Will Shackleford {@literal } + */ +public class SideViewJPanel extends JPanel { + + private SimRobotEnum robotType = SimRobotEnum.SIMPLE; + + /** + * Get the value of robotType + * + * @return the value of robotType + */ + public SimRobotEnum getRobotType() { + return robotType; + } + + /** + * Set the value of robotType + * + * @param robotType new value of robotType + */ + public void setRobotType(SimRobotEnum robotType) { + this.robotType = robotType; + this.repaint(); + } + + private double[] jointvals; + + /** + * Get the value of jointvals + * + * @return the value of jointvals + */ + public double[] getJointvals() { + return jointvals; + } + + /** + * Set the value of jointvals + * + * @param jointvals new value of jointvals + */ + public void setJointvals(double[] jointvals) { + this.jointvals = jointvals; + } + + private double[] seglengths = SimulatedKinematicsPlausible.DEFAULT_SEGLENGTHS; + + /** + * Get the value of seglengths + * + * @return the value of seglengths + */ + public double[] getSeglengths() { + return seglengths; + } + + /** + * Set the value of seglengths + * + * @param seglengths new value of seglengths + */ + public void setSeglengths(double[] seglengths) { + this.seglengths = seglengths; + if(null == seglengths || seglengths.length < 1) { + return; + } + l0rect.width = seglengths[0]; + if(seglengths.length < 2) { + return; + } + l1rect.width = seglengths[1]; + if(seglengths.length < 3) { + return; + } + l2rect.width = seglengths[2]; + if(seglengths.length < 4) { + return; + } + l3rect.width = seglengths[3]; + if(seglengths.length < 5) { + return; + } + l4rect.height = seglengths[4]; + if(seglengths.length < 6) { + return; + } + l5rect.width = seglengths[5]; + } + + Arc2D.Double j1circle = new Arc2D.Double(-10.0, -10.0 // x,y + , seglengths[3], seglengths[3] // w,h + , 0, 360.0, Arc2D.CHORD); + + Arc2D.Double j2circle = new Arc2D.Double(-6, -6.0 // x,y + , 12, 12 // w,h + , 0, 360, Arc2D.CHORD); + + //Rectangle2D.Double jrect = new Rectangle2D.Double(0.0, -5.0, 10.0, 10.0); + Rectangle2D.Double l0rect = new Rectangle2D.Double(0.0, -5.0, seglengths[0], 10.0); + Rectangle2D.Double l1rect = new Rectangle2D.Double(0.0, -5.0, seglengths[1], 10.0); + Rectangle2D.Double l2rect = new Rectangle2D.Double(0.0, -5.0, seglengths[2], 10.0); + Rectangle2D.Double l3rect = new Rectangle2D.Double(0.0, -5.0, seglengths[3], 10.0); + Rectangle2D.Double l4rect = new Rectangle2D.Double(0.0, -10.0, 5.0, seglengths[4]); + Rectangle2D.Double l5rect = new Rectangle2D.Double(0.0, -0.5, seglengths[5], 1.0); + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + try { + Graphics2D g2d = (Graphics2D) g; + Dimension d = this.getSize(); + g2d.translate(d.width / 2.0, d.height / 2.0); + switch (robotType) { + case PLAUSIBLE: + if (paintPlausibleRobot(d, g2d)) { + return; + } + break; + + case SIMPLE: + if (paintSimpleRobot(d, g2d)) { + return; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private double maxSimpleJv0 = 0; + + private boolean paintSimpleRobot(Dimension d, Graphics2D g2d) { + if(null == jointvals || jointvals.length < SimulatedKinematicsSimple.NUM_JOINTS) { + return true; + } + maxSimpleJv0 = Math.max(maxSimpleJv0, jointvals[0]); + double sfactor = Math.min(d.width / 2.0, d.height / 2.0) / (Math.abs(maxSimpleJv0) + SimulatedKinematicsSimple.DEFAULT_SEGLENGTHS[0]); + g2d.scale(sfactor, -1.0 * sfactor); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + l0rect.width = jointvals[0]; + g2d.rotate(Math.toRadians(jointvals[2])); + g2d.setColor(Color.yellow); + g2d.fill(l0rect); + g2d.translate(l0rect.width, 0.0); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + l1rect.width = Math.cos(Math.toRadians(jointvals[5] - jointvals[2])) * SimulatedKinematicsSimple.DEFAULT_SEGLENGTHS[0]; + g2d.rotate(Math.toRadians(jointvals[4] - jointvals[2])); + g2d.setColor(Color.yellow); + g2d.fill(l1rect); + return false; + } + + private boolean paintPlausibleRobot(Dimension d, Graphics2D g2d) { + double sfactor = Math.min(d.width / 2.0, d.height / 2.0) / (seglengths[0] + seglengths[1] + seglengths[2] + seglengths[3]); + g2d.scale(sfactor, -1.0 * sfactor); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + if (null == jointvals) { + return true; + } + g2d.rotate(Math.toRadians(jointvals[1])); + g2d.setColor(Color.yellow); + g2d.fill(l0rect); + g2d.translate(l0rect.width, 0.0); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + g2d.rotate(Math.toRadians(jointvals[2])); + g2d.setColor(Color.yellow); + g2d.fill(l1rect); + g2d.translate(l1rect.width, 0.0); + g2d.setColor(Color.gray); + g2d.fill(j1circle); + g2d.rotate(Math.toRadians(jointvals[3])); + g2d.setColor(Color.yellow); + g2d.fill(l2rect); + g2d.translate(l2rect.width, 0.0); + l3rect.width = this.seglengths[3] * Math.cos(Math.toRadians(jointvals[4])); + if (l3rect.width <= 0) { + return true; + } + g2d.setColor(Color.yellow); + g2d.fill(l3rect); + g2d.setColor(Color.gray); + g2d.fill(j2circle); + g2d.translate(l3rect.width, 0.0); + g2d.setColor(Color.BLACK); + l4rect.height = seglengths[4] * Math.abs(Math.cos(Math.toRadians(jointvals[5]))); + l4rect.y = -0.5 * l4rect.height; + g2d.fill(l4rect); + g2d.translate(0.0, l4rect.height / 2.0); + g2d.fill(l5rect); + g2d.translate(0.0, -l4rect.height); + g2d.fill(l5rect); + return false; + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimRobotEnum.java b/crcl4java-utils/src/main/java/crcl/utils/SimRobotEnum.java new file mode 100644 index 0000000..2043fbe --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimRobotEnum.java @@ -0,0 +1,29 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +/** + * + * @author Will Shackleford {@literal } + */ +public enum SimRobotEnum { + PLAUSIBLE, + SIMPLE +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServer.form b/crcl4java-utils/src/main/java/crcl/utils/SimServer.form new file mode 100644 index 0000000..0459da1 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimServer.form @@ -0,0 +1,614 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServer.java b/crcl4java-utils/src/main/java/crcl/utils/SimServer.java new file mode 100644 index 0000000..51dc7b2 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimServer.java @@ -0,0 +1,1045 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United Statesm + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStateEnumType; +import crcl.base.GetStatusType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.LengthUnitEnumType; +import crcl.base.PoseType; +import java.io.File; +import java.io.IOException; +import java.math.BigInteger; +import java.util.List; +import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.ParserConfigurationException; + +/** + * + * @author Will Shackleford{@literal } + */ +public class SimServer extends javax.swing.JFrame implements SimServerOuter { + + /** + * Creates new form SimServer + * + * @throws javax.xml.parsers.ParserConfigurationException when + * javax.xml.parsers.DocumentBuilderFactory fails in XpathUtils + */ + public SimServer() throws ParserConfigurationException { + initComponents(); + + this.inner = new SimServerInner(this); + this.updatePanels(true); + this.jComboBoxLengthUnit.setModel(new DefaultComboBoxModel(LengthUnitEnumType.values())); + this.jComboBoxLengthUnit.setSelectedItem(LengthUnitEnumType.METER); + inner.setLengthUnit(LengthUnitEnumType.METER); + this.jComboBoxRobotType.setModel(new DefaultComboBoxModel(SimRobotEnum.values())); + this.jComboBoxRobotType.setSelectedItem(SimRobotEnum.SIMPLE); + this.setRobotType(SimRobotEnum.SIMPLE); + this.setStatSchema(CRCLSocket.readStatSchemaFiles(SimServer.statSchemasFile)); + this.setCmdSchema(CRCLSocket.readCmdSchemaFiles(SimServer.cmdSchemasFile)); + String portPropertyString = System.getProperty("crcljava.port"); + if (null != portPropertyString) { + inner.setPort(Integer.valueOf(portPropertyString)); + this.jTextFieldPort.setText(portPropertyString); + } else { + this.jTextFieldPort.setText(Integer.toString(inner.getPort())); + } + inner.restartServer(); + } + + private boolean toolChangerOpen; + + /** + * Get the value of toolChangerOpen + * + * @return the value of toolChangerOpen + */ + public boolean isToolChangerOpen() { + return toolChangerOpen; + } + + /** + * Set the value of toolChangerOpen + * + * @param toolChangerOpen new value of toolChangerOpen + */ + public void setToolChangerOpen(boolean toolChangerOpen) { + this.toolChangerOpen = toolChangerOpen; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jSplitPane1 = new javax.swing.JSplitPane(); + jPanel1 = new javax.swing.JPanel(); + overHeadJPanel1 = new crcl.utils.OverHeadJPanel(); + jPanel2 = new javax.swing.JPanel(); + sideViewJPanel1 = new crcl.utils.SideViewJPanel(); + jPanel3 = new javax.swing.JPanel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextAreaErrors = new javax.swing.JTextArea(); + jPanel4 = new javax.swing.JPanel(); + jLabel1 = new javax.swing.JLabel(); + jTextFieldPort = new javax.swing.JTextField(); + jLabel3 = new javax.swing.JLabel(); + jTextFieldCycleTime = new javax.swing.JTextField(); + jButtonReset = new javax.swing.JButton(); + jCheckBoxInitialized = new javax.swing.JCheckBox(); + jCheckBoxSendStatusWithoutRequest = new javax.swing.JCheckBox(); + jButtonRestartServer = new javax.swing.JButton(); + jComboBoxRobotType = new javax.swing.JComboBox(); + jPanel5 = new javax.swing.JPanel(); + jLabel2 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jTextFieldConnectedClients = new javax.swing.JTextField(); + jTextFieldCycleCount = new javax.swing.JTextField(); + jLabel5 = new javax.swing.JLabel(); + jTextFieldNumWaypoints = new javax.swing.JTextField(); + jLabel6 = new javax.swing.JLabel(); + jTextFieldCurWaypoint = new javax.swing.JTextField(); + jLabel7 = new javax.swing.JLabel(); + jComboBoxLengthUnit = new javax.swing.JComboBox(); + jLabel8 = new javax.swing.JLabel(); + jTextFieldEndEffector = new javax.swing.JTextField(); + jLabel9 = new javax.swing.JLabel(); + jTextFieldCurrentCommandType = new javax.swing.JTextField(); + jMenuBar1 = new javax.swing.JMenuBar(); + jMenu1 = new javax.swing.JMenu(); + jMenuItemExit = new javax.swing.JMenuItem(); + jMenu2 = new javax.swing.JMenu(); + jMenuItemEditStatus = new javax.swing.JMenuItem(); + jMenu3 = new javax.swing.JMenu(); + jMenuItemSetSchema = new javax.swing.JMenuItem(); + jCheckBoxMenuItemValidateXML = new javax.swing.JCheckBoxMenuItem(); + jMenu4 = new javax.swing.JMenu(); + jCheckBoxMenuItemRandomPacket = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemAppendZero = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemIncludeGripperStatus = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemReplaceState = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemDebugMoveDone = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemDebugReadCommand = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemDebugSendStatus = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemReplaceXmlHeader = new javax.swing.JCheckBoxMenuItem(); + jCheckBoxMenuItemEXI = new javax.swing.JCheckBoxMenuItem(); + + FormListener formListener = new FormListener(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("CRCL SImulation Server"); + + jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Overhead View")); + jPanel1.setLayout(new java.awt.BorderLayout()); + + javax.swing.GroupLayout overHeadJPanel1Layout = new javax.swing.GroupLayout(overHeadJPanel1); + overHeadJPanel1.setLayout(overHeadJPanel1Layout); + overHeadJPanel1Layout.setHorizontalGroup( + overHeadJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 279, Short.MAX_VALUE) + ); + overHeadJPanel1Layout.setVerticalGroup( + overHeadJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 233, Short.MAX_VALUE) + ); + + jPanel1.add(overHeadJPanel1, java.awt.BorderLayout.CENTER); + + jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Side View")); + jPanel2.setLayout(new java.awt.BorderLayout()); + + sideViewJPanel1.addComponentListener(formListener); + + javax.swing.GroupLayout sideViewJPanel1Layout = new javax.swing.GroupLayout(sideViewJPanel1); + sideViewJPanel1.setLayout(sideViewJPanel1Layout); + sideViewJPanel1Layout.setHorizontalGroup( + sideViewJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 279, Short.MAX_VALUE) + ); + sideViewJPanel1Layout.setVerticalGroup( + sideViewJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 233, Short.MAX_VALUE) + ); + + jPanel2.add(sideViewJPanel1, java.awt.BorderLayout.CENTER); + + jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Errors and Messages")); + + jTextAreaErrors.setColumns(20); + jTextAreaErrors.setLineWrap(true); + jTextAreaErrors.setRows(5); + jScrollPane1.setViewportView(jTextAreaErrors); + + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); + jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1) + .addContainerGap()) + ); + jPanel3Layout.setVerticalGroup( + jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE) + .addContainerGap()) + ); + + jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Setup")); + + jLabel1.setText("Port: "); + + jTextFieldPort.setText("64444"); + jTextFieldPort.addActionListener(formListener); + + jLabel3.setText("Cycle Time (ms): "); + + jTextFieldCycleTime.setText("100"); + jTextFieldCycleTime.addActionListener(formListener); + + jButtonReset.setText("Reset"); + jButtonReset.addActionListener(formListener); + + jCheckBoxInitialized.setText("Initialized"); + + jCheckBoxSendStatusWithoutRequest.setText("Send Status Without Requests"); + + jButtonRestartServer.setText("Restart Server"); + jButtonRestartServer.addActionListener(formListener); + + jComboBoxRobotType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); + jComboBoxRobotType.addActionListener(formListener); + + javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4); + jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1) + .addComponent(jLabel3)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldPort, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldCycleTime, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(12, 12, 12) + .addComponent(jCheckBoxSendStatusWithoutRequest)) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addComponent(jButtonReset) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jButtonRestartServer) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jComboBoxRobotType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGroup(jPanel4Layout.createSequentialGroup() + .addGap(12, 12, 12) + .addComponent(jCheckBoxInitialized) + .addGap(0, 0, Short.MAX_VALUE))) + .addContainerGap(25, Short.MAX_VALUE)) + ); + + jPanel4Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jTextFieldCycleTime, jTextFieldPort}); + + jPanel4Layout.setVerticalGroup( + jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel4Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jTextFieldPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel3) + .addComponent(jTextFieldCycleTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonReset) + .addComponent(jButtonRestartServer) + .addComponent(jComboBoxRobotType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxInitialized) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jCheckBoxSendStatusWithoutRequest) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + jPanel5.setBorder(javax.swing.BorderFactory.createTitledBorder("Status")); + + jLabel2.setText("Connected Clients: "); + + jLabel4.setText("Cycle Count:"); + + jTextFieldConnectedClients.setEditable(false); + jTextFieldConnectedClients.setText("0"); + + jTextFieldCycleCount.setEditable(false); + jTextFieldCycleCount.setText("0"); + + jLabel5.setText("Number of Waypoints: "); + + jTextFieldNumWaypoints.setEditable(false); + jTextFieldNumWaypoints.setText("0"); + + jLabel6.setText("Current Waypoint:"); + + jTextFieldCurWaypoint.setEditable(false); + jTextFieldCurWaypoint.setText("0"); + + jLabel7.setText("Length Units: "); + + jLabel8.setText("End Effector: "); + + jLabel9.setText("Current Commant Type:"); + + javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5); + jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel2) + .addComponent(jLabel4) + .addComponent(jLabel6) + .addComponent(jLabel8) + .addComponent(jLabel7) + .addComponent(jLabel9)) + .addGap(18, 18, Short.MAX_VALUE) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldCurrentCommandType, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldEndEffector, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldCurWaypoint, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldNumWaypoints, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldCycleCount, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jTextFieldConnectedClients, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGap(126, 126, 126) + .addComponent(jComboBoxLengthUnit, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + jPanel5Layout.setVerticalGroup( + jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel5Layout.createSequentialGroup() + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jTextFieldConnectedClients, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel4) + .addComponent(jTextFieldCycleCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel5) + .addComponent(jTextFieldNumWaypoints, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jTextFieldCurWaypoint, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel6)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jComboBoxLengthUnit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel7)) + .addGap(18, 18, 18) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jTextFieldEndEffector, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel8)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel9) + .addComponent(jTextFieldCurrentCommandType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap()) + ); + + jMenu1.setText("File"); + + jMenuItemExit.setText("Exit"); + jMenuItemExit.addActionListener(formListener); + jMenu1.add(jMenuItemExit); + + jMenuBar1.add(jMenu1); + + jMenu2.setText("Edit"); + + jMenuItemEditStatus.setText("Status in Table ..."); + jMenuItemEditStatus.addActionListener(formListener); + jMenu2.add(jMenuItemEditStatus); + + jMenuBar1.add(jMenu2); + + jMenu3.setText("XML Schemas"); + + jMenuItemSetSchema.setText("Set Schema File(s) ... "); + jMenuItemSetSchema.addActionListener(formListener); + jMenu3.add(jMenuItemSetSchema); + + jCheckBoxMenuItemValidateXML.setSelected(true); + jCheckBoxMenuItemValidateXML.setText("Validate XML with Schema(s)"); + jMenu3.add(jCheckBoxMenuItemValidateXML); + + jMenuBar1.add(jMenu3); + + jMenu4.setText("Options"); + + jCheckBoxMenuItemRandomPacket.setText("Randomize Packeting"); + jMenu4.add(jCheckBoxMenuItemRandomPacket); + + jCheckBoxMenuItemAppendZero.setText("Append 0 for string termination"); + jMenu4.add(jCheckBoxMenuItemAppendZero); + + jCheckBoxMenuItemIncludeGripperStatus.setText("Include Gripper Status ..."); + jCheckBoxMenuItemIncludeGripperStatus.addActionListener(formListener); + jMenu4.add(jCheckBoxMenuItemIncludeGripperStatus); + + jCheckBoxMenuItemReplaceState.setText("Replace CRCL_Working,CRCL_Done with Working,Done ..."); + jMenu4.add(jCheckBoxMenuItemReplaceState); + + jCheckBoxMenuItemDebugMoveDone.setText("Debug MOVE Done"); + jMenu4.add(jCheckBoxMenuItemDebugMoveDone); + + jCheckBoxMenuItemDebugReadCommand.setText("Debug Read Command"); + jMenu4.add(jCheckBoxMenuItemDebugReadCommand); + + jCheckBoxMenuItemDebugSendStatus.setText("Debug Send Status"); + jMenu4.add(jCheckBoxMenuItemDebugSendStatus); + + jCheckBoxMenuItemReplaceXmlHeader.setSelected(true); + jCheckBoxMenuItemReplaceXmlHeader.setText("Replace XML Headers"); + jMenu4.add(jCheckBoxMenuItemReplaceXmlHeader); + + jCheckBoxMenuItemEXI.setText("Use EXI (Efficient XML Interchange)"); + jCheckBoxMenuItemEXI.addActionListener(formListener); + jMenu4.add(jCheckBoxMenuItemEXI); + + jMenuBar1.add(jMenu4); + + setJMenuBar(jMenuBar1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(0, 0, Short.MAX_VALUE))) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + + pack(); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener, java.awt.event.ComponentListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jTextFieldPort) { + SimServer.this.jTextFieldPortActionPerformed(evt); + } + else if (evt.getSource() == jTextFieldCycleTime) { + SimServer.this.jTextFieldCycleTimeActionPerformed(evt); + } + else if (evt.getSource() == jButtonReset) { + SimServer.this.jButtonResetActionPerformed(evt); + } + else if (evt.getSource() == jButtonRestartServer) { + SimServer.this.jButtonRestartServerActionPerformed(evt); + } + else if (evt.getSource() == jComboBoxRobotType) { + SimServer.this.jComboBoxRobotTypeActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemExit) { + SimServer.this.jMenuItemExitActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemEditStatus) { + SimServer.this.jMenuItemEditStatusActionPerformed(evt); + } + else if (evt.getSource() == jMenuItemSetSchema) { + SimServer.this.jMenuItemSetSchemaActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxMenuItemIncludeGripperStatus) { + SimServer.this.jCheckBoxMenuItemIncludeGripperStatusActionPerformed(evt); + } + else if (evt.getSource() == jCheckBoxMenuItemEXI) { + SimServer.this.jCheckBoxMenuItemEXIActionPerformed(evt); + } + } + + public void componentHidden(java.awt.event.ComponentEvent evt) { + } + + public void componentMoved(java.awt.event.ComponentEvent evt) { + } + + public void componentResized(java.awt.event.ComponentEvent evt) { + if (evt.getSource() == sideViewJPanel1) { + SimServer.this.sideViewJPanel1ComponentResized(evt); + } + } + + public void componentShown(java.awt.event.ComponentEvent evt) { + } + }// //GEN-END:initComponents + + private void jTextFieldPortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldPortActionPerformed + int new_port = Integer.valueOf(this.jTextFieldPort.getText()); + inner.setPort(new_port); + inner.restartServer(); + }//GEN-LAST:event_jTextFieldPortActionPerformed + + private void jTextFieldCycleTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldCycleTimeActionPerformed + long newDelayMillis = Long.valueOf(this.jTextFieldCycleTime.getText()); + inner.setDelayMillis(newDelayMillis); + }//GEN-LAST:event_jTextFieldCycleTimeActionPerformed + + private boolean editing_status = false; + +// public String getDocumentation(String name) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { +// return xpu.queryXml(statSchemaFiles, "/schema/complexType[@name=\""+name+"\"]/annotation/documentation/text()"); +// } + final SimServerInner inner; + + @Override + public boolean isValidateXMLSelected() { + return jCheckBoxMenuItemValidateXML.isSelected(); + } + + private CRCLStatusType getStatus() { + return inner.getStatus(); + } + + private void jMenuItemEditStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemEditStatusActionPerformed + this.editing_status = true; + try { + CRCLStatusType newstat = ObjTableJPanel.editObject(this.getStatus(), + this, "Edit Status", true, + inner.getXpu(), this.checkStatusValidPredicate); + if (null != newstat) { + inner.setStatus(newstat); + JointStatusesType jsst = this.getStatus().getJointStatuses(); + if (null == jsst) { + return; + } + List jsl = jsst.getJointStatus(); + for (JointStatusType jst : jsl) { + int jvindex = jst.getJointNumber().intValue() - 1; + double pos = jst.getJointPosition().doubleValue(); + inner.setJointPosition(pos, jvindex); + inner.setCommandedJointPosition(pos, jvindex); + } + this.updatePanels(true); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + this.editing_status = false; + } + }//GEN-LAST:event_jMenuItemEditStatusActionPerformed + + private void jMenuItemExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemExitActionPerformed + System.exit(0); + }//GEN-LAST:event_jMenuItemExitActionPerformed + + private void jMenuItemSetSchemaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemSetSchemaActionPerformed + JFileChooser jFileChooser = new JFileChooser(); + javax.swing.filechooser.FileFilter[] ffa = jFileChooser.getChoosableFileFilters(); + for (javax.swing.filechooser.FileFilter ff : ffa) { + jFileChooser.removeChoosableFileFilter(ff); + } + jFileChooser.addChoosableFileFilter(new FileNameExtensionFilter("XML Schema file", "xsd")); + jFileChooser.setMultiSelectionEnabled(true); + int result = jFileChooser.showOpenDialog(this); + if (result == JFileChooser.APPROVE_OPTION) { + File fa[] = jFileChooser.getSelectedFiles(); + setCmdSchema(fa); + CRCLSocket.saveCmdSchemaFiles(SimServer.cmdSchemasFile, fa); + setStatSchema(fa); + CRCLSocket.saveStatSchemaFiles(SimServer.statSchemasFile, fa); + } + }//GEN-LAST:event_jMenuItemSetSchemaActionPerformed + + private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResetActionPerformed + inner.reset(); + this.updatePanels(true); + }//GEN-LAST:event_jButtonResetActionPerformed + + private void sideViewJPanel1ComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_sideViewJPanel1ComponentResized + this.updatePanels(true); + }//GEN-LAST:event_sideViewJPanel1ComponentResized + + private void jButtonRestartServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRestartServerActionPerformed + int new_port = Integer.valueOf(this.jTextFieldPort.getText()); + inner.setPort(new_port); + inner.restartServer(); + }//GEN-LAST:event_jButtonRestartServerActionPerformed + + private CRCLSocket gripperSocket = null; + private Thread gripperReadThread = null; + private int gripperPort = 4005; + private String gripperHost = "localhost"; + private boolean sendGripperStatusRequests = true; + + private void closeGripperSocket() { + if (null != gripperSocket) { + try { + gripperSocket.close(); + gripperSocket = null; + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + if (null != gripperReadThread) { + try { + gripperReadThread.interrupt(); + gripperReadThread.join(100); + gripperReadThread = null; + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + public static final Logger LOGGER = Logger.getLogger(SimServer.class.getName()); + + private void jCheckBoxMenuItemIncludeGripperStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemIncludeGripperStatusActionPerformed + if (this.jCheckBoxMenuItemIncludeGripperStatus.isSelected()) { + try { + this.closeGripperSocket(); + String gripperPortString = JOptionPane.showInputDialog(this, "Gripper Server Port?", this.gripperPort); + gripperPort = Integer.valueOf(gripperPortString); + String gripperHostString = JOptionPane.showInputDialog(this, "Gripper Server Host?", this.gripperHost); + gripperPort = Integer.valueOf(gripperPortString); + sendGripperStatusRequests = (JOptionPane.showConfirmDialog(this, "Send status requests?") == JOptionPane.YES_OPTION); + this.gripperSocket = new CRCLSocket(gripperHost, gripperPort); + this.gripperReadThread = new Thread(new Runnable() { + + @Override + public void run() { + try { + GetStatusType getStatus = new GetStatusType(); + getStatus.setCommandID(BigInteger.ONE); + CRCLCommandInstanceType cmdInstance = new CRCLCommandInstanceType(); + cmdInstance.setCRCLCommand(getStatus); + while (!Thread.currentThread().isInterrupted()) { + if (sendGripperStatusRequests) { + Thread.sleep(inner.getDelayMillis()); + getStatus.setCommandID(getStatus.getCommandID().add(BigInteger.ONE)); + gripperSocket.writeCommand(cmdInstance, false); + } + CRCLStatusType gripperStatus + = gripperSocket.readStatus(jCheckBoxMenuItemValidateXML.isSelected()); + SimServer.this.getStatus().setGripperStatus(gripperStatus.getGripperStatus()); + } + } catch (JAXBException | IOException | EXIException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + }, "simServerReadGripperThread"); + gripperReadThread.start(); + + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + }//GEN-LAST:event_jCheckBoxMenuItemIncludeGripperStatusActionPerformed + + private void setRobotType(SimRobotEnum robotType) { + this.inner.setRobotType(robotType); + this.overHeadJPanel1.setJointvals(inner.getJointPositions()); + this.sideViewJPanel1.setJointvals(inner.getJointPositions()); + this.overHeadJPanel1.setSeglengths(inner.getSeglengths()); + this.sideViewJPanel1.setSeglengths(inner.getSeglengths()); + this.overHeadJPanel1.setRobotType(robotType); + this.sideViewJPanel1.setRobotType(robotType); + this.updatePanels(true); + } + + private void jComboBoxRobotTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBoxRobotTypeActionPerformed + SimRobotEnum robotType = SimRobotEnum.valueOf(this.jComboBoxRobotType.getSelectedItem().toString()); + this.setRobotType(robotType); + }//GEN-LAST:event_jComboBoxRobotTypeActionPerformed + + private void jCheckBoxMenuItemEXIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxMenuItemEXIActionPerformed + inner.restartServer(); + }//GEN-LAST:event_jCheckBoxMenuItemEXIActionPerformed + + @Override + public boolean isEXISelected() { + return this.jCheckBoxMenuItemEXI.isSelected(); + } + + + + private final static File cmdSchemasFile = new File(System.getProperty("user.home"), + ".crcljava_simserver_cmd_schemas.txt"); + + private final static File statSchemasFile = new File(System.getProperty("user.home"), + ".crcljava_simserver_stat_schemas.txt"); + + private void setCmdSchema(File[] fa) { + inner.setCmdSchema(fa); + } + + private void setStatSchema(File[] fa) { + inner.setStatSchema(fa); + } + +// public String getStatusXmlString() { +// try { +// StringWriter sw = new StringWriter(); +// JAXBContext jc = JAXBContext.newInstance("crcl"); +// Marshaller m = jc.createMarshaller(); +// m.setProperty(Marshaller.JAXB_FRAGMENT, true); +// m.marshal(jaxb_status, sw); +// return sw.toString(); +// } catch (JAXBException ex) { +// Logger.getLogger(SimServer.class.getName()).log(Level.SEVERE, null, ex); +// } +// return null; +// } +// JointControlModeEnumType controlmodes[] = new JointControlModeEnumType[]{ +// JointControlModeEnumType.POSITION, +// JointControlModeEnumType.POSITION, +// JointControlModeEnumType.POSITION, +// JointControlModeEnumType.POSITION, +// JointControlModeEnumType.POSITION, +// JointControlModeEnumType.POSITION,}; + public void setCommandState(CommandStateEnumType state) { + inner.setCommandState(state); + } + + public CommandStateEnumType getCommandState() { + return inner.getCommandState(); + } + + public boolean checkPose(PoseType goalPose) { + return inner.checkPose(goalPose); + } + + @Override + public boolean isAppendZeroSelected() { + return this.jCheckBoxMenuItemAppendZero.isSelected(); + } + + @Override + public boolean isReplaceXmlHeaderSelected() { + return this.jCheckBoxMenuItemReplaceXmlHeader.isSelected(); + } + + @Override + public boolean isRandomPacketSelected() { + return this.jCheckBoxMenuItemRandomPacket.isSelected(); + } + + @Override + public boolean isReplaceStateSelected() { + return this.jCheckBoxMenuItemReplaceState.isSelected(); + } + + @Override + public boolean isEditingStatus() { + return this.editing_status; + } + + @Override + public void updateCycleCount(int _newCycleCount) { + this.jTextFieldCycleCount.setText(Integer.toString(_newCycleCount)); + } + + private Predicate checkStatusValidPredicate + = this::checkStatusValid; + + public boolean checkStatusValid(CRCLStatusType statusObj) { + try { + String s = inner.getCheckerCRCLSocket().statusToPrettyString(statusObj, true); + return MultiLineStringJPanel.showText(s); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex); + } + return false; + } + + @Override + public boolean isSendStatusWithoutRequestSelected() { + return jCheckBoxSendStatusWithoutRequest.isSelected(); + } + + public void showMessage(Throwable t) { + showMessage(t.toString()); + } + + private volatile long last_message_show_time = 0; + + @Override + public void showDebugMessage(final String s) { + final String sWithThread = "Thread:" + Thread.currentThread().getName()+" \n"+s; + LOGGER.log(Level.FINE, sWithThread); + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + jTextAreaErrors.setText(jTextAreaErrors.getText() + "\n" + sWithThread); + } + }); + } + + @Override + public void updateNumWaypoints(int numWaypoints) { + this.jTextFieldNumWaypoints.setText(Integer.toString(numWaypoints)); + } + + @Override + public void showMessage(final String s) { + showDebugMessage(s); + if (showing_message) { + return; + } + showing_message = true; + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + long t = System.currentTimeMillis(); + if (t - last_message_show_time > 5000) { + last_message_show_time = System.currentTimeMillis(); + MultiLineStringJPanel.showText(s, SimServer.this, "SimServer Message", true); + } + last_message_show_time = System.currentTimeMillis(); + showing_message = false; + } + }); + } + + @Override + public void updatePanels(boolean jointschanged) { + if (jointschanged) { + this.overHeadJPanel1.setJointvals(inner.getJointPositions()); + this.overHeadJPanel1.setSeglengths(inner.getSeglengths()); + this.overHeadJPanel1.repaint(); + this.sideViewJPanel1.setJointvals(inner.getJointPositions()); + this.sideViewJPanel1.repaint(); + } + } + + @Override + public void finishSetCurrentWaypoint(int currentWaypoint) { + this.jTextFieldCurWaypoint.setText(Integer.toString(currentWaypoint)); + } + + @Override + public void updateIsInitialized(boolean initialized) { + this.jCheckBoxInitialized.setSelected(initialized); + } + + @Override + public void updateCurrentCommandType(String cmdName) { + this.jTextFieldCurrentCommandType.setText(cmdName); + } + private boolean showing_message = false; + + @Override + public boolean isInitializedSelected() { + return this.jCheckBoxInitialized.isSelected(); + } + + @Override + public void updateEndEffector(String text) { + this.jTextFieldEndEffector.setText(text); + } + + @Override + public void updateToolChangerIsOpen(boolean isOpen) { + this.setToolChangerOpen(isOpen); + } + + public void updateLengthUnit(LengthUnitEnumType lu) { + this.jComboBoxLengthUnit.setSelectedItem(lu); + } + + @Override + public void updateConnectedClients(int numClients) { + this.jTextFieldConnectedClients.setText(Integer.toString(numClients)); + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + LOGGER.log(java.util.logging.Level.SEVERE, null, ex); + } + // + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + try { + new SimServer().setVisible(true); + } catch (ParserConfigurationException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonReset; + private javax.swing.JButton jButtonRestartServer; + private javax.swing.JCheckBox jCheckBoxInitialized; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemAppendZero; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemDebugMoveDone; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemDebugReadCommand; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemDebugSendStatus; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemEXI; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemIncludeGripperStatus; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemRandomPacket; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemReplaceState; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemReplaceXmlHeader; + private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItemValidateXML; + private javax.swing.JCheckBox jCheckBoxSendStatusWithoutRequest; + private javax.swing.JComboBox jComboBoxLengthUnit; + private javax.swing.JComboBox jComboBoxRobotType; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + private javax.swing.JLabel jLabel5; + private javax.swing.JLabel jLabel6; + private javax.swing.JLabel jLabel7; + private javax.swing.JLabel jLabel8; + private javax.swing.JLabel jLabel9; + private javax.swing.JMenu jMenu1; + private javax.swing.JMenu jMenu2; + private javax.swing.JMenu jMenu3; + private javax.swing.JMenu jMenu4; + private javax.swing.JMenuBar jMenuBar1; + private javax.swing.JMenuItem jMenuItemEditStatus; + private javax.swing.JMenuItem jMenuItemExit; + private javax.swing.JMenuItem jMenuItemSetSchema; + private javax.swing.JPanel jPanel1; + private javax.swing.JPanel jPanel2; + private javax.swing.JPanel jPanel3; + private javax.swing.JPanel jPanel4; + private javax.swing.JPanel jPanel5; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JSplitPane jSplitPane1; + private javax.swing.JTextArea jTextAreaErrors; + private javax.swing.JTextField jTextFieldConnectedClients; + private javax.swing.JTextField jTextFieldCurWaypoint; + private javax.swing.JTextField jTextFieldCurrentCommandType; + private javax.swing.JTextField jTextFieldCycleCount; + private javax.swing.JTextField jTextFieldCycleTime; + private javax.swing.JTextField jTextFieldEndEffector; + private javax.swing.JTextField jTextFieldNumWaypoints; + private javax.swing.JTextField jTextFieldPort; + private crcl.utils.OverHeadJPanel overHeadJPanel1; + private crcl.utils.SideViewJPanel sideViewJPanel1; + // End of variables declaration//GEN-END:variables + + @Override + public boolean isDebugMoveDoneSelected() { + return this.jCheckBoxMenuItemDebugMoveDone.isSelected(); + } + + @Override + public boolean isDebugReadCommandSelected() { + return this.jCheckBoxMenuItemDebugReadCommand.isSelected(); + } + + @Override + public boolean isDebugSendStatusSelected() { + return this.jCheckBoxMenuItemDebugSendStatus.isSelected(); + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java b/crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java new file mode 100644 index 0000000..2b383bf --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java @@ -0,0 +1,1797 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.ActuateJointType; +import crcl.base.ActuateJointsType; +import crcl.base.AngleUnitEnumType; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLStatusType; +import crcl.base.CloseToolChangerType; +import crcl.base.CommandStateEnumType; +import crcl.base.CommandStatusType; +import crcl.base.ConfigureJointReportType; +import crcl.base.ConfigureJointReportsType; +import crcl.base.DwellType; +import crcl.base.EndCanonType; +import crcl.base.GetStatusType; +import crcl.base.InitCanonType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.LengthUnitEnumType; +import static crcl.base.LengthUnitEnumType.INCH; +import static crcl.base.LengthUnitEnumType.METER; +import static crcl.base.LengthUnitEnumType.MILLIMETER; +import crcl.base.MessageType; +import crcl.base.MoveScrewType; +import crcl.base.MoveThroughToType; +import crcl.base.MoveToType; +import crcl.base.OpenToolChangerType; +import crcl.base.PoseAndSetType; +import crcl.base.PoseType; +import crcl.base.PoseToleranceType; +import crcl.base.RotAccelAbsoluteType; +import crcl.base.RotAccelRelativeType; +import crcl.base.RotAccelType; +import crcl.base.RotSpeedAbsoluteType; +import crcl.base.RotSpeedRelativeType; +import crcl.base.RotSpeedType; +import crcl.base.SetAngleUnitsType; +import crcl.base.SetEndEffectorType; +import crcl.base.SetEndPoseToleranceType; +import crcl.base.SetIntermediatePoseToleranceType; +import crcl.base.SetLengthUnitsType; +import crcl.base.SetRotAccelType; +import crcl.base.SetRotSpeedType; +import crcl.base.SetTransAccelType; +import crcl.base.SetTransSpeedType; +import crcl.base.StopMotionType; +import crcl.base.TransAccelAbsoluteType; +import crcl.base.TransAccelRelativeType; +import crcl.base.TransAccelType; +import crcl.base.TransSpeedAbsoluteType; +import crcl.base.TransSpeedRelativeType; +import crcl.base.TransSpeedType; +import java.io.File; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBException; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.parsers.ParserConfigurationException; +import static crcl.utils.CRCLPosemath.maxDiffDoubleArray; +import static crcl.utils.CRCLPosemath.multiply; +import static crcl.utils.CRCLPosemath.pointToPmCartesian; +import static crcl.utils.CRCLPosemath.shift; +import static crcl.utils.CRCLPosemath.toPmRotationVector; +import static crcl.utils.CRCLPosemath.toPoseType; +import static crcl.utils.CRCLPosemath.vectorToPmCartesian; +import java.io.EOFException; +import java.io.PrintStream; +import java.net.SocketException; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.Optional; +import java.util.Set; +import org.xml.sax.SAXException; +import rcs.posemath.PmCartesian; +import rcs.posemath.PmException; +import rcs.posemath.PmRotationVector; +import rcs.posemath.Posemath; + +/** + * + * @author Will Shackleford {@literal } + */ +public class SimServerInner { + + private final static Set runningServers = new HashSet<>(); + + private final XpathUtils xpu; + private final SimServerOuter outer; + Queue cmdQueue = new ConcurrentLinkedQueue(); + + double[] jointPositions; // = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + double[] lastJointPositions;// = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + double[] commandedJointPositions;// = new double[]{0.0, 45.0, -90.0, 90.0, 0.0, 0.0}; + double[] jointVelocites;// = new double[jointPositions.length]; + double[] jointmins; // = new double[]{-170.0, 5.0, -170.0, +10.0, -135.0, -135.0}; + double[] jointmaxs;// = new double[]{+170.0, 85.0, -10.0, 170.0, +135.0, +135.0}; + double[] seglengths;// = SimulatedKinematicsPlausible.DEFAULT_SEGLENGTHS; + +// double[] jointPositions = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); +// double[] lastJointPositions = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); +// double[] commandedJointPositions = new double[]{0.0, 45.0, -90.0, 90.0, 0.0, 0.0}; +// double[] jointVelocites = new double[jointPositions.length]; +// double jointmins[] = new double[]{-170.0, 5.0, -170.0, +10.0, -135.0, -135.0}; +// double jointmaxs[] = new double[]{+170.0, 85.0, -10.0, 170.0, +135.0, +135.0}; +// double seglengths[] = SimulatedKinematicsPlausible.DEFAULT_SEGLENGTHS; + private PoseType goalPose; + + private double maxTransSpeed = getDoubleProperty("SimServer.maxTransSpeed", 2.0); + private double maxTransAccel = getDoubleProperty("SimServer.maxTransAccell", 2.0); + + private double curTransSpeed = 0; + private double commandedTransSpeed = maxTransSpeed * 0.5; + private double curTransAccel = 0; + private double commandedTransAccel = maxTransAccel * 0.5; + + private double maxRotSpeed = getDoubleProperty("SimServer.maxRotSpeed", 2.0); + private double maxRotAccel = getDoubleProperty("SimServer.maxRotAccell", 2.0); + + private double curRotSpeed = 0; + private double commandedRotSpeed = maxRotSpeed * 0.5; + private double curRotAccel = 0; + private double commandedRotAccel = maxRotAccel * 0.5; + + private void resetToPlausibleDefaults() { + jointPositions = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + lastJointPositions = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + commandedJointPositions = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + jointVelocites = new double[jointPositions.length]; + jointmins = new double[]{-170.0, 5.0, -170.0, +10.0, -135.0, -135.0}; + jointmaxs = new double[]{+170.0, 85.0, -10.0, 170.0, +135.0, +135.0}; + seglengths = SimulatedKinematicsPlausible.DEFAULT_SEGLENGTHS; + } + + private void resetToSimpleDefaults() { + jointPositions = Arrays.copyOf(SimulatedKinematicsSimple.DEFAULT_JOINTVALS, SimulatedKinematicsSimple.DEFAULT_JOINTVALS.length); + lastJointPositions = Arrays.copyOf(SimulatedKinematicsSimple.DEFAULT_JOINTVALS, SimulatedKinematicsSimple.DEFAULT_JOINTVALS.length); + commandedJointPositions = Arrays.copyOf(SimulatedKinematicsSimple.DEFAULT_JOINTVALS, SimulatedKinematicsSimple.DEFAULT_JOINTVALS.length);; + jointVelocites = new double[jointPositions.length]; + jointmins = null;// new double[]{-170.0, 5.0, -170.0, +10.0, -135.0, -135.0}; + jointmaxs = null;//new double[]{+170.0, 85.0, -10.0, 170.0, +135.0, +135.0}; + seglengths = SimulatedKinematicsSimple.DEFAULT_SEGLENGTHS; + } + + private SimRobotEnum robotType = SimRobotEnum.SIMPLE; + + /** + * Get the value of robotType + * + * @return the value of robotType + */ + public SimRobotEnum getRobotType() { + return robotType; + } + + /** + * Set the value of robotType + * + * @param robotType new value of robotType + */ + public void setRobotType(SimRobotEnum robotType) { + this.robotType = robotType; + switch (robotType) { + case PLAUSIBLE: + resetToPlausibleDefaults(); + break; + + case SIMPLE: + resetToSimpleDefaults(); + break; + } + } + + public SimServerInner(SimServerOuter _outer) throws ParserConfigurationException { + this.outer = _outer; + this.xpu = new XpathUtils(); + this.status = new CRCLStatusType(); + this.setRobotType(SimRobotEnum.SIMPLE); + this.port = CRCLSocket.DEFAULT_PORT; + String portPropertyString = System.getProperty("crcljava.port"); + if (null != portPropertyString) { + this.setPort(Integer.valueOf(portPropertyString)); + } + } + + public XpathUtils getXpu() { + return xpu; + } + + private int port; + + /** + * Get the value of port + * + * @return the value of port + */ + public int getPort() { + return port; + } + + public void simulatedTeleportToPose(PoseType pose) { + switch (robotType) { + case PLAUSIBLE: + jointPositions = skPlausible.poseToJoints(this.jointPositions, pose); + this.getStatus().setPose(skPlausible.jointsToPose(jointPositions, this.getStatus().getPose())); + break; + + case SIMPLE: + jointPositions = skSimple.poseToJoints(this.jointPositions, pose); + this.getStatus().setPose(skSimple.jointsToPose(jointPositions, this.getStatus().getPose())); + break; + } + commandedJointPositions = Arrays.copyOf(jointPositions, jointPositions.length); + this.goalPose = null; + this.setWaypoints(null); + CommandStatusType cst = this.getStatus().getCommandStatus(); + if (cst == null) { + cst = new CommandStatusType(); + } + if (null == cst.getStatusID()) { + cst.setStatusID(BigInteger.ONE); + } + setCommandState(CommandStateEnumType.DONE); + } + + /** + * Set the value of port + * + * @param port new value of port + */ + public void setPort(int port) { + this.port = port; + if (null != this.ssock) { + this.restartServer(); + } + } + + private boolean moveStraight = false; + + /** + * Get the value of moveStraight + * + * @return the value of moveStraight + */ + public boolean isMoveStraight() { + return moveStraight; + } + + private ServerSocket ssock = null; + private SimulatedKinematicsPlausible skPlausible = new SimulatedKinematicsPlausible(); + private SimulatedKinematicsSimple skSimple = new SimulatedKinematicsSimple(); + + private CRCLStatusType status; + + private File[] statSchemaFiles = null; + + public void setJointPosition(double _position, int index) { + this.jointPositions[index] = _position; + } + + public void setCommandedJointPosition(double _position, int index) { + this.commandedJointPositions[index] = _position; + } + + public void reset() { + jointPositions = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + switch (robotType) { + case PLAUSIBLE: + this.getStatus().setPose(skPlausible.jointsToPose(jointPositions, this.getStatus().getPose())); + break; + + case SIMPLE: + this.getStatus().setPose(skSimple.jointsToPose(jointPositions, this.getStatus().getPose())); + break; + } + commandedJointPositions = Arrays.copyOf(jointPositions, jointPositions.length); + this.goalPose = null; + this.setWaypoints(null); + CommandStatusType cst = this.getStatus().getCommandStatus(); + if (cst == null) { + cst = new CommandStatusType(); + } + if (null == cst.getStatusID()) { + cst.setStatusID(BigInteger.ONE); + } + setCommandState(CommandStateEnumType.DONE); + } + + public double[] getJointPositions() { + return jointPositions; + } + + public double[] getSeglengths() { + return seglengths; + } + + public void setGoalPose(PoseType goalPose) { + this.goalPose = goalPose; + if (null != goalPose) { + checkPose(goalPose); + } + } + + private CRCLCommandType multiStepCommand = null; + private int moveScrewStep = 0; + + public boolean isFinishedMove() { + double jointdiffs[] = new double[this.jointPositions.length]; + Arrays.setAll(jointdiffs, (i) -> Math.abs(jointPositions[i] - commandedJointPositions[i])); + double maxdiff = Arrays.stream(jointdiffs).max().orElse(0); + if (maxdiff > getJointDiffMax()) { + return false; + } + Arrays.setAll(jointdiffs, (i) -> Math.abs(jointPositions[i] - lastJointPositions[i])); + maxdiff = Arrays.stream(jointdiffs).max().orElse(0); + if (maxdiff > getJointDiffMax()) { + return false; + } + return true; + } + + private BigDecimal moveScriptTurnComplete = BigDecimal.ZERO; + + private boolean handleContinueMoveScrew(MoveScrewType moveScrew) { + switch (moveScrewStep) { + case 0: + setCommandState(CommandStateEnumType.WORKING); + if (moveScrew.getStartPosition() != null) { + goalPose = moveScrew.getStartPosition(); + moveScrewStep = 1; + } else { + moveScrewStep = 2; + } + break; + + case 1: + if (isFinishedMove()) { + if (!PoseToleranceChecker.isInTolerance(status.getPose(), goalPose, + expectedEndPoseTolerance, angleType)) { + multiStepCommand = null; + setCommandState(CommandStateEnumType.ERROR); + return false; + } + } + break; + + case 2: + if (moveScrew.getAxialDistanceFree() != null && moveScrew.getAxialDistanceFree().compareTo(BigDecimal.ZERO) > 0) { + goalPose = shift(status.getPose(), + multiply(moveScrew.getAxialDistanceFree(), status.getPose().getXAxis())); + setMoveStraight(true); + moveScrewStep = 3; + } else { + moveScrewStep = 4; + } + break; + + case 3: + if (isFinishedMove()) { + moveScrewStep = 4; + } + break; + + case 4: + moveScriptTurnComplete = BigDecimal.ZERO; + moveScrewStep = 5; + break; + + case 5: + multiStepCommand = null; + setCommandState(CommandStateEnumType.DONE); + return false; + } + return true; +// setCommandState(CommandStateEnumType.DONE); +// multiStepCommand = null; +// return false; + } + + private boolean handleMultiStepCommand() { + if (null == multiStepCommand) { + return false; + } + if (multiStepCommand instanceof MoveScrewType) { + return handleContinueMoveScrew((MoveScrewType) multiStepCommand); + } + multiStepCommand = null; + return false; + } + + public void setCommandState(CommandStateEnumType state) { + synchronized (status) { + CommandStatusType cst = status.getCommandStatus(); + if (null == cst) { + cst = new CommandStatusType(); + status.setCommandStatus(cst); + } + cst.setCommandState(state); + } + } + + public CommandStateEnumType getCommandState() { + CommandStatusType cst = status.getCommandStatus(); + if (null == cst) { + setCommandState(CommandStateEnumType.ERROR); + } + cst = status.getCommandStatus(); + return cst.getCommandState(); + } + + private void showMessage(String s) { + outer.showMessage(s); + } + + public boolean checkPose(PoseType goalPose) { + PmCartesian xvec = vectorToPmCartesian(goalPose.getXAxis()); + if (Math.abs(xvec.mag() - 1.0) > 1e-3) { + showMessage("Bad postion : xvec " + xvec + " has magnitude not equal to one."); + setCommandState(CommandStateEnumType.ERROR); + return false; + } + PmCartesian zvec = vectorToPmCartesian(goalPose.getZAxis()); + if (Math.abs(zvec.mag() - 1.0) > 1e-3) { + showMessage("Bad postion : zvec " + zvec + " has magnitude not equal to one."); + setCommandState(CommandStateEnumType.ERROR); + return false; + } + if (Math.abs(Posemath.pmCartCartDot(xvec, zvec)) > 1e-3) { + showMessage("Bad postion : xvec " + xvec + " and zvec " + zvec + " are not orthogonal."); + setCommandState(CommandStateEnumType.ERROR); + return false; + } + return true; + } + + private static double getDoubleProperty(String propName, double defaultVal) { + return Double.valueOf(System.getProperty(propName, Double.toString(defaultVal))); + } + + public double getJointSpeedMax() { + return jointSpeedMax; + } + + public void setJointSpeedMax(double jointSpeedMax) { + this.jointSpeedMax = jointSpeedMax; + } + + private double jointSpeedMax = getDoubleProperty("SimServer.jointSpeedMax", 200.0); + + public PoseType limitSpeedAccel(PoseType goal, + PoseType current) { + PoseType newGoal = goal; + try { + PmCartesian goalPt = pointToPmCartesian(goalPose.getPoint()); + PmCartesian currentPt = pointToPmCartesian(current.getPoint()); + PmCartesian diffPt = goalPt.subtract(currentPt); + double lastTransSpeed = this.curTransSpeed; + double diffTransSpeed = diffPt.mag() / (delayMillis * 1e-3); + this.curTransSpeed = diffTransSpeed; + this.curTransAccel = this.curTransSpeed - lastTransSpeed; + if (Math.abs(curTransAccel) > this.commandedTransAccel) { + this.curTransSpeed = lastTransSpeed + + Math.signum(curTransAccel) * this.commandedTransAccel; + } + if (this.curTransSpeed > this.commandedTransSpeed) { + this.curTransSpeed = this.commandedTransSpeed; + } + PmRotationVector goalRotv = toPmRotationVector(goalPose); + PmRotationVector currentRotv = toPmRotationVector(current); + PmRotationVector diffRotv = goalRotv.multiply(currentRotv.inv()); + double lastRotSpeed = this.curRotSpeed; + double diffRotSpeed = diffRotv.s / (delayMillis * 1e-3); + this.curRotSpeed = diffRotSpeed; + this.curRotAccel = this.curRotSpeed - lastRotSpeed; + if (Math.abs(curRotAccel) > this.commandedRotAccel) { + this.curRotSpeed = lastRotSpeed + + Math.signum(curRotAccel) * this.commandedRotAccel; + } + if (this.curRotSpeed > this.commandedRotSpeed) { + this.curRotSpeed = this.commandedRotSpeed; + } + double transMoveFraction = 1.0; + if (Math.abs(diffTransSpeed - this.curTransSpeed) > this.commandedTransSpeed * 0.1 + && Math.abs(diffTransSpeed) > 1e-6) { + transMoveFraction = curTransSpeed / diffTransSpeed; + } + double rotMoveFraction = 1.0; + if (Math.abs(diffRotSpeed - this.curRotSpeed) > this.commandedRotSpeed * 0.1 + && Math.abs(diffRotSpeed) > 1e-6) { + rotMoveFraction = curRotSpeed / diffRotSpeed; + } + double moveFraction = Math.min(transMoveFraction, rotMoveFraction); + assert (moveFraction > 0); + if (moveFraction < 0.99) { + PmCartesian newGoalPt = currentPt.add(diffPt.multiply(moveFraction)); + PmRotationVector newGoalRotv = currentRotv.multiply(diffRotv.multiply(moveFraction)); + newGoal = toPoseType(newGoalPt, newGoalRotv); + } + } catch (PmException ex) { + LOGGER.log(Level.SEVERE, null, ex); + outer.showMessage(ex.toString()); + } + return newGoal; + } + + private static final Logger LOGGER = Logger.getLogger(SimServerInner.class.getName()); + + ; + + public double[] getStraightMoveCommandedJointVals(PoseType curGoalPose) { + try { + final double JOINT_DIFF_MAX = getJointDiffMax(); + PmCartesian goalPt = pointToPmCartesian(curGoalPose.getPoint()); + PmCartesian currentPt = pointToPmCartesian(status.getPose().getPoint()); + PmCartesian diffPt = goalPt.subtract(currentPt); + PmRotationVector goalRotv = toPmRotationVector(curGoalPose); + PmRotationVector currentRotv = toPmRotationVector(status.getPose()); + PmRotationVector diffRotv = goalRotv.multiply(currentRotv.inv()); + PoseType newGoalPose = curGoalPose; + goalPoseToCommandedPositions(newGoalPose); + double maxdiff = maxDiffDoubleArray(this.commandedJointPositions, this.jointPositions); + double scale = 1.0; + while (maxdiff > JOINT_DIFF_MAX) { + scale *= JOINT_DIFF_MAX / (maxdiff + 0.01); + PmCartesian scaledDiffPt = diffPt.multiply(scale); + PmCartesian newGoalPt = currentPt.add(scaledDiffPt); + PmRotationVector scaledDiffRot = diffRotv.multiply(scale); + PmRotationVector newGoalRotv = currentRotv.multiply(scaledDiffRot); + newGoalPose = toPoseType(newGoalPt, newGoalRotv); + this.goalPoseToCommandedPositions(newGoalPose); + maxdiff = maxDiffDoubleArray(this.commandedJointPositions, this.jointPositions); + } + } catch (PmException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return this.commandedJointPositions; + } + + private int cycle_count = 0; + + public void setCmdSchema(File[] fa) { + try { + fa = CRCLSocket.reorderCommandSchemaFiles(fa); + CRCLSocket.defaultCmdSchema = CRCLSocket.filesToSchema(fa); + for (ClientState state : this.clientStates) { + state.getCs().setCmdSchema(CRCLSocket.defaultCmdSchema); + } + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public void setStatSchema(File[] fa) { + try { + fa = CRCLSocket.reorderStatSchemaFiles(fa); + CRCLSocket.defaultStatSchema = CRCLSocket.filesToSchema(fa); + for (ClientState state : this.clientStates) { + state.getCs().setStatSchema(CRCLSocket.defaultStatSchema); + } + this.statSchemaFiles = fa; + xpu.setSchemaFiles(statSchemaFiles); + } catch (SAXException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + + public synchronized void setStatus(CRCLStatusType status) { + this.status = status; + } + + private List clientStates = new ArrayList<>(); + private Map clientThreadMap = new HashMap<>(); + + /** + * Set the value of moveStraight + * + * @param moveStraight new value of moveStraight + */ + public void setMoveStraight(boolean moveStraight) { + this.moveStraight = moveStraight; + } + + Thread simThread = null; + + private volatile int close_count = 0; + + public void closeServer() { + try { + SimServerInner.runningServers.remove(this); + } catch (Exception e) { + e.printStackTrace(); + } + this.close_count++; +// System.out.println("close_count = " + close_count); + if (null != acceptClientsThread) { + try { + acceptClientsThread.interrupt(); + acceptClientsThread.join(100); + acceptClientsThread = null; + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + if (null != simThread) { + try { + simThread.interrupt(); + simThread.join(100); + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + simThread = null; + } + if (null != clientStates) { + for (ClientState s : clientStates) { + try { + s.close(); + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + clientStates.removeAll(clientStates); + } + if (null != ssock) { + try { + this.ssock.close(); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + this.ssock = null; + } + this.updateConnectedClients(); + this.lastStatusMap = null; + } + + BigInteger maxCmdId = BigInteger.ONE; + + private static class LastStatusInfo { + + BigInteger lastSentCid = null; + CommandStateEnumType lastSentState = null; + }; + + Map lastStatusMap = null; + + private void sendStatus(CRCLSocket socket) { + CRCLSocket curSocket = socket; + try { + if (null == socket) { + if (!outer.isSendStatusWithoutRequestSelected() + || null == clientStates + || clientStates.size() < 1) { + return; + } + } + synchronized (status) { + CommandStatusType cst = status.getCommandStatus(); + if (null == cst) { + cst = new CommandStatusType(); + status.setCommandStatus(cst); + } + if (null == getCommandState()) { + setCommandState(CommandStateEnumType.WORKING); + } + BigInteger sid = cst.getStatusID(); + if (sid == null) { + cst.setStatusID(BigInteger.ONE); + } + BigInteger cid = cst.getCommandID(); + if (cid == null) { + cst.setCommandID(BigInteger.ONE); + } +// outer.showDebugMessage("status="+CRCLSocket.statToDebugString(status)); + if (null != socket) { + try { + socket.appendTrailingZero = outer.isAppendZeroSelected(); + socket.randomPacketing = outer.isRandomPacketSelected(); + socket.setReplaceHeader(outer.isReplaceXmlHeaderSelected()); + if (outer.isReplaceStateSelected()) { + socket.setStatusStringOutputFilter(CRCLSocket.removeCRCLFromState); + } else { + socket.setStatusStringOutputFilter(null); + } + boolean new_state = true; + if (null != this.lastStatusMap) { + LastStatusInfo lsi = this.lastStatusMap.get(socket); + new_state = (null == lsi + || null == lsi.lastSentCid + || null == lsi.lastSentState + || !lsi.lastSentCid.equals(status.getCommandStatus().getCommandID()) + || !lsi.lastSentState.equals(status.getCommandStatus().getCommandState())); + } + if (outer.isDebugSendStatusSelected() && new_state) { + outer.showDebugMessage("Status sent to " + socket.getInetAddress() + ":" + socket.getPort() + + " CommandId=" + + status.getCommandStatus().getCommandID() + + " StatusId=" + + status.getCommandStatus().getStatusID() + + " State=" + + status.getCommandStatus().getCommandState()); + } + socket.writeStatus(status, outer.isValidateXMLSelected()); + if (outer.isDebugSendStatusSelected() && new_state) { + outer.showDebugMessage("writeStatus Complete"); + } + if (new_state) { + if (null == this.lastStatusMap) { + this.lastStatusMap = new IdentityHashMap<>(); + } + LastStatusInfo lsi = new LastStatusInfo(); + lsi.lastSentCid = status.getCommandStatus().getCommandID(); + lsi.lastSentState = status.getCommandStatus().getCommandState(); + this.lastStatusMap.put(socket, lsi); + } + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + try { + socket.close(); + } catch (IOException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + this.clientStates.remove(socket); +// showMessage(ex); + } catch (InterruptedException | EXIException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + return; + } + curSocket = clientStates.get(0).getCs(); + if (outer.isReplaceStateSelected()) { + curSocket.setStatusStringOutputFilter(CRCLSocket.removeCRCLFromState); + } else { + curSocket.setStatusStringOutputFilter(null); + } + boolean new_state = true; + if (null != this.lastStatusMap) { + LastStatusInfo lsi = this.lastStatusMap.get(curSocket); + new_state = (null == lsi + || null == lsi.lastSentCid + || null == lsi.lastSentState + || !lsi.lastSentCid.equals(status.getCommandStatus().getCommandID()) + || !lsi.lastSentState.equals(status.getCommandStatus().getCommandState())); + } + if (outer.isDebugSendStatusSelected() && new_state) { + outer.showDebugMessage("Status sent to " + socket.getInetAddress() + ":" + socket.getPort() + + " CommandId=" + + status.getCommandStatus().getCommandID() + + " StatusId=" + + status.getCommandStatus().getStatusID() + + " State=" + + status.getCommandStatus().getCommandState()); + } + String xmls = curSocket.statusToString(status, outer.isValidateXMLSelected()); +// System.out.println("SimServer.sendStatus() : xmls = " + xmls); +// String strout = "\n"+xmls; + +// byte ba[] = xmls.getBytes(); +// byte fill[] = new byte[2000]; + int write_count = 0; + for (int i = 0; i < clientStates.size(); i++) { + curSocket = clientStates.get(i).getCs(); + + try { + curSocket.appendTrailingZero = outer.isAppendZeroSelected(); + curSocket.randomPacketing = outer.isRandomPacketSelected(); + curSocket.setReplaceHeader(outer.isReplaceXmlHeaderSelected()); + curSocket.writeWithFill(xmls); + write_count++; + } catch (IOException ex) { + try { + LOGGER.log(Level.SEVERE, null, ex); + clientStates.remove(i); + Thread t = clientThreadMap.get(curSocket); + t.interrupt(); + t.join(100); + clientThreadMap.remove(curSocket); + updateConnectedClients(); + } catch (InterruptedException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + } catch (InterruptedException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + if (outer.isDebugSendStatusSelected() && new_state) { + outer.showDebugMessage("writeStatus to " + write_count + " clients complete."); + } + if (new_state) { + if (null == this.lastStatusMap) { + this.lastStatusMap = new IdentityHashMap<>(); + } + LastStatusInfo lsi = new LastStatusInfo(); + lsi.lastSentCid = status.getCommandStatus().getCommandID(); + lsi.lastSentState = status.getCommandStatus().getCommandState(); + this.lastStatusMap.put(socket, lsi); + } + } +// System.out.println("SimServer.sendStatus() sent data to " + write_count + " clients."); + } catch (JAXBException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage(ex + "\n" + ((curSocket != null) ? curSocket.getLastStatusString() : "")); + } + } + + private boolean isCoordinated(PoseType pose) { + if (pose instanceof PoseAndSetType) { + PoseAndSetType pas = (PoseAndSetType) pose; + return pas.isCoordinated(); + } + return false; + } + + public XMLGregorianCalendar getXMLGregorianCalendarNow() + throws DatatypeConfigurationException { + GregorianCalendar gregorianCalendar = new GregorianCalendar(); + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + XMLGregorianCalendar now + = datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); + return now; + } + + private boolean executingMoveCommand = false; + + private synchronized void incStatusId() { + synchronized (status) { + CommandStatusType cst = status.getCommandStatus(); + if (null != cst) { + cst.setStatusID( + Optional.ofNullable(cst.getStatusID()) + .orElse(BigInteger.ZERO) + .add(BigInteger.ONE) + ); + } + } + } + + /** + * + * @return the boolean + */ + private synchronized boolean updateStatus() { + boolean jointschanged = false; + synchronized (status) { + if (!outer.isEditingStatus()) { + if (null == status.getCommandStatus()) { + CommandStatusType cst = new CommandStatusType(); + cst.setCommandID(BigInteger.ONE); + cst.setStatusID(BigInteger.ONE); + cst.setCommandState(CommandStateEnumType.WORKING); + status.setCommandStatus(new CommandStatusType()); + } + this.incStatusId(); + if (null == goalPose + && null != waypoints + && this.currentWaypoint < waypoints.size() - 1) { + int new_waypoint = this.currentWaypoint + 1; + this.setCurrentWaypoint(new_waypoint); + this.goalPose = this.waypoints.get(this.currentWaypoint); + } + if (null != goalPose) { + PoseType curGoalPose = this.limitSpeedAccel(goalPose, status.getPose()); + if (this.moveStraight || isCoordinated(goalPose)) { + this.commandedJointPositions = getStraightMoveCommandedJointVals(curGoalPose); + } else { + goalPoseToCommandedPositions(curGoalPose); + } + } + final double JOINT_DIFF_MAX = getJointDiffMax(); + for (int i = 0; i < jointPositions.length; i++) { + if (Math.abs(commandedJointPositions[i] - jointPositions[i]) < JOINT_DIFF_MAX) { + if (Math.abs(commandedJointPositions[i] - jointPositions[i]) > 1e-4) { + jointschanged = true; + } + jointPositions[i] = commandedJointPositions[i]; + + } else { + jointPositions[i] += JOINT_DIFF_MAX * Math.signum(commandedJointPositions[i] - jointPositions[i]); + jointschanged = true; + } + if (jointmins != null && jointmins.length > i && jointPositions[i] < jointmins[i]) { + goalPose = null; + setCommandState(CommandStateEnumType.ERROR); + showMessage("Joint " + (i + 1) + " at " + jointPositions[i] + " less than limit " + jointmins[i]); + jointPositions[i] = jointmins[i]; + commandedJointPositions[i] = jointPositions[i]; + } + if (jointmaxs != null && jointmaxs.length > i && jointPositions[i] > jointmaxs[i]) { + goalPose = null; + setCommandState(CommandStateEnumType.ERROR); + showMessage("Joint " + (i + 1) + " at " + jointPositions[i] + " more than limit " + jointmaxs[i]); + jointPositions[i] = jointmaxs[i]; + commandedJointPositions[i] = jointPositions[i]; + } + jointVelocites[i] = (jointPositions[i] - lastJointPositions[i]) / (1000.0 * delayMillis); + lastJointPositions[i] = jointPositions[i]; + JointStatusesType jsst = status.getJointStatuses(); + if (null == jsst) { + jsst = new JointStatusesType(); + status.setJointStatuses(jsst); + } + List jsl = jsst.getJointStatus(); + JointStatusType js = null; + if (i < jsl.size()) { + js = jsl.get(i); + } + if (null == js) { + js = new JointStatusType(); + jsl.add(i, js); + } + js.setJointNumber(BigInteger.valueOf(i + 1)); + js.setJointPosition(BigDecimal.valueOf(jointPositions[i])); + if (null != cjrList && cjrList.size() > 0) { + js.setJointPosition(null); + js.setJointVelocity(null); + js.setJointTorqueOrForce(null); + for (ConfigureJointReportType cjrt : this.cjrList) { + if (cjrt.getJointNumber().compareTo(js.getJointNumber()) == 0) { + if (cjrt.isReportPosition()) { + js.setJointPosition(BigDecimal.valueOf(jointPositions[i])); + } + if (cjrt.isReportVelocity()) { + js.setJointVelocity(BigDecimal.valueOf(jointVelocites[i])); + } + if (cjrt.isReportTorqueOrForce()) { + js.setJointTorqueOrForce(BigDecimal.TEN); + } + } + } + } else { + js.setJointPosition(BigDecimal.valueOf(jointPositions[i])); + } + } + if (jointschanged || null == status.getPose()) { + switch (robotType) { + case PLAUSIBLE: + status.setPose(skPlausible.jointsToPose(jointPositions, status.getPose())); + break; + + case SIMPLE: + status.setPose(skSimple.jointsToPose(jointPositions, status.getPose())); + break; + } +// try { +//// status.getPose().setTimestamp(getXMLGregorianCalendarNow()); +// } catch (DatatypeConfigurationException ex) { +// LOGGER.log(Level.SEVERE, null, ex); +// } + } + outer.updatePanels(jointschanged); + if (!jointschanged + && this.getCommandState() == CommandStateEnumType.WORKING + && executingMoveCommand) { + if (null == goalPose + || null == this.waypoints + || this.currentWaypoint >= this.waypoints.size()) { + setCommandState(CommandStateEnumType.DONE); + if (outer.isDebugMoveDoneSelected()) { + outer.showDebugMessage("SimServerInner DONE move command: " + status.getCommandStatus().getCommandID()); + outer.showDebugMessage("SimServerInner jointpositions = " + Arrays.toString(jointPositions)); + } + this.setMoveStraight(false); + this.setWaypoints(null); + } else { + goalPose = null; + } + } + cycle_count++; + } + } + return false; + } + + private double getJointDiffMax() { + return jointSpeedMax * delayMillis * 1e-3; + } + + /** + * + * @param _goalPose the value of _goalPose + */ + public void goalPoseToCommandedPositions(PoseType _goalPose) { + switch (robotType) { + case PLAUSIBLE: + this.commandedJointPositions = skPlausible.poseToJoints(this.commandedJointPositions, _goalPose); + break; + + case SIMPLE: + this.commandedJointPositions = skSimple.poseToJoints(this.commandedJointPositions, _goalPose); + break; + } + } + private int currentWaypoint; + + /** + * Get the value of currentWaypoint + * + * @return the value of currentWaypoint + */ + public int getCurrentWaypoint() { + return currentWaypoint; + } + + /** + * Set the value of currentWaypoint + * + * @param currentWaypoint new value of currentWaypoint + */ + public void setCurrentWaypoint(int currentWaypoint) { + this.currentWaypoint = currentWaypoint; + outer.finishSetCurrentWaypoint(currentWaypoint); + } + + public void printClientStates(final PrintStream ps) { + if (null != clientStates) { + clientStates.forEach(ps::println); + } + if (null != this.cmdQueue) { + ps.println("cmdQueue.peek() = " + cmdQueue.peek()); + } + } + + static public void printAllClientStates(final PrintStream ps) { + SimServerInner.runningServers.forEach(s -> s.printClientStates(ps)); + } + + private final boolean enableGetStatusIDCheck + = Boolean.valueOf(System.getProperty("crcl.utils.SimServerInner.enableGetStatusIDCheck", "false")); + + private void readCommandsRepeatedly(ClientState state) { + final int start_close_count = this.close_count; + final CRCLSocket cs = state.getCs(); + try { + while (!Thread.currentThread().isInterrupted()) { + final CRCLCommandInstanceType cmdInstance + = cs.readCommand(outer.isValidateXMLSelected()); + LOGGER.log(Level.FINER, () -> "cmdInstance = " + cmdInstance); + if (null != cmdInstance && null != cmdInstance.getCRCLCommand()) { + CRCLCommandType cmd = cmdInstance.getCRCLCommand(); + LOGGER.log(Level.FINEST, () -> "SimServerInner.readCommandsRepeatedly() : cmd = " + cmd+ ", state="+state); + if (cmd instanceof GetStatusType) { + state.getStatusRequests++; + state.lastStatRequestTime = System.currentTimeMillis(); + GetStatusType getStatus = (GetStatusType) cmd; + if (outer.isDebugReadCommandSelected() && !getStatus.getCommandID().equals(state.getStatusCmdId)) { + outer.showDebugMessage("SimServerInner.readCommandsRepeatedly() : (getStatus=" + getStatus + " ID=" + getStatus.getCommandID() + ") state = " + state); + } + state.getStatusCmdId = getStatus.getCommandID(); + if (enableGetStatusIDCheck + && !state.getStatusCmdId.equals(state.cmdId)) { + LOGGER.log(Level.SEVERE, + "SimServerInner.readCommandsRepeatedly() : state.getStatusCmdId=" + + state.getStatusCmdId + ", state.cmdId = " + state.cmdId + + ",status=" + CRCLSocket.statToDebugString(status)); + LOGGER.setLevel(Level.OFF); + new Thread(() -> closeServer()).start(); + return; + } + synchronized (status) { + CommandStatusType cst = status.getCommandStatus(); + if (null == cst) { + cst = new CommandStatusType(); + setCommandState(CommandStateEnumType.WORKING); + cst.setCommandID(cmd.getCommandID()); + cst.setStatusID(BigInteger.ONE); + status.setCommandStatus(cst); + } + SimServerInner.this.sendStatus(cs); + } + continue; + } + state.cmdsRecieved++; + state.lastCmdTime = System.currentTimeMillis(); + state.cmdId = cmdInstance.getCRCLCommand().getCommandID(); + if (outer.isDebugReadCommandSelected()) { + outer.showDebugMessage("SimServerInner.readCommandsRepeatedly() : cmdInstance.getCRCLCommand() = " + cmdInstance.getCRCLCommand() + + " cmdInstance.getCRCLCommand().getCommandID() = " + cmdInstance.getCRCLCommand().getCommandID() + ", state=" + state); + } + SimServerInner.this.cmdQueue.offer(cmdInstance); + } + } + } catch (SocketException se) { + try { + cs.close(); + } catch (IOException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + this.clientStates.remove(state); + return; + } catch (JAXBException | IllegalStateException ex) { +// System.err.println("ex.getCause() ="+ex.getCause()); +// if(null != ex.getCause()) { +// System.err.println("ex.getCause().getCause()="+ex.getCause().getCause()); +// } +// System.out.println("start_close_count = " + start_close_count); +// System.out.println("close_count = " + close_count); + if (ex.getCause() instanceof EOFException) { + try { + cs.close(); + } catch (IOException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + this.clientStates.remove(state); + return; + } + if (null != ex.getCause() && ex.getCause().getCause() instanceof EOFException) { + try { + cs.close(); + } catch (IOException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + this.clientStates.remove(state); + return; + } +// System.out.println("start_close_count = " + start_close_count); +// System.out.println("close_count = " + close_count); + if (close_count <= start_close_count) { + System.err.println("String to parse was:" + cs.getLastCommandString()); + LOGGER.log(Level.SEVERE, null, ex); + this.showMessage(ex.toString() + "\nString to parse was:" + cs.getLastCommandString()); + } + } catch (IOException ex) { +// System.out.println("start_close_count = " + start_close_count); +// System.out.println("close_count = " + close_count); + if (close_count <= start_close_count) { + String str = cs.getReadInProgressString(); + if (str.length() == 0) { + return; + } + LOGGER.log(Level.SEVERE, "ReadInProgressString:" + str); + LOGGER.log(Level.SEVERE, null, ex); + } + try { + cs.close(); + } catch (IOException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + this.clientStates.remove(state); + } catch (EXIException ex) { + System.err.println("ex.getCause() =" + ex.getCause()); +// System.out.println("start_close_count = " + start_close_count); +// System.out.println("close_count = " + close_count); + if (ex.getCause() instanceof EOFException) { + try { + cs.close(); + } catch (IOException ex1) { + LOGGER.log(Level.SEVERE, null, ex1); + } + this.clientStates.remove(state); + return; + } + if (close_count <= start_close_count) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + + private static class ClientState implements AutoCloseable { + + private final CRCLSocket cs; + public int getStatusRequests = 0; + public int cmdsRecieved = 0; + public long lastCmdTime = 0; + public long lastStatRequestTime = 0; + BigInteger getStatusCmdId = null; + BigInteger cmdId = null; + + public ClientState(CRCLSocket cs) { + this.cs = cs; + } + + @Override + public void close() throws Exception { + cs.close(); + } + + public CRCLSocket getCs() { + return cs; + } + + @Override + public String toString() { + return "ClientState{" + "cs=" + cs + ", getStatusRequests=" + getStatusRequests + ", cmdsRecieved=" + cmdsRecieved + ", lastCmdTime=" + lastCmdTime + ", lastStatRequestTime=" + lastStatRequestTime + ", getStatusCmdId=" + getStatusCmdId + ", cmdId=" + cmdId + '}'; + } + + } + + public void runAcceptClients() { + final int start_close_count = this.close_count; + while (!Thread.currentThread().isInterrupted()) { + try { + final Socket s = ssock.accept(); + final CRCLSocket cs = new CRCLSocket(s); + final ClientState state = new ClientState(cs); + cs.setEXIEnabled(outer.isEXISelected()); + clientStates.add(state); + Thread t = new Thread(() -> readCommandsRepeatedly(state), + "client" + s.getInetAddress().toString() + ":" + s.getPort() + ); + clientThreadMap.put(cs, t); + t.start(); + this.updateConnectedClients(); + } catch (SocketException ex) { + if (close_count <= start_close_count) { + LOGGER.log(Level.SEVERE, null, ex); + } + } catch (IOException | EXIException ex) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + Thread acceptClientsThread = null; + + private static long getLongProperty(String propName, long defaultLong) { + return Long.valueOf(System.getProperty(propName, Long.toString(defaultLong))); + } + + private long delayMillis = getLongProperty("SimServer.delayMillis", 100); + + public double getCurTransSpeed() { + return curTransSpeed; + } + + public void setCurTransSpeed(double curTransSpeed) { + this.curTransSpeed = curTransSpeed; + } + + public double getCommandedTransSpeed() { + return commandedTransSpeed; + } + + public void setCommandedTransSpeed(double commandedTransSpeed) { + this.commandedTransSpeed = commandedTransSpeed; + } + + public double getCurTransAccel() { + return curTransAccel; + } + + public void setCurTransAccel(double curTransAccel) { + this.curTransAccel = curTransAccel; + } + + public double getCommandedTransAccel() { + return commandedTransAccel; + } + + public void setCommandedTransAccel(double commandedTransAccel) { + this.commandedTransAccel = commandedTransAccel; + } + + public double getCurRotSpeed() { + return curRotSpeed; + } + + public void setCurRotSpeed(double curRotSpeed) { + this.curRotSpeed = curRotSpeed; + } + + public double getCommandedRotSpeed() { + return commandedRotSpeed; + } + + public void setCommandedRotSpeed(double commandedRotSpeed) { + this.commandedRotSpeed = commandedRotSpeed; + } + + public double getCurRotAccel() { + return curRotAccel; + } + + public void setCurRotAccel(double curRotAccel) { + this.curRotAccel = curRotAccel; + } + + public double getCommandedRotAccel() { + return commandedRotAccel; + } + + public void setCommandedRotAccel(double commandedRotAccel) { + this.commandedRotAccel = commandedRotAccel; + } + + /** + * Get the value of delayMillis + * + * @return the value of delayMillis + */ + public long getDelayMillis() { + return delayMillis; + } + + /** + * Set the value of delayMillis + * + * @param delay_millis new value of delayMillis + */ + public void setDelayMillis(long delay_millis) { + this.delayMillis = delay_millis; + } + + private static final double SCALE_FUDGE_FACTOR = 0.5; + + private ConfigureJointReportsType cjr = null; + private List cjrList = null; + + private AngleUnitEnumType angleType = AngleUnitEnumType.RADIAN; + + /** + * Get the value of angleType + * + * @return the value of angleType + */ + public AngleUnitEnumType getAngleType() { + return angleType; + } + + public void setAngleType(AngleUnitEnumType newAngleType) { + this.angleType = newAngleType; + } + + private PoseToleranceType expectedEndPoseTolerance = new PoseToleranceType(); + + /** + * Get the value of expectedEndPoseTolerance + * + * @return the value of expectedEndPoseTolerance + */ + public PoseToleranceType getExpectedEndPoseTolerance() { + return expectedEndPoseTolerance; + } + + /** + * Set the value of expectedEndPoseTolerance + * + * @param expectedEndPoseTolerance new value of expectedEndPoseTolerance + */ + public void setExpectedEndPoseTolerance(PoseToleranceType expectedEndPoseTolerance) { + this.expectedEndPoseTolerance = expectedEndPoseTolerance; + } + + private PoseToleranceType expectedIntermediatePoseTolerance; + + /** + * Get the value of expectedIntermediatePoseTolerance + * + * @return the value of expectedIntermediatePoseTolerance + */ + public PoseToleranceType getExpectedIntermediatePoseTolerance() { + return expectedIntermediatePoseTolerance; + } + + /** + * Set the value of expectedIntermediatePoseTolerance + * + * @param expectedIntermediatePoseToleranceType new value of + * expectedIntermediatePoseTolerance + */ + public void setExpectedIntermediatePoseTolerance(PoseToleranceType expectedIntermediatePoseToleranceType) { + this.expectedIntermediatePoseTolerance = expectedIntermediatePoseToleranceType; + } + + public void updateConnectedClients() { + outer.updateConnectedClients(Math.max(clientStates.size(), clientThreadMap.size())); + } + + private long dwellEndTime = 0; + + private void readCommand() { + if (dwellEndTime > 0 && System.currentTimeMillis() < dwellEndTime) { +// System.out.println("Dwelling"); +// System.out.println("dwellEndTime = " + dwellEndTime); +// System.out.println("System.currentTimeMillis() = " + System.currentTimeMillis()); +// System.out.println("(dwellEndTime - System.currentTimeMillis()) = " + (dwellEndTime - System.currentTimeMillis())); +// System.out.println("getCommandState() = " + getCommandState()); +// System.out.println("status.getCommandStatus().getCommandID() = " + status.getCommandStatus().getCommandID()); + return; + } + if (dwellEndTime > 0) { + setCommandState(CommandStateEnumType.DONE); + dwellEndTime = 0; + return; + } + CRCLCommandInstanceType instance = cmdQueue.poll(); + while (null != instance) { + CRCLCommandType cmd = instance.getCRCLCommand(); + if (null == cmd) { + System.err.println("cmd is null"); + return; + } + if (outer.isDebugReadCommandSelected()) { + outer.showDebugMessage("SimServerInner.readCommand() : cmd = " + cmd + + " cmd.getCommandID() = " + cmd.getCommandID()); + } + String cmdName = cmd.getClass().getCanonicalName(); + int pindex = cmdName.indexOf('.'); + if (pindex > 0) { + cmdName = cmdName.substring(pindex + 1); + } + outer.updateCurrentCommandType(cmdName); + synchronized (status) { + CommandStatusType cst = status.getCommandStatus(); + if (null == cst) { + cst = new CommandStatusType(); + status.setCommandStatus(cst); + } + if (getCommandState() == CommandStateEnumType.DONE) { + setCommandState(CommandStateEnumType.WORKING); + } + } + executingMoveCommand = false; + +// System.out.println("cmd = " + cmd); +// System.out.println("cmd.getCommandID() = " + cmd.getCommandID()); + if (cmd instanceof InitCanonType) { + InitCanonType init = (InitCanonType) cmd; + setCommandState(CommandStateEnumType.DONE); + outer.updateIsInitialized(true); +// System.out.println("INIT"); + this.setWaypoints(null); + this.setGoalPose(null); + this.commandedJointPositions = Arrays.copyOf(jointPositions, jointPositions.length); + } else { + if (this.getCommandState() == CommandStateEnumType.DONE) { + this.setWaypoints(null); + } + if (!outer.isInitializedSelected()) { + setCommandState(CommandStateEnumType.ERROR); + showMessage("Command other than init recieved when not initialized."); + return; + } + if (cmd instanceof SetEndEffectorType) { + SetEndEffectorType seet = (SetEndEffectorType) cmd; + outer.updateEndEffector(seet.getSetting().toString()); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof CloseToolChangerType) { + CloseToolChangerType ctc = (CloseToolChangerType) cmd; + outer.updateToolChangerIsOpen(false); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof OpenToolChangerType) { + OpenToolChangerType otc = (OpenToolChangerType) cmd; + outer.updateToolChangerIsOpen(true); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof MessageType) { + MessageType mt = (MessageType) cmd; + this.showMessage("MESSAGE: " + mt.getMessage() + "\n"); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof ConfigureJointReportsType) { + cjr = (ConfigureJointReportsType) cmd; + if (cjr.isResetAll() || null == this.cjrList) { + this.cjrList = new ArrayList(); + } + this.cjrList.addAll(cjr.getConfigureJointReport()); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetLengthUnitsType) { + SetLengthUnitsType slu = (SetLengthUnitsType) cmd; + LengthUnitEnumType lu = slu.getUnitName(); + setLengthUnit(lu); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetTransSpeedType) { + SetTransSpeedType sts = (SetTransSpeedType) cmd; + TransSpeedType ts = sts.getTransSpeed(); + if (ts instanceof TransSpeedAbsoluteType) { + TransSpeedAbsoluteType tsa = (TransSpeedAbsoluteType) ts; + this.setCommandedTransSpeed(tsa.getSetting().doubleValue()); + } else if (ts instanceof TransSpeedRelativeType) { + TransSpeedRelativeType tsr = (TransSpeedRelativeType) ts; + this.setCommandedTransSpeed(tsr.getFraction().doubleValue() * maxTransSpeed); + } else { + outer.showMessage("Unrecognized type of TransSpeed in SetTransSpeedType"); + setCommandState(CommandStateEnumType.ERROR); + return; + } + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetTransAccelType) { + SetTransAccelType sts = (SetTransAccelType) cmd; + TransAccelType ts = sts.getTransAccel(); + if (ts instanceof TransAccelAbsoluteType) { + TransAccelAbsoluteType taa = (TransAccelAbsoluteType) ts; + this.setCommandedTransAccel(taa.getSetting().doubleValue()); + } else if (ts instanceof TransAccelRelativeType) { + TransAccelRelativeType tar = (TransAccelRelativeType) ts; + this.setCommandedTransAccel(tar.getFraction().doubleValue() * maxTransAccel); + } else { + outer.showMessage("Unrecognized type of TransAccel in SetTransAccelType"); + setCommandState(CommandStateEnumType.ERROR); + return; + } + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetRotSpeedType) { + SetRotSpeedType sts = (SetRotSpeedType) cmd; + RotSpeedType ts = sts.getRotSpeed(); + if (ts instanceof RotSpeedAbsoluteType) { + RotSpeedAbsoluteType tsa = (RotSpeedAbsoluteType) ts; + this.setCommandedRotSpeed(tsa.getSetting().doubleValue()); + } else if (ts instanceof RotSpeedRelativeType) { + RotSpeedRelativeType tsr = (RotSpeedRelativeType) ts; + this.setCommandedRotSpeed(tsr.getFraction().doubleValue() * maxRotSpeed); + } else { + outer.showMessage("Unrecognized type of RotSpeed in SetRotSpeedType"); + setCommandState(CommandStateEnumType.ERROR); + return; + } + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetRotAccelType) { + SetRotAccelType sts = (SetRotAccelType) cmd; + RotAccelType ts = sts.getRotAccel(); + if (ts instanceof RotAccelAbsoluteType) { + RotAccelAbsoluteType taa = (RotAccelAbsoluteType) ts; + this.setCommandedRotAccel(taa.getSetting().doubleValue()); + } else if (ts instanceof RotAccelRelativeType) { + RotAccelRelativeType tar = (RotAccelRelativeType) ts; + this.setCommandedRotAccel(tar.getFraction().doubleValue() * maxRotAccel); + } else { + outer.showMessage("Unrecognized type of RotAccel in SetRotAccelType"); + setCommandState(CommandStateEnumType.ERROR); + return; + } + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof EndCanonType) { + EndCanonType end = (EndCanonType) cmd; + setCommandState(CommandStateEnumType.DONE); +// System.out.println("END"); + outer.updateIsInitialized(false); + this.setWaypoints(null); + this.setGoalPose(null); + this.commandedJointPositions = Arrays.copyOf(jointPositions, jointPositions.length); + } else if (cmd instanceof MoveThroughToType) { + this.executingMoveCommand = true; + MoveThroughToType mv = (MoveThroughToType) cmd; +// System.out.println("MoveThroughToType"); +// System.out.println("mv.getNumPositions() = " + mv.getNumPositions()); +// System.out.println("mv.isMoveStraight() = " + mv.isMoveStraight()); + List wpts = mv.getWaypoint(); + int numpositions = mv.getNumPositions().intValue(); + if (numpositions < 2) { + throw new RuntimeException("MoveThroughToType must set NumPositions to at-least 2 but NumPositions=" + numpositions + "."); + } + if (wpts.size() < 2) { + throw new RuntimeException("MoveThroughToType must have at-least two waypoints but " + wpts.size() + " were given."); + } + if (wpts.size() != numpositions) { + throw new RuntimeException("MoveThroughToType has NumPositions=" + numpositions + " but " + wpts.size() + " waypoints."); + } + this.setWaypoints(wpts); +// System.out.println("wpts = " + wpts); + if (null != wpts) { + for (PoseType pose : wpts) { + checkPose(pose); + } + } + this.setCommandState(CommandStateEnumType.WORKING); + this.setCurrentWaypoint(0); + this.setGoalPose(wpts.get(0)); + +// } else if (cmd instanceof SetJointControlModesType) { +// SetJointControlModesType setjcm = (SetJointControlModesType) cmd; +// List ljcm = setjcm.getJointControlMode(); +// for (JointControlModeType jcm : ljcm) { +// int index = jcm.getJointNumber().intValue(); +// if (index < 0 || index > this.controlmodes.length) { +// setCommandState(CommandStateEnumType.ERROR); +// Message("Bad joint index:" + index); +// break; +// } +// this.controlmodes[index] = jcm.getMode(); +// } + } else if (cmd instanceof ActuateJointsType) { + this.executingMoveCommand = true; + ActuateJointsType ajst = (ActuateJointsType) cmd; + this.goalPose = null; + List ajl = ajst.getActuateJoint(); + for (ActuateJointType aj : ajl) { + int index = aj.getJointNumber().intValue() - 1; + if (index < 0 || index > this.jointPositions.length) { + setCommandState(CommandStateEnumType.ERROR); + showMessage("Bad joint index:" + index); + break; + } + if (index >= 0 && index < this.jointPositions.length) { + this.commandedJointPositions[index] = aj.getJointPosition().doubleValue(); + } + } + outer.showDebugMessage("SimServer commandedJointPositions = " + Arrays.toString(commandedJointPositions)); + setCommandState(CommandStateEnumType.WORKING); + outer.updatePanels(true); + } else if (cmd instanceof MoveToType) { + this.executingMoveCommand = true; + MoveToType moveto = (MoveToType) cmd; + this.setGoalPose(moveto.getEndPosition()); + setCommandState(CommandStateEnumType.WORKING); + this.setMoveStraight(moveto.isMoveStraight()); + this.setCurrentWaypoint(0); + outer.updatePanels(true); + } else if (cmd instanceof StopMotionType) { + this.executingMoveCommand = true; + StopMotionType stop = (StopMotionType) cmd; + this.setGoalPose(null); + this.setWaypoints(null); + System.arraycopy(this.jointPositions, 0, this.commandedJointPositions, 0, + Math.min(this.jointPositions.length, this.commandedJointPositions.length)); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetAngleUnitsType) { + SetAngleUnitsType setAngle = (SetAngleUnitsType) cmd; + this.setAngleType(setAngle.getUnitName()); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetEndPoseToleranceType) { + SetEndPoseToleranceType endPoseTol = (SetEndPoseToleranceType) cmd; + this.setExpectedEndPoseTolerance(endPoseTol.getTolerance()); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof SetIntermediatePoseToleranceType) { + SetIntermediatePoseToleranceType intermediatePoseTol = (SetIntermediatePoseToleranceType) cmd; + this.setExpectedIntermediatePoseTolerance(intermediatePoseTol.getTolerance()); + setCommandState(CommandStateEnumType.DONE); + } else if (cmd instanceof DwellType) { + DwellType dwellCmd = (DwellType) cmd; + dwellEndTime = System.currentTimeMillis() + dwellCmd.getDwellTime().longValue() * 1000; + setCommandState(CommandStateEnumType.WORKING); + } else if (cmd instanceof MoveScrewType) { + MoveScrewType moveScrew = (MoveScrewType) cmd; + setCommandState(CommandStateEnumType.WORKING); + this.multiStepCommand = moveScrew; + this.moveScrewStep = 0; + } else { + setCommandState(CommandStateEnumType.DONE); +// System.err.println("Ignored type: " + cmd.getClass().getSimpleName()); + outer.showDebugMessage("\nIgnored type: " + cmd.getClass().getSimpleName() + "\n"); +// showMessage("Unrecognized command type: " + cmd.getClass().getSimpleName()); + } + } + synchronized (status) { + status.getCommandStatus().setCommandID(cmd.getCommandID()); + } + instance = cmdQueue.poll(); + } + } + + public void setLengthUnit(LengthUnitEnumType lu) { + outer.updateLengthUnit(lu); + switch (robotType) { + case PLAUSIBLE: + switch (lu) { + case METER: + this.skPlausible.setScale(0.01 * SCALE_FUDGE_FACTOR); + break; + + case INCH: + this.skPlausible.setScale(0.393701 * SCALE_FUDGE_FACTOR); + break; + + case MILLIMETER: + this.skPlausible.setScale(10.0 * SCALE_FUDGE_FACTOR); + break; + } + break; + + case SIMPLE: + switch (lu) { + case METER: + this.skSimple.setScale(0.01 * SCALE_FUDGE_FACTOR); + break; + + case INCH: + this.skSimple.setScale(0.393701 * SCALE_FUDGE_FACTOR); + break; + + case MILLIMETER: + this.skSimple.setScale(10.0 * SCALE_FUDGE_FACTOR); + break; + } + break; + } + } + private List waypoints; + + /** + * Get the value of waypoints + * + * @return the value of waypoints + */ + public List getWaypoints() { + return waypoints; + } + + /** + * Set the value of waypoints + * + * @param waypoints new value of waypoints + */ + public void setWaypoints(List waypoints) { + this.waypoints = waypoints; + if (null != waypoints) { + outer.updateNumWaypoints(waypoints.size()); + } else { + outer.updateNumWaypoints(0); + this.setCurrentWaypoint(0); + } + } + + public void restartServer() { + try { + closeServer(); + ssock = new ServerSocket(port); + if (port == 0) { + // This is a hack so the integration test can be run on a port + // found automatically with the client run in the same + // process. + // For this test only force port to zero then it will be bound + // to a free port which gets passed back to the client with a system property. + this.port = ssock.getLocalPort(); + System.setProperty("crcljava.port", Integer.toString(port)); + } + ssock.setReuseAddress(true); + acceptClientsThread = new Thread(this::runAcceptClients, + "acceptClientsThread"); + acceptClientsThread.start(); + final int start_close_count = this.close_count; + simThread = new Thread(new Runnable() { + @Override + public void run() { + + try { + while (!Thread.currentThread().isInterrupted()) { + Thread.sleep(delayMillis); + if (!handleMultiStepCommand()) { + readCommand(); + } + if (!updateStatus()) { + sendStatus(null); + } + } + } catch (InterruptedException ex) { + if (SimServerInner.this.close_count <= start_close_count) { + LOGGER.log(Level.SEVERE, null, ex); + } + } + } + }, "simThread"); + simThread.start(); + SimServerInner.runningServers.add(this); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, null, ex); + showMessage("Can not start server on port " + port + " : " + ex.getMessage()); + } + } + + public CRCLStatusType getStatus() { + return status; + } + + public String getStatusXmlString() throws JAXBException { + return this.getCheckerCRCLSocket().statusToPrettyString(this.getStatus(), false); + } + + private CRCLSocket checkerCRCLSocket = null; + + public CRCLSocket getCheckerCRCLSocket() { + if (null == checkerCRCLSocket) { + checkerCRCLSocket = new CRCLSocket(); + } + return checkerCRCLSocket; + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServerOuter.java b/crcl4java-utils/src/main/java/crcl/utils/SimServerOuter.java new file mode 100644 index 0000000..cf86033 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimServerOuter.java @@ -0,0 +1,56 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.LengthUnitEnumType; + + +/** + * This class defines the interface between the SimServerInner and a GUI frame. + * The class could also be stubbed for command line implementations. + * + * @author Will Shackleford {@literal } + */ +public interface SimServerOuter { + public void updateConnectedClients(int numClients); + public boolean isValidateXMLSelected(); + public boolean isSendStatusWithoutRequestSelected(); + public boolean isAppendZeroSelected(); + public boolean isReplaceXmlHeaderSelected(); + public boolean isRandomPacketSelected(); + public boolean isReplaceStateSelected(); + public boolean isEditingStatus(); + public void updateCycleCount(int _newCycleCount); + public void updatePanels(boolean jointschanged); + public void updateIsInitialized(boolean initialized); + public void updateCurrentCommandType(String cmdName); + public void updateEndEffector(String text); + public void updateToolChangerIsOpen(boolean isOpen); + public boolean isInitializedSelected(); + public void showMessage(String msgString); + public void finishSetCurrentWaypoint(int currentWaypoint); + public void updateLengthUnit(LengthUnitEnumType lu); + public void showDebugMessage(final String s); + public void updateNumWaypoints(int numWaypoints); + public boolean isDebugMoveDoneSelected(); + public boolean isDebugReadCommandSelected(); + public boolean isDebugSendStatusSelected(); + public boolean isEXISelected(); +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServerOuterStub.java b/crcl4java-utils/src/main/java/crcl/utils/SimServerOuterStub.java new file mode 100644 index 0000000..ec0332d --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimServerOuterStub.java @@ -0,0 +1,218 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.LengthUnitEnumType; +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * + * @author Will Shackleford {@literal } + */ +public class SimServerOuterStub implements SimServerOuter{ + + + @Override + public void showMessage(String s) { + final String sWithThread = "Thread:" + Thread.currentThread().getName()+" \n"+s; + Logger.getLogger(this.getClass().getName()).log(Level.FINE, sWithThread); + } + + @Override + public void showDebugMessage(String s) { + showMessage(s); + } + + @Override + public void updateConnectedClients(int numClients) { + } + + private final boolean validateXML; + + @Override + public boolean isValidateXMLSelected() { + return this.validateXML; + } + + private final boolean sendStatusWithoutRequest; + + @Override + public boolean isSendStatusWithoutRequestSelected() { + return this.sendStatusWithoutRequest; + } + + private final boolean appendZero; + + @Override + public boolean isAppendZeroSelected() { + return this.appendZero; + } + + private final boolean randomPacket; + + @Override + public boolean isRandomPacketSelected() { + return this.randomPacket; + } + + private final boolean replaceState; + + @Override + public boolean isReplaceStateSelected() { + return this.replaceState; + } + + + @Override + public boolean isEditingStatus() { + return false; + } + + @Override + public void updateCycleCount(int _newCycleCount) { + } + + @Override + public void updatePanels(boolean jointschanged) { + } + + @Override + public void updateIsInitialized(boolean _initialized) { + this.initialized = _initialized; + } + + @Override + public void updateCurrentCommandType(String cmdName) { + } + + @Override + public void updateEndEffector(String text) { + } + + @Override + public void updateToolChangerIsOpen(boolean isOpen) { + } + + private boolean initialized=false; + + @Override + public boolean isInitializedSelected() { + return this.initialized; + } + + + + @Override + public void finishSetCurrentWaypoint(int currentWaypoint) { + } + + @Override + public void updateLengthUnit(LengthUnitEnumType lu) { + } + + + @Override + public void updateNumWaypoints(int numWaypoints) { + } + + private final boolean debugMoveDone; + + @Override + public boolean isDebugMoveDoneSelected() { + return this.debugMoveDone; + } + + private static boolean prop(String propName, boolean defaultVal) { + return Boolean.valueOf(System.getProperty(propName,Boolean.toString(defaultVal))); + } + + + + public SimServerOuterStub() { + this( + prop("crcjava.SimServer.validateXML",false),// validateXML + prop("crcjava.SimServer.sendStatusWithoutRequest",false),// sendStatusWithoutRequest + prop("crcjava.SimServer.appendZero",false),// appendZero + prop("crcjava.SimServer.randomPacket",false),// randomPacket + prop("crcjava.SimServer.replaceState",false),// replaceState + prop("crcjava.SimServer.debugMoveDone",false),// debugMoveDone + prop("crcjava.SimServer.debugReadCommand",false),// debugReadCommand + prop("crcjava.SimServer.replaceXmlHeader",true),// replaceXmlHeader + prop("crcjava.SimServer.debugSendStatus",false),// debugSendStatus + prop("crcjava.SimServer.exiSelected",false)// exiSelected + ); + } + + public SimServerOuterStub( + boolean validateXML, + boolean sendStatusWithoutRequest, + boolean appendZero, + boolean randomPacket, + boolean replaceState, + boolean debugMoveDone, + boolean debugReadCommand, + boolean replaceXmlHeader, + boolean debugSendStatus, + boolean exiSelected) { + this.validateXML = validateXML; + this.sendStatusWithoutRequest = sendStatusWithoutRequest; + this.appendZero = appendZero; + this.randomPacket = randomPacket; + this.replaceState = replaceState; + this.debugMoveDone = debugMoveDone; + this.debugReadCommand = debugReadCommand; + this.replaceXmlHeader = replaceXmlHeader; + this.degugSendStatus = debugSendStatus; + this.exiSelected = exiSelected; + } + + + private final boolean degugSendStatus; + + @Override + public boolean isDebugSendStatusSelected() { + return this.degugSendStatus; + } + + private final boolean debugReadCommand; + + @Override + public boolean isDebugReadCommandSelected() { + return this.debugReadCommand; + } + + private final boolean replaceXmlHeader; + + @Override + public boolean isReplaceXmlHeaderSelected() { + return this.replaceXmlHeader; + } + + private final boolean exiSelected; + + @Override + public boolean isEXISelected() { + return this.exiSelected; + } + + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsPlausible.java b/crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsPlausible.java new file mode 100644 index 0000000..336b2db --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsPlausible.java @@ -0,0 +1,320 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.PoseType; +import crcl.base.VectorType; +import java.awt.geom.Point2D; +import java.math.BigDecimal; +import java.util.Arrays; + +/** + * + * @author Will Shackleford{@literal } + */ +public class SimulatedKinematicsPlausible { + + public static final double DEFAULT_SEGLENGTHS[] = new double[]{60.0, 50.0, 25.0, 15.0, 20.0, 10.0}; + public static final double DEFAULT_JOINTVALS[] = new double[]{0.0, 45.0, -90.0, 90.0, 0.0, 0.0}; + + public PoseType jointsToPose(double jv[]) { + PoseType pose = new PoseType(); + return jointsToPose(jv, pose); + } + + private double[] seglengths = DEFAULT_SEGLENGTHS; + + private double[] scaled_seglengths = Arrays.copyOf(seglengths, seglengths.length); + + private double scale = 1.0; + + /** + * Get the value of scale + * + * @return the value of scale + */ + public double getScale() { + return scale; + } + + /** + * Set the value of scale + * + * @param scale new value of scale + */ + public void setScale(double scale) { + this.scale = scale; + updateScaledSeglengths(scale); + } + + private void updateScaledSeglengths(double scale1) { + scaled_seglengths = new double [seglengths.length]; + for (int i = 0; i < scaled_seglengths.length; i++) { + scaled_seglengths[i] = scale1 * seglengths[i]; + } + } + + /** + * Get the value of seglengths + * + * @return the value of seglengths + */ + public double[] getSeglengths() { + return seglengths; + } + + /** + * Set the value of seglengths + * + * @param seglengths new value of seglengths + */ + public void setSeglengths(double[] seglengths) { + this.seglengths = seglengths; + updateScaledSeglengths(scale); + } + +// public static void printRot9x9(double[][] r) { +// for (int i = 0; i < 3; i++) { +// for (int j = 0; j < 3; j++) { +// //System.err.printf("%+.3g, ", r[i][j]); +// } +// //System.err.println(""); +// } +// } + public static double[][] rot9x9mult(double[][] r1, double[][] r2) { + double[][] rout + = { + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0},}; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 3; k++) { + rout[i][j] += r1[i][k] * r2[k][j]; + } + } + } + return rout; + } + + public double[] poseToJoints(double[] _jv, PoseType pose) { + double[] jv = _jv; + double[] sl = this.scaled_seglengths; + if (null == jv || jv.length != NUM_JOINTS) { + jv = new double[NUM_JOINTS]; + } + //System.err.println("poseToJoints("+Arrays.toString(_jv)+","+pose+") called."); + for (int i = 0; i < jv.length; i++) { + if (Double.isNaN(jv[i])) { + throw new IllegalArgumentException("poseToJoints: jv[" + i + "] isNaN"); + } + if (Double.isInfinite(jv[i])) { + throw new IllegalArgumentException("poseToJoints: jv[" + i + "] isInfinite"); + } + } + PointType pt = pose.getPoint(); + Point2D.Double endPtXY = new Point2D.Double( + pt.getX().doubleValue(), + pt.getY().doubleValue()); + double r = Math.sqrt( + endPtXY.x * endPtXY.x + + endPtXY.y * endPtXY.y + ); + double z = pt.getZ().doubleValue(); + VectorType xv = pose.getXAxis(); + double xvi = xv.getI().doubleValue(); + double xvj = xv.getJ().doubleValue(); + double xvk = xv.getK().doubleValue(); + //System.err.println("xvi="+xvi+",xvj="+xvj+",xvk="+xvk); + VectorType zv = pose.getZAxis(); + double zvi = zv.getI().doubleValue(); + double zvj = zv.getJ().doubleValue(); + double zvk = zv.getK().doubleValue(); + //System.err.println("zvi="+zvi+",zvj="+zvj+",zvk="+zvk); + double a2 = Math.atan2(xvk, + Math.sqrt(xvj * xvj + xvi * xvi)); + //System.err.println("r,z,angle 3 = " + r+","+z+","+Math.toDegrees(a2)); + Point2D.Double j4PointXY = new Point2D.Double( + endPtXY.x - sl[3] * xvi, + endPtXY.y - sl[3] * xvj); + double j4z = pt.getZ().doubleValue() - sl[3] * xvk; + double a1 = Math.atan2(j4PointXY.y, j4PointXY.x); + jv[0] = Math.toDegrees(a1); + jv[4] = Math.toDegrees(Math.atan2(xvj, xvi) - a1); + double yvi = xvj * zvk - xvk * zvj; + double yvj = xvi * zvk - xvk * zvi; + double yvk = xvi * zvj - xvj * zvi; + jv[5] = Math.toDegrees(Math.atan2(yvk, Math.sqrt(yvi * yvi + yvj * yvj))); + + r = Math.sqrt( + j4PointXY.x * j4PointXY.x + + j4PointXY.y * j4PointXY.y + ); + z = j4z; + //System.err.println("r,z,angle 2 = " + r+","+z+","+Math.toDegrees(a2)); + r -= sl[2] * Math.cos(a2); + z -= sl[2] * Math.sin(a2); + //System.err.println("r,z 1 = " + r+","+z); + double mag1 = Math.sqrt(r * r + z * z); + //System.err.println("mag1 = " + mag1); + double s12_sum2 = sl[0] * sl[0] + sl[1] * sl[1]; + double s12_sum2_sqrt = Math.sqrt(s12_sum2); + double sum = (sl[0] + sl[1]); + if (mag1 >= sum) { + throw new IllegalArgumentException( + "distance to Joint3 " + mag1 + " required to be greater than sum of robot segments 1 and 2" + sum); + } + double diff = Math.abs(sl[0] - sl[1]); + if (mag1 <= diff) { + throw new IllegalArgumentException( + "distance to Joint3 " + mag1 + " required to be less than difference of robot segments 1 and 2" + diff); + } + //System.err.println("s12_sum2_sqrt = " + s12_sum2_sqrt); + double a3 = Math.acos((s12_sum2 - mag1 * mag1) / (2 * sl[0] * sl[1])) - Math.PI; + jv[2] = Math.toDegrees(a3); + //System.err.println("jv[2] = " + jv[2]); + double a40 = Math.atan2(z, r); + //System.err.println("Math.toDegrees(a40) = " + Math.toDegrees(a40)); + double a41 = Math.asin(Math.sin(a3 + Math.PI) * sl[1] / mag1);//Math.acos((sl[0]*sl[0]-sl[1]*sl[1]+mag1*mag1)/(2*sl[0]*mag1)); + //System.err.println("Math.toDegrees(a41) = " + Math.toDegrees(a41)); + double a4 = a40 + a41; + //System.err.println("Math.toDegrees(a4) = " + Math.toDegrees(a4)); + double z2 = z + Math.cos(a4); + double mag2 = mag1 - Math.sin(a4); + double a5 = Math.atan2(z2, mag2); + jv[1] = Math.toDegrees(a4); + jv[3] = Math.toDegrees(a2) - jv[2] - jv[1]; + //System.err.println("poseToJoints("+Arrays.toString(_jv)+","+pose+") returning:"+ Arrays.toString(jv)); + return jv; + } + public static final int NUM_JOINTS = 6; + + public PoseType jointsToPose(double[] jv, PoseType _pose) { + PoseType pose = _pose; + double[] sl = this.scaled_seglengths; + if (null == pose) { + pose = new PoseType(); + } + //System.err.println("jointsToPose("+Arrays.toString(jv)+","+_pose+") called."); + for (int i = 0; i < jv.length; i++) { + if (Double.isNaN(jv[i])) { + throw new IllegalArgumentException("jv[" + i + "]=" + jv[i]); + } + if (Double.isInfinite(jv[i])) { + throw new IllegalArgumentException("jv[" + i + "]=" + jv[i]); + } + } + double angle = jv[1]; + double r = sl[0] * Math.cos(Math.toRadians(angle)); + double z = sl[0] * Math.sin(Math.toRadians(angle)); + //System.err.println("r,z,angle 0 = " + r+","+z+","+angle); + angle += jv[2]; + r += sl[1] * Math.cos(Math.toRadians(angle)); + z += sl[1] * Math.sin(Math.toRadians(angle)); + //System.err.println("r,z,angle 1 = " + r+","+z+","+angle); + double mag1 = Math.sqrt(r * r + z * z); + //System.err.println("mag1 = " + mag1); + if (mag1 > sl[0] + sl[1]) { + throw new RuntimeException("distance to joint2 must be less than " + (sl[0] + sl[1])); + } + if (mag1 < Math.abs(sl[0] - sl[1])) { + throw new RuntimeException("distance to joint2 must be atleast than " + Math.abs(sl[0] - sl[1])); + } + + angle += jv[3]; + r += sl[2] * Math.cos(Math.toRadians(angle)); + z += sl[2] * Math.sin(Math.toRadians(angle)); + //System.err.println("r,z,angle 2 = " + r+","+z+","+angle); + double x = r * Math.cos(Math.toRadians(jv[0])) + sl[3] * Math.cos(Math.toRadians(jv[4] + jv[0])) * Math.cos(Math.toRadians(angle)); + //System.err.println("x = " + x); + double y = r * Math.sin(Math.toRadians(jv[0])) + sl[3] * Math.sin(Math.toRadians(jv[4] + jv[0])) * Math.cos(Math.toRadians(angle)); + //System.err.println("y = " + y); + //System.err.println("Math.sqrt(x*x+y*y)="+Math.sqrt(x*x+y*y)); + r += sl[3] * Math.cos(Math.toRadians(angle)) * Math.cos(Math.toRadians(jv[4])); + z += sl[3] * Math.sin(Math.toRadians(angle)); + //System.err.println("r,z,angle 3 = " + r+","+z+","+angle); + PointType p = pose.getPoint(); + if (null == p) { + p = new PointType(); + } + p.setX(BigDecimal.valueOf(x)); + p.setY(BigDecimal.valueOf(y)); + p.setZ(BigDecimal.valueOf(z)); + pose.setPoint(p); + double cz = Math.cos(Math.toRadians(jv[0] + jv[4])); + double sz = Math.sin(Math.toRadians(jv[0] + jv[4])); + double cy = Math.cos(Math.toRadians(angle)); + double sy = Math.sin(Math.toRadians(angle)); + double cx = Math.cos(Math.toRadians(jv[5])); + double sx = Math.sin(Math.toRadians(jv[5])); + //System.err.println("jv = " + Arrays.toString(jv)); + //System.err.println("angle = " + angle); + double[][] rx + = { + {1.0, 0.0, 0.0}, + {0.0, cx, -sx}, + {0.0, sx, cx},}; + //System.err.println("rx = " + Arrays.deepToString(rx)); + //printRot9x9(rx); + double[][] ry + = { + {cy, 0.0, sy}, + {0.0, 1.0, 0.0}, + {-sy, 0.0, cy},}; + //System.err.println("ry = " + Arrays.deepToString(ry)); + //printRot9x9(ry); + double[][] rz + = { + {cz, sz, 0.0}, + {-sz, cz, 0.0}, + {0.0, 0.0, 1.0},}; + //System.err.println("rz = " + Arrays.deepToString(rz)); + //printRot9x9(rz); + double[][] Rxy = rot9x9mult(rx, ry); + //System.err.println("Rxy = " + Arrays.deepToString(Rxy)); + //printRot9x9(Rxy); + double[][] R = rot9x9mult(Rxy, rz); + //System.err.println("R = " + Arrays.deepToString(R)); + //printRot9x9(R); + VectorType xunitv = pose.getXAxis(); + if (null == xunitv) { + xunitv = new VectorType(); + } + xunitv.setI(BigDecimal.valueOf(R[0][0])); + xunitv.setJ(BigDecimal.valueOf(R[0][1])); + xunitv.setK(BigDecimal.valueOf(R[0][2])); +// //System.out.println("xunitv = " + xunitv); + //System.err.println("xunitv.getK().doubleValue() = " + xunitv.getK().doubleValue()); + pose.setXAxis(xunitv); + VectorType zunitv = pose.getZAxis(); + if (null == zunitv) { + zunitv = new VectorType(); + } + zunitv.setI(BigDecimal.valueOf(R[2][0])); + zunitv.setJ(BigDecimal.valueOf(R[2][1])); + zunitv.setK(BigDecimal.valueOf(R[2][2])); + pose.setZAxis(zunitv); + //System.err.println("jointsToPose("+Arrays.toString(jv)+","+_pose+") returning : "+ pose); + return pose; + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsSimple.java b/crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsSimple.java new file mode 100644 index 0000000..f49d3b4 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/SimulatedKinematicsSimple.java @@ -0,0 +1,180 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + + +import crcl.base.PoseType; +import crcl.base.PoseType; +import java.util.Arrays; +import java.util.logging.Level; +import java.util.logging.Logger; +import rcs.posemath.PmCartesian; +import rcs.posemath.PmException; +import rcs.posemath.PmRotationMatrix; +import rcs.posemath.PmRotationVector; +import rcs.posemath.PmRpy; +import rcs.posemath.PmSpherical; +import rcs.posemath.Posemath; + +/** + * + * @author Will Shackleford{@literal } + */ +public class SimulatedKinematicsSimple { + + public static final int NUM_JOINTS = 6; + public static final double DEFAULT_SEGLENGTHS[] = new double[]{50.0}; + public static final double DEFAULT_JOINTVALS[] = new double[]{200.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + public PoseType jointsToPose(double jv[]) { + PoseType pose = new PoseType(); + return jointsToPose(jv, pose); + } + + private double[] seglengths = DEFAULT_SEGLENGTHS; + + private double[] scaled_seglengths = Arrays.copyOf(seglengths, seglengths.length); + + private double scale = 1.0; + + /** + * Get the value of scale + * + * @return the value of scale + */ + public double getScale() { + return scale; + } + + /** + * Set the value of scale + * + * @param scale new value of scale + */ + public void setScale(double scale) { + this.scale = scale; + updateScaledSeglengths(scale); + } + + private void updateScaledSeglengths(double scale1) { + scaled_seglengths = new double[seglengths.length]; + for (int i = 0; i < scaled_seglengths.length; i++) { + scaled_seglengths[i] = scale1 * seglengths[i]; + } + } + + /** + * Get the value of seglengths + * + * @return the value of seglengths + */ + public double[] getSeglengths() { + return seglengths; + } + + /** + * Set the value of seglengths + * + * @param seglengths new value of seglengths + */ + public void setSeglengths(double[] seglengths) { + this.seglengths = seglengths; + updateScaledSeglengths(scale); + } + +// public static void printRot9x9(double[][] r) { +// for (int i = 0; i < 3; i++) { +// for (int j = 0; j < 3; j++) { +// //System.err.printf("%+.3g, ", r[i][j]); +// } +// //System.err.println(""); +// } +// } + public static double[][] rot9x9mult(double[][] r1, double[][] r2) { + double[][] rout + = { + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0},}; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 3; k++) { + rout[i][j] += r1[i][k] * r2[k][j]; + } + } + } + return rout; + } + + public double[] poseToJoints(double[] _jv, PoseType pose) { + double[] jv = _jv; + if (null == jv || _jv.length != NUM_JOINTS) { + jv = new double[NUM_JOINTS]; + } + try { + double[] sl = this.scaled_seglengths; + PmCartesian cart = CRCLPosemath.pointToPmCartesian(pose.getPoint()); + double r = cart.mag(); + double endr = sl[0]; + PmRotationMatrix rmat = CRCLPosemath.toPmRotationMatrix(pose); + PmCartesian endSeg = cart.add(rmat.multiply(new PmCartesian(-endr, 0.0, 0.0))); + PmSpherical sphereTran = new PmSpherical(); + Posemath.pmCartSphConvert(endSeg, sphereTran); + jv[0] = sphereTran.r/this.scale; + jv[1] = Math.toDegrees(sphereTran.theta); + jv[2] = Math.toDegrees(sphereTran.phi)-90.0; + PmRpy rpy = new PmRpy(); + Posemath.pmMatRpyConvert(rmat, rpy); + jv[3] = Math.toDegrees(rpy.r); + jv[4] = Math.toDegrees(rpy.p); + jv[5] = Math.toDegrees(rpy.y); + //System.err.println("poseToJoints("+Arrays.toString(_jv)+","+pose+") returning:"+ Arrays.toString(jv)); +// return jv; + } catch (PmException ex) { + Logger.getLogger(SimulatedKinematicsSimple.class.getName()).log(Level.SEVERE, null, ex); + return null; + } + return jv; + } + + public PoseType jointsToPose(double[] jv, PoseType _pose) { + PoseType pose = null; + try { + double[] sl = this.scaled_seglengths; + PmSpherical sphereTran = new PmSpherical(Math.toRadians(jv[1]), Math.toRadians(jv[2]+90.0), jv[0]*this.scale); + PmCartesian endSeg = new PmCartesian(); + Posemath.pmSphCartConvert(sphereTran, endSeg); + PmRpy rpy = new PmRpy(Math.toRadians(jv[3]), Math.toRadians(jv[4]), Math.toRadians(jv[5])); + PmRotationMatrix rmat = new PmRotationMatrix(); + Posemath.pmRpyMatConvert(rpy, rmat); + PmCartesian cart = endSeg.add(rmat.multiply(new PmCartesian(sl[0],0,0))); + PmRotationVector rv = new PmRotationVector(); + Posemath.pmMatRotConvert(rmat, rv); + pose = CRCLPosemath.toPoseType(cart, rv,_pose); + //System.err.println("jointsToPose("+Arrays.toString(jv)+","+_pose+") returning : "+ pose); + } catch (PmException ex) { + Logger.getLogger(SimulatedKinematicsSimple.class.getName()).log(Level.SEVERE, null, ex); + return null; + } + return pose; + + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/TestInstance.java b/crcl4java-utils/src/main/java/crcl/utils/TestInstance.java new file mode 100644 index 0000000..f7bc2f0 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/TestInstance.java @@ -0,0 +1,105 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + + +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.EndCanonType; +import crcl.base.InitCanonType; +import crcl.base.MoveThroughToType; +import crcl.base.ObjectFactory; +import crcl.base.PoseType; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.math.BigInteger; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +/** + * + * @author Will Shackleford{@literal } + */ +public class TestInstance { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + try { + System.out.println("This program is just for testing. Pass it an xml instance file for crcl and it will print some info."); + for (String arg : args) { + JAXBContext jc = JAXBContext.newInstance("crcl"); + Unmarshaller u = jc.createUnmarshaller(); + JAXBElement el = (JAXBElement) u.unmarshal(new FileInputStream(arg)); + CRCLCommandInstanceType instance + = (CRCLCommandInstanceType) el.getValue(); + System.out.println("instance = " + instance); + CRCLCommandType cmd = instance.getCRCLCommand(); + System.out.println("cmd = " + cmd); + System.out.println("cmd.getCommandID() = " + cmd.getCommandID()); + if(cmd instanceof InitCanonType) { + InitCanonType init = (InitCanonType) cmd; + System.out.println("INIT"); + } else if(cmd instanceof EndCanonType) { + EndCanonType end = (EndCanonType) cmd; + System.out.println("END"); + } else if(cmd instanceof MoveThroughToType) { + MoveThroughToType mv = (MoveThroughToType) cmd; + System.out.println("MoveThroughToType"); + System.out.println("mv.getNumPositions() = " + mv.getNumPositions()); + System.out.println("mv.isMoveStraight() = " + mv.isMoveStraight()); + List wpts = mv.getWaypoint(); + System.out.println("wpts = " + wpts); + if(null != wpts) { + for(PoseType pol : wpts) { + System.out.println("pol = " + pol); + System.out.println("pol.getPoint().getX() = " + pol.getPoint().getX()); + System.out.println("pol.getPoint().getY() = " + pol.getPoint().getY()); + System.out.println("pol.getPoint().getZ() = " + pol.getPoint().getZ()); + } + } + + }else { + System.err.println("Unrecognize type"); + } + System.out.println(""); +// System.out.println("init = " + init.getName()); + Marshaller m = jc.createMarshaller(); + ObjectFactory of = new ObjectFactory(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + cmd.setCommandID(cmd.getCommandID().add(BigInteger.ONE)); + m.marshal(of.createCRCLCommandInstance(instance), System.out); + } + } catch (JAXBException ex) { + Logger.getLogger(TestInstance.class.getName()).log(Level.SEVERE, null, ex); + } catch (FileNotFoundException ex) { + Logger.getLogger(TestInstance.class.getName()).log(Level.SEVERE, null, ex); + } + } + +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.form b/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.form new file mode 100644 index 0000000..ab23862 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.form @@ -0,0 +1,125 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java b/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java new file mode 100644 index 0000000..2816c49 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java @@ -0,0 +1,305 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.io.ByteArrayInputStream; +import java.io.StringWriter; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JOptionPane; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * + * @author Will Shackleford{@literal } + */ +public class XpathQueryJFrame extends javax.swing.JFrame { + + /** + * Creates new form XpathQueryJFrame + * + * @throws javax.xml.parsers.ParserConfigurationException when + * javax.xml.parsers.DocumentBuilderFactory fails in XpathUtils + */ + public XpathQueryJFrame() throws ParserConfigurationException { + initComponents(); + this.xpu = new XpathUtils(); + this.checkQuery(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jComboBoxXpathQuery = new javax.swing.JComboBox(); + jLabel1 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextArea1 = new javax.swing.JTextArea(); + jButtonClose = new javax.swing.JButton(); + jCheckBoxUpdateAutomatically = new javax.swing.JCheckBox(); + + FormListener formListener = new FormListener(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setTitle("CRCL Status Xpath Query"); + + jComboBoxXpathQuery.setEditable(true); + jComboBoxXpathQuery.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "/", "//JointStatus" })); + jComboBoxXpathQuery.addActionListener(formListener); + + jLabel1.setText("Query: "); + + jLabel2.setText("Result:"); + + jTextArea1.setColumns(20); + jTextArea1.setRows(5); + jScrollPane1.setViewportView(jTextArea1); + + jButtonClose.setText("Close"); + jButtonClose.addActionListener(formListener); + + jCheckBoxUpdateAutomatically.setSelected(true); + jCheckBoxUpdateAutomatically.setText("Update Automatically"); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 497, Short.MAX_VALUE) + .addComponent(jComboBoxXpathQuery, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1) + .addComponent(jLabel2)) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(jCheckBoxUpdateAutomatically) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jButtonClose))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addGap(5, 5, 5) + .addComponent(jComboBoxXpathQuery, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButtonClose) + .addComponent(jCheckBoxUpdateAutomatically)) + .addContainerGap()) + ); + + pack(); + } + + // Code for dispatching events from components to event handlers. + + private class FormListener implements java.awt.event.ActionListener { + FormListener() {} + public void actionPerformed(java.awt.event.ActionEvent evt) { + if (evt.getSource() == jComboBoxXpathQuery) { + XpathQueryJFrame.this.jComboBoxXpathQueryActionPerformed(evt); + } + else if (evt.getSource() == jButtonClose) { + XpathQueryJFrame.this.jButtonCloseActionPerformed(evt); + } + } + }// //GEN-END:initComponents + + private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCloseActionPerformed + this.setVisible(false); + }//GEN-LAST:event_jButtonCloseActionPerformed + + private String query; + + /** + * Get the value of query + * + * @return the value of query + */ + public String getQuery() { + return query; + } + + /** + * Set the value of query + * + * @param query new value of query + */ + public void setQuery(String query) { + this.query = query; + } + + private String result; + + /** + * Get the value of result + * + * @return the value of result + */ + public String getResult() { + return result; + } + + public void setResult(final String _result) { + this.result = _result; + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + jTextArea1.setText(_result); + } + }); + } + + private void jComboBoxXpathQueryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBoxXpathQueryActionPerformed + checkQuery(); + }//GEN-LAST:event_jComboBoxXpathQueryActionPerformed + + private void checkQuery() { + String q = this.jComboBoxXpathQuery.getSelectedItem().toString(); + boolean found = false; + for (int i = 0; i < this.jComboBoxXpathQuery.getItemCount(); i++) { + if (this.jComboBoxXpathQuery.getItemAt(i).equals(q)) { + found = true; + break; + } + } + if (!found) { + this.jComboBoxXpathQuery.addItem(q); + } + this.setQuery(q); + } + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(XpathQueryJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(XpathQueryJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(XpathQueryJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(XpathQueryJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + try { + new XpathQueryJFrame().setVisible(true); + } catch (ParserConfigurationException ex) { + Logger.getLogger(XpathQueryJFrame.class.getName()).log(Level.SEVERE, null, ex); + } + } + }); + } + + String failedQuery = null; + + public void Message(String s) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + JOptionPane.showMessageDialog(XpathQueryJFrame.this, s); + } + }); + } + + final XpathUtils xpu; + + boolean isUpdateAutomaticallySelected() { + return this.jCheckBoxUpdateAutomatically.isSelected(); + } + + public String runQuery(String query, String status) { + String resultString = ""; + try { + if (query.equals(failedQuery)) { + return null; + } + resultString = xpu.queryXmlString(status, query); + } catch (Exception ex) { + Logger.getLogger(PendantClient.class.getName()).log(Level.SEVERE, null, ex); + Message("Query :" + query + " of " + status + " failed"); + failedQuery = query; + } + this.setResult(resultString); + return resultString; + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButtonClose; + private javax.swing.JCheckBox jCheckBoxUpdateAutomatically; + private javax.swing.JComboBox jComboBoxXpathQuery; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + // End of variables declaration//GEN-END:variables +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java b/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java new file mode 100644 index 0000000..a2ce1c9 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java @@ -0,0 +1,133 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * + * @author Will Shackleford{@literal } + */ +public class XpathUtils { + + final TransformerFactory transformerFactory; + final DocumentBuilderFactory documentBuilderFactory; + final DocumentBuilder documentBuilder; + + XpathUtils() throws ParserConfigurationException { + transformerFactory = TransformerFactory.newInstance(); + documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + } + + private File[] schemaFiles = null; + + /** + * Get the value of schemaFiles + * + * @return the value of schemaFiles + */ + public File[] getSchemaFiles() { + return schemaFiles; + } + + /** + * Set the value of schemaFiles + * + * @param schemaFiles new value of schemaFiles + */ + public void setSchemaFiles(File[] schemaFiles) { + this.schemaFiles = schemaFiles; + } + + public String getDocumentation(String name) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + return queryXml(schemaFiles, "/schema/complexType[@name=\""+name+"\"]/annotation/documentation/text()"); + } + + final + public String nodeToString(Node node) { + StringWriter sw = new StringWriter(); + try { + Transformer t = transformerFactory.newTransformer(); + t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + t.setOutputProperty(OutputKeys.INDENT, "yes"); + t.transform(new DOMSource(node), new StreamResult(sw)); + } catch (TransformerException te) { + System.out.println("nodeToString Transformer Exception"); + } + return sw.toString(); + } + + public String queryXml(File xsdFile, String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + Document doc = documentBuilder.parse(xsdFile); + final XPathFactory xPathfactory = XPathFactory.newInstance(); + final XPath xpath = xPathfactory.newXPath(); + NodeList nl = (NodeList) xpath.evaluate(query, doc, XPathConstants.NODESET); + return nodeListToString(nl); + } + + public String queryXml(File fa[], String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + StringBuilder sb = new StringBuilder(); + for(File f : fa) { + sb.append(queryXml(f, query)); + } + return sb.toString(); + } + + public String nodeListToString(NodeList nl) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < nl.getLength(); i++) { + Node n = nl.item(i); +// resultString += "\n"; + sb.append(nodeToString(n)); + } + return sb.toString(); + } + + public String queryXmlString(String string, String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + Document doc = documentBuilder.parse(new ByteArrayInputStream(string.getBytes())); + final XPathFactory xPathfactory = XPathFactory.newInstance(); + final XPath xpath = xPathfactory.newXPath(); + NodeList nl = (NodeList) xpath.evaluate(query, doc, XPathConstants.NODESET); + return nodeListToString(nl); + } + +} diff --git a/crcl4java-utils/src/test/java/crcl/utils/CRCLPosemathTest.java b/crcl4java-utils/src/test/java/crcl/utils/CRCLPosemathTest.java new file mode 100644 index 0000000..39c15fa --- /dev/null +++ b/crcl4java-utils/src/test/java/crcl/utils/CRCLPosemathTest.java @@ -0,0 +1,978 @@ +/* + * This is public domain software, however it is preferred + * that the following disclaimers be attached. + * + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. This software is experimental. + * NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgment if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.PoseType; +import crcl.base.VectorType; +import java.math.BigDecimal; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.commons.math3.geometry.euclidean.threed.Rotation; +import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import rcs.posemath.PmCartesian; +import rcs.posemath.PmException; +import rcs.posemath.PmPose; +import rcs.posemath.PmQuaternion; +import rcs.posemath.PmRotationMatrix; +import rcs.posemath.PmRotationVector; +import rcs.posemath.PmRpy; +import rcs.posemath.Posemath; + +/** + * + * @author Will Shackleford + */ +public class CRCLPosemathTest { + + public CRCLPosemathTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + private PointType pt123 = null; + private PointType pt321 = null; + private PmCartesian cart123 = null; + private PmCartesian cart321 = null; + private VectorType xvec = null; + private VectorType yvec = null; + private VectorType zvec = null; + private PoseType pose123 = null; + private PoseType pose321 = null; + private PoseType pose321rot90 = null; + + static final private double ASSERT_TOLERANCE_DELTA = 1e-6; + + private void checkEquals(String msg, double v1, double v2) { + assertEquals(msg, v1, v2, ASSERT_TOLERANCE_DELTA); + } + +// private void checkEquals(String msg, BigDecimal v1,double v2) { +// assertEquals(msg, v1.doubleValue(), v2, ASSERT_TOLERANCE_DELTA); +// } +// +// private void checkEquals(String msg, double v1, BigDecimal v2) { +// assertEquals(msg, v1, v2.doubleValue(), ASSERT_TOLERANCE_DELTA); +// } + private void checkEquals(String msg, BigDecimal v1, BigDecimal v2) { + assertTrue(msg + " both are null or neither is null", (v1 == null) == (v2 == null)); + if (v1 == null) { + return; + } + checkEquals(msg, v1.doubleValue(), v2.doubleValue()); + } + +// private void checkEquals(String msg, PmCartesian cart, PointType pt) { +// checkEquals(msg+".x",cart.x, pt.getX()); +// checkEquals(msg+".y",cart.y, pt.getY()); +// checkEquals(msg+".z",cart.z, pt.getZ()); +// } + private void checkEquals(String msg, PmCartesian cart1, PmCartesian cart2) { + checkEquals(msg + ".x", cart1.x, cart2.x); + checkEquals(msg + ".y", cart1.y, cart2.y); + checkEquals(msg + ".z", cart1.z, cart2.z); + } + + private void checkEquals(String msg, PmQuaternion quat1, PmQuaternion quat2) { + checkEquals(msg + ".s", quat1.s, quat2.s); + checkEquals(msg + ".x", quat1.x, quat2.x); + checkEquals(msg + ".y", quat1.y, quat2.y); + checkEquals(msg + ".z", quat1.z, quat2.z); + } + + private void checkEquals(String msg, PmRotationMatrix cart1, PmRotationMatrix cart2) { + checkEquals(msg + ".x", cart1.x, cart2.x); + checkEquals(msg + ".y", cart1.y, cart2.y); + checkEquals(msg + ".z", cart1.z, cart2.z); + } + + private void checkEquals(String msg, PointType pt1, PointType pt2) { + checkEquals(msg + ".getX()", pt1.getX(), pt2.getX()); + checkEquals(msg + ".getY()", pt1.getY(), pt2.getY()); + checkEquals(msg + ".getZ()", pt1.getZ(), pt2.getZ()); + } + + private void checkEquals(String msg, VectorType v1, VectorType v2) { + checkEquals(msg + ".getI()", v1.getI(), v2.getI()); + checkEquals(msg + ".getJ()", v1.getJ(), v2.getJ()); + checkEquals(msg + ".getK()", v1.getK(), v2.getK()); + } + + private void checkEquals(String msg, PoseType pose1, PoseType pt2) { + checkEquals(msg + ".getPoint()", pose1.getPoint(), pt2.getPoint()); + checkEquals(msg + ".getXAxis()", pose1.getXAxis(), pt2.getXAxis()); + checkEquals(msg + ".getZAxis()", pose1.getZAxis(), pt2.getZAxis()); + } + + private void checkEquals(String msg, Rotation rot1, Rotation rot2) { + double m1[][] = rot1.getMatrix(); + double m2[][] = rot2.getMatrix(); + assertArrayEquals(msg + "[0]", m1[0], m2[0], ASSERT_TOLERANCE_DELTA); + assertArrayEquals(msg + "[1]", m1[1], m2[1], ASSERT_TOLERANCE_DELTA); + assertArrayEquals(msg + "[2]", m1[2], m2[2], ASSERT_TOLERANCE_DELTA); + } + + @Before + public void setUp() { + pt123 = new PointType(); + pt123.setX(BIG_DECIMAL_1); + pt123.setY(BIG_DECIMAL_2); + pt123.setZ(BIG_DECIMAL_3); + + pt321 = new PointType(); + pt321.setX(BIG_DECIMAL_3); + pt321.setY(BIG_DECIMAL_2); + pt321.setZ(BIG_DECIMAL_1); + + xvec = new VectorType(); + xvec.setI(BigDecimal.ONE); + xvec.setJ(BigDecimal.ZERO); + xvec.setK(BigDecimal.ZERO); + + yvec = new VectorType(); + yvec.setI(BigDecimal.ZERO); + yvec.setJ(BigDecimal.ONE); + yvec.setK(BigDecimal.ZERO); + + zvec = new VectorType(); + zvec.setI(BigDecimal.ZERO); + zvec.setJ(BigDecimal.ZERO); + zvec.setK(BigDecimal.ONE); + + pose123 = new PoseType(); + pose123.setPoint(pt123); + pose123.setXAxis(xvec); + pose123.setZAxis(zvec); + + pose321 = new PoseType(); + pose321.setPoint(pt321); + pose321.setXAxis(xvec); + pose321.setZAxis(zvec); + + pose321rot90 = new PoseType(); + pose321rot90.setPoint(pt321); + pose321rot90.setXAxis(yvec); + pose321rot90.setZAxis(zvec); + + cart123 = new PmCartesian(1.0, 2.0, 3.0); + cart321 = new PmCartesian(3.0, 2.0, 1.0); + } + + private static final BigDecimal BIG_DECIMAL_1 = BigDecimal.ONE; + private static final BigDecimal BIG_DECIMAL_2 = new BigDecimal("2"); + private static final BigDecimal BIG_DECIMAL_3 = new BigDecimal("3"); + private static final BigDecimal BIG_DECIMAL_4 = new BigDecimal("4"); + + @After + public void tearDown() { + } + + /** + * Test of pointToPmCartesian method, of class CRCLToPosemath. + */ + @Test + public void testPointToPmCartesian() { + System.out.println("pointToPmCartesian"); + PointType pt = this.pt123; + PmCartesian expResult = this.cart123; + PmCartesian result = CRCLPosemath.pointToPmCartesian(pt); + checkEquals("123", expResult, result); + } + + /** + * Test of diffPoints method, of class CRCLToPosemath. + */ + @Test + public void testDiffPoints() { + System.out.println("diffPoints"); + PointType pt1 = this.pt123; + PointType pt2 = this.pt321; + + // result should = sqrt((3-1)^2 + (2-2)^2 + (1-3)^2) = sqrt(8) + double expResult = Math.sqrt(8); + double result = CRCLPosemath.diffPoints(pt1, pt2); + + assertEquals(expResult, result, ASSERT_TOLERANCE_DELTA); + } + + /** + * Test of diffPosesTran method, of class CRCLToPosemath. + */ + @Test + public void testDiffPosesTran() { + System.out.println("diffPosesTran"); + PoseType p1 = this.pose123; + PoseType p2 = this.pose321; + // result should = sqrt((3-1)^2 + (2-2)^2+(1-3)^2) = sqrt(8) + double expResult = Math.sqrt(8.0); + double result = CRCLPosemath.diffPosesTran(p1, p2); + assertEquals(expResult, result, ASSERT_TOLERANCE_DELTA); + } + + /** + * Test of vectorToPmCartesian method, of class CRCLToPosemath. + */ + @Test + public void testVectorToPmCartesian() { + System.out.println("vectorToPmCartesian"); + VectorType v = this.xvec; + PmCartesian expResult = new PmCartesian(1.0, 0.0, 0.0); + PmCartesian result = CRCLPosemath.vectorToPmCartesian(v); + checkEquals("xvec", result, expResult); + } + + /** + * Test of toPoseType method, of class CRCLToPosemath. + */ + @Test + public void testToPoseType() throws Exception { + System.out.println("toPoseType"); + PmCartesian tran = this.cart321; + PmRotationVector v = new PmRotationVector(Math.PI / 2, 0.0, 0.0, 1.0); + PoseType expResult = this.pose321rot90; + PoseType result = CRCLPosemath.toPoseType(tran, v); + checkEquals("pose321rot90", result, expResult); + } + + /** + * Test of toPmRotationMatrix method, of class CRCLToPosemath. + */ + @Test + public void testToPmRotationMatrix() throws Exception { + System.out.println("toPmRotationMatrix"); + PoseType p = this.pose123; + PmRotationMatrix expResult = new PmRotationMatrix( + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0 + ); + PmRotationMatrix result = CRCLPosemath.toPmRotationMatrix(p); + checkEquals("RotMat", expResult, result); + + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 300; i++) { + PmRpy rpy1 = new PmRpy(r.nextDouble()*2.0*Math.PI-Math.PI, + r.nextDouble()*Math.PI - Math.PI/2.0, + r.nextDouble() * 2.0 * Math.PI - Math.PI); + expResult = Posemath.toMat(rpy1); + p = CRCLPosemath.toPoseType(cart123, Posemath.toRot(rpy1)); + result = CRCLPosemath.toPmRotationMatrix(p); + checkEquals("randRotMat", expResult, result); + } + } + + /** + * Test of toPmRotationVector method, of class CRCLToPosemath. + */ + @Test + public void testToPmRotationVector() throws Exception { + System.out.println("toPmRotationVector"); + PoseType p = this.pose321rot90; + PmRotationVector expResult = new PmRotationVector(Math.PI / 2, 0.0, 0.0, 1.0); + PmRotationVector result = CRCLPosemath.toPmRotationVector(p); + + assertEquals("s", expResult.s, result.s, ASSERT_TOLERANCE_DELTA); + assertEquals("x", expResult.x, result.x, ASSERT_TOLERANCE_DELTA); + assertEquals("y", expResult.y, result.y, ASSERT_TOLERANCE_DELTA); + assertEquals("z", expResult.z, result.z, ASSERT_TOLERANCE_DELTA); + } + + /** + * Test of maxDiffDoubleArray method, of class CRCLToPosemath. + */ + @Test + public void testMaxDiffDoubleArray() { + System.out.println("maxDiffDoubleArray"); + double[] da = new double[]{0, 0, 0.2, 0}; + double[] da2 = new double[]{0, 0, -0.2, 0}; + double expResult = 0.4; + double result = CRCLPosemath.maxDiffDoubleArray(da, da2); + assertEquals(expResult, result, ASSERT_TOLERANCE_DELTA); + try { + CRCLPosemath.maxDiffDoubleArray(da, new double[1]); + fail("Expected IllegalArgumentException since array lengths don't match"); + } catch (IllegalArgumentException expectedException) { + } + } + + /** + * Test of diffPosesRot method, of class CRCLToPosemath. + */ + @Test + public void testDiffPosesRot() throws Exception { + System.out.println("diffPosesRot"); + PoseType pose1 = this.pose321; + PoseType pose2 = this.pose321rot90; + double expResult = Math.PI / 2; + double result = CRCLPosemath.diffPosesRot(pose1, pose2); + assertEquals(expResult, result, ASSERT_TOLERANCE_DELTA); + } + + /** + * Test of toPointType method, of class CRCLToPosemath. + */ + @Test + public void testToPointType() { + System.out.println("toPointType"); + PmCartesian c = this.cart123; + PointType expResult = this.pt123; + PointType result = CRCLPosemath.toPointType(c); + checkEquals("123", result, expResult); + } + +// /** +// * Test of toPoseType method, of class CRCLToPosemath. +// */ +// @Test +// public void testToPoseType() throws Exception { +// System.out.println("toPoseType"); +// PmCartesian tran = this.cart123; +// PmRotationVector v = new PmRotationVector(Math.toRadians(30), 0.0, 0.0, 1.0); +// PoseType expResult = new PoseType(); +// VectorType xvector = new VectorType(); +// xvector.setI(BigDecimal.valueOf(Math.cos(Math.toRadians(30.0)))); +// xvector.setJ(BigDecimal.valueOf(Math.sin(Math.toRadians(30.0)))); +// xvector.setK(BigDecimal.ZERO); +// VectorType zvector = new VectorType(); +// zvector.setI(BigDecimal.ZERO); +// zvector.setJ(BigDecimal.ZERO); +// zvector.setK(BigDecimal.ONE); +// PointType pt = new PointType(); +// pt.setX(BigDecimal.ONE); +// pt.setY(BIG_DECIMAL_2); +// pt.setZ(BIG_DECIMAL_3); +// expResult.setPoint(pt); +// expResult.setXAxis(xvector); +// expResult.setZAxis(zvector); +// PoseType result = CRCLPosemath.toPoseType(tran, v); +// checkEquals("123", result, expResult); +// } + + /** + * Test of toPmRpy method, of class CRCLToPosemath. + */ + @Test + public void testToPmRpy() throws Exception { + System.out.println("toPmRpy"); + PoseType p = new PoseType() { + }; + PmRpy expResult = new PmRpy(Math.toRadians(20.0), Math.toRadians(25.0), Math.toRadians(30.0)); + PmRotationMatrix mat = Posemath.toMat(expResult); + VectorType xvector = new VectorType(); + xvector.setI(BigDecimal.valueOf(mat.x.x)); + xvector.setJ(BigDecimal.valueOf(mat.x.y)); + xvector.setK(BigDecimal.valueOf(mat.x.z)); + p.setXAxis(xvector); + VectorType zvector = new VectorType(); + zvector.setI(BigDecimal.valueOf(mat.z.x)); + zvector.setJ(BigDecimal.valueOf(mat.z.y)); + zvector.setK(BigDecimal.valueOf(mat.z.z)); + p.setZAxis(zvector); + PmRpy result = CRCLPosemath.toPmRpy(p); + assertEquals(expResult.r, result.r, 1e-4); + assertEquals(expResult.p, result.p, 1e-4); + assertEquals(expResult.y, result.y, 1e-4); + } + + /** + * Test of poseToString method, of class CRCLToPosemath. + */ + @Test + public void testPoseToString() throws Exception { + System.out.println("poseToString"); + PoseType pose = pose321rot90; + String expResult = "{\n" + + "{0.00,1.00,0.00,3.00},\n" + + "{-1.00,0.00,0.00,2.00},\n" + + "{0.00,0.00,1.00,1.00},\n" + + "{0.00,0.00,0.00,1.00}\n" + + "}"; + String result = CRCLPosemath.poseToString(pose); + assertEquals(expResult, result); + } + + /** + * Test of toPoseType method, of class CRCLToPosemath. + */ + @Test + public void testToPoseType_3args() throws Exception { + System.out.println("toPoseType"); + PmCartesian tran = this.cart321; + PmRotationVector v = new PmRotationVector(Math.PI / 2, 0.0, 0.0, 1.0); + PoseType pose_in = new PoseType(); + PoseType expResult = pose_in; + PoseType result = CRCLPosemath.toPoseType(tran, v, pose_in); + // result refences the same memory as expResult + assertTrue(expResult == result); + + result = CRCLPosemath.toPoseType(tran, v, null); + // result no longer refences the same memory but all members are approximately equal + assertTrue(expResult != result); + checkEquals("123rot90", result, expResult); + + } + + /** + * Test of add method, of class CRCLPosemath. + */ + @Test + public void testAdd() { + System.out.println("add"); + PointType p1 = this.pt123; + PointType p2 = this.pt321; + PointType expResult = new PointType(); + expResult.setX(BIG_DECIMAL_4); + expResult.setY(BIG_DECIMAL_4); + expResult.setZ(BIG_DECIMAL_4); + PointType result = CRCLPosemath.add(p1, p2); + checkEquals("444", result, expResult); + } + + /** + * Test of subtract method, of class CRCLPosemath. + */ + @Test + public void testSubtract() { + System.out.println("subtract"); + PointType p1 = this.pt123; + PointType p2 = this.pt321; + PointType expResult = new PointType(); + expResult.setX(BigDecimal.valueOf(-2.0)); + expResult.setY(BigDecimal.valueOf(0.0)); + expResult.setZ(BigDecimal.valueOf(+2.0)); + PointType result = CRCLPosemath.subtract(p1, p2); + checkEquals("-2,0,+2", result, expResult); + } + + /** + * Test of multiply method, of class CRCLPosemath. + */ + @Test + public void testMultiply_BigDecimal_VectorType() { + System.out.println("multiply"); + BigDecimal dist = BigDecimal.valueOf(2.5); + VectorType v = this.xvec; + PointType expResult = new PointType(); + expResult.setX(BigDecimal.valueOf(2.5)); + expResult.setY(BigDecimal.ZERO); + expResult.setZ(BigDecimal.ZERO); + PointType result = CRCLPosemath.multiply(dist, v); + checkEquals("2.5,0,0", expResult, result); + } + + /** + * Test of multiply method, of class CRCLPosemath. + */ + @Test + public void testMultiply_double_VectorType() { + System.out.println("multiply"); + double dist = 2.5; + VectorType v = this.zvec; + PointType expResult = new PointType(); + expResult.setX(BigDecimal.ZERO); + expResult.setY(BigDecimal.ZERO); + expResult.setZ(BigDecimal.valueOf(2.5)); + PointType result = CRCLPosemath.multiply(dist, v); + checkEquals("0,0,2.5", expResult, result); + } + + /** + * Test of multiply method, of class CRCLPosemath. + */ + @Test + public void testMultiply_BigDecimal_PointType() { + System.out.println("multiply"); + BigDecimal dist = BigDecimal.valueOf(3.5); + PointType p = this.pt123; + PointType expResult = new PointType(); + expResult.setX(BigDecimal.valueOf(1.0 * 3.5)); + expResult.setY(BigDecimal.valueOf(2.0 * 3.5)); + expResult.setZ(BigDecimal.valueOf(3.0 * 3.5)); + PointType result = CRCLPosemath.multiply(dist, p); + checkEquals("3.5*(1,2,3)", expResult, result); + } + + /** + * Test of multiply method, of class CRCLPosemath. + */ + @Test + public void testMultiply_double_PointType() { + System.out.println("multiply"); + double dist = 0.3; + PointType p = this.pt321; + PointType expResult = new PointType(); + expResult.setX(BigDecimal.valueOf(3.0 * 0.3)); + expResult.setY(BigDecimal.valueOf(2.0 * 0.3)); + expResult.setZ(BigDecimal.valueOf(1.0 * 0.3)); + PointType result = CRCLPosemath.multiply(dist, p); + checkEquals("0.3*(3,2,1)", expResult, result); + } + + /** + * Test of dot method, of class CRCLPosemath. + */ + @Test + public void testDot_VectorType_VectorType() { + System.out.println("dot"); + VectorType v1 = this.xvec; + VectorType v2 = this.yvec; + BigDecimal expResult = BigDecimal.ZERO; + BigDecimal result = CRCLPosemath.dot(v1, v2); + checkEquals("x dot y", expResult, result); + v1 = this.zvec; + v2 = this.zvec; + expResult = BigDecimal.ONE; + result = CRCLPosemath.dot(v1, v2); + checkEquals("z dot z", expResult, result); + } + + /** + * Test of dot method, of class CRCLPosemath. + */ + @Test + public void testDot_VectorType_PointType() { + System.out.println("dot"); + VectorType v1 = this.zvec; + PointType p2 = this.pt123; + BigDecimal expResult = BIG_DECIMAL_3; + BigDecimal result = CRCLPosemath.dot(v1, p2); + checkEquals("z dot (1,2,3)", expResult, result); + } + + /** + * Test of cross method, of class CRCLPosemath. + */ + @Test + public void testCross() { + System.out.println("cross"); + VectorType v1 = this.xvec; + VectorType v2 = this.yvec; + VectorType expResult = this.zvec; + VectorType result = CRCLPosemath.cross(v1, v2); + checkEquals("x cross y", expResult, result); + v1 = this.zvec; + v2 = this.xvec; + expResult = this.yvec; + result = CRCLPosemath.cross(v1, v2); + checkEquals("z cross x", expResult, result); + + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 100; i++) { + try { + PmCartesian cart1 = new PmCartesian(r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0); + cart1 = cart1.multiply(1.0 / Posemath.mag(cart1)); + PmCartesian cart2 = new PmCartesian(r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0); + cart2 = cart2.multiply(1.0 / Posemath.mag(cart2)); + v1 = new VectorType(); + v1.setI(BigDecimal.valueOf(cart1.x)); + v1.setJ(BigDecimal.valueOf(cart1.y)); + v1.setK(BigDecimal.valueOf(cart1.z)); + v2 = new VectorType(); + v2.setI(BigDecimal.valueOf(cart2.x)); + v2.setJ(BigDecimal.valueOf(cart2.y)); + v2.setK(BigDecimal.valueOf(cart2.z)); + PmCartesian cross = new PmCartesian(); + Posemath.pmCartCartCross(cart1, cart2, cross); + expResult = new VectorType(); + expResult.setI(BigDecimal.valueOf(cross.x)); + expResult.setJ(BigDecimal.valueOf(cross.y)); + expResult.setK(BigDecimal.valueOf(cross.z)); + + + result = CRCLPosemath.cross(v1, v2); + checkEquals("randomCross (posemath)", result, expResult); + + Vector3D v3Da = new Vector3D(cart1.x,cart1.y,cart1.z); + Vector3D v3Db = new Vector3D(cart2.x,cart2.y,cart2.z); + Vector3D cross2 = v3Da.crossProduct(v3Db); + expResult = CRCLPosemath.toCRCLVector(cross2); + checkEquals("randomCross2 (commons-math)", result, expResult); + + } catch (PmException ex) { + Logger.getLogger(CRCLPosemathTest.class.getName()).log(Level.SEVERE, null, ex); + fail("Exception not expected."); + } + } + } + + private static final int RANDOM_SEED = 9321; + + /** + * Test of multiply method, of class CRCLPosemath. + */ + @Test + public void testMultiply_PoseType_PoseType() { + System.out.println("multiply"); + PoseType p1 = this.pose123; + PoseType p2 = this.pose321; + PoseType expResult = new PoseType(); + PointType pt444 = new PointType(); + pt444.setX(BIG_DECIMAL_4); + pt444.setY(BIG_DECIMAL_4); + pt444.setZ(BIG_DECIMAL_4); + expResult.setPoint(pt444); + expResult.setXAxis(xvec); + expResult.setZAxis(zvec); + PoseType result = CRCLPosemath.multiply(p1, p2); + checkEquals("444", expResult, result); + p1 = this.pose321rot90; + p2 = this.pose123; + expResult = new PoseType(); + PointType pt2 = new PointType(); + pt2.setX(BigDecimal.valueOf(3.0 - 2.0)); + pt2.setY(BigDecimal.valueOf(2.0 + 1.0)); + pt2.setZ(BigDecimal.valueOf(1.0 + 3.0)); + expResult.setPoint(pt2); + expResult.setXAxis(yvec); + expResult.setZAxis(zvec); + result = CRCLPosemath.multiply(p1, p2); + try { + PmCartesian chkCart + = CRCLPosemath.toPmRotationMatrix(p1).multiply(CRCLPosemath.pointToPmCartesian(p2.getPoint())); + System.out.println("chkCart = " + chkCart); + } catch (PmException ex) { + Logger.getLogger(CRCLPosemathTest.class.getName()).log(Level.SEVERE, null, ex); + } + checkEquals("234", expResult, result); + + testWithRandomMults(); + } + + public void testWithRandomMults() { + PoseType p1; + PoseType p2; + PoseType result; + PoseType expResult; + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 100; i++) { + try { + PmRpy rpy1 = new PmRpy(r.nextDouble() * 2.0 * Math.PI - Math.PI, + r.nextDouble() * Math.PI - Math.PI / 2.0, + r.nextDouble() * 2.0 * Math.PI - Math.PI + ); + PmRpy rpy2 = new PmRpy(r.nextDouble() * 2.0 * Math.PI - Math.PI, + r.nextDouble() * Math.PI - Math.PI / 2.0, + r.nextDouble() * 2.0 * Math.PI - Math.PI + ); + PmCartesian cart1 = new PmCartesian(r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0); + + PmCartesian cart2 = new PmCartesian(r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0); + + PmPose pose1 = new PmPose(cart1, Posemath.toQuat(rpy1)); + PmPose pose2 = new PmPose(cart2, Posemath.toQuat(rpy2)); + PmPose poseProduct = new PmPose(); + Posemath.pmPosePoseMult(pose1, pose2, poseProduct); + PmPose revPoseProduct = new PmPose(); + Posemath.pmPosePoseMult(pose2, pose1, revPoseProduct); + p1 = CRCLPosemath.toPoseType(cart1, Posemath.toRot(rpy1)); + p2 = CRCLPosemath.toPoseType(cart2, Posemath.toRot(rpy2)); + result = CRCLPosemath.multiply(p1, p2); + expResult = CRCLPosemath.toPoseType(poseProduct.tran, Posemath.toRot(poseProduct.rot)); + checkEquals("poseProduct", result, expResult); + } catch (PmException ex) { + Logger.getLogger(CRCLPosemathTest.class.getName()).log(Level.SEVERE, null, ex); + fail("PmException thrown."); + } + + } + } + + /** + * Test of shift method, of class CRCLPosemath. + */ + @Test + public void testShift() { + System.out.println("shift"); + PoseType poseIn = this.pose321rot90; + PointType pt = this.pt123; + PoseType expResult = new PoseType(); + PointType expResultPt = CRCLPosemath.add(pose321rot90.getPoint(), pt); + expResult.setPoint(expResultPt); + expResult.setXAxis(poseIn.getXAxis()); + expResult.setZAxis(poseIn.getZAxis()); + PoseType result = CRCLPosemath.shift(poseIn, pt); + checkEquals("444rot90", result, expResult); + } + + /** + * Test of pointXAxisZAxisToPose method, of class CRCLPosemath. + */ + @Test + public void testPointXAxisZAxisToPose() { + System.out.println("pointXAxisZAxisToPose"); + PointType pt = this.pt123; + VectorType x = this.xvec; + VectorType z = this.zvec; + PoseType expResult = this.pose123; + PoseType result = CRCLPosemath.pointXAxisZAxisToPose(pt, x, z); + checkEquals("123", expResult, result); + } + + /** + * Test of toPoseType method, of class CRCLPosemath. + */ + @Test + public void testToPoseType_PmCartesian_PmRotationVector() throws Exception { + System.out.println("toPoseType"); + PmCartesian tran = this.cart321; + PmRotationVector v = new PmRotationVector(Math.PI / 2.0, 0.0, 0.0, 1.0); + PoseType expResult = this.pose321rot90; + PoseType result = CRCLPosemath.toPoseType(tran, v); + checkEquals("pose321rot90", result, expResult); + } + + /** + * Test of toPose method, of class CRCLPosemath. + */ + @Test + public void testToPose() { + System.out.println("toPose"); + double[][] mat = new double[][]{ + {+0.0, +1.0, +0.0, +3.0}, + {-1.0, +0.0, +0.0, +2.0}, + {+0.0, +0.0, +1.0, +1.0}, + {+0.0, +0.0, +0.0, +1.0} + }; + PoseType expResult = this.pose321rot90; + PoseType result = CRCLPosemath.toPose(mat); + checkEquals("fromMat", result, expResult); + } + + /** + * Test of invert method, of class CRCLPosemath. + */ + @Test + public void testInvert() { + System.out.println("invert"); + PoseType p = this.pose123; + PoseType expResult = new PoseType(); + PointType pt = new PointType(); + pt.setX(BIG_DECIMAL_1.negate()); + pt.setY(BIG_DECIMAL_2.negate()); + pt.setZ(BIG_DECIMAL_3.negate()); + expResult.setPoint(pt); + expResult.setXAxis(xvec); + expResult.setZAxis(zvec); + PoseType result = CRCLPosemath.invert(p); + checkEquals("invert", expResult, result); + + PoseType identity = CRCLPosemath.identityPose(); + PoseType identityCheck = CRCLPosemath.multiply(p, result); + checkEquals("identity", identityCheck, identity); + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 100; i++) { + try { + PmRpy rpy1 = new PmRpy(r.nextDouble() * 2.0 * Math.PI - Math.PI, + r.nextDouble() * Math.PI - Math.PI / 2.0, + r.nextDouble() * 2.0 * Math.PI - Math.PI + ); + PmCartesian cart1 = new PmCartesian(r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0, + r.nextDouble() * 2.0 - 1.0); + + p = CRCLPosemath.toPoseType(cart1, Posemath.toRot(rpy1)); + result = CRCLPosemath.invert(p); + identityCheck = CRCLPosemath.multiply(p, result); + checkEquals("identity", identityCheck, identity); + } catch (PmException ex) { + Logger.getLogger(CRCLPosemathTest.class.getName()).log(Level.SEVERE, null, ex); + fail("PmException thrown."); + } + } + } + + /** + * Test of toCommonsVector3D method, of class CRCLPosemath. + */ + @Test + public void testToCommonsVector3D_VectorType() { + System.out.println("toCommonsVector3D"); + VectorType vIn = xvec; + Vector3D expResult = Vector3D.PLUS_I; + Vector3D result = CRCLPosemath.toCommonsVector3D(vIn); + assertEquals(expResult, result); + } + + /** + * Test of toCommonsVector3D method, of class CRCLPosemath. + */ + @Test + public void testToCommonsVector3D_PointType() { + System.out.println("toCommonsVector3D"); + PointType ptIn = pt123; + Vector3D expResult = new Vector3D(1, 2, 3); + Vector3D result = CRCLPosemath.toCommonsVector3D(ptIn); + assertEquals(expResult, result); + } + + /** + * Test of toCommonsVector3D method, of class CRCLPosemath. + */ + @Test + public void testToCommonsVector3D_PoseType() { + System.out.println("toCommonsVector3D"); + PoseType poseIn = pose321rot90; + Vector3D expResult = new Vector3D(3, 2, 1); + Vector3D result = CRCLPosemath.toCommonsVector3D(poseIn); + assertEquals(expResult, result); + } + + /** + * Test of toCRCLUnitVector method, of class CRCLPosemath. + */ + @Test + public void testToCRCLUnitVector_Vector3D_VectorType() { + System.out.println("toCRCLUnitVector"); + Vector3D vIn = Vector3D.PLUS_I; + VectorType vOut = null; + VectorType expResult = xvec; + VectorType result = CRCLPosemath.toCRCLUnitVector(vIn, vOut); + checkEquals("xvec", result, expResult); + } + + /** + * Test of toCRCLUnitVector method, of class CRCLPosemath. + */ + @Test + public void testToCRCLUnitVector_Vector3D() { + System.out.println("toCRCLUnitVector"); + Vector3D vIn = Vector3D.PLUS_I; + VectorType expResult = xvec; + VectorType result = CRCLPosemath.toCRCLUnitVector(vIn); + checkEquals("xvec", result, expResult); + } + + /** + * Test of toCommonsRotation method, of class CRCLPosemath. + */ + @Test + public void testToCommonsRotation() { + System.out.println("toCommonsRotation"); + PoseType poseIn = pose321rot90; + // NOTICE the MINUS sign, commons-math uses opposite convention + Rotation expResult = new Rotation(Vector3D.PLUS_K, -Math.PI / 2); + Rotation result = CRCLPosemath.toCommonsRotation(poseIn); + checkEquals("rot90", expResult, result); + } + + /** + * Test of toCRCLPoint method, of class CRCLPosemath. + */ + @Test + public void testToCRCLPoint_Vector3D_PointType() { + System.out.println("toCRCLPoint"); + Vector3D vIn = new Vector3D(1, 2, 3); + PointType ptOut = new PointType(); + PointType expResult = pt123; + PointType result = CRCLPosemath.toCRCLPoint(vIn, null); + checkEquals("pt123", result, expResult); + result = CRCLPosemath.toCRCLPoint(vIn, ptOut); + checkEquals("pt123", result, expResult); + assertTrue(ptOut == result); + } + + /** + * Test of toCRCLPoint method, of class CRCLPosemath. + */ + @Test + public void testToCRCLPoint_Vector3D() { + System.out.println("toCRCLPoint"); + Vector3D vIn = new Vector3D(1, 2, 3); + PointType expResult = pt123; + PointType result = CRCLPosemath.toCRCLPoint(vIn); + checkEquals("pt123", result, expResult); + } + + /** + * Test of identityPose method, of class CRCLPosemath. + */ + @Test + public void testIdentityPose() { + System.out.println("identityPose"); +// PoseType expResult = null; + PoseType result = CRCLPosemath.identityPose(); + checkEquals("xvec", xvec, result.getXAxis()); + checkEquals("zvec", zvec, result.getZAxis()); + PointType zeroPoint = new PointType(); + zeroPoint.setX(BigDecimal.ZERO); + zeroPoint.setY(BigDecimal.ZERO); + zeroPoint.setZ(BigDecimal.ZERO); + checkEquals("point", zeroPoint, result.getPoint()); + } + + /** + * Test of toPmPose method, of class CRCLPosemath. + */ + @Test + public void testToPmPose() throws Exception { + System.out.println("toPmPose"); + PoseType p = pose321rot90; + PmPose expResult = new PmPose(cart321, + new PmQuaternion(new PmRotationVector(Math.PI / 2, 0, 0, 1))); + PmPose result = CRCLPosemath.toPmPose(p); + checkEquals("tran", result.tran, expResult.tran); + checkEquals("rot", result.rot, expResult.rot); + + } + + /** + * Test of toHomMat method, of class CRCLPosemath. + */ + @Test + public void testToHomMat() { + System.out.println("toHomMat"); + PoseType poseIn = pose321rot90; + double[][] expResult = new double[][]{ + {+0, 1, 0, 3}, + {-1, 0, 0, 2}, + {+0, 0, 1, 1}, + {+0, 0, 0, 1} + }; + double[][] result = CRCLPosemath.toHomMat(poseIn); + assertArrayEquals("mat[0]", expResult[0], result[0], ASSERT_TOLERANCE_DELTA); + assertArrayEquals("mat[1]", expResult[1], result[1], ASSERT_TOLERANCE_DELTA); + assertArrayEquals("mat[2]", expResult[2], result[2], ASSERT_TOLERANCE_DELTA); + assertArrayEquals("mat[3]", expResult[3], result[3], ASSERT_TOLERANCE_DELTA); + } + +} diff --git a/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketIT.java b/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketIT.java new file mode 100644 index 0000000..a414c9a --- /dev/null +++ b/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketIT.java @@ -0,0 +1,894 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * + */ +package crcl.utils; + + +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLProgramType; +import crcl.base.InitCanonType; +import java.math.BigInteger; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Will Shackleford {@literal } + */ +public class CRCLSocketIT { + + public CRCLSocketIT() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of stringToCommand method, of class CRCLSocket. + */ + @Test + public void testStringToCommand() throws Exception { + System.out.println("stringToCommand"); + String str = "\n" + + "\n" + + " \n" + + " 1\n" + + " \n" + + ""; + boolean validate = false; + CRCLSocket instance = new CRCLSocket(); + CRCLCommandInstanceType result = instance.stringToCommand(str, validate); + assertTrue(result.getCRCLCommand().getCommandID().compareTo(BigInteger.ONE) == 0); + assertTrue(result.getCRCLCommand() instanceof InitCanonType); +// fail("forced failure"); + } + + /** + * Test of stringToProgram method, of class CRCLSocket. + */ + @Test + public void testStringToProgram() throws Exception { + System.out.println("stringToProgram"); + String str = "\n" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " 2\n" + + " meter\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " 1.0\n" + + " \n" + + " \n" + + " \n" + + " 4\n" + + " \n" + + " 0.80\n" + + " \n" + + " \n" + + " \n" + + " 5\n" + + " \n" + + " 0.002\n" + + " 0.002\n" + + " 0.002\n" + + " \n" + + " \n" + + " \n" + + " 6\n" + + " \n" + + " 0.01\n" + + " 0.01\n" + + " 0.01\n" + + " \n" + + " \n" + + " \n" + + " 7\n" + + " 0\n" + + " \n" + + " \n" + + " 8\n" + + " false\n" + + " \n" + + " \n" + + " 1.5 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1.5 1 0.0001\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " \n" + + " 9\n" + + " 1\n" + + " \n" + + " \n" + + " 10\n" + + " false\n" + + " \n" + + " \n" + + " 1.5 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4 1 0.5001\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 11\n" + + " 0\n" + + " \n" + + " \n" + + " 12\n" + + " false\n" + + " \n" + + " \n" + + " 4 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.25 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.25 1 0.4\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 13\n" + + " \n" + + " \n" + + " 14\n" + + " false\n" + + " \n" + + " \n" + + " 8.25 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.75 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.75 1 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 15\n" + + " \n" + + " \n" + + " 16\n" + + " false\n" + + " \n" + + " \n" + + " 8.75 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 5.659 1.1 1.8\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 5.659 1.1 0.1501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 17\n" + + " 1\n" + + " \n" + + " \n" + + " 18\n" + + " false\n" + + " \n" + + " \n" + + " 5.659 1.1 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3.86 1.07 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3.86 1.07 0.6501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 19\n" + + " 0\n" + + " \n" + + " \n" + + " 20\n" + + " false\n" + + " \n" + + " \n" + + " 3.86 1.07 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 5.659 0.9 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 5.659 0.9 0.1501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 21\n" + + " 1\n" + + " \n" + + " \n" + + " 22\n" + + " false\n" + + " \n" + + " \n" + + " 5.659 0.9 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3.86 0.93 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 3.86 0.93 0.6501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 23\n" + + " 0\n" + + " \n" + + " \n" + + " 24\n" + + " false\n" + + " \n" + + " \n" + + " 3.86 0.93 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 6.42 1 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 6.42 1 0.1501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 25\n" + + " 1\n" + + " \n" + + " \n" + + " 26\n" + + " false\n" + + " \n" + + " \n" + + " 6.42 1 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4.14 0.93 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4.14 0.93 0.6501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 27\n" + + " 0\n" + + " \n" + + " \n" + + " 28\n" + + " false\n" + + " \n" + + " \n" + + " 4.14 0.93 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 7.61 1.02 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 7.61 1.02 0.1501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 29\n" + + " 1\n" + + " \n" + + " \n" + + " 30\n" + + " false\n" + + " \n" + + " \n" + + " 7.61 1.02 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4.14 1.07 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4.14 1.07 0.6501\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 31\n" + + " 0\n" + + " \n" + + " \n" + + " 32\n" + + " false\n" + + " \n" + + " \n" + + " 4.14 1.07 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.75 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.75 1 0.475\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 33\n" + + " \n" + + " \n" + + " 34\n" + + " false\n" + + " \n" + + " \n" + + " 8.75 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.25 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 8.25 1 0.5\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 35\n" + + " \n" + + " \n" + + " 36\n" + + " false\n" + + " \n" + + " \n" + + " 8.25 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 4 1 0.5001\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 37\n" + + " 1\n" + + " \n" + + " \n" + + " 38\n" + + " false\n" + + " \n" + + " \n" + + " 4 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 2.5 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 2.5 1 0.0001\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 39\n" + + " 0\n" + + " \n" + + " \n" + + " 40\n" + + " false\n" + + " \n" + + " \n" + + " 2.5 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 0.5 0 2\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " \n" + + " 41\n" + + " \n" + + ""; + boolean validate = false; + CRCLSocket instance = new CRCLSocket(); + CRCLProgramType result = instance.stringToProgram(str, validate); + assertTrue(result.getInitCanon().getCommandID().compareTo(BigInteger.ONE) == 0); + assertEquals(result.getMiddleCommand().size(), 39); + assertTrue(result.getEndCanon().getCommandID().compareTo(BigInteger.valueOf(41)) == 0); + + } + + /** + * Test of statusToString method, of class CRCLSocket. + */ +// @Test +// public void testStatusToString() throws Exception { +// System.out.println("statusToPrettyString"); +// boolean validate = false; +// CRCLSocket instance = new CRCLSocket(); +// CRCLStatusType status = instance.stringToStatus("\n" +// + "\n" +// + " \n" +// + " 5\n" +// + " 1\n" +// + " Working\n" +// + " \n" +// + " \n" +// + " \n" +// + " 1\n" +// + " 8.000000\n" +// + " \n" +// + " \n" +// + " 2\n" +// + " 53.000000\n" +// + " \n" +// + " \n" +// + " 3\n" +// + " -98.000000\n" +// + " \n" +// + " \n" +// + " 4\n" +// + " 82.000000\n" +// + " \n" +// + " \n" +// + " 5\n" +// + " -8.000000\n" +// + " \n" +// + " \n" +// + " 6\n" +// + " 0.000000\n" +// + " \n" +// + " \n" +// + " \n" +// + " 2015-04-02T09:55:44.455-04:00\n" +// + " \n" +// + " 102.519869\n" +// + " 12.724614\n" +// + " 36.635392\n" +// + " \n" +// + " \n" +// + " 0.798636\n" +// + " 0.000000\n" +// + " 0.601815\n" +// + " \n" +// + " \n" +// + " -0.601815\n" +// + " 0.000000\n" +// + " 0.798636\n" +// + " \n" +// + " \n" +// + " ", validate); +// String expResult = "\n" +// + "5118.000000253.0000003-98.000000482.0000005-8.00000060.0000002015-04-02T09:55:44.455-04:00102.51986912.72461436.6353920.7986360.0000000.601815-0.6018150.0000000.798636"; +// String result = instance.statusToString(status, validate); +// System.out.println("result = " + result); +// +// for (int i = 0; i < Math.min(result.length(), expResult.length()); i++) { +// if (expResult.charAt(i) != result.charAt(i)) { +// System.out.println("expResult.substring(" + i + ")=" + expResult.substring(i)); +// System.out.println("result.substring(" + i + ")=" + result.substring(i)); +// break; +// } +// } +//// System.out.println("resultPart = " + resultPart); +//// System.out.println("expResultPart = " + expResultPart); +// assertEquals(expResult, result); +// } + +} diff --git a/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java b/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java new file mode 100644 index 0000000..0966d1e --- /dev/null +++ b/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java @@ -0,0 +1,439 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLProgramType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStatusType; +import crcl.base.GetStatusType; +import crcl.base.InitCanonType; +import crcl.base.MoveThroughToType; +import crcl.base.PointType; +import crcl.base.PoseType; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBException; +import javax.xml.transform.sax.SAXSource; +import javax.xml.validation.Schema; +import org.junit.Assert; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Will Shackleford {@literal } + */ +public class CRCLSocketTest { + + public CRCLSocketTest() { + } + +// /** +// * Test of statusToEXI method, of class CRCLSocket. +// */ +// @Test +// public void testMessage() throws Exception { +// crcl.base.MessageType m = new MessageType(); +// crcl.base.CRCLCommandInstanceType cmd = new CRCLCommandInstanceType(); +// m.setMessage("
"); +// cmd.setCRCLCommand(m); +// CRCLSocket s = new CRCLSocket(); +// String xmlPrettyS = s.commandToPrettyDocString(cmd, true); +// LOGGER.log(Level.INFO,"xmlPrettyS = " + xmlPrettyS); +// String xmlS = s.commandToString(cmd, true); +// LOGGER.log(Level.INFO,"xmlS = " + xmlS); +// } + /** + * Test of statusToEXI method, of class CRCLSocket. + */ + @Test + public void testStatusToEXI() throws Exception { + LOGGER.log(Level.INFO, "statusToEXI"); + CRCLStatusType status = new CRCLStatusType(); + CommandStatusType cst = new CommandStatusType(); + cst.setCommandID(BigInteger.ONE); + cst.setStatusID(BigInteger.TEN); + status.setCommandStatus(cst); + PoseType p = new PoseType(); + PointType pt = new PointType(); + pt.setX(BigDecimal.ONE); + p.setPoint(pt); + status.setPose(p); + CRCLSocket instance = new CRCLSocket(); + byte[] expResult = null; + byte[] result = instance.statusToEXI(status); +// LOGGER.log(Level.INFO,"status = " + instance.statusToString(status, true)); +// LOGGER.log(Level.INFO,"result = " + Arrays.toString(result)); + CRCLStatusType statusCopy = instance.exiToStatus(result); +// LOGGER.log(Level.INFO,"statusCopy = " + instance.statusToString(statusCopy, false)); +// LOGGER.log(Level.INFO,"status="+CRCLSocket.statToDebugString(status)); + assertEquals(status.getCommandStatus().getCommandID(), + statusCopy.getCommandStatus().getCommandID()); + assertEquals(status.getCommandStatus().getStatusID(), + statusCopy.getCommandStatus().getStatusID()); + assertTrue(status.getPose().getPoint().getX().subtract( + statusCopy.getPose().getPoint().getX()).abs().compareTo(BigDecimal.valueOf(1e-6)) < 0); + } + + private static final Logger LOGGER = Logger.getLogger(CRCLSocketTest.class.getName()); + + /** + * Test of commandToEXI method, of class CRCLSocket. + */ + @Test + public void testCommandToEXI() throws Exception { + LOGGER.log(Level.INFO, "commandToEXI"); + CRCLCommandInstanceType initCmdInstance = new CRCLCommandInstanceType(); + crcl.base.InitCanonType init = new InitCanonType(); + init.setCommandID(BigInteger.valueOf(100)); + initCmdInstance.setCRCLCommand(init); + CRCLSocket instance = new CRCLSocket(); + byte[] initBytes = instance.commandToEXI(initCmdInstance); +// LOGGER.log(Level.INFO,"result = " + Arrays.toString(result)); + CRCLCommandInstanceType returnCmd = instance.exiToCommand(initBytes); + assertEquals(initCmdInstance.getCRCLCommand().getCommandID(), + returnCmd.getCRCLCommand().getCommandID()); + CRCLCommandInstanceType getStatusCmdInstance = new CRCLCommandInstanceType(); + GetStatusType getStatus = new GetStatusType(); + getStatus.setCommandID(BigInteger.valueOf(101)); + getStatusCmdInstance.setCRCLCommand(getStatus); + byte[] getStatusBytes = instance.commandToEXI(getStatusCmdInstance); +// LOGGER.log(Level.INFO,"result = " + Arrays.toString(result)); + returnCmd = instance.exiToCommand(getStatusBytes); + assertEquals(getStatusCmdInstance.getCRCLCommand().getCommandID(), + returnCmd.getCRCLCommand().getCommandID()); + byte twocmdsArray[] = new byte[initBytes.length + getStatusBytes.length + 1]; + System.arraycopy(initBytes, 0, twocmdsArray, 0, initBytes.length); + System.arraycopy(getStatusBytes, 0, twocmdsArray, initBytes.length, getStatusBytes.length); + LOGGER.log(Level.INFO, "initBytes = " + Arrays.toString(initBytes)); + LOGGER.log(Level.INFO, "getStatusBytes = " + Arrays.toString(getStatusBytes)); + LOGGER.log(Level.INFO, "twocmdsArray = " + Arrays.toString(twocmdsArray)); + try (final InputStream inputStream = new ByteArrayInputStream(twocmdsArray)) { + returnCmd = instance.readCommandFromEXIStream(inputStream); + LOGGER.log(Level.INFO, "returnCmd = " + returnCmd); + CRCLCommandType c = returnCmd.getCRCLCommand(); + LOGGER.log(Level.INFO, "c = " + c); + assertEquals(init.getCommandID(), + returnCmd.getCRCLCommand().getCommandID()); + returnCmd = instance.readCommandFromEXIStream(inputStream); + LOGGER.log(Level.INFO, "returnCmd = " + returnCmd); + c = returnCmd.getCRCLCommand(); + LOGGER.log(Level.INFO, "c = " + c); + assertEquals(getStatus.getCommandID(), + returnCmd.getCRCLCommand().getCommandID()); + } + LOGGER.log(Level.INFO, ""); + LOGGER.log(Level.INFO, "Start socket over TCP tests"); +// byte partarryay[] = new byte[initBytes.length + getStatusBytes.length/2]; +// System.arraycopy(twocmdsArray, 0, partarryay, 0, partarryay.length); +// try (final InputStream inputStream = new ByteArrayInputStream(partarryay)) { +// returnCmd = instance.readCommandFromEXIStream(inputStream); +// LOGGER.log(Level.INFO,"returnCmd = " + returnCmd); +// CRCLCommandType c = returnCmd.getCRCLCommand(); +// LOGGER.log(Level.INFO,"c = " + c); +// assertEquals(init.getCommandID(), +// returnCmd.getCRCLCommand().getCommandID()); +// returnCmd = instance.readCommandFromEXIStream(inputStream); +// LOGGER.log(Level.INFO,"returnCmd = " + returnCmd); +// c = returnCmd.getCRCLCommand(); +// LOGGER.log(Level.INFO,"c = " + c); +// assertEquals(getStatus.getCommandID(), +// returnCmd.getCRCLCommand().getCommandID()); +// } + System.setProperty("crcl.prefixEXISizeEnabled", "false"); + ServerSocket ss = new ServerSocket(0); + ExecutorService serv = Executors.newWorkStealingPool(); + for (int i = 0; i < 10; i++) { + LOGGER.log(Level.INFO, "i = " + i); + Future f = serv.submit(() -> ss.accept()); + CRCLSocket csClient = new CRCLSocket("127.0.0.1", ss.getLocalPort()); + csClient.setPrefixEXISizeEnabled(false); + csClient.setEXIEnabled(true); + CRCLSocket csServer = new CRCLSocket(f.get()); + csServer.setEXIEnabled(true); + csServer.setPrefixEXISizeEnabled(false); + final CRCLCommandInstanceType initCmdInstanceF = initCmdInstance; + final CRCLCommandInstanceType getStatusCmdInstanceF = getStatusCmdInstance; + final int MAX_J = 2; + Runnable r = () -> { + Random rand = new Random(138); +// try { Thread.sleep(2000); } catch(Exception e) {}; + for (int j = 0; j < MAX_J; j++) { + try { + csClient.writeCommand(initCmdInstanceF, true); + csClient.writeCommand(getStatusCmdInstanceF, true); + if (rand.nextBoolean()) { + try { + Thread.sleep(rand.nextInt(50)); + } catch (Exception e) { + }; + } + LOGGER.log(Level.INFO, "j = " + j); + } catch (JAXBException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (EXIException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + }; +// new Thread(r).start(); + r.run(); + for (int j = 0; j < MAX_J; j++) { + LOGGER.log(Level.INFO, "i = " + i); + LOGGER.log(Level.INFO, "j = " + j); + csServer.setEXIEnabled(true); + LOGGER.log(Level.INFO, () -> "csServer.available() = " + csServer.available()); + returnCmd = csServer.readCommand(true); + LOGGER.log(Level.INFO, "returnCmd = " + returnCmd); + CRCLCommandType c = returnCmd.getCRCLCommand(); + LOGGER.log(Level.INFO, "c = " + c); + assertEquals(init.getCommandID(), + returnCmd.getCRCLCommand().getCommandID()); + LOGGER.log(Level.INFO, () -> "csServer.available() = " + csServer.available()); + returnCmd = csServer.readCommand(true); + LOGGER.log(Level.INFO, "returnCmd = " + returnCmd); + c = returnCmd.getCRCLCommand(); + LOGGER.log(Level.INFO, "c = " + c); + assertEquals(getStatus.getCommandID(), + returnCmd.getCRCLCommand().getCommandID()); + } + try { + csServer.close(); + } catch (Exception e) { + } + try { + csClient.close(); + } catch (Exception e) { + } + } + try { + ss.close(); + } catch (Exception e) { + } + try { + serv.shutdownNow(); + } catch (Exception e) { + } + try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + getStatusCmdInstance = new CRCLCommandInstanceType(); + getStatusCmdInstance.setCRCLCommand(init); + instance.writeEXICommandToStream(outputStream, getStatusCmdInstance); + getStatusCmdInstance = new CRCLCommandInstanceType(); + getStatusCmdInstance.setCRCLCommand(getStatus); + instance.writeEXICommandToStream(outputStream, getStatusCmdInstance); + byte ba[] = outputStream.toByteArray(); + LOGGER.log(Level.INFO, () -> "ba = " + Arrays.toString(ba)); + Assert.assertArrayEquals(ba, Arrays.copyOf(twocmdsArray, twocmdsArray.length - 1)); + } + } + + /** + * Test of stringToCommand method, of class CRCLSocket. + */ + @Test + public void testStringToCommand() throws Exception { + System.out.println("stringToCommand"); + String str = MOVETHROUGHTO_XML; + boolean validate = true; + CRCLSocket instance = new CRCLSocket(); + CRCLCommandInstanceType result = instance.stringToCommand(str, validate); + final CRCLCommandType c = result.getCRCLCommand(); + assertTrue(c != null && c instanceof MoveThroughToType); + final MoveThroughToType moveCommand = (MoveThroughToType) c; + assertEquals(new BigInteger("2"), c.getCommandID()); + assertEquals(new BigInteger("2"), moveCommand.getNumPositions()); + } + private static final String MOVETHROUGHTO_XML = "\n" + + "\n" + + " \n" + + " 2\n" + + " false\n" + + " \n" + + " \n" + + " 2.5 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 0.5 0 2\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + ""; + + /** + * Test of readCommandFromStream method, of class CRCLSocket. + */ + @Test + public void testReadCommandFromStream() throws Exception { + System.out.println("readCommandFromStream"); +// byte ba[] = new byte[MOVETHROUGHTO_XML.length()*2]; +// System.arraycopy(MOVETHROUGHTO_XML.getBytes(), 0, ba, 0, MOVETHROUGHTO_XML.length()); + //System.arraycopy(MOVETHROUGHTO_XML.getBytes(), 0, ba, MOVETHROUGHTO_XML.length(), MOVETHROUGHTO_XML.length()); + InputStream is = new ByteArrayInputStream(MOVETHROUGHTO_XML.getBytes()); + boolean validate = true; + CRCLSocket instance = new CRCLSocket(); + CRCLCommandInstanceType expResult = null; + CRCLCommandInstanceType result = instance.readCommandFromStream(is, validate); + final CRCLCommandType c = result.getCRCLCommand(); + assertTrue(c != null && c instanceof MoveThroughToType); + final MoveThroughToType moveCommand = (MoveThroughToType) c; + assertEquals(new BigInteger("2"), c.getCommandID()); + assertEquals(new BigInteger("2"), moveCommand.getNumPositions()); + } + + /** + * Test of stringToStatus method, of class CRCLSocket. + */ + @Test + public void testStringToStatus() throws Exception { + System.out.println("stringToStatus"); + String str = STATUS_XML; + boolean validate = true; + CRCLSocket instance = new CRCLSocket(); + CRCLStatusType result = instance.stringToStatus(str, validate); + assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); + assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); + } + private static final String STATUS_XML = "\n" + + "\n" + + "\n" + + " \n" + + " 1\n" + + " 1\n" + + " Working\n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 30.0\n" + + " 3.7\n" + + " \n" + + " \n" + + " 3\n" + + " 90.0\n" + + " 0.87\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1.5 1 1\n" + + " \n" + + " \n" + + " 1 0 0\n" + + " \n" + + " \n" + + " 0 0 -1\n" + + " \n" + + " \n" + + " \n" + + " jaws\n" + + " 0.44\n" + + " \n" + + "\n" + + ""; + + /** + * Test of readStatusFromStream method, of class CRCLSocket. + */ + @Test + public void testReadStatusFromStream() throws Exception { + System.out.println("readStatusFromStream"); + InputStream is = new ByteArrayInputStream(STATUS_XML.getBytes()); + boolean validate = false; + CRCLSocket instance = new CRCLSocket(); + CRCLStatusType result = instance.readStatusFromStream(is, validate); + assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); + assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); + } + + /** + * Test of readStatusFromStream method, of class CRCLSocket. + */ + @Test + public void testReadUntilEndTag() throws Exception { + System.out.println("readUntilEndTag"); + InputStream is = new ByteArrayInputStream(STATUS_XML.getBytes()); + boolean validate = false; + CRCLSocket instance = new CRCLSocket(); + String str = instance.readUntilEndTag("CRCLStatus",is); + CRCLStatusType result = instance.stringToStatus(str, validate); + assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); + assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); + is = new ByteArrayInputStream((STATUS_XML+STATUS_XML).getBytes()); + str = instance.readUntilEndTag("CRCLStatus",is); + result = instance.stringToStatus(str, validate); + assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); + assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); + str = instance.readUntilEndTag("CRCLStatus",is); + result = instance.stringToStatus(str, validate); + assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); + assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); + str = instance.readUntilEndTag("CRCLStatus", + new ByteArrayInputStream(" ".getBytes())); + assertEquals(str, ""); + str = instance.readUntilEndTag("CRCLStatus", + new ByteArrayInputStream(" ".getBytes())); + assertEquals(str, " "); + } + +} diff --git a/crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java b/crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java new file mode 100644 index 0000000..684266b --- /dev/null +++ b/crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java @@ -0,0 +1,206 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.utils; + +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Will Shackleford {@literal } + */ +public class CmdLineClientIT { + + public CmdLineClientIT() { + System.setProperty("java.awt.headless", "true"); + } + + /** + * Test of main method, of class CmdLineClient. + */ + @Test + public void testMain() { + try { + System.err.println(""); + System.err.flush(); + LOGGER.log(Level.INFO,""); + LOGGER.log(Level.INFO,"Begin CmdLineClientIT.testMain"); + LOGGER.log(Level.INFO,"user.dir=" + System.getProperty("user.dir")); + CmdLineClient.programSucceeded = false; + URL programURL = getClass().getResource("/main/programAll.xml"); + Path programPath = Paths.get(programURL.toURI()); + System.setProperty("crcljava.program", programPath.toString()); + System.setProperty("crcljava.port", "0"); + URL initPoseURL = getClass().getResource("/main/initPose.csv"); + Path initPosePath = Paths.get(initPoseURL.toURI()); + System.setProperty("crcljava.program", programPath.toString()); + System.setProperty("crcljava.port", "0"); + + System.setProperty("crcjava.SimServer.validateXML", "true");// validateXML + System.setProperty("crcjava.SimServer.sendStatusWithoutRequest", "false");// sendStatusWithoutRequest + System.setProperty("crcjava.SimServer.appendZero", "false");// appendZero + System.setProperty("crcjava.SimServer.randomPacket", "false");// randomPacket + System.setProperty("crcjava.SimServer.replaceState", "false");// replaceState + System.setProperty("crcjava.SimServer.debugMoveDone", "true");// debugMoveDone + System.setProperty("crcjava.SimServer.debugReadCommand", "true");// debugReadCommand + System.setProperty("crcjava.SimServer.replaceXmlHeader", "true");// replaceXmlHeader + System.setProperty("crcjava.SimServer.debugSendStatus", "true");// debugSendStatus + System.setProperty("crcjava.SimServer.exiSelected", "false");// exiSelected + + System.setProperty("crcjava.PendandClient.validateXML", "true");// validateXML + System.setProperty("crcjava.PendandClient.replaceState", "false");// validateXML + System.setProperty("crcjava.PendandClient.debugWaitForDone", "false");// debugWaitForDone + System.setProperty("crcjava.PendandClient.debugSendCommand", "true");// debugSendCommand + System.setProperty("crcjava.PendandClient.recordPose", "false");// recordPose + System.setProperty("crcjava.PendandClient.exiSelected", "false");// exiSelected + System.setProperty("crcjava.PendandClient.useReadStatusThreadSelected","false"); + System.setProperty("crcl.utils.SimServerInner.enableGetStatusIDCheck", "true"); +// System.setProperty("crcl.prefixEXISizeEnabled", "true"); + CmdLineSimServer.main(new String[]{ + "--delayMillis", "10", + "--jointSpeedMax", "1000.0", + "--initPose", initPosePath.toString(), + "--maxTransSpeed", "200.0", + "--maxTransAccel", "200.0" + }); + for (int i = 0; i < 2; i++) { + LOGGER.log(Level.INFO,"i = " + i); + CmdLineClient.main(new String[]{"--waitForDoneDelay", DELAY_STRING}); + if (!CmdLineClient.programSucceeded) { + LOGGER.log(Level.SEVERE, + "CmdLineSimServer.simServerInner.getStatus = " + + CmdLineSimServer.simServerInner.getStatusXmlString()); +// Thread.getAllStackTraces().entrySet().forEach((x) -> { +// System.err.println("Thread:" + x.getKey().getName()); +// Arrays.stream(x.getValue()).forEach((xx) -> { +// System.err.println("\t" + xx); +// }); +// System.err.println(""); +// }); + fail("Program did NOT succeed."); + } + } + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, null, ex); + fail("Exception thrown"); + } + if (null != CmdLineSimServer.simServerInner) { + CmdLineSimServer.simServerInner.closeServer(); + CmdLineSimServer.simServerInner = null; + } + LOGGER.log(Level.INFO,"End CmdLineClientIT.testMain"); + System.err.println(""); + System.out.flush(); + System.err.flush(); + LOGGER.log(Level.INFO,""); + } + private static final Logger LOGGER = Logger.getLogger(CmdLineClientIT.class.getName()); + + /** + * Test of main method, of class CmdLineClient. + */ + @Test + public void testMainEXI() { + try { + if (null != CmdLineSimServer.simServerInner) { + CmdLineSimServer.simServerInner.closeServer(); + CmdLineSimServer.simServerInner = null; + } + System.err.println(""); + System.err.flush(); + LOGGER.log(Level.INFO,""); + LOGGER.log(Level.INFO,"Begin CmdLineClientIT.testMainEXI"); + LOGGER.log(Level.INFO,"user.dir=" + System.getProperty("user.dir")); + CmdLineClient.programSucceeded = false; + URL programURL = getClass().getResource("/main/programAll.xml"); + Path programPath = Paths.get(programURL.toURI()); + System.setProperty("crcljava.program", programPath.toString()); + System.setProperty("crcljava.port", "0"); + URL initPoseURL = getClass().getResource("/main/initPose.csv"); + Path initPosePath = Paths.get(initPoseURL.toURI()); + System.setProperty("crcljava.program", programPath.toString()); + System.setProperty("crcljava.port", "0"); + + System.setProperty("crcjava.SimServer.validateXML", "false");// validateXML + System.setProperty("crcjava.SimServer.sendStatusWithoutRequest", "false");// sendStatusWithoutRequest + System.setProperty("crcjava.SimServer.appendZero", "false");// appendZero + System.setProperty("crcjava.SimServer.randomPacket", "false");// randomPacket + System.setProperty("crcjava.SimServer.replaceState", "false");// replaceState + System.setProperty("crcjava.SimServer.debugMoveDone", "true");// debugMoveDone + System.setProperty("crcjava.SimServer.debugReadCommand", "true");// debugReadCommand + System.setProperty("crcjava.SimServer.replaceXmlHeader", "false");// replaceXmlHeader + System.setProperty("crcjava.SimServer.debugSendStatus", "true");// debugSendStatus + System.setProperty("crcjava.SimServer.exiSelected", "true");// exiSelected + + System.setProperty("crcjava.PendandClient.validateXML", "false");// validateXML + System.setProperty("crcjava.PendandClient.replaceState", "false");// validateXML + System.setProperty("crcjava.PendandClient.debugWaitForDone", "false");// debugWaitForDone + System.setProperty("crcjava.PendandClient.debugSendCommand", "true");// debugSendCommand + System.setProperty("crcjava.PendandClient.recordPose", "false");// recordPose + System.setProperty("crcjava.PendandClient.exiSelected", "true");// exiSelected + System.setProperty("crcl.utils.SimServerInner.enableGetStatusIDCheck", "true"); + System.setProperty("crcl.prefixEXISizeEnabled", "false"); + System.setProperty("crcjava.PendandClient.useReadStatusThreadSelected","false"); + CmdLineSimServer.main(new String[]{ + "--delayMillis", "10", + "--jointSpeedMax", "1000.0", + "--initPose", initPosePath.toString(), + "--maxTransSpeed", "200.0", + "--maxTransAccel", "200.0" + }); + for (int i = 0; i < 2; i++) { + LOGGER.log(Level.INFO,"i = " + i); + CmdLineClient.main(new String[]{"--waitForDoneDelay", DELAY_STRING}); + if (!CmdLineClient.programSucceeded) { + System.err.println("CmdLineSimServer.simServerInner.getStatus = " + + CmdLineSimServer.simServerInner.getStatusXmlString()); +// Thread.getAllStackTraces().entrySet().forEach((x) -> { +// System.err.println("Thread:" + x.getKey().getName()); +// Arrays.stream(x.getValue()).forEach((xx) -> { +// System.err.println("\t" + xx); +// }); +// System.err.println(""); +// }); + fail("Program did NOT succeed."); + } + } + } catch (Exception ex) { + LOGGER.log(Level.SEVERE, null, ex); + fail("Exception thrown: " + ex); + } + if (null != CmdLineSimServer.simServerInner) { + CmdLineSimServer.simServerInner.closeServer(); + CmdLineSimServer.simServerInner = null; + } + LOGGER.log(Level.INFO,"End CmdLineClientIT.testMainEXI"); + System.err.println(""); + System.out.flush(); + System.err.flush(); + LOGGER.log(Level.INFO,""); + } + private static final String DELAY_STRING = "0"; + +} diff --git a/crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsPlausibleTest.java b/crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsPlausibleTest.java new file mode 100644 index 0000000..70179f4 --- /dev/null +++ b/crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsPlausibleTest.java @@ -0,0 +1,190 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * + */ +package crcl.utils; + +import crcl.base.PointType; +import crcl.base.PoseType; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Random; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Will Shackleford + */ +public class SimulatedKinematicsPlausibleTest { + + public SimulatedKinematicsPlausibleTest() { + } + + static SimulatedKinematicsPlausible sk = new SimulatedKinematicsPlausible(); + + private static final int RANDOM_SEED = 8321; + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of jointsToPose method, of class SimulatedKinematicsPlausible. + */ + @Test + public void testJointsToPose_doubleArr_doubleArr() { +// double jtest[] = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, +// SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); +// PoseType pose = sk.jointsToPose(jtest); +// double j2[] = sk.poseToJoints(null, pose); +// //System.err.println("j2 = " + Arrays.toString(j2)); +// //System.err.println("jtest = " + Arrays.toString(jtest)); +// assertArrayEquals(jtest, j2, 0.05); +// +// Random r = new Random(); +// for (int i = 0; i < 500; i++) { +// try { +// //System.err.println(""); +// //System.err.println("i = " + i); +// int index = r.nextInt(jtest.length - 2); +// //System.err.println("index = " + index); +// //System.err.println("jtest[index] = " + jtest[index]); +// jtest[index] += r.nextDouble() * 10.0 - 5.0; +// if (Math.abs(90 - jtest[1] - jtest[2] - jtest[3]) < 5.0) { +// jtest = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); +// continue; +// } +// //System.err.println("jtest[index] = " + jtest[index]); +// pose = sk.jointsToPose(jtest); +// j2 = sk.poseToJoints(j2, pose); +// //System.err.println("j2 = " + Arrays.toString(j2)); +// //System.err.println("jtest = " + Arrays.toString(jtest)); +// for(int ii= 0; ii < jtest.length; ii++) { +// if(Math.abs(jtest[ii]-j2[ii]) > 1.0) { +// try { +// System.err.println("pose="+CRCLToPosemath.poseToString(pose)); +// } catch (PmException ex) { +// Logger.getLogger(SimulatedKinematicsPlausibleTest.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.err.println("j2="+Arrays.toString(j2)); +// System.err.println("jtest="+Arrays.toString(jtest)); +// break; +// } +// } +// assertArrayEquals(jtest, j2, 1.0); +// } catch (IllegalArgumentException iae) { +// // ignore +// } +// } + } + + /** + * Test of printRot9x9 method, of class SimulatedKinematicsPlausible. + */ + @Test + public void testPrintRot9x9() { + } + + /** + * Test of rot9x9mult method, of class SimulatedKinematicsPlausible. + */ + @Test + public void testRot9x9mult() { + } + + /** + * Test of poseToJoints method, of class SimulatedKinematicsPlausible. + */ + @Test + public void testPoseToJoints() { + double jtest[] = Arrays.copyOf(SimulatedKinematicsPlausible.DEFAULT_JOINTVALS, + SimulatedKinematicsPlausible.DEFAULT_JOINTVALS.length); + PoseType pose = sk.jointsToPose(jtest); + + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 100; i++) { + try { + //System.err.println(""); + //System.err.println("i = " + i); + int index = r.nextInt(3); + //System.err.println("index = " + index); + PointType pt = pose.getPoint(); + switch (index) { + case 0: + //System.err.println("pt.getX().doubleValue() = " + pt.getX().doubleValue()); + pt.setX(pt.getX().add(BigDecimal.valueOf(r.nextDouble() * 20.0 - 10.0))); + //System.err.println("pt.getX().doubleValue() = " + pt.getX().doubleValue()); + pose.setPoint(pt); + break; + + case 1: + //System.err.println("pt.getY().doubleValue() = " + pt.getY().doubleValue()); + pt.setY(pt.getY().add(BigDecimal.valueOf(r.nextDouble() * 20.0 - 10.0))); + //System.err.println("pt.getY().doubleValue() = " + pt.getY().doubleValue()); + pose.setPoint(pt); + break; + + case 2: + //System.err.println("pt.getZ().doubleValue() = " + pt.getZ().doubleValue()); + pt.setZ(pt.getZ().add(BigDecimal.valueOf(r.nextDouble() * 20.0 - 10.0))); + //System.err.println("pt.getZ().doubleValue() = " + pt.getZ().doubleValue()); + pose.setPoint(pt); + break; + } + + jtest = sk.poseToJoints(jtest, pose); + //System.err.println("jtest = " + Arrays.toString(jtest)); + PoseType pose2 = sk.jointsToPose(jtest); + //System.err.println("jtest = " + Arrays.toString(jtest)); + double j2[] = sk.poseToJoints(null, pose2); + //System.err.println("jtest = " + Arrays.toString(jtest)); + //System.err.println("j2 = " + Arrays.toString(j2)); + + PointType pt1 = pose.getPoint(); + //System.err.printf("pt1 = (%+.3g,%+.3g,%+.3g)\n", +// pt1.getX().doubleValue(), +// pt1.getY().doubleValue(), +// pt1.getZ().doubleValue() +// ); + PointType pt2 = pose2.getPoint(); + //System.err.printf("pt2 = (%+.3g,%+.3g,%+.3g)\n", +// pt2.getX().doubleValue(), +// pt2.getY().doubleValue(), +// pt2.getZ().doubleValue() +// ); + assertArrayEquals(j2, jtest, 1.0); + assertEquals(pt1.getX().doubleValue(), pt2.getX().doubleValue(), 5.0); + assertEquals(pt1.getY().doubleValue(), pt2.getY().doubleValue(), 5.0); + assertEquals(pt1.getZ().doubleValue(), pt2.getZ().doubleValue(), 5.0); + } catch (IllegalArgumentException iae) { + // ignore + } + } + } + + /** + * Test of jointsToPose method, of class SimulatedKinematicsPlausible. + */ + @Test + public void testJointsToPose_3args() { + } + +} \ No newline at end of file diff --git a/crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsSimpleTest.java b/crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsSimpleTest.java new file mode 100644 index 0000000..331b28e --- /dev/null +++ b/crcl4java-utils/src/test/java/crcl/utils/SimulatedKinematicsSimpleTest.java @@ -0,0 +1,212 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * + */ +package crcl.utils; + +import crcl.base.PointType; +import crcl.base.PoseType; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; +import rcs.posemath.PmException; + +/** + * + * @author Will Shackleford + */ +public class SimulatedKinematicsSimpleTest { + + public SimulatedKinematicsSimpleTest() { + } + + static SimulatedKinematicsSimple sk = new SimulatedKinematicsSimple(); + + private static final int RANDOM_SEED = 7321; + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of jointsToPose method, of class SimulatedKinematicsSimple. + */ + @Test + public void testJointsToPose_doubleArr_doubleArr() { + double jtest[] = Arrays.copyOf(SimulatedKinematicsSimple.DEFAULT_JOINTVALS, + SimulatedKinematicsSimple.DEFAULT_JOINTVALS.length); + PoseType pose = sk.jointsToPose(jtest); + double j2[] = sk.poseToJoints(null, pose); + //System.err.println("j2 = " + Arrays.toString(j2)); + //System.err.println("jtest = " + Arrays.toString(jtest)); + for (int ii = 0; ii < jtest.length; ii++) { + if (Math.abs(jtest[ii] - j2[ii]) > 1.0) { + try { + System.err.println("pose=" + CRCLPosemath.poseToString(pose)); + } catch (PmException ex) { + Logger.getLogger(SimulatedKinematicsSimpleTest.class.getName()).log(Level.SEVERE, null, ex); + } + System.err.println("j2=" + Arrays.toString(j2)); + System.err.println("jtest=" + Arrays.toString(jtest)); + break; + } + } + assertArrayEquals(jtest, j2, 0.05); + + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 500; i++) { + try { + //System.err.println(""); + //System.err.println("i = " + i); + int index = r.nextInt(jtest.length - 2); + //System.err.println("index = " + index); + //System.err.println("jtest[index] = " + jtest[index]); + jtest[index] += r.nextDouble() * 10.0 - 5.0; + if (Math.abs(90 - jtest[1] - jtest[2] - jtest[3]) < 5.0) { + jtest = Arrays.copyOf(SimulatedKinematicsSimple.DEFAULT_JOINTVALS, + SimulatedKinematicsSimple.DEFAULT_JOINTVALS.length); + continue; + } + //System.err.println("jtest[index] = " + jtest[index]); + pose = sk.jointsToPose(jtest); + j2 = sk.poseToJoints(j2, pose); + //System.err.println("j2 = " + Arrays.toString(j2)); + //System.err.println("jtest = " + Arrays.toString(jtest)); + for (int ii = 0; ii < jtest.length; ii++) { + if (Math.abs(jtest[ii] - j2[ii]) > 1.0) { + try { + System.err.println("pose=" + CRCLPosemath.poseToString(pose)); + } catch (PmException ex) { + Logger.getLogger(SimulatedKinematicsSimpleTest.class.getName()).log(Level.SEVERE, null, ex); + } + System.err.println("j2=" + Arrays.toString(j2)); + System.err.println("jtest=" + Arrays.toString(jtest)); + break; + } + } + assertArrayEquals(jtest, j2, 1.0); + } catch (IllegalArgumentException iae) { + // ignore + } + } + } + + /** + * Test of printRot9x9 method, of class SimulatedKinematicsSimple. + */ + @Test + public void testPrintRot9x9() { + } + + /** + * Test of rot9x9mult method, of class SimulatedKinematicsSimple. + */ + @Test + public void testRot9x9mult() { + } + + /** + * Test of poseToJoints method, of class SimulatedKinematicsSimple. + */ + @Test + public void testPoseToJoints() { + double jtest[] = Arrays.copyOf(SimulatedKinematicsSimple.DEFAULT_JOINTVALS, + SimulatedKinematicsSimple.DEFAULT_JOINTVALS.length); + PoseType pose = sk.jointsToPose(jtest); + + Random r = new Random(RANDOM_SEED); + for (int i = 0; i < 100; i++) { + try { + //System.err.println(""); + //System.err.println("i = " + i); + int index = r.nextInt(3); + //System.err.println("index = " + index); + PointType pt = pose.getPoint(); + switch (index) { + case 0: + //System.err.println("pt.getX().doubleValue() = " + pt.getX().doubleValue()); + pt.setX(pt.getX().add(BigDecimal.valueOf(r.nextDouble() * 20.0 - 10.0))); + //System.err.println("pt.getX().doubleValue() = " + pt.getX().doubleValue()); + pose.setPoint(pt); + break; + + case 1: + //System.err.println("pt.getY().doubleValue() = " + pt.getY().doubleValue()); + pt.setY(pt.getY().add(BigDecimal.valueOf(r.nextDouble() * 20.0 - 10.0))); + //System.err.println("pt.getY().doubleValue() = " + pt.getY().doubleValue()); + pose.setPoint(pt); + break; + + case 2: + //System.err.println("pt.getZ().doubleValue() = " + pt.getZ().doubleValue()); + pt.setZ(pt.getZ().add(BigDecimal.valueOf(r.nextDouble() * 20.0 - 10.0))); + //System.err.println("pt.getZ().doubleValue() = " + pt.getZ().doubleValue()); + pose.setPoint(pt); + break; + } + + jtest = sk.poseToJoints(jtest, pose); + //System.err.println("jtest = " + Arrays.toString(jtest)); + PoseType pose2 = sk.jointsToPose(jtest); + //System.err.println("jtest = " + Arrays.toString(jtest)); + double j2[] = sk.poseToJoints(null, pose2); + //System.err.println("jtest = " + Arrays.toString(jtest)); + //System.err.println("j2 = " + Arrays.toString(j2)); + + PointType pt1 = pose.getPoint(); + //System.err.printf("pt1 = (%+.3g,%+.3g,%+.3g)\n", +// pt1.getX().doubleValue(), +// pt1.getY().doubleValue(), +// pt1.getZ().doubleValue() +// ); + PointType pt2 = pose2.getPoint(); + //System.err.printf("pt2 = (%+.3g,%+.3g,%+.3g)\n", +// pt2.getX().doubleValue(), +// pt2.getY().doubleValue(), +// pt2.getZ().doubleValue() +// ); + for (int ii = 0; ii < jtest.length; ii++) { + if (Math.abs(jtest[ii] - j2[ii]) > 1.0) { + try { + System.err.println("pose=" + CRCLPosemath.poseToString(pose)); + System.err.println("pose2=" + CRCLPosemath.poseToString(pose2)); + } catch (PmException ex) { + Logger.getLogger(SimulatedKinematicsSimpleTest.class.getName()).log(Level.SEVERE, null, ex); + } + System.err.println("j2=" + Arrays.toString(j2)); + System.err.println("jtest=" + Arrays.toString(jtest)); + break; + } + } + assertArrayEquals(j2, jtest, 1.0); + assertEquals(pt1.getX().doubleValue(), pt2.getX().doubleValue(), 5.0); + assertEquals(pt1.getY().doubleValue(), pt2.getY().doubleValue(), 5.0); + assertEquals(pt1.getZ().doubleValue(), pt2.getZ().doubleValue(), 5.0); + } catch (IllegalArgumentException iae) { + // ignore + } + } + } + +} diff --git a/crcl4java-utils/src/test/resources/logging.properties b/crcl4java-utils/src/test/resources/logging.properties new file mode 100644 index 0000000..be3dcc5 --- /dev/null +++ b/crcl4java-utils/src/test/resources/logging.properties @@ -0,0 +1,7 @@ +handlers = java.util.logging.ConsoleHandler +.level = INFO +java.util.logging.ConsoleHandler.level = ALL +java.util.logging.SimpleFormatter.format="%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %1$tQ ms %2$s%n%4$s: %5$s %6$s%n" +crcl.utils.level = ALL +javax.xml.bind.level = INFO +com.sun.xml.internal.bind.level = INFO \ No newline at end of file diff --git a/crcl4java-utils/src/test/resources/main/initPose.csv b/crcl4java-utils/src/test/resources/main/initPose.csv new file mode 100644 index 0000000..a323f26 --- /dev/null +++ b/crcl4java-utils/src/test/resources/main/initPose.csv @@ -0,0 +1,2 @@ +x,y,z,roll,pitch,yaw +8.2,1.0,0.5,180.0,0.0,0.0 \ No newline at end of file diff --git a/crcl4java-utils/src/test/resources/main/programAll.xml b/crcl4java-utils/src/test/resources/main/programAll.xml new file mode 100755 index 0000000..ace2409 --- /dev/null +++ b/crcl4java-utils/src/test/resources/main/programAll.xml @@ -0,0 +1,262 @@ + + + + + start + 1 + + + 2 + + 1 + 3.8 + + 3.7 + 11 + + + + 3 + 3.8 + + 7 + 13.0 + + + + + 3 + + + 4 + true + + 1 + true + false + false + + + 3 + true + true + false + + + + 5 + 2.5 + + + 6 + + + 7 + Hi Mom + + + + 8 + + 8.25 1 0.5 + + 6.10 + -3.14 + + + 9 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + true + + 0.9 + + + 0.5 + + + 0.005 + 0.01 + 0.015 + 1.0 + + + 2 + + + 12 + true + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 13 + + + 14 + GH$%kkk457 xxx 65 + + + 15 + degree + + + 16 + + rhabdaciousness + on + + + fluoxity + 33 + + + + 17 + 1.0 + + + 18 + + 0.005 + 0.01 + 0.015 + 1.0 + 1.0 + + + + 19 + ounce + + + 20 + + 0.1 + 0.05 + 0.06 + 1.0 + 1.0 + + + + 21 + meter + + + 22 + true + + + 23 + + empathy + 3.2 + + + air pressure + 701 + + + + 24 + + 4.08 + + + + 25 + + 0.77 + + + + 26 + + 6.28 + + + + 27 + + 0.55 + + + + 28 + newtonMeter + + + 29 + + 9.80 + + + + 30 + + 0.75 + + + + 31 + + 5.0 + + + + 32 + + 0.85 + + + + 33 + Normal + + + 34 + + diff --git a/crcl4java-utils/src/test/resources/main/programExample.xml b/crcl4java-utils/src/test/resources/main/programExample.xml new file mode 100755 index 0000000..4b0a65e --- /dev/null +++ b/crcl4java-utils/src/test/resources/main/programExample.xml @@ -0,0 +1,731 @@ + + + + 1 + + + 2 + meter + + + 3 + + 1.0 + + + + 4 + + 0.80 + + + + 5 + + 0.002 + 0.002 + 0.002 + + + + 6 + + 0.01 + 0.01 + 0.01 + + + + 7 + 0 + + + 8 + false + + + 1.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 1.5 1 0.0001 + + + 1 0 0 + + + 0 0 -1 + + + 2 + + + 9 + 1 + + + 10 + false + + + 1.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 0.5001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 11 + 0 + + + 12 + false + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.4 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 13 + + + 14 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 15 + + + 16 + false + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 1.1 1.8 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 1.1 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 17 + 1 + + + 18 + false + + + 5.659 1.1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 1.07 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 19 + 0 + + + 20 + false + + + 3.86 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 0.9 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 0.9 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 21 + 1 + + + 22 + false + + + 5.659 0.9 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 0.93 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 23 + 0 + + + 24 + false + + + 3.86 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 6.42 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 6.42 1 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 25 + 1 + + + 26 + false + + + 6.42 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 0.93 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 27 + 0 + + + 28 + false + + + 4.14 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 7.61 1.02 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 7.61 1.02 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 29 + 1 + + + 30 + false + + + 7.61 1.02 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 1.07 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 31 + 0 + + + 32 + false + + + 4.14 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 0.475 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 33 + + + 34 + false + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 35 + + + 36 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 0.5001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 37 + 1 + + + 38 + false + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 2.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 2.5 1 0.0001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 39 + 0 + + + 40 + false + + + 2.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 0.5 0 2 + + + 1 0 0 + + + 0 0 -1 + + + 2 + + + 41 + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8738089 --- /dev/null +++ b/pom.xml @@ -0,0 +1,125 @@ + + + 4.0.0 + com.github.wshackle + crcl4java + 1.0-SNAPSHOT + pom + + crcl4java-base + crcl4java-utils + + + + UTF-8 + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + + + Public Domain(US Government Work) + http://www.copyright.gov/title17/92chap1.html#105 + repo + + + + + wshackle + Will Shackleford + william.shackleford@nist.gov + https://github.com/wshackle + NIST + http://www.nist.gov + + developer + + America/New_York + + + + scm:git:git@github.com:usnistgov/crac.git + scm:git:git@github.com:usnistgov/crac.git + https://github.com/usnistgov/crac + HEAD + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + + -Xdiags:verbose + + + + + + + + + release + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + crcl4java + \ No newline at end of file From 69ff1739c9f35a09a52d05ddeab8f08215bd733a Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 10:42:15 -0400 Subject: [PATCH 03/14] add .travis.yml --- .travis.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b8ebfff --- /dev/null +++ b/.travis.yml @@ -0,0 +1,21 @@ +language: java + +sudo: required + +jdk: + - oraclejdk8 + +install: true + +script: + - sudo apt-get update && sudo apt-get install oracle-java8-installer + - java -version + +notifications: + email: + - william.shackleford@nist.gov + - wshackle@gmail.com + +# Change this to your needs +#script: ./configure && make && make check && cd rcsjava_maven/rcslib && mvn -version && mvn -e compile && mvn test && mvn verify + From f27949cecb3c34d79597f691f59fc10211b811e1 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 11:03:01 -0400 Subject: [PATCH 04/14] increase allowed dwell time --- crcl4java-base/pom.xml | 2 +- crcl4java-utils/pom.xml | 4 ++-- .../src/main/java/crcl/utils/PendantClientInner.java | 2 +- pom.xml | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crcl4java-base/pom.xml b/crcl4java-base/pom.xml index 9749eef..c3d327d 100644 --- a/crcl4java-base/pom.xml +++ b/crcl4java-base/pom.xml @@ -8,7 +8,7 @@ .. com.github.wshackle - CRCLJavaParent + crcl4java 1.0-SNAPSHOT diff --git a/crcl4java-utils/pom.xml b/crcl4java-utils/pom.xml index ae100f0..f0fa216 100644 --- a/crcl4java-utils/pom.xml +++ b/crcl4java-utils/pom.xml @@ -8,7 +8,7 @@ .. com.github.wshackle - CRCLJavaParent + crcl4java 1.0-SNAPSHOT @@ -24,7 +24,7 @@ com.github.wshackle - CRCLJavaBase + crcl4java-base 1.0-SNAPSHOT diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java index 459d09b..dc2bf3e 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java @@ -994,7 +994,7 @@ private boolean testMoveThroughToEffect(MoveThroughToType moveThroughTo) { private boolean testDwellEffect(DwellType dwell, long startTime) { long elapsed = System.currentTimeMillis() - startTime; long expected = (long) (dwell.getDwellTime().doubleValue() * 1000.0); - if (Math.abs(elapsed - expected) > 1500) { + if (Math.abs(elapsed - expected) > 3500) { outer.showMessage("Dwell expected to take " + expected + " ms but took " + elapsed + " ms."); return false; } diff --git a/pom.xml b/pom.xml index 8738089..cd754ac 100644 --- a/pom.xml +++ b/pom.xml @@ -41,9 +41,9 @@ - scm:git:git@github.com:usnistgov/crac.git - scm:git:git@github.com:usnistgov/crac.git - https://github.com/usnistgov/crac + https://github.com/wshackle/crcl4java.git + git@github.com:wshackle/crcl4java.git + https://github.com/wshackle/crcl4java HEAD From c81ed9a14d8d277fcb5c79c8c42d129a4e1a7b69 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 11:31:14 -0400 Subject: [PATCH 05/14] try new Travis-CI --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b8ebfff..d3d86c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,15 @@ language: java -sudo: required +sudo: false jdk: - oraclejdk8 install: true -script: - - sudo apt-get update && sudo apt-get install oracle-java8-installer - - java -version +#script: +# - sudo apt-get update && sudo apt-get install oracle-java8-installer + # - java -version notifications: email: From b7bc41f293fcb8f51b9130662d60106ab3a4d34d Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 13:22:29 -0400 Subject: [PATCH 06/14] back to old travis setup --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index d3d86c8..83d4f64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,16 @@ language: java -sudo: false +sudo: required jdk: - oraclejdk8 install: true -#script: -# - sudo apt-get update && sudo apt-get install oracle-java8-installer - # - java -version +script: + - sudo apt-get update && sudo apt-get install oracle-java8-installer + - java -version + - mvn test notifications: email: From d3c780cf2f228e71c31e553c789f6666d7a6a755 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 13:34:57 -0400 Subject: [PATCH 07/14] force -U maven option for travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 83d4f64..c660dab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ install: true script: - sudo apt-get update && sudo apt-get install oracle-java8-installer - java -version - - mvn test + - mvn -U test notifications: email: From b95e2cf0089199129bb373354fe29e9cb7980fd1 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 13:42:10 -0400 Subject: [PATCH 08/14] =?UTF-8?q?still=20trying=20to=20fix=20=E2=80=9Creso?= =?UTF-8?q?lution=20will=20not=20be=20reattempted=20until=20the=20update?= =?UTF-8?q?=20interval=20of=20=20has=20elapsed=E2=80=9D,=20failure=20on=20?= =?UTF-8?q?Travis-CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crcl4java-utils/pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crcl4java-utils/pom.xml b/crcl4java-utils/pom.xml index f0fa216..d7af2cd 100644 --- a/crcl4java-utils/pom.xml +++ b/crcl4java-utils/pom.xml @@ -62,6 +62,14 @@ ossrh https://oss.sonatype.org/content/repositories/snapshots + + true + always + + + true + always + From ca1a19593fe78033f38f3f83b91c885de27d7f01 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 13:53:00 -0400 Subject: [PATCH 09/14] switch dependency to 1.1 for poseListPlot3D --- crcl4java-utils/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crcl4java-utils/pom.xml b/crcl4java-utils/pom.xml index d7af2cd..2f11ba7 100644 --- a/crcl4java-utils/pom.xml +++ b/crcl4java-utils/pom.xml @@ -20,7 +20,7 @@ com.github.wshackle poseList3DPlot - 1.0-SNAPSHOT + 1.1-SNAPSHOT com.github.wshackle From c4bd2cab83b024ab98adf9ceb222bfe36419a334 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 1 Sep 2015 14:45:47 -0400 Subject: [PATCH 10/14] add Travis-CI tag --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ef526a..5e505a5 100644 --- a/README.md +++ b/README.md @@ -34,4 +34,7 @@ Contents The two subdirectories correspond to two artifacts. * crcl4java-base -- xjc autogenerated JAXB annotated classes corresponding to the CRCL schemas. - * crcl4java-utils -- class for sending and receiving CRCL classes over a TCP Socket, graphical user interfaces, Pose math conversions, robot simulation for testing. \ No newline at end of file + * crcl4java-utils -- class for sending and receiving CRCL classes over a TCP Socket, graphical user interfaces, Pose math conversions, robot simulation for testing. + + +[![Build Status](https://travis-ci.org/wshackle/crcl4java.svg?branch=master)](https://travis-ci.org/wshackle/crcl4java) From 9829131bb050d54df3e8b66f2cf75763f16ca70c Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Mon, 7 Sep 2015 17:24:17 -0400 Subject: [PATCH 11/14] Add python examples, add a couple of convenience functions to CRCLSocket --- .../src/main/java/crcl/utils/CRCLSocket.java | 8 ++ .../java/crcl/utils/CRCLSocketExample.java | 7 +- examples/python/jpype/crclclient.py | 77 +++++++++++++++++++ examples/python/jython/crclclient.py | 72 +++++++++++++++++ 4 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 examples/python/jpype/crclclient.py create mode 100644 examples/python/jython/crclclient.py diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java index ba46614..d27ccd5 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java @@ -1228,6 +1228,10 @@ public CRCLCommandInstanceType readCommandFromEXIStream(final InputStream inputS } } + public CRCLStatusType readStatus() throws JAXBException, IOException, EXIException { + return readStatus(false); + } + public CRCLStatusType readStatus(boolean validate) throws JAXBException, IOException, EXIException { if (this.isEXIEnabled()) { @@ -1406,6 +1410,10 @@ public String programToPrettyDocString(CRCLProgramType prog, boolean validate) t return this.lastProgramString; } + public void writeCommand(CRCLCommandInstanceType cmd) throws JAXBException, IOException, InterruptedException, EXIException { + writeCommand(cmd,false); + } + public synchronized void writeCommand(CRCLCommandInstanceType cmd, boolean validate) throws JAXBException, IOException, InterruptedException, EXIException { final CRCLCommandType cc = cmd.getCRCLCommand(); final boolean EXI = this.isEXIEnabled(); diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java index 7f96399..f6dc0b8 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java @@ -20,6 +20,7 @@ */ package crcl.utils; +import com.siemens.ct.exi.exceptions.EXIException; import crcl.base.CRCLCommandInstanceType; import crcl.base.CRCLStatusType; import crcl.base.CommandStatusType; @@ -31,11 +32,13 @@ import crcl.base.PointType; import crcl.base.PoseType; import crcl.base.VectorType; +import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import javax.xml.bind.JAXBException; /** * @@ -54,7 +57,7 @@ public static void main(String[] args) { InitCanonType init = new InitCanonType(); init.setCommandID(BigInteger.valueOf(7)); instance.setCRCLCommand(init); - s.writeCommand(instance,false); + s.writeCommand(instance); // Create and send MoveTo command. MoveToType moveTo = new MoveToType(); @@ -100,7 +103,7 @@ public static void main(String[] args) { List l = jst.getJointStatus(); System.out.println("Joints:"); l.forEach(js -> System.out.println("Num="+js.getJointNumber()+" Pos="+js.getJointPosition())); - } catch (Exception ex) { + } catch (IOException | JAXBException | InterruptedException | EXIException ex) { Logger.getLogger(CRCLSocketExample.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/examples/python/jpype/crclclient.py b/examples/python/jpype/crclclient.py new file mode 100644 index 0000000..e4f9e18 --- /dev/null +++ b/examples/python/jpype/crclclient.py @@ -0,0 +1,77 @@ +#!/usr/bin/python + +# CRCL Client Example using Java CRCL Library and JPype (http://jpype.sourceforge.net/) +# Run with: +# python crclclient.py + +from jpype import * + +startJVM("/usr/local/jdk1.8.0_60/jre/lib/i386/client/libjvm.so","-Djava.class.path=../../../crcl4java-utils/target/crcl4java-utils-1.0-SNAPSHOT-jar-with-dependencies.jar") +crcl = JPackage('crcl') +#CRCLSocket = JClass('crcl.utils.CRCLSocket') +BigInteger = JClass('java.math.BigInteger') +BigDecimal = JClass('java.math.BigDecimal') + +print "Connect" +s = crcl.utils.CRCLSocket(JString("localhost"), JInt(64444)) +instance = crcl.base.CRCLCommandInstanceType() + +## Create and send InitCanon command +print "Send InitCanon" +init = crcl.base.InitCanonType() +init.setCommandID(BigInteger.valueOf(7)) +instance.setCRCLCommand(init) +s.writeCommand(instance) + +## Create and send MoveTo command. +print "Send MoveTo" +moveTo = crcl.base.MoveToType() +moveTo.setCommandID(BigInteger.valueOf(8)) +pose = crcl.base.PoseType() +pt = crcl.base.PointType() +pt.setX(BigDecimal.valueOf(1.1)) +pt.setY(BigDecimal.valueOf(0.0)) +pt.setZ(BigDecimal.valueOf(0.1)) +pose.setPoint(pt) +xAxis = crcl.base.VectorType() +xAxis.setI(BigDecimal.ONE) +xAxis.setI(BigDecimal.ZERO) +xAxis.setI(BigDecimal.ZERO) +pose.setXAxis(xAxis) +zAxis = crcl.base.VectorType() +zAxis.setI(BigDecimal.ZERO) +zAxis.setI(BigDecimal.ZERO) +zAxis.setI(BigDecimal.ONE) +pose.setXAxis(zAxis) +moveTo.setEndPosition(pose) +moveTo.setMoveStraight(False) +s.writeCommand(instance) + + +### Create and send getStatus request. +print "Send GetStatus" +getStat = crcl.base.GetStatusType() +getStat.setCommandID(BigInteger.valueOf(9)) +instance.setCRCLCommand(getStat) +s.writeCommand(instance) + +### Read status from server +stat = s.readStatus() + + +### Print out the status details. +cmdStat = stat.getCommandStatus() +IDback = cmdStat.getCommandID() +print "Status:" +print("CommandID = " + IDback.toString()) +print("State = " + cmdStat.getCommandState().toString()) +pt = stat.getPose().getPoint() +print("pose = " + pt.getX().toString() + "," + pt.getY().toString() + "," + pt.getZ().toString()) +jst = stat.getJointStatuses() +l = jst.getJointStatus() +print "Joints:" +for i in range(0,l.size()): + js = l.get(i) + print("Num="+js.getJointNumber().toString()+" Pos="+js.getJointPosition().toString()) + +shutdownJVM() \ No newline at end of file diff --git a/examples/python/jython/crclclient.py b/examples/python/jython/crclclient.py new file mode 100644 index 0000000..2df431c --- /dev/null +++ b/examples/python/jython/crclclient.py @@ -0,0 +1,72 @@ +#!/usr/bin/jython + +# CRCL Client Example using Java CRCL Library and Jython (http://www.jython.org) +# Run with: +# env CLASSPATH=../../../crcl4java-utils/target/crcl4java-utils-1.0-SNAPSHOT-jar-with-dependencies.jar jython crclclient.py + +from crcl.base import * +from crcl.utils import CRCLSocket +from java.math import * +import java.lang.Boolean + +print "Connect" +s = CRCLSocket("localhost", 64444) +instance = CRCLCommandInstanceType() + +## Create and send InitCanon command +print "Send InitCanon" +init = InitCanonType() +init.setCommandID(BigInteger.valueOf(7)) +instance.setCRCLCommand(init) +s.writeCommand(instance) +# +## Create and send MoveTo command. +print "Send MoveTo" +moveTo = MoveToType() +moveTo.setCommandID(BigInteger.valueOf(8)) +pose = PoseType() +pt = PointType() +pt.setX(BigDecimal.valueOf(1.1)) +pt.setY(BigDecimal.valueOf(0.0)) +pt.setZ(BigDecimal.valueOf(0.1)) +pose.setPoint(pt) +xAxis = VectorType() +xAxis.setI(BigDecimal.ONE) +xAxis.setI(BigDecimal.ZERO) +xAxis.setI(BigDecimal.ZERO) +pose.setXAxis(xAxis) +zAxis = VectorType() +zAxis.setI(BigDecimal.ZERO) +zAxis.setI(BigDecimal.ZERO) +zAxis.setI(BigDecimal.ONE) +pose.setXAxis(zAxis) +moveTo.setEndPosition(pose) +moveTo.setMoveStraight(java.lang.Boolean.FALSE) +s.writeCommand(instance) + + +## Create and send getStatus request. +print "Send GetStatus" +getStat = GetStatusType() +getStat.setCommandID(BigInteger.valueOf(9)) +instance.setCRCLCommand(getStat) +s.writeCommand(instance) + +## Read status from server +stat = s.readStatus() + + +## Print out the status details. +cmdStat = stat.getCommandStatus() +IDback = cmdStat.getCommandID() +print "Status:" +print("CommandID = " + IDback.toString()) +print("State = " + cmdStat.getCommandState().toString()) +pt = stat.getPose().getPoint() +print("pose = " + pt.getX().toString() + "," + pt.getY().toString() + "," + pt.getZ().toString()) +jst = stat.getJointStatuses() +l = jst.getJointStatus() +print "Joints:" +for i in range(0,l.size()): + js = l.get(i) + print("Num="+js.getJointNumber().toString()+" Pos="+js.getJointPosition().toString()) \ No newline at end of file From 1361fb4a53ab016305530aac6263f73193f854f2 Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 8 Sep 2015 16:42:00 -0400 Subject: [PATCH 12/14] reorganizing so utils depends only on jdk7 --- .gitignore | 4 +- crcl4java-base/nb-configuration.xml | 1 + crcl4java-base/pom.xml | 6 +- crcl4java-ui/nbactions.xml | 17 + crcl4java-ui/pom.xml | 350 +++++++++ .../src/main/java/crcl/ui}/CmdLineClient.java | 3 +- .../main/java/crcl/ui}/CmdLineSimServer.java | 5 +- .../src/main/java/crcl/ui}/DefaultMain.java | 2 +- .../src/main/java/crcl/ui}/GripperJFrame.form | 0 .../src/main/java/crcl/ui}/GripperJFrame.java | 3 +- .../main/java/crcl/ui}/LauncherJFrame.form | 0 .../main/java/crcl/ui}/LauncherJFrame.java | 2 +- .../main/java/crcl/ui}/ListChooserJPanel.form | 0 .../main/java/crcl/ui}/ListChooserJPanel.java | 2 +- .../java/crcl/ui}/MultiLineStringJPanel.form | 0 .../java/crcl/ui}/MultiLineStringJPanel.java | 2 +- .../main/java/crcl/ui}/ObjTableJPanel.form | 0 .../main/java/crcl/ui}/ObjTableJPanel.java | 34 +- .../main/java/crcl/ui}/OverHeadJPanel.java | 7 +- .../src/main/java/crcl/ui}/PendantClient.form | 0 .../src/main/java/crcl/ui}/PendantClient.java | 15 +- .../java/crcl/ui}/PendantClientInner.java | 8 +- .../java/crcl/ui/PendantClientOuterStub.java | 213 +++++ .../src/main/java/crcl/ui/PerfTest.java | 186 +++++ .../main/java/crcl/ui}/SideViewJPanel.java | 7 +- .../src/main/java/crcl/ui}/SimServer.form | 13 +- .../src/main/java/crcl/ui}/SimServer.java | 48 +- .../main/java/crcl/ui}/SimServerInner.java | 9 +- .../main/java/crcl/ui}/XpathQueryJFrame.form | 0 .../main/java/crcl/ui}/XpathQueryJFrame.java | 19 +- .../test/java/crcl/ui}/CmdLineClientIT.java | 29 +- .../src/test/resources/logging.properties | 7 + .../src/test/resources/main/initPose.csv | 2 + .../src/test/resources/main/programAll.xml | 262 +++++++ .../test/resources/main/programExample.xml | 731 ++++++++++++++++++ crcl4java-utils/nb-configuration.xml | 1 + crcl4java-utils/pom.xml | 12 +- .../src/main/java/crcl/utils/CRCLSocket.java | 85 +- .../java/crcl/utils/CRCLSocketExample.java | 4 +- .../src/main/java/crcl/utils/Function.java | 31 + .../java/crcl/utils/PendantClientOuter.java | 1 + .../crcl/utils/PendantClientOuterStub.java | 5 + .../src/main/java/crcl/utils/PerfTest.java | 14 +- .../src/main/java/crcl/utils/Predicate.java | 31 + .../src/main/java/crcl/utils/XpathUtils.java | 33 +- .../test/java/crcl/utils/CRCLSocketTest.java | 81 +- examples/matlab/crclclient.m | 6 + pom.xml | 3 + 48 files changed, 2093 insertions(+), 201 deletions(-) create mode 100644 crcl4java-ui/nbactions.xml create mode 100644 crcl4java-ui/pom.xml rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/CmdLineClient.java (98%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/CmdLineSimServer.java (96%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/DefaultMain.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/GripperJFrame.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/GripperJFrame.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/LauncherJFrame.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/LauncherJFrame.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/ListChooserJPanel.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/ListChooserJPanel.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/MultiLineStringJPanel.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/MultiLineStringJPanel.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/ObjTableJPanel.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/ObjTableJPanel.java (98%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/OverHeadJPanel.java (97%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/PendantClient.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/PendantClient.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/PendantClientInner.java (97%) create mode 100644 crcl4java-ui/src/main/java/crcl/ui/PendantClientOuterStub.java create mode 100644 crcl4java-ui/src/main/java/crcl/ui/PerfTest.java rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/SideViewJPanel.java (96%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/SimServer.form (98%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/SimServer.java (97%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/SimServerInner.java (99%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/XpathQueryJFrame.form (100%) rename {crcl4java-utils/src/main/java/crcl/utils => crcl4java-ui/src/main/java/crcl/ui}/XpathQueryJFrame.java (94%) rename {crcl4java-utils/src/test/java/crcl/utils => crcl4java-ui/src/test/java/crcl/ui}/CmdLineClientIT.java (89%) create mode 100644 crcl4java-ui/src/test/resources/logging.properties create mode 100644 crcl4java-ui/src/test/resources/main/initPose.csv create mode 100755 crcl4java-ui/src/test/resources/main/programAll.xml create mode 100755 crcl4java-ui/src/test/resources/main/programExample.xml create mode 100644 crcl4java-utils/src/main/java/crcl/utils/Function.java create mode 100644 crcl4java-utils/src/main/java/crcl/utils/Predicate.java create mode 100644 examples/matlab/crclclient.m diff --git a/.gitignore b/.gitignore index 60a9ef8..ac11be0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,6 @@ hs_err_pid* /CRCLJavaBase/target/ /crcl4java-base/target/ /crcl4java-utils/target/ -/crcl4java-utils/nbproject/ \ No newline at end of file +/crcl4java-utils/nbproject/ +/crcl-ui/target/ +/crcl4java-ui/target/ \ No newline at end of file diff --git a/crcl4java-base/nb-configuration.xml b/crcl4java-base/nb-configuration.xml index 9723198..b4a5d7d 100644 --- a/crcl4java-base/nb-configuration.xml +++ b/crcl4java-base/nb-configuration.xml @@ -14,5 +14,6 @@ That way multiple projects can share the same settings (useful for formatting ru Any value defined here will override the pom.xml file value but is only applicable to the current project. --> ${project.basedir}/license-NIST.txt + JDK_1.7 diff --git a/crcl4java-base/pom.xml b/crcl4java-base/pom.xml index c3d327d..8e1ac48 100644 --- a/crcl4java-base/pom.xml +++ b/crcl4java-base/pom.xml @@ -21,8 +21,8 @@ UTF-8 - 1.8 - 1.8 + 1.7 + 1.7 UTF-8 UTF-8 https://raw.githubusercontent.com/ros-industrial/crcl/master/schemas/ @@ -35,6 +35,7 @@ + org.apache.maven.plugins maven-project-info-reports-plugin diff --git a/crcl4java-ui/nbactions.xml b/crcl4java-ui/nbactions.xml new file mode 100644 index 0000000..4b52f18 --- /dev/null +++ b/crcl4java-ui/nbactions.xml @@ -0,0 +1,17 @@ + + + + run + + jar + + + process-classes + org.codehaus.mojo:exec-maven-plugin:1.2.1:exec + + + -classpath %classpath crcl.ui.DefaultMain + java + + + diff --git a/crcl4java-ui/pom.xml b/crcl4java-ui/pom.xml new file mode 100644 index 0000000..39c9e22 --- /dev/null +++ b/crcl4java-ui/pom.xml @@ -0,0 +1,350 @@ + + + 4.0.0 + + .. + com.github.wshackle + crcl4java + 1.0-SNAPSHOT + + crcl4java-ui + jar + + 1.8 + 1.8 + crcl.ui.DefaultMain + UTF-8 + UTF-8 + + + + ${project.groupId} + crcl4java-base + ${project.version} + + + com.github.wshackle + rcslib + 2015.05.04.02 + + + com.github.wshackle + poseList3DPlot + 1.1-SNAPSHOT + + + junit + junit + 4.10 + test + + + org.apache.commons + commons-math3 + 3.5 + jar + + + commons-io + commons-io + 2.4 + jar + + + com.siemens.ct.exi + exificient + 0.9.4 + + + ${project.groupId} + crcl4java-utils + ${project.version} + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.8 + + + maven-failsafe-plugin + 2.18.1 + + + + integration-test + verify + + + + + + + src/test/resources/logging.properties + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.6 + + + + ${main.class} + + + + + + maven-assembly-plugin + 2.5.5 + + + + ${main.class} + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + codecoverage + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + + ${surefireArgLine} + + ${skip.unit.tests} + + + **/IT*.java + + + + src/test/resources/logging.properties + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.15 + + + + integration-tests + + integration-test + verify + + + + ${failsafeArgLine} + + ${skip.integration.tests} + + + src/test/resources/logging.properties + + + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.4.201502262128 + + + + prepare-agent + + + + report + prepare-package + + report + + + + + pre-unit-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + surefireArgLine + + + + + post-unit-test + test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-ut.exec + + ${project.reporting.outputDirectory}/jacoco-ut + + + + + pre-integration-test + pre-integration-test + + prepare-agent + + + + ${project.build.directory}/coverage-reports/jacoco-it.exec + + failsafeArgLine + + + + + post-integration-test + post-integration-test + + report + + + + ${project.build.directory}/coverage-reports/jacoco-it.exec + + ${project.reporting.outputDirectory}/jacoco-it + + + + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.3 + true + + ossrh + https://oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + crcl4java-ui + \ No newline at end of file diff --git a/crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java b/crcl4java-ui/src/main/java/crcl/ui/CmdLineClient.java similarity index 98% rename from crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java rename to crcl4java-ui/src/main/java/crcl/ui/CmdLineClient.java index 01c5bdd..68711a2 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/CmdLineClient.java +++ b/crcl4java-ui/src/main/java/crcl/ui/CmdLineClient.java @@ -17,8 +17,9 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; +import crcl.utils.PendantClientOuterStub; import java.io.File; import java.io.FileWriter; import java.io.IOException; diff --git a/crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java b/crcl4java-ui/src/main/java/crcl/ui/CmdLineSimServer.java similarity index 96% rename from crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java rename to crcl4java-ui/src/main/java/crcl/ui/CmdLineSimServer.java index 2b45080..f91e770 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/CmdLineSimServer.java +++ b/crcl4java-ui/src/main/java/crcl/ui/CmdLineSimServer.java @@ -16,8 +16,11 @@ * bear some notice that they are derived from it, and any modified * versions bear some notice that they have been modified. */ -package crcl.utils; +package crcl.ui; +import crcl.ui.SimServerInner; +import crcl.utils.CRCLPosemath; +import crcl.utils.SimServerOuterStub; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.ParserConfigurationException; diff --git a/crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java b/crcl4java-ui/src/main/java/crcl/ui/DefaultMain.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java rename to crcl4java-ui/src/main/java/crcl/ui/DefaultMain.java index 09c64b5..482bd72 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/DefaultMain.java +++ b/crcl4java-ui/src/main/java/crcl/ui/DefaultMain.java @@ -19,7 +19,7 @@ * See http://www.copyright.gov/title17/92chap1.html#105 * */ -package crcl.utils; +package crcl.ui; /** * diff --git a/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.form b/crcl4java-ui/src/main/java/crcl/ui/GripperJFrame.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.form rename to crcl4java-ui/src/main/java/crcl/ui/GripperJFrame.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java b/crcl4java-ui/src/main/java/crcl/ui/GripperJFrame.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java rename to crcl4java-ui/src/main/java/crcl/ui/GripperJFrame.java index 809884e..0028276 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/GripperJFrame.java +++ b/crcl4java-ui/src/main/java/crcl/ui/GripperJFrame.java @@ -17,7 +17,7 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; import com.siemens.ct.exi.exceptions.EXIException; @@ -32,6 +32,7 @@ import crcl.base.ParallelGripperStatusType; import crcl.base.ThreeFingerGripperStatusType; import crcl.base.VacuumGripperStatusType; +import crcl.utils.CRCLSocket; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.form b/crcl4java-ui/src/main/java/crcl/ui/LauncherJFrame.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.form rename to crcl4java-ui/src/main/java/crcl/ui/LauncherJFrame.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java b/crcl4java-ui/src/main/java/crcl/ui/LauncherJFrame.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java rename to crcl4java-ui/src/main/java/crcl/ui/LauncherJFrame.java index 3d43178..42b0f28 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/LauncherJFrame.java +++ b/crcl4java-ui/src/main/java/crcl/ui/LauncherJFrame.java @@ -18,7 +18,7 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; /** * diff --git a/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.form b/crcl4java-ui/src/main/java/crcl/ui/ListChooserJPanel.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.form rename to crcl4java-ui/src/main/java/crcl/ui/ListChooserJPanel.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java b/crcl4java-ui/src/main/java/crcl/ui/ListChooserJPanel.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java rename to crcl4java-ui/src/main/java/crcl/ui/ListChooserJPanel.java index c243671..75f240d 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/ListChooserJPanel.java +++ b/crcl4java-ui/src/main/java/crcl/ui/ListChooserJPanel.java @@ -19,7 +19,7 @@ * See http://www.copyright.gov/title17/92chap1.html#105 * */ -package crcl.utils; +package crcl.ui; import java.awt.Frame; import javax.swing.DefaultComboBoxModel; diff --git a/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.form b/crcl4java-ui/src/main/java/crcl/ui/MultiLineStringJPanel.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.form rename to crcl4java-ui/src/main/java/crcl/ui/MultiLineStringJPanel.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java b/crcl4java-ui/src/main/java/crcl/ui/MultiLineStringJPanel.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java rename to crcl4java-ui/src/main/java/crcl/ui/MultiLineStringJPanel.java index dad7c55..487e47a 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/MultiLineStringJPanel.java +++ b/crcl4java-ui/src/main/java/crcl/ui/MultiLineStringJPanel.java @@ -18,7 +18,7 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; import java.awt.Frame; import javax.swing.JDialog; diff --git a/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.form b/crcl4java-ui/src/main/java/crcl/ui/ObjTableJPanel.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.form rename to crcl4java-ui/src/main/java/crcl/ui/ObjTableJPanel.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java b/crcl4java-ui/src/main/java/crcl/ui/ObjTableJPanel.java similarity index 98% rename from crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java rename to crcl4java-ui/src/main/java/crcl/ui/ObjTableJPanel.java index 79720a4..75eceab 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/ObjTableJPanel.java +++ b/crcl4java-ui/src/main/java/crcl/ui/ObjTableJPanel.java @@ -18,10 +18,12 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; import crcl.base.CRCLCommandType; import crcl.base.CRCLStatusType; +import crcl.utils.CRCLSocket; +import crcl.utils.XpathUtils; import java.awt.Color; import java.awt.Component; import java.awt.Frame; @@ -423,7 +425,6 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole // } // // }; - private static String removeTypeParams(String type) { String typenoparams = type; int ltindex = typenoparams.indexOf("<"); @@ -965,7 +966,7 @@ public static T editObject(T _obj, Frame _owner, String _title, boolean _mod return editObjectPriv(dialog, _obj, xpu, isValid); } - public static T editObject(T _obj, XpathUtils xpu, java.util.function.Predicate isValid) { + public static T editObject(T _obj, XpathUtils xpu, Predicate isValid) { JDialog dialog = new JDialog(); dialog.setTitle(_obj.getClass().getCanonicalName()); dialog.setModal(true); @@ -1213,7 +1214,7 @@ private void jButtonOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIR static private List addClasses(String prefix, File dir, List classes) { File fa[] = dir.listFiles(); - if(fa == null) { + if (fa == null) { return classes; } for (File f : fa) { @@ -1237,7 +1238,7 @@ static private List addClasses(String prefix, File dir, List class } } catch (Exception ex) { Logger.getLogger(ObjTableJPanel.class - .getName()).log(Level.SEVERE, "clssNameToLookup="+clssNameToLookup); + .getName()).log(Level.SEVERE, "clssNameToLookup=" + clssNameToLookup); Logger.getLogger(ObjTableJPanel.class .getName()).log(Level.SEVERE, null, ex); } @@ -1252,8 +1253,10 @@ static public List getClasses() { List classes = new ArrayList<>(); try { for (String classpathEntry : System.getProperty("java.class.path").split(System.getProperty("path.separator"))) { -// System.out.println("classpathEntry = " + classpathEntry); - if (classpathEntry.endsWith(".jar") +// System.out.println("classpathEntry = " + classpathEntry); + if (classpathEntry.endsWith(".jar") + && !classpathEntry.contains("commons-io") + && !classpathEntry.contains("commons-math") && !classpathEntry.contains("xerces") && !classpathEntry.contains("exificient")) { JarInputStream is = null; @@ -1262,6 +1265,9 @@ static public List getClasses() { is = new JarInputStream(new FileInputStream(jar)); JarEntry entry; while ((entry = is.getNextJarEntry()) != null) { + if(!entry.getName().startsWith("crcl")) { + continue; + } if (entry.getName().endsWith(".class")) { name = entry.getName(); name = name.substring(0, name.length() - 6); @@ -1277,13 +1283,13 @@ static public List getClasses() { && !clss.isAnonymousClass() && !clss.isMemberClass()) { classes.add(clss); - + } } catch (ClassNotFoundException ex) { Logger.getLogger(ObjTableJPanel.class .getName()).log(Level.SEVERE, null, ex); } - + } } } catch (IOException ex) { @@ -1291,12 +1297,12 @@ static public List getClasses() { .getName()).log(Level.SEVERE, null, ex); } finally { try { - if(null != is) { + if (null != is) { is.close(); } } catch (IOException ex) { Logger.getLogger(ObjTableJPanel.class - .getName()).log(Level.SEVERE, null, ex); + .getName()).log(Level.SEVERE, "classpathEntry=" + classpathEntry, ex); } } } else { @@ -1305,10 +1311,10 @@ static public List getClasses() { } } } catch (Throwable t) { - System.err.println("name = "+ name); - System.err.println("jar = "+jar); + System.err.println("name = " + name); + System.err.println("jar = " + jar); Logger.getLogger(ObjTableJPanel.class - .getName()).log(Level.SEVERE, null, t); + .getName()).log(Level.SEVERE, null, t); } // classes.add(javax.xml.datatype.XMLGregorianCalendar.class); // classes.add(javax.xml.datatype.Duration.class); diff --git a/crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java b/crcl4java-ui/src/main/java/crcl/ui/OverHeadJPanel.java similarity index 97% rename from crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java rename to crcl4java-ui/src/main/java/crcl/ui/OverHeadJPanel.java index 6113c4d..a8164ef 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/OverHeadJPanel.java +++ b/crcl4java-ui/src/main/java/crcl/ui/OverHeadJPanel.java @@ -18,8 +18,13 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; +import crcl.utils.SimRobotEnum; +import static crcl.utils.SimRobotEnum.PLAUSIBLE; +import static crcl.utils.SimRobotEnum.SIMPLE; +import crcl.utils.SimulatedKinematicsPlausible; +import crcl.utils.SimulatedKinematicsSimple; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClient.form b/crcl4java-ui/src/main/java/crcl/ui/PendantClient.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/PendantClient.form rename to crcl4java-ui/src/main/java/crcl/ui/PendantClient.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClient.java b/crcl4java-ui/src/main/java/crcl/ui/PendantClient.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/PendantClient.java rename to crcl4java-ui/src/main/java/crcl/ui/PendantClient.java index 234382d..d36e6d3 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/PendantClient.java +++ b/crcl4java-ui/src/main/java/crcl/ui/PendantClient.java @@ -18,8 +18,9 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; +import static crcl.ui.ObjTableJPanel.getAssignableClasses; import crcl.base.ActuateJointType; import crcl.base.ActuateJointsType; import crcl.base.CRCLCommandInstanceType; @@ -37,9 +38,11 @@ import crcl.base.MoveToType; import crcl.base.PointType; import crcl.base.PoseType; -import crcl.base.PoseType; import crcl.base.VectorType; -import static crcl.utils.ObjTableJPanel.getAssignableClasses; +import crcl.utils.AnnotatedPose; +import crcl.utils.CRCLPosemath; +import crcl.utils.CRCLSocket; +import crcl.utils.PendantClientOuter; import diagapplet.plotter.PlotData; import diagapplet.plotter.plotterJFrame; import java.awt.Color; @@ -78,7 +81,6 @@ import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.table.DefaultTableModel; import javax.xml.bind.JAXBException; -import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathExpressionException; import org.xml.sax.SAXException; @@ -2836,6 +2838,11 @@ public void showLastProgramLineExecTimeMillisDists(long millis, double dist) { dtm.setValueAt(dist, row, 3); } } + + @Override + public boolean checkUserText(String text) { + return MultiLineStringJPanel.showText(text); + } } diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java b/crcl4java-ui/src/main/java/crcl/ui/PendantClientInner.java similarity index 97% rename from crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java rename to crcl4java-ui/src/main/java/crcl/ui/PendantClientInner.java index dc2bf3e..913ccb0 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/PendantClientInner.java +++ b/crcl4java-ui/src/main/java/crcl/ui/PendantClientInner.java @@ -17,7 +17,7 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; import com.siemens.ct.exi.exceptions.EXIException; import crcl.base.ActuateJointType; @@ -46,6 +46,12 @@ import crcl.base.SetIntermediatePoseToleranceType; import crcl.base.StopConditionEnumType; import crcl.base.StopMotionType; +import crcl.utils.AnnotatedPose; +import crcl.utils.CRCLPosemath; +import crcl.utils.CRCLSocket; +import crcl.utils.PendantClientOuter; +import crcl.utils.PoseToleranceChecker; +import crcl.utils.XpathUtils; import java.io.File; import java.io.FileWriter; import java.io.IOException; diff --git a/crcl4java-ui/src/main/java/crcl/ui/PendantClientOuterStub.java b/crcl4java-ui/src/main/java/crcl/ui/PendantClientOuterStub.java new file mode 100644 index 0000000..45f2fc2 --- /dev/null +++ b/crcl4java-ui/src/main/java/crcl/ui/PendantClientOuterStub.java @@ -0,0 +1,213 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + */ +package crcl.ui; + + +import crcl.base.CRCLProgramType; +import crcl.utils.CRCLSocket; +import crcl.utils.PendantClientOuter; +import java.io.File; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author Will Shackleford {@literal } + */ +public class PendantClientOuterStub implements PendantClientOuter{ + + @Override + public void showMessage(String s) { + final String sWithThread = "Thread:" + Thread.currentThread().getName()+" "+s; + Logger.getLogger(this.getClass().getName()).log(Level.FINE, sWithThread); + } + + @Override + public void showMessage(Throwable t) { + Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, t.toString()); + } + + @Override + public boolean showDebugMessage(String s) { + showMessage(s); + return false; + } + + private final boolean validateXml; + + @Override + public boolean validateXmlSelected() { + return this.validateXml; + } + + private final boolean replaceState; + + @Override + public boolean replaceStateSelected() { + return this.replaceState; + } + + private final String host; + + @Override + public String getHost() { + return this.host; + } + + private final int port; + @Override + public int getPort() { + return this.port; + } + + @Override + public void finishDisconnect() { + } + + @Override + public void finishConnect() { + } + + @Override + public void finishSetStatus() { + } + + @Override + public void checkXmlQuery(CRCLSocket crclSocket) { + } + + @Override + public void stopPollTimer() { + } + + @Override + public void checkPollSelected() { + } + + private final boolean debugWaitForDone; + + @Override + public boolean isDebugWaitForDoneSelected() { + return this.debugWaitForDone; + } + + private final boolean debugSendCommand; + + @Override + public boolean isDebugSendCommandSelected() { + return this.debugSendCommand; + } + + private final boolean debugReadStatus; + + @Override + public boolean isDebugReadStatusSelected() { + return this.debugReadStatus; + } + + + @Override + public void showCurrentProgramLine(int line) { + } + + @Override + public void finishOpenXmlProgramFile(File f, CRCLProgramType program) { + } + + @Override + public CRCLProgramType editProgram(CRCLProgramType program) { + return program; + } + + @Override + public void showLastProgramLineExecTimeMillisDists(long millis, double dist) { + } + + private final boolean recordPose; + @Override + public boolean isRecordPoseSelected() { + return this.recordPose; + } + + private static boolean prop(String propName, boolean defaultVal) { + return Boolean.valueOf(System.getProperty(propName,Boolean.toString(defaultVal))); + } + + public PendantClientOuterStub() { + this( + prop("crcjava.PendandClient.validateXML",false),// validateXML + prop("crcjava.PendandClient.replaceState",false),// validateXML + System.getProperty("crcljava.host","localhost"), //host + Integer.valueOf(System.getProperty("crcljava.port", + Integer.toString(CRCLSocket.DEFAULT_PORT))), //port + prop("crcjava.PendandClient.debugWaitForDone",false),// debugWaitForDone + prop("crcjava.PendandClient.debugSendCommand",false),// debugSendCommand + prop("crcjava.PendandClient.debugReadStatus",false),// debugReadStatus + prop("crcjava.PendandClient.recordPose",false),// recordPose + prop("crcjava.PendandClient.exiSelected",false),// exiSelected + prop("crcjava.PendandClient.useReadStatusThreadSelected",true)// exiSelected + ); + } + + public PendantClientOuterStub + ( + boolean validateXml, + boolean replaceState, + String host, + int port, + boolean debugWaitForDone, + boolean debugSendCommand, + boolean debugReadStatus, + boolean recordPose, + boolean exiSelected, + boolean useReadStatusThreadSelected) { + this.validateXml = validateXml; + this.replaceState = replaceState; + this.host = host; + this.port = port; + this.debugWaitForDone = debugWaitForDone; + this.debugSendCommand = debugSendCommand; + this.debugReadStatus = debugReadStatus; + this.recordPose = recordPose; + this.exiSelected = exiSelected; + this.useReadStatusThreadSelected = useReadStatusThreadSelected; + } + + + private final boolean exiSelected; + + @Override + public boolean isEXISelected() { + return this.exiSelected; + } + + private final boolean useReadStatusThreadSelected; + + @Override + public boolean isUseReadStatusThreadSelected() { + return this.useReadStatusThreadSelected; + } + + @Override + public boolean checkUserText(String text) { + return true; + } + +} diff --git a/crcl4java-ui/src/main/java/crcl/ui/PerfTest.java b/crcl4java-ui/src/main/java/crcl/ui/PerfTest.java new file mode 100644 index 0000000..699b182 --- /dev/null +++ b/crcl4java-ui/src/main/java/crcl/ui/PerfTest.java @@ -0,0 +1,186 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.ui; + +import com.siemens.ct.exi.exceptions.EXIException; +import crcl.base.CRCLCommandInstanceType; +import crcl.base.CRCLCommandType; +import crcl.base.CRCLStatusType; +import crcl.base.CommandStateEnumType; +import crcl.base.CommandStatusType; +import crcl.base.GetStatusType; +import crcl.base.GripperStatusType; +import crcl.base.JointStatusType; +import crcl.base.JointStatusesType; +import crcl.base.PointType; +import crcl.base.PoseType; +import crcl.base.VacuumGripperStatusType; +import crcl.base.VectorType; +import crcl.utils.CRCLSocket; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Arrays; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.xml.bind.JAXBException; + +/** + * + * @author Will Shackleford {@literal } + */ +public class PerfTest { + + private static CRCLStatusType createStatus() { + CRCLStatusType stat = new CRCLStatusType(); + CommandStatusType cst = new CommandStatusType(); + cst.setCommandID(BigInteger.ONE); + cst.setStatusID(BigInteger.ONE); + cst.setCommandState(CommandStateEnumType.WORKING); + stat.setCommandStatus(cst); + PoseType pose = new PoseType(); + PointType pt = new PointType(); + pt.setX(BigDecimal.ZERO); + pt.setY(BigDecimal.ONE); + pt.setZ(BigDecimal.TEN); + pose.setPoint(pt); + VectorType xAxis = new VectorType(); + xAxis.setI(BigDecimal.ONE); + xAxis.setJ(BigDecimal.ZERO); + xAxis.setK(BigDecimal.ZERO); + pose.setXAxis(xAxis); + VectorType zAxis = new VectorType(); + zAxis.setI(BigDecimal.ZERO); + zAxis.setJ(BigDecimal.ZERO); + zAxis.setK(BigDecimal.ONE); + pose.setZAxis(zAxis); + stat.setPose(pose); + GripperStatusType gst = new VacuumGripperStatusType(); + stat.setGripperStatus(gst); + JointStatusesType jst = new JointStatusesType(); + jst.getJointStatus().add(new JointStatusType()); + stat.setJointStatuses(jst); + return stat; + } + + public static void main(String[] args) { + runPerfTest(true); + runPerfTest(false); + } + + public static void runPerfTest(final boolean enableEXI) throws RuntimeException { + try { + CRCLSocket csTst = new CRCLSocket(); + csTst.setReplaceHeader(true); + CRCLStatusType stat0 = createStatus(); + String xmlS = csTst.statusToString(stat0, false); + System.out.println("Starting runPerfTest("+enableEXI+") ..."); + System.out.println("enableEXI = " + enableEXI); + System.out.println("xmlS = " + xmlS); + System.out.println("xmlS.length() = " + xmlS.length()); + byte ba[] = csTst.statusToEXI(stat0); + System.out.println("ba.length = " + ba.length); + System.out.println("ba = " + Arrays.toString(ba)); + ExecutorService exServ = Executors.newWorkStealingPool(); + try (ServerSocket ss = new ServerSocket(44004)) { + System.out.println("ss.getLocalPort() = " + ss.getLocalPort()); + exServ.execute(() -> { + while (!Thread.currentThread().isInterrupted() && !exServ.isShutdown()) { + try { + Socket s = ss.accept(); + final CRCLSocket cs = new CRCLSocket(s); + cs.setEXIEnabled(enableEXI); + final CRCLStatusType status = createStatus(); + exServ.execute(() -> { + try { + while (!Thread.currentThread().isInterrupted() && !exServ.isShutdown()) { + CRCLCommandInstanceType cmdInstance = cs.readCommand(false); + CRCLCommandType cmd = cmdInstance.getCRCLCommand(); +// System.out.println("cmd.getCommandID() = " + cmd.getCommandID()); + status.getCommandStatus().setCommandID(cmd.getCommandID()); + status.getCommandStatus().setStatusID(status.getCommandStatus().getStatusID().add(BigInteger.ONE)); + cs.writeStatus(status, false); + } + } catch (JAXBException | IOException | EXIException | InterruptedException ex) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } finally { + try { + cs.close(); + } catch (IOException ex) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + }); + } catch (IOException | EXIException ex) { + if(null != ss && !ss.isClosed()) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + }); + CRCLSocket cs = new CRCLSocket("localhost", ss.getLocalPort()); + cs.setEXIEnabled(enableEXI); + CRCLCommandInstanceType cmdInstance = new CRCLCommandInstanceType(); + GetStatusType getStatus = new GetStatusType(); + getStatus.setCommandID(BigInteger.ONE); + cmdInstance.setCRCLCommand(getStatus); + long start = System.currentTimeMillis(); + final long repeats = 10000; + long diff_max = 0; + for (int i = 0; i < repeats; i++) { + long t1 = System.currentTimeMillis(); + getStatus.setCommandID(getStatus.getCommandID().add(BigInteger.ONE)); +// System.out.println("getStatus.getCommandID() = " + getStatus.getCommandID()); + cs.writeCommand(cmdInstance, false); + CRCLStatusType stat = cs.readStatus(false); +// System.out.println("stat.getCommandStatus().getCommandID() = " + stat.getCommandStatus().getCommandID()); + if(stat.getCommandStatus().getCommandID().compareTo(getStatus.getCommandID()) != 0) { + throw new RuntimeException("Command ID doesn't match : " + +stat.getCommandStatus().getCommandID()+ " != "+ getStatus.getCommandID()); + } + long t2 = System.currentTimeMillis(); + long diff = t2 - t1; + if(diff > diff_max) { + diff_max = diff; + } + } + long end = System.currentTimeMillis(); + System.out.println("(end-start) = " + (end-start) + " ms"); + System.out.println("Average time = " + ((double)(end-start))/repeats + " ms"); + System.out.println("Max time = " + diff_max + " ms"); + exServ.shutdown(); + exServ.awaitTermination(5, TimeUnit.SECONDS); + exServ.shutdownNow(); + } + } catch (IOException | JAXBException | InterruptedException | EXIException ex) { + Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); + } finally { + System.out.println("End of runPerfTest("+enableEXI+")"); + System.out.println(""); + } + } +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java b/crcl4java-ui/src/main/java/crcl/ui/SideViewJPanel.java similarity index 96% rename from crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java rename to crcl4java-ui/src/main/java/crcl/ui/SideViewJPanel.java index 1d4cbaa..dda8b93 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/SideViewJPanel.java +++ b/crcl4java-ui/src/main/java/crcl/ui/SideViewJPanel.java @@ -18,8 +18,13 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; +import crcl.utils.SimRobotEnum; +import static crcl.utils.SimRobotEnum.PLAUSIBLE; +import static crcl.utils.SimRobotEnum.SIMPLE; +import crcl.utils.SimulatedKinematicsPlausible; +import crcl.utils.SimulatedKinematicsSimple; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServer.form b/crcl4java-ui/src/main/java/crcl/ui/SimServer.form similarity index 98% rename from crcl4java-utils/src/main/java/crcl/utils/SimServer.form rename to crcl4java-ui/src/main/java/crcl/ui/SimServer.form index 0459da1..c938455 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/SimServer.form +++ b/crcl4java-ui/src/main/java/crcl/ui/SimServer.form @@ -201,7 +201,7 @@ - + @@ -211,7 +211,7 @@ - + @@ -234,10 +234,7 @@ - - - - + @@ -247,7 +244,7 @@ - + @@ -611,4 +608,4 @@ - + \ No newline at end of file diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServer.java b/crcl4java-ui/src/main/java/crcl/ui/SimServer.java similarity index 97% rename from crcl4java-utils/src/main/java/crcl/utils/SimServer.java rename to crcl4java-ui/src/main/java/crcl/ui/SimServer.java index 51dc7b2..371b620 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/SimServer.java +++ b/crcl4java-ui/src/main/java/crcl/ui/SimServer.java @@ -18,7 +18,7 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; import com.siemens.ct.exi.exceptions.EXIException; import crcl.base.CRCLCommandInstanceType; @@ -29,6 +29,9 @@ import crcl.base.JointStatusesType; import crcl.base.LengthUnitEnumType; import crcl.base.PoseType; +import crcl.utils.CRCLSocket; +import crcl.utils.SimRobotEnum; +import crcl.utils.SimServerOuter; import java.io.File; import java.io.IOException; import java.math.BigInteger; @@ -109,9 +112,9 @@ private void initComponents() { jSplitPane1 = new javax.swing.JSplitPane(); jPanel1 = new javax.swing.JPanel(); - overHeadJPanel1 = new crcl.utils.OverHeadJPanel(); + overHeadJPanel1 = new crcl.ui.OverHeadJPanel(); jPanel2 = new javax.swing.JPanel(); - sideViewJPanel1 = new crcl.utils.SideViewJPanel(); + sideViewJPanel1 = new crcl.ui.SideViewJPanel(); jPanel3 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); jTextAreaErrors = new javax.swing.JTextArea(); @@ -171,7 +174,7 @@ private void initComponents() { overHeadJPanel1.setLayout(overHeadJPanel1Layout); overHeadJPanel1Layout.setHorizontalGroup( overHeadJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 279, Short.MAX_VALUE) + .addGap(0, 281, Short.MAX_VALUE) ); overHeadJPanel1Layout.setVerticalGroup( overHeadJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -183,13 +186,11 @@ private void initComponents() { jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Side View")); jPanel2.setLayout(new java.awt.BorderLayout()); - sideViewJPanel1.addComponentListener(formListener); - javax.swing.GroupLayout sideViewJPanel1Layout = new javax.swing.GroupLayout(sideViewJPanel1); sideViewJPanel1.setLayout(sideViewJPanel1Layout); sideViewJPanel1Layout.setHorizontalGroup( sideViewJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 279, Short.MAX_VALUE) + .addGap(0, 281, Short.MAX_VALUE) ); sideViewJPanel1Layout.setVerticalGroup( sideViewJPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -499,7 +500,7 @@ private void initComponents() { // Code for dispatching events from components to event handlers. - private class FormListener implements java.awt.event.ActionListener, java.awt.event.ComponentListener { + private class FormListener implements java.awt.event.ActionListener { FormListener() {} public void actionPerformed(java.awt.event.ActionEvent evt) { if (evt.getSource() == jTextFieldPort) { @@ -533,21 +534,6 @@ else if (evt.getSource() == jCheckBoxMenuItemEXI) { SimServer.this.jCheckBoxMenuItemEXIActionPerformed(evt); } } - - public void componentHidden(java.awt.event.ComponentEvent evt) { - } - - public void componentMoved(java.awt.event.ComponentEvent evt) { - } - - public void componentResized(java.awt.event.ComponentEvent evt) { - if (evt.getSource() == sideViewJPanel1) { - SimServer.this.sideViewJPanel1ComponentResized(evt); - } - } - - public void componentShown(java.awt.event.ComponentEvent evt) { - } }// //GEN-END:initComponents private void jTextFieldPortActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jTextFieldPortActionPerformed @@ -714,6 +700,7 @@ public void run() { } }//GEN-LAST:event_jCheckBoxMenuItemIncludeGripperStatusActionPerformed + private void setRobotType(SimRobotEnum robotType) { this.inner.setRobotType(robotType); this.overHeadJPanel1.setJointvals(inner.getJointPositions()); @@ -817,8 +804,15 @@ public void updateCycleCount(int _newCycleCount) { this.jTextFieldCycleCount.setText(Integer.toString(_newCycleCount)); } - private Predicate checkStatusValidPredicate - = this::checkStatusValid; + + private final Predicate checkStatusValidPredicate = new Predicate() { + @Override + public boolean test(CRCLStatusType t) { + return checkStatusValid(t); + } + }; + +// = this::checkStatusValid; public boolean checkStatusValid(CRCLStatusType statusObj) { try { @@ -1023,8 +1017,8 @@ public void run() { private javax.swing.JTextField jTextFieldEndEffector; private javax.swing.JTextField jTextFieldNumWaypoints; private javax.swing.JTextField jTextFieldPort; - private crcl.utils.OverHeadJPanel overHeadJPanel1; - private crcl.utils.SideViewJPanel sideViewJPanel1; + private crcl.ui.OverHeadJPanel overHeadJPanel1; + private crcl.ui.SideViewJPanel sideViewJPanel1; // End of variables declaration//GEN-END:variables @Override diff --git a/crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java b/crcl4java-ui/src/main/java/crcl/ui/SimServerInner.java similarity index 99% rename from crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java rename to crcl4java-ui/src/main/java/crcl/ui/SimServerInner.java index 2b383bf..0e19c54 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/SimServerInner.java +++ b/crcl4java-ui/src/main/java/crcl/ui/SimServerInner.java @@ -17,7 +17,7 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; import com.siemens.ct.exi.exceptions.EXIException; import crcl.base.ActuateJointType; @@ -71,6 +71,13 @@ import crcl.base.TransSpeedAbsoluteType; import crcl.base.TransSpeedRelativeType; import crcl.base.TransSpeedType; +import crcl.utils.CRCLSocket; +import crcl.utils.PoseToleranceChecker; +import crcl.utils.SimRobotEnum; +import crcl.utils.SimServerOuter; +import crcl.utils.SimulatedKinematicsPlausible; +import crcl.utils.SimulatedKinematicsSimple; +import crcl.utils.XpathUtils; import java.io.File; import java.io.IOException; import java.math.BigDecimal; diff --git a/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.form b/crcl4java-ui/src/main/java/crcl/ui/XpathQueryJFrame.form similarity index 100% rename from crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.form rename to crcl4java-ui/src/main/java/crcl/ui/XpathQueryJFrame.form diff --git a/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java b/crcl4java-ui/src/main/java/crcl/ui/XpathQueryJFrame.java similarity index 94% rename from crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java rename to crcl4java-ui/src/main/java/crcl/ui/XpathQueryJFrame.java index 2816c49..992ef0a 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/XpathQueryJFrame.java +++ b/crcl4java-ui/src/main/java/crcl/ui/XpathQueryJFrame.java @@ -18,28 +18,13 @@ * versions bear some notice that they have been modified. * */ -package crcl.utils; +package crcl.ui; -import java.io.ByteArrayInputStream; -import java.io.StringWriter; +import crcl.utils.XpathUtils; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; /** * diff --git a/crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java b/crcl4java-ui/src/test/java/crcl/ui/CmdLineClientIT.java similarity index 89% rename from crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java rename to crcl4java-ui/src/test/java/crcl/ui/CmdLineClientIT.java index 684266b..0e8d083 100644 --- a/crcl4java-utils/src/test/java/crcl/utils/CmdLineClientIT.java +++ b/crcl4java-ui/src/test/java/crcl/ui/CmdLineClientIT.java @@ -1,30 +1,17 @@ /* - * This software is public domain software, however it is preferred - * that the following disclaimers be attached. - * Software Copywrite/Warranty Disclaimer - * - * This software was developed at the National Institute of Standards and - * Technology by employees of the Federal Government in the course of their - * official duties. Pursuant to title 17 Section 105 of the United States - * Code this software is not subject to copyright protection and is in the - * public domain. NIST Real-Time Control System software is an experimental - * system. NIST assumes no responsibility whatsoever for its use by other - * parties, and makes no guarantees, expressed or implied, about its - * quality, reliability, or any other characteristic. We would appreciate - * acknowledgement if the software is used. This software can be - * redistributed and/or modified freely provided that any derivative works - * bear some notice that they are derived from it, and any modified - * versions bear some notice that they have been modified. - * + * 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 crcl.utils; +package crcl.ui; +import java.net.URISyntaxException; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.logging.Level; import java.util.logging.Logger; - +import javax.xml.bind.JAXBException; import org.junit.Test; import static org.junit.Assert.*; @@ -103,7 +90,7 @@ public void testMain() { fail("Program did NOT succeed."); } } - } catch (Exception ex) { + } catch (URISyntaxException | JAXBException ex) { LOGGER.log(Level.SEVERE, null, ex); fail("Exception thrown"); } @@ -187,7 +174,7 @@ public void testMainEXI() { fail("Program did NOT succeed."); } } - } catch (Exception ex) { + } catch (URISyntaxException | JAXBException ex) { LOGGER.log(Level.SEVERE, null, ex); fail("Exception thrown: " + ex); } diff --git a/crcl4java-ui/src/test/resources/logging.properties b/crcl4java-ui/src/test/resources/logging.properties new file mode 100644 index 0000000..be3dcc5 --- /dev/null +++ b/crcl4java-ui/src/test/resources/logging.properties @@ -0,0 +1,7 @@ +handlers = java.util.logging.ConsoleHandler +.level = INFO +java.util.logging.ConsoleHandler.level = ALL +java.util.logging.SimpleFormatter.format="%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %1$tQ ms %2$s%n%4$s: %5$s %6$s%n" +crcl.utils.level = ALL +javax.xml.bind.level = INFO +com.sun.xml.internal.bind.level = INFO \ No newline at end of file diff --git a/crcl4java-ui/src/test/resources/main/initPose.csv b/crcl4java-ui/src/test/resources/main/initPose.csv new file mode 100644 index 0000000..a323f26 --- /dev/null +++ b/crcl4java-ui/src/test/resources/main/initPose.csv @@ -0,0 +1,2 @@ +x,y,z,roll,pitch,yaw +8.2,1.0,0.5,180.0,0.0,0.0 \ No newline at end of file diff --git a/crcl4java-ui/src/test/resources/main/programAll.xml b/crcl4java-ui/src/test/resources/main/programAll.xml new file mode 100755 index 0000000..ace2409 --- /dev/null +++ b/crcl4java-ui/src/test/resources/main/programAll.xml @@ -0,0 +1,262 @@ + + + + + start + 1 + + + 2 + + 1 + 3.8 + + 3.7 + 11 + + + + 3 + 3.8 + + 7 + 13.0 + + + + + 3 + + + 4 + true + + 1 + true + false + false + + + 3 + true + true + false + + + + 5 + 2.5 + + + 6 + + + 7 + Hi Mom + + + + 8 + + 8.25 1 0.5 + + 6.10 + -3.14 + + + 9 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + true + + 0.9 + + + 0.5 + + + 0.005 + 0.01 + 0.015 + 1.0 + + + 2 + + + 12 + true + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 13 + + + 14 + GH$%kkk457 xxx 65 + + + 15 + degree + + + 16 + + rhabdaciousness + on + + + fluoxity + 33 + + + + 17 + 1.0 + + + 18 + + 0.005 + 0.01 + 0.015 + 1.0 + 1.0 + + + + 19 + ounce + + + 20 + + 0.1 + 0.05 + 0.06 + 1.0 + 1.0 + + + + 21 + meter + + + 22 + true + + + 23 + + empathy + 3.2 + + + air pressure + 701 + + + + 24 + + 4.08 + + + + 25 + + 0.77 + + + + 26 + + 6.28 + + + + 27 + + 0.55 + + + + 28 + newtonMeter + + + 29 + + 9.80 + + + + 30 + + 0.75 + + + + 31 + + 5.0 + + + + 32 + + 0.85 + + + + 33 + Normal + + + 34 + + diff --git a/crcl4java-ui/src/test/resources/main/programExample.xml b/crcl4java-ui/src/test/resources/main/programExample.xml new file mode 100755 index 0000000..4b0a65e --- /dev/null +++ b/crcl4java-ui/src/test/resources/main/programExample.xml @@ -0,0 +1,731 @@ + + + + 1 + + + 2 + meter + + + 3 + + 1.0 + + + + 4 + + 0.80 + + + + 5 + + 0.002 + 0.002 + 0.002 + + + + 6 + + 0.01 + 0.01 + 0.01 + + + + 7 + 0 + + + 8 + false + + + 1.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 1.5 1 0.0001 + + + 1 0 0 + + + 0 0 -1 + + + 2 + + + 9 + 1 + + + 10 + false + + + 1.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 0.5001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 11 + 0 + + + 12 + false + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.4 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 13 + + + 14 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 15 + + + 16 + false + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 1.1 1.8 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 1.1 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 17 + 1 + + + 18 + false + + + 5.659 1.1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 1.07 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 19 + 0 + + + 20 + false + + + 3.86 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 0.9 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 5.659 0.9 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 21 + 1 + + + 22 + false + + + 5.659 0.9 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 3.86 0.93 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 23 + 0 + + + 24 + false + + + 3.86 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 6.42 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 6.42 1 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 25 + 1 + + + 26 + false + + + 6.42 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 0.93 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 27 + 0 + + + 28 + false + + + 4.14 0.93 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 7.61 1.02 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 7.61 1.02 0.1501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 29 + 1 + + + 30 + false + + + 7.61 1.02 0.5 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4.14 1.07 0.6501 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 31 + 0 + + + 32 + false + + + 4.14 1.07 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.75 1 0.475 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 33 + + + 34 + false + + + 8.75 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 8.25 1 0.5 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 35 + + + 36 + false + + + 8.25 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 4 1 0.5001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 37 + 1 + + + 38 + false + + + 4 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 2.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 2.5 1 0.0001 + + + 1 0 0 + + + 0 0 -1 + + + 3 + + + 39 + 0 + + + 40 + false + + + 2.5 1 1 + + + 1 0 0 + + + 0 0 -1 + + + + + 0.5 0 2 + + + 1 0 0 + + + 0 0 -1 + + + 2 + + + 41 + + diff --git a/crcl4java-utils/nb-configuration.xml b/crcl4java-utils/nb-configuration.xml index 9723198..b4a5d7d 100644 --- a/crcl4java-utils/nb-configuration.xml +++ b/crcl4java-utils/nb-configuration.xml @@ -14,5 +14,6 @@ That way multiple projects can share the same settings (useful for formatting ru Any value defined here will override the pom.xml file value but is only applicable to the current project. --> ${project.basedir}/license-NIST.txt + JDK_1.7 diff --git a/crcl4java-utils/pom.xml b/crcl4java-utils/pom.xml index 2f11ba7..555c37b 100644 --- a/crcl4java-utils/pom.xml +++ b/crcl4java-utils/pom.xml @@ -52,9 +52,9 @@ - 1.8 - 1.8 - crcl.utils.DefaultMain + 1.7 + 1.7 + UTF-8 UTF-8 @@ -112,7 +112,7 @@ - + maven-assembly-plugin 2.5.5 - ${main.class} + diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java index d27ccd5..7b205ee 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocket.java @@ -39,7 +39,6 @@ import crcl.base.PointType; import crcl.base.PoseType; import crcl.base.VectorType; -import java.awt.Component; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -65,15 +64,11 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.Random; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.function.UnaryOperator; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; -import java.util.stream.Collectors; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; @@ -96,7 +91,7 @@ */ public class CRCLSocket implements AutoCloseable { - CRCLSocket() { + public CRCLSocket() { this(null); } @@ -129,6 +124,11 @@ private static String addCRCLToStatePriv(String in) { .replaceAll("Ready", "CRCL_Ready"); } + static public interface UnaryOperator { + + public T apply(T t); + } + static final public UnaryOperator addCRCLToState = new UnaryOperator() { @Override @@ -342,6 +342,11 @@ public Schema getStatSchema() { return statSchema; } + static interface Supplier { + + public T get(); + } + /** * Set the value of statSchema * @@ -361,15 +366,19 @@ public CRCLSocket(Socket sock) { Marshaller tmp_m_prog = null; Unmarshaller tmp_u_prog = null; try { - Supplier jc = () -> { - try { - JAXBContext jc2 = JAXBContext.newInstance("crcl.base"); - return jc2; - } catch (JAXBException ex) { - LOGGER.log(Level.SEVERE, null, ex); + Supplier jc = new Supplier() { + @Override + public JAXBContext get() { + try { + JAXBContext jc2 = JAXBContext.newInstance("crcl.base"); + return jc2; + } catch (JAXBException ex) { +// LOGGER.log(Level.SEVERE, null, ex); + throw new RuntimeException(ex); + } } - return null; }; + tmp_u_cmd = jc.get().createUnmarshaller(); tmp_m_cmd = jc.get().createMarshaller(); // tmp_m_cmd.setProperty(Marshaller.JAXB_FRAGMENT, jaxbFragment); @@ -442,12 +451,12 @@ protected void finalize() throws Throwable { private final Marshaller m_stat; private final Unmarshaller u_stat; - static JointStatusType getJointStatus(CRCLStatusType _status, int i) { + public static JointStatusType getJointStatus(CRCLStatusType _status, int i) { BigInteger bi = BigInteger.valueOf(i); return getJointStatus(_status, bi); } - static JointStatusType getJointStatus(CRCLStatusType _status, BigInteger bi) { + public static JointStatusType getJointStatus(CRCLStatusType _status, BigInteger bi) { if (null == _status) { return null; } @@ -488,8 +497,7 @@ public String readUntilEndTag(final String tag, final InputStream is) throws IOE Level lvl = rips.length() > 0 ? Level.SEVERE : Level.FINE; final int brF = bytes_read; final String ripsF = rips; - LOGGER.log(lvl, - () -> "CRCLSocket.readUntilEndTag(" + tag + "): read returned " + brF + " before end of tag was found. str = " + ripsF); + LOGGER.log(lvl,"CRCLSocket.readUntilEndTag(" + tag + "): read returned " + brF + " before end of tag was found. str = " + ripsF); throw new SocketException("socket closed after read returned:" + bytes_read); } if (ba1[0] == 0) { @@ -525,7 +533,7 @@ public String readUntilEndTag(final String tag, final InputStream is) throws IOE final String threadName = Thread.currentThread().getName(); final String skipped_str_f = skipped_str; LOGGER.log(Level.FINER, - () -> "readUntilEndTag(" + tag + ") called with skipped_str=\"" + skipped_str_f + "\" from Thread: " + threadName); + "readUntilEndTag(" + tag + ") called with skipped_str=\"" + skipped_str_f + "\" from Thread: " + threadName); return str; } @@ -572,8 +580,7 @@ public synchronized CRCLCommandInstanceType readCommand(boolean validate) throws final CRCLCommandInstanceType c = this.readCommandFromEXIStream(getBufferedInputStream()); final CRCLCommandType cc = c.getCRCLCommand(); final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; - LOGGER.log(loglevel, - () -> "readCommand() returning " + cc + " ID=" + cc.getCommandID() + " called from Thread: " + threadName); + LOGGER.log(loglevel,"readCommand() returning " + cc + " ID=" + cc.getCommandID() + " called from Thread: " + threadName); return c; } else { byte sizeba[] = new byte[4]; @@ -592,7 +599,7 @@ public synchronized CRCLCommandInstanceType readCommand(boolean validate) throws final CRCLCommandType cc = c.getCRCLCommand(); final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; LOGGER.log(loglevel, - () -> "readCommand() returning " + cc + "readCommand() returning " + cc + " ID=" + cc.getCommandID() + " called from Thread: " + threadName); return c; @@ -607,7 +614,7 @@ public synchronized CRCLCommandInstanceType readCommand(boolean validate) throws final CRCLCommandType cc = cmd.getCRCLCommand(); final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; LOGGER.log(loglevel, - () -> "readCommand() returning " + cc + " ID=" + cc.getCommandID() + "str=" + str + " called from Thread: " + threadName); + "readCommand() returning " + cc + " ID=" + cc.getCommandID() + "str=" + str + " called from Thread: " + threadName); this.lastCommandString = str; return cmd; } @@ -806,10 +813,20 @@ private static String jointStatusToDebugString(final JointStatusType j) { } private static String jointStatusListToDebugString(final List l) { - return l == null ? "null" : l.toString() + " { " - + l.stream() - .map(CRCLSocket::jointStatusToDebugString) - .collect(Collectors.joining(",")) + " } "; +// return l == null ? "null" : l.toString() + " { " +// + l.stream() +// .map(CRCLSocket::jointStatusToDebugString) +// .collect(Collectors.joining(",")) + " } "; + StringBuilder sb = new StringBuilder(); + Iterator it = l.iterator(); + while(it.hasNext()) { + JointStatusType jst = it.next(); + sb.append(CRCLSocket.jointStatusToDebugString(jst)); + if(it.hasNext()) { + sb.append(','); + } + } + return sb.toString(); } private static String jointStatusesToDebugString(final JointStatusesType j) { @@ -1231,7 +1248,7 @@ public CRCLCommandInstanceType readCommandFromEXIStream(final InputStream inputS public CRCLStatusType readStatus() throws JAXBException, IOException, EXIException { return readStatus(false); } - + public CRCLStatusType readStatus(boolean validate) throws JAXBException, IOException, EXIException { if (this.isEXIEnabled()) { @@ -1411,22 +1428,22 @@ public String programToPrettyDocString(CRCLProgramType prog, boolean validate) t } public void writeCommand(CRCLCommandInstanceType cmd) throws JAXBException, IOException, InterruptedException, EXIException { - writeCommand(cmd,false); + writeCommand(cmd, false); } - + public synchronized void writeCommand(CRCLCommandInstanceType cmd, boolean validate) throws JAXBException, IOException, InterruptedException, EXIException { final CRCLCommandType cc = cmd.getCRCLCommand(); final boolean EXI = this.isEXIEnabled(); final String threadName = Thread.currentThread().getName(); final Level loglevel = (cc instanceof GetStatusType) ? Level.FINER : Level.FINE; LOGGER.log(loglevel, - () -> "writeCommand(" + cc + " ID=" + cc.getCommandID() + ") with EXI = " + EXI + " called from Thread: " + threadName); + "writeCommand(" + cc + " ID=" + cc.getCommandID() + ") with EXI = " + EXI + " called from Thread: " + threadName); if (this.isEXIEnabled()) { if (!this.isPrefixEXISizeEnabled()) { this.writeEXICommandToStream(sock.getOutputStream(), cmd); } else { final byte ba[] = this.commandToEXI(cmd); - LOGGER.log(loglevel, () -> "writeCommand() : ba = " + Arrays.toString(ba)); + LOGGER.log(loglevel,"writeCommand() : ba = " + Arrays.toString(ba)); ByteBuffer bb = ByteBuffer.allocate(ba.length + 4); bb.putInt(ba.length); // LOGGER.log(Level.FINEST,() ->"writeCommand: ba.length = " + ba.length); @@ -1442,7 +1459,7 @@ public synchronized void writeCommand(CRCLCommandInstanceType cmd, boolean valid } final String str = commandToString(cmd, validate); LOGGER.log(loglevel, - () -> "writeCommand(" + cc + " ID=" + cc.getCommandID() + ") with str = " + str + " called from Thread: " + threadName); + "writeCommand(" + cc + " ID=" + cc.getCommandID() + ") with str = " + str + " called from Thread: " + threadName); writeWithFill(str); this.lastCommandString = str; } @@ -1602,7 +1619,7 @@ public String statusToPrettyString(CRCLStatusType status, boolean validate) thro static { File startFile = new File(System.getProperty("user.home")); - crclSchemaDirFile = new File(startFile, String.join(File.separator, "crclXmlSchemas")); + crclSchemaDirFile = new File(startFile, "crclXmlSchemas"); } public static File[] findSchemaFiles() { diff --git a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java index f6dc0b8..724e587 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java +++ b/crcl4java-utils/src/main/java/crcl/utils/CRCLSocketExample.java @@ -102,7 +102,9 @@ public static void main(String[] args) { JointStatusesType jst = stat.getJointStatuses(); List l = jst.getJointStatus(); System.out.println("Joints:"); - l.forEach(js -> System.out.println("Num="+js.getJointNumber()+" Pos="+js.getJointPosition())); + for(JointStatusType js : l) { + System.out.println("Num="+js.getJointNumber()+" Pos="+js.getJointPosition()); + } } catch (IOException | JAXBException | InterruptedException | EXIException ex) { Logger.getLogger(CRCLSocketExample.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/crcl4java-utils/src/main/java/crcl/utils/Function.java b/crcl4java-utils/src/main/java/crcl/utils/Function.java new file mode 100644 index 0000000..92d813d --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/Function.java @@ -0,0 +1,31 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +/** + * + * @author Will Shackleford {@literal } + */ +public interface Function { + + public RETURNTYPE apply(ARGTYPE t); +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java index 5837e45..d7bf21a 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuter.java @@ -51,4 +51,5 @@ public interface PendantClientOuter { public boolean isRecordPoseSelected(); public boolean isEXISelected(); public boolean isUseReadStatusThreadSelected(); + public boolean checkUserText(String text); } diff --git a/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java index 9339977..ec5dd80 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java +++ b/crcl4java-utils/src/main/java/crcl/utils/PendantClientOuterStub.java @@ -202,5 +202,10 @@ public boolean isEXISelected() { public boolean isUseReadStatusThreadSelected() { return this.useReadStatusThreadSelected; } + + @Override + public boolean checkUserText(String text) { + return true; + } } diff --git a/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java b/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java index 84b2de0..96201fa 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java +++ b/crcl4java-utils/src/main/java/crcl/utils/PerfTest.java @@ -104,17 +104,23 @@ public static void runPerfTest(final boolean enableEXI) throws RuntimeException byte ba[] = csTst.statusToEXI(stat0); System.out.println("ba.length = " + ba.length); System.out.println("ba = " + Arrays.toString(ba)); - ExecutorService exServ = Executors.newWorkStealingPool(); + final ExecutorService exServ = Executors.newCachedThreadPool(); try (ServerSocket ss = new ServerSocket(44004)) { System.out.println("ss.getLocalPort() = " + ss.getLocalPort()); - exServ.execute(() -> { + exServ.execute(new Runnable(){ + + @Override + public void run() { while (!Thread.currentThread().isInterrupted() && !exServ.isShutdown()) { try { Socket s = ss.accept(); final CRCLSocket cs = new CRCLSocket(s); cs.setEXIEnabled(enableEXI); final CRCLStatusType status = createStatus(); - exServ.execute(() -> { + exServ.execute(new Runnable() { + + @Override + public void run() { try { while (!Thread.currentThread().isInterrupted() && !exServ.isShutdown()) { CRCLCommandInstanceType cmdInstance = cs.readCommand(false); @@ -133,6 +139,7 @@ public static void runPerfTest(final boolean enableEXI) throws RuntimeException Logger.getLogger(PerfTest.class.getName()).log(Level.SEVERE, null, ex); } } + } }); } catch (IOException | EXIException ex) { if(null != ss && !ss.isClosed()) { @@ -140,6 +147,7 @@ public static void runPerfTest(final boolean enableEXI) throws RuntimeException } } } + } }); CRCLSocket cs = new CRCLSocket("localhost", ss.getLocalPort()); cs.setEXIEnabled(enableEXI); diff --git a/crcl4java-utils/src/main/java/crcl/utils/Predicate.java b/crcl4java-utils/src/main/java/crcl/utils/Predicate.java new file mode 100644 index 0000000..c113581 --- /dev/null +++ b/crcl4java-utils/src/main/java/crcl/utils/Predicate.java @@ -0,0 +1,31 @@ +/* + * This software is public domain software, however it is preferred + * that the following disclaimers be attached. + * Software Copywrite/Warranty Disclaimer + * + * This software was developed at the National Institute of Standards and + * Technology by employees of the Federal Government in the course of their + * official duties. Pursuant to title 17 Section 105 of the United States + * Code this software is not subject to copyright protection and is in the + * public domain. NIST Real-Time Control System software is an experimental + * system. NIST assumes no responsibility whatsoever for its use by other + * parties, and makes no guarantees, expressed or implied, about its + * quality, reliability, or any other characteristic. We would appreciate + * acknowledgement if the software is used. This software can be + * redistributed and/or modified freely provided that any derivative works + * bear some notice that they are derived from it, and any modified + * versions bear some notice that they have been modified. + * + * See http://www.copyright.gov/title17/92chap1.html#105 + * + */ +package crcl.utils; + +/** + * + * @author Will Shackleford {@literal } + */ +public interface Predicate { + + public boolean test(T t); +} diff --git a/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java b/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java index a2ce1c9..18953a2 100644 --- a/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java +++ b/crcl4java-utils/src/main/java/crcl/utils/XpathUtils.java @@ -47,18 +47,18 @@ * @author Will Shackleford{@literal } */ public class XpathUtils { - + final TransformerFactory transformerFactory; final DocumentBuilderFactory documentBuilderFactory; final DocumentBuilder documentBuilder; - - XpathUtils() throws ParserConfigurationException { + + public XpathUtils() throws ParserConfigurationException { transformerFactory = TransformerFactory.newInstance(); documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilder = documentBuilderFactory.newDocumentBuilder(); } - - private File[] schemaFiles = null; + + private File[] schemaFiles = null; /** * Get the value of schemaFiles @@ -79,11 +79,10 @@ public void setSchemaFiles(File[] schemaFiles) { } public String getDocumentation(String name) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { - return queryXml(schemaFiles, "/schema/complexType[@name=\""+name+"\"]/annotation/documentation/text()"); + return queryXml(schemaFiles, "/schema/complexType[@name=\"" + name + "\"]/annotation/documentation/text()"); } - - final - public String nodeToString(Node node) { + + final public String nodeToString(Node node) { StringWriter sw = new StringWriter(); try { Transformer t = transformerFactory.newTransformer(); @@ -96,7 +95,7 @@ public String nodeToString(Node node) { return sw.toString(); } - public String queryXml(File xsdFile, String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + public String queryXml(File xsdFile, String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { Document doc = documentBuilder.parse(xsdFile); final XPathFactory xPathfactory = XPathFactory.newInstance(); final XPath xpath = xPathfactory.newXPath(); @@ -104,15 +103,15 @@ public String queryXml(File xsdFile, String query) throws SAXException, IOExcep return nodeListToString(nl); } - public String queryXml(File fa[], String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + public String queryXml(File fa[], String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { StringBuilder sb = new StringBuilder(); - for(File f : fa) { + for (File f : fa) { sb.append(queryXml(f, query)); } return sb.toString(); } - - public String nodeListToString(NodeList nl) { + + public String nodeListToString(NodeList nl) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < nl.getLength(); i++) { Node n = nl.item(i); @@ -121,13 +120,13 @@ public String nodeListToString(NodeList nl) { } return sb.toString(); } - - public String queryXmlString(String string, String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { + + public String queryXmlString(String string, String query) throws SAXException, IOException, XPathExpressionException, ParserConfigurationException { Document doc = documentBuilder.parse(new ByteArrayInputStream(string.getBytes())); final XPathFactory xPathfactory = XPathFactory.newInstance(); final XPath xpath = xPathfactory.newXPath(); NodeList nl = (NodeList) xpath.evaluate(query, doc, XPathConstants.NODESET); return nodeListToString(nl); } - + } diff --git a/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java b/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java index 0966d1e..c96234a 100644 --- a/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java +++ b/crcl4java-utils/src/test/java/crcl/utils/CRCLSocketTest.java @@ -45,6 +45,7 @@ import java.util.Arrays; import java.util.List; import java.util.Random; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -179,12 +180,18 @@ public void testCommandToEXI() throws Exception { // returnCmd.getCRCLCommand().getCommandID()); // } System.setProperty("crcl.prefixEXISizeEnabled", "false"); - ServerSocket ss = new ServerSocket(0); - ExecutorService serv = Executors.newWorkStealingPool(); + final ServerSocket ss = new ServerSocket(0); + ExecutorService serv = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { LOGGER.log(Level.INFO, "i = " + i); - Future f = serv.submit(() -> ss.accept()); - CRCLSocket csClient = new CRCLSocket("127.0.0.1", ss.getLocalPort()); + Future f = serv.submit(new Callable() { + + @Override + public Socket call() throws Exception { + return ss.accept(); + } + }); + final CRCLSocket csClient = new CRCLSocket("127.0.0.1", ss.getLocalPort()); csClient.setPrefixEXISizeEnabled(false); csClient.setEXIEnabled(true); CRCLSocket csServer = new CRCLSocket(f.get()); @@ -193,28 +200,32 @@ public void testCommandToEXI() throws Exception { final CRCLCommandInstanceType initCmdInstanceF = initCmdInstance; final CRCLCommandInstanceType getStatusCmdInstanceF = getStatusCmdInstance; final int MAX_J = 2; - Runnable r = () -> { - Random rand = new Random(138); + Runnable r = new Runnable() { + + @Override + public void run() { + Random rand = new Random(138); // try { Thread.sleep(2000); } catch(Exception e) {}; - for (int j = 0; j < MAX_J; j++) { - try { - csClient.writeCommand(initCmdInstanceF, true); - csClient.writeCommand(getStatusCmdInstanceF, true); - if (rand.nextBoolean()) { - try { - Thread.sleep(rand.nextInt(50)); - } catch (Exception e) { - }; + for (int j = 0; j < MAX_J; j++) { + try { + csClient.writeCommand(initCmdInstanceF, true); + csClient.writeCommand(getStatusCmdInstanceF, true); + if (rand.nextBoolean()) { + try { + Thread.sleep(rand.nextInt(50)); + } catch (Exception e) { + }; + } + LOGGER.log(Level.INFO, "j = " + j); + } catch (JAXBException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (IOException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (EXIException ex) { + Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); } - LOGGER.log(Level.INFO, "j = " + j); - } catch (JAXBException ex) { - Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); - } catch (IOException ex) { - Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); - } catch (InterruptedException ex) { - Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); - } catch (EXIException ex) { - Logger.getLogger(CRCLSocketTest.class.getName()).log(Level.SEVERE, null, ex); } } }; @@ -224,14 +235,14 @@ public void testCommandToEXI() throws Exception { LOGGER.log(Level.INFO, "i = " + i); LOGGER.log(Level.INFO, "j = " + j); csServer.setEXIEnabled(true); - LOGGER.log(Level.INFO, () -> "csServer.available() = " + csServer.available()); + LOGGER.log(Level.INFO, "csServer.available() = " + csServer.available()); returnCmd = csServer.readCommand(true); LOGGER.log(Level.INFO, "returnCmd = " + returnCmd); CRCLCommandType c = returnCmd.getCRCLCommand(); LOGGER.log(Level.INFO, "c = " + c); assertEquals(init.getCommandID(), returnCmd.getCRCLCommand().getCommandID()); - LOGGER.log(Level.INFO, () -> "csServer.available() = " + csServer.available()); + LOGGER.log(Level.INFO, "csServer.available() = " + csServer.available()); returnCmd = csServer.readCommand(true); LOGGER.log(Level.INFO, "returnCmd = " + returnCmd); c = returnCmd.getCRCLCommand(); @@ -264,7 +275,7 @@ public void testCommandToEXI() throws Exception { getStatusCmdInstance.setCRCLCommand(getStatus); instance.writeEXICommandToStream(outputStream, getStatusCmdInstance); byte ba[] = outputStream.toByteArray(); - LOGGER.log(Level.INFO, () -> "ba = " + Arrays.toString(ba)); + LOGGER.log(Level.INFO,"ba = " + Arrays.toString(ba)); Assert.assertArrayEquals(ba, Arrays.copyOf(twocmdsArray, twocmdsArray.length - 1)); } } @@ -338,7 +349,7 @@ public void testReadCommandFromStream() throws Exception { assertEquals(new BigInteger("2"), c.getCommandID()); assertEquals(new BigInteger("2"), moveCommand.getNumPositions()); } - + /** * Test of stringToStatus method, of class CRCLSocket. */ @@ -415,25 +426,25 @@ public void testReadUntilEndTag() throws Exception { InputStream is = new ByteArrayInputStream(STATUS_XML.getBytes()); boolean validate = false; CRCLSocket instance = new CRCLSocket(); - String str = instance.readUntilEndTag("CRCLStatus",is); + String str = instance.readUntilEndTag("CRCLStatus", is); CRCLStatusType result = instance.stringToStatus(str, validate); assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); - is = new ByteArrayInputStream((STATUS_XML+STATUS_XML).getBytes()); - str = instance.readUntilEndTag("CRCLStatus",is); + is = new ByteArrayInputStream((STATUS_XML + STATUS_XML).getBytes()); + str = instance.readUntilEndTag("CRCLStatus", is); result = instance.stringToStatus(str, validate); assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); - str = instance.readUntilEndTag("CRCLStatus",is); + str = instance.readUntilEndTag("CRCLStatus", is); result = instance.stringToStatus(str, validate); assertEquals(BigInteger.ONE, result.getCommandStatus().getCommandID()); assertEquals(BigInteger.ONE, result.getCommandStatus().getStatusID()); - str = instance.readUntilEndTag("CRCLStatus", + str = instance.readUntilEndTag("CRCLStatus", new ByteArrayInputStream(" ".getBytes())); assertEquals(str, ""); - str = instance.readUntilEndTag("CRCLStatus", + str = instance.readUntilEndTag("CRCLStatus", new ByteArrayInputStream(" ".getBytes())); assertEquals(str, " "); } - + } diff --git a/examples/matlab/crclclient.m b/examples/matlab/crclclient.m new file mode 100644 index 0000000..b62bbb1 --- /dev/null +++ b/examples/matlab/crclclient.m @@ -0,0 +1,6 @@ +javaaddpath('/home/shackle/crcl4java/crcl4java-utils/target/crcl4java-utils-1.0-SNAPSHOT-jar-with-dependencies.jar') + +import crcl.base.*; +import crcl.utils.*; + +s = CRCLSocket('localhost',64444) diff --git a/pom.xml b/pom.xml index cd754ac..c3de0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -8,6 +8,7 @@ crcl4java-base crcl4java-utils + crcl4java-ui @@ -57,6 +58,7 @@ + From 20052307bb5f3969d36bdd75a349917cdcaeed0b Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 8 Sep 2015 16:51:08 -0400 Subject: [PATCH 13/14] update run script. --- .gitignore | 2 ++ crcl4java-utils/run.sh | 15 +-------------- crcl4java-utils/run.bat => run.bat | 0 run.sh | 20 ++++++++++++++++++++ 4 files changed, 23 insertions(+), 14 deletions(-) rename crcl4java-utils/run.bat => run.bat (100%) create mode 100755 run.sh diff --git a/.gitignore b/.gitignore index ac11be0..bae8c0d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ *.jar *.war *.ear +run*.log +run*.err # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/crcl4java-utils/run.sh b/crcl4java-utils/run.sh index 5356a49..dd306db 100755 --- a/crcl4java-utils/run.sh +++ b/crcl4java-utils/run.sh @@ -1,16 +1,3 @@ #!/bin/sh -if test ! -f ./run.sh ; then - cd "${0%%run.sh}"; -fi - -if test "x" != "x${JAVA_HOME}" ; then - export PATH="${JAVA_HOME}/bin/:${PATH}"; -fi - -if test ! -f target/CRCLJava-1.0-SNAPSHOT-jar-with-dependencies.jar ; then - mvn -version || ( echo "Please install maven." && false) - mvn package -fi; - -java -jar target/CRCLJava-1.0-SNAPSHOT-jar-with-dependencies.jar $* +../run.sh diff --git a/crcl4java-utils/run.bat b/run.bat similarity index 100% rename from crcl4java-utils/run.bat rename to run.bat diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..532a3e3 --- /dev/null +++ b/run.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +if test ! -f ./run.sh ; then + cd "${0%%run.sh}"; +fi + +if test "x" != "x${JAVA_HOME}" ; then + export PATH="${JAVA_HOME}/bin/:${PATH}"; +fi + +export JARFILE=crcl4java-ui/target/crcl4java-ui-1.0-SNAPSHOT-jar-with-dependencies.jar +if test ! -f "${JARFILE}" ; then + mvn -version || ( echo "Please install maven." && false) + mvn package +fi; + +\rm -f run[0-9]*.log run[0-9]*.err >/dev/null 2>/dev/null || true + +java -jar "${JARFILE}" $* > run$$.log 2> run$$.err + From 401e7ff1da8d653c19f36f1e6a1a700292e4b46b Mon Sep 17 00:00:00 2001 From: Will Shackleford Date: Tue, 8 Sep 2015 16:55:34 -0400 Subject: [PATCH 14/14] update run script. --- crcl4java-ui/run.sh | 3 +++ run.sh | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100755 crcl4java-ui/run.sh diff --git a/crcl4java-ui/run.sh b/crcl4java-ui/run.sh new file mode 100755 index 0000000..dd306db --- /dev/null +++ b/crcl4java-ui/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +../run.sh diff --git a/run.sh b/run.sh index 532a3e3..eea4c7c 100755 --- a/run.sh +++ b/run.sh @@ -1,6 +1,7 @@ #!/bin/sh -if test ! -f ./run.sh ; then +#CRCL4JAVARUN.sh +if test ! -f ./run.sh || grep -v '#CRCL4JAVARUN.sh' ./run.sh ; then cd "${0%%run.sh}"; fi