Merge remote-tracking branch 'remotes/svn/master'
This commit is contained in:
74
build.xml
Normal file
74
build.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="wiigee-lib" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project JavaLibrary6.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar-with-manifest: JAR building (if you are using a manifest)
|
||||
-do-jar-without-manifest: JAR building (if you are not using a manifest)
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="JavaLibrary6-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
10
lib/nblibraries.properties
Normal file
10
lib/nblibraries.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
libs.junit_4.classpath=\
|
||||
${base}/junit_4/junit-4.5.jar
|
||||
libs.junit_4.javadoc=\
|
||||
${base}/junit_4/junit-4.5-api.zip
|
||||
libs.junit_4.src=\
|
||||
${base}/junit_4/junit-4.5-src.jar
|
||||
libs.junit.classpath=\
|
||||
${base}/junit/junit-3.8.2.jar
|
||||
libs.junit.javadoc=\
|
||||
${base}/junit/junit-3.8.2-api.zip
|
||||
721
nbproject/build-impl.xml
Normal file
721
nbproject/build-impl.xml
Normal file
@@ -0,0 +1,721 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
*** GENERATED FROM project.xml - DO NOT EDIT ***
|
||||
*** EDIT ../build.xml INSTEAD ***
|
||||
|
||||
For the purpose of easier reading the script
|
||||
is divided into following sections:
|
||||
|
||||
- initialization
|
||||
- compilation
|
||||
- jar
|
||||
- execution
|
||||
- debugging
|
||||
- javadoc
|
||||
- junit compilation
|
||||
- junit execution
|
||||
- junit debugging
|
||||
- applet
|
||||
- cleanup
|
||||
|
||||
-->
|
||||
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="wiigee-lib-impl">
|
||||
<fail message="Please build using Ant 1.7.1 or higher.">
|
||||
<condition>
|
||||
<not>
|
||||
<antversion atleast="1.7.1"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
|
||||
<!--
|
||||
======================
|
||||
INITIALIZATION SECTION
|
||||
======================
|
||||
-->
|
||||
<target name="-pre-init">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="-pre-init" name="-init-private">
|
||||
<property file="nbproject/private/config.properties"/>
|
||||
<property file="nbproject/private/configs/${config}.properties"/>
|
||||
<property file="nbproject/private/private.properties"/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private" name="-init-libraries">
|
||||
<property location="lib/nblibraries.properties" name="libraries.1.path"/>
|
||||
<dirname file="${libraries.1.path}" property="libraries.1.dir.nativedirsep"/>
|
||||
<pathconvert dirsep="/" property="libraries.1.dir">
|
||||
<path path="${libraries.1.dir.nativedirsep}"/>
|
||||
</pathconvert>
|
||||
<basename file="${libraries.1.path}" property="libraries.1.basename" suffix=".properties"/>
|
||||
<touch file="${libraries.1.dir}/${libraries.1.basename}-private.properties"/>
|
||||
<loadproperties encoding="ISO-8859-1" srcfile="${libraries.1.dir}/${libraries.1.basename}-private.properties">
|
||||
<filterchain>
|
||||
<replacestring from="$${base}" to="${libraries.1.dir}"/>
|
||||
<escapeunicode/>
|
||||
</filterchain>
|
||||
</loadproperties>
|
||||
<loadproperties encoding="ISO-8859-1" srcfile="${libraries.1.path}">
|
||||
<filterchain>
|
||||
<replacestring from="$${base}" to="${libraries.1.dir}"/>
|
||||
<escapeunicode/>
|
||||
</filterchain>
|
||||
</loadproperties>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-libraries" name="-init-user">
|
||||
<property file="${user.properties.file}"/>
|
||||
<!-- The two properties below are usually overridden -->
|
||||
<!-- by the active platform. Just a fallback. -->
|
||||
<property name="default.javac.source" value="1.4"/>
|
||||
<property name="default.javac.target" value="1.4"/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-libraries,-init-user" name="-init-project">
|
||||
<property file="nbproject/configs/${config}.properties"/>
|
||||
<property file="nbproject/project.properties"/>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-init-macrodef-property" name="-do-init">
|
||||
<available file="${manifest.file}" property="manifest.available"/>
|
||||
<condition property="manifest.available+main.class">
|
||||
<and>
|
||||
<isset property="manifest.available"/>
|
||||
<isset property="main.class"/>
|
||||
<not>
|
||||
<equals arg1="${main.class}" arg2="" trim="true"/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="manifest.available+main.class+mkdist.available">
|
||||
<and>
|
||||
<istrue value="${manifest.available+main.class}"/>
|
||||
<isset property="libs.CopyLibs.classpath"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="have.tests">
|
||||
<or>
|
||||
<available file="${test.src.dir}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition property="have.sources">
|
||||
<or>
|
||||
<available file="${src.dir}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition property="netbeans.home+have.tests">
|
||||
<and>
|
||||
<isset property="netbeans.home"/>
|
||||
<isset property="have.tests"/>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="no.javadoc.preview">
|
||||
<and>
|
||||
<isset property="javadoc.preview"/>
|
||||
<isfalse value="${javadoc.preview}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="run.jvmargs" value=""/>
|
||||
<property name="javac.compilerargs" value=""/>
|
||||
<property name="work.dir" value="${basedir}"/>
|
||||
<condition property="no.deps">
|
||||
<and>
|
||||
<istrue value="${no.dependencies}"/>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="javac.debug" value="true"/>
|
||||
<property name="javadoc.preview" value="true"/>
|
||||
<property name="application.args" value=""/>
|
||||
<property name="source.encoding" value="${file.encoding}"/>
|
||||
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
|
||||
<and>
|
||||
<isset property="javadoc.encoding"/>
|
||||
<not>
|
||||
<equals arg1="${javadoc.encoding}" arg2=""/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<property name="javadoc.encoding.used" value="${source.encoding}"/>
|
||||
<property name="includes" value="**"/>
|
||||
<property name="excludes" value=""/>
|
||||
<property name="do.depend" value="false"/>
|
||||
<condition property="do.depend.true">
|
||||
<istrue value="${do.depend}"/>
|
||||
</condition>
|
||||
<condition else="" property="javac.compilerargs.jaxws" value="-Djava.endorsed.dirs='${jaxws.endorsed.dir}'">
|
||||
<and>
|
||||
<isset property="jaxws.endorsed.dir"/>
|
||||
<available file="nbproject/jaxws-build.xml"/>
|
||||
</and>
|
||||
</condition>
|
||||
</target>
|
||||
<target name="-post-init">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-do-init" name="-init-check">
|
||||
<fail unless="src.dir">Must set src.dir</fail>
|
||||
<fail unless="test.src.dir">Must set test.src.dir</fail>
|
||||
<fail unless="build.dir">Must set build.dir</fail>
|
||||
<fail unless="dist.dir">Must set dist.dir</fail>
|
||||
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
|
||||
<fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
|
||||
<fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
|
||||
<fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
|
||||
<fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
|
||||
<fail unless="dist.jar">Must set dist.jar</fail>
|
||||
</target>
|
||||
<target name="-init-macrodef-property">
|
||||
<macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute name="name"/>
|
||||
<attribute name="value"/>
|
||||
<sequential>
|
||||
<property name="@{name}" value="${@{value}}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-macrodef-javac">
|
||||
<macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${src.dir}" name="srcdir"/>
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<attribute default="${javac.classpath}" name="classpath"/>
|
||||
<attribute default="${includes}" name="includes"/>
|
||||
<attribute default="${excludes}" name="excludes"/>
|
||||
<attribute default="${javac.debug}" name="debug"/>
|
||||
<attribute default="${empty.dir}" name="sourcepath"/>
|
||||
<attribute default="${empty.dir}" name="gensrcdir"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<property location="${build.dir}/empty" name="empty.dir"/>
|
||||
<mkdir dir="${empty.dir}"/>
|
||||
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
|
||||
<src>
|
||||
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
|
||||
<include name="*"/>
|
||||
</dirset>
|
||||
</src>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<compilerarg line="${javac.compilerargs} ${javac.compilerargs.jaxws}"/>
|
||||
<customize/>
|
||||
</javac>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${src.dir}" name="srcdir"/>
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<attribute default="${javac.classpath}" name="classpath"/>
|
||||
<sequential>
|
||||
<depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
</depend>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${build.classes.dir}" name="destdir"/>
|
||||
<sequential>
|
||||
<fail unless="javac.includes">Must set javac.includes</fail>
|
||||
<pathconvert pathsep="," property="javac.includes.binary">
|
||||
<path>
|
||||
<filelist dir="@{destdir}" files="${javac.includes}"/>
|
||||
</path>
|
||||
<globmapper from="*.java" to="*.class"/>
|
||||
</pathconvert>
|
||||
<delete>
|
||||
<files includes="${javac.includes.binary}"/>
|
||||
</delete>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-macrodef-junit">
|
||||
<macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${includes}" name="includes"/>
|
||||
<attribute default="${excludes}" name="excludes"/>
|
||||
<attribute default="**" name="testincludes"/>
|
||||
<sequential>
|
||||
<junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true">
|
||||
<batchtest todir="${build.test.results.dir}">
|
||||
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
|
||||
<filename name="@{testincludes}"/>
|
||||
</fileset>
|
||||
</batchtest>
|
||||
<classpath>
|
||||
<path path="${run.test.classpath}"/>
|
||||
</classpath>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="test-sys-prop."/>
|
||||
<mapper from="test-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<formatter type="brief" usefile="false"/>
|
||||
<formatter type="xml"/>
|
||||
<jvmarg line="${run.jvmargs}"/>
|
||||
</junit>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
|
||||
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute default="${main.class}" name="name"/>
|
||||
<attribute default="${debug.classpath}" name="classpath"/>
|
||||
<attribute default="" name="stopclassname"/>
|
||||
<sequential>
|
||||
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
</nbjpdastart>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute default="${build.classes.dir}" name="dir"/>
|
||||
<sequential>
|
||||
<nbjpdareload>
|
||||
<fileset dir="@{dir}" includes="${fix.classes}">
|
||||
<include name="${fix.includes}*.class"/>
|
||||
</fileset>
|
||||
</nbjpdareload>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-debug-args">
|
||||
<property name="version-output" value="java version "${ant.java.version}"/>
|
||||
<condition property="have-jdk-older-than-1.4">
|
||||
<or>
|
||||
<contains string="${version-output}" substring="java version "1.0"/>
|
||||
<contains string="${version-output}" substring="java version "1.1"/>
|
||||
<contains string="${version-output}" substring="java version "1.2"/>
|
||||
<contains string="${version-output}" substring="java version "1.3"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
|
||||
<istrue value="${have-jdk-older-than-1.4}"/>
|
||||
</condition>
|
||||
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
|
||||
<os family="windows"/>
|
||||
</condition>
|
||||
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
|
||||
<isset property="debug.transport"/>
|
||||
</condition>
|
||||
</target>
|
||||
<target depends="-init-debug-args" name="-init-macrodef-debug">
|
||||
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<attribute default="${main.class}" name="classname"/>
|
||||
<attribute default="${debug.classpath}" name="classpath"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||
<jvmarg line="${debug-args-line}"/>
|
||||
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
|
||||
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
|
||||
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
|
||||
<jvmarg line="${run.jvmargs}"/>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="run-sys-prop."/>
|
||||
<mapper from="run-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<customize/>
|
||||
</java>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-macrodef-java">
|
||||
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<attribute default="${main.class}" name="classname"/>
|
||||
<attribute default="${run.classpath}" name="classpath"/>
|
||||
<element name="customize" optional="true"/>
|
||||
<sequential>
|
||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
|
||||
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
|
||||
<jvmarg line="${run.jvmargs}"/>
|
||||
<classpath>
|
||||
<path path="@{classpath}"/>
|
||||
</classpath>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="run-sys-prop."/>
|
||||
<mapper from="run-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<customize/>
|
||||
</java>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
</target>
|
||||
<target name="-init-presetdef-jar">
|
||||
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||
<jar compress="${jar.compress}" jarfile="${dist.jar}">
|
||||
<j2seproject1:fileset dir="${build.classes.dir}"/>
|
||||
</jar>
|
||||
</presetdef>
|
||||
</target>
|
||||
<target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar" name="init"/>
|
||||
<!--
|
||||
===================
|
||||
COMPILATION SECTION
|
||||
===================
|
||||
-->
|
||||
<target depends="init" name="deps-jar" unless="no.deps"/>
|
||||
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
|
||||
<target depends="init" name="-check-automatic-build">
|
||||
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
|
||||
</target>
|
||||
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
|
||||
<antcall target="clean"/>
|
||||
</target>
|
||||
<target depends="init,deps-jar" name="-pre-pre-compile">
|
||||
<mkdir dir="${build.classes.dir}"/>
|
||||
</target>
|
||||
<target name="-pre-compile">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target if="do.depend.true" name="-compile-depend">
|
||||
<pathconvert property="build.generated.subdirs">
|
||||
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||
<include name="*"/>
|
||||
</dirset>
|
||||
</pathconvert>
|
||||
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
|
||||
</target>
|
||||
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
|
||||
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
|
||||
<copy todir="${build.classes.dir}">
|
||||
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||
</copy>
|
||||
</target>
|
||||
<target name="-post-compile">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
|
||||
<target name="-pre-compile-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||
<j2seproject3:force-recompile/>
|
||||
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
|
||||
</target>
|
||||
<target name="-post-compile-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
|
||||
<!--
|
||||
====================
|
||||
JAR BUILDING SECTION
|
||||
====================
|
||||
-->
|
||||
<target depends="init" name="-pre-pre-jar">
|
||||
<dirname file="${dist.jar}" property="dist.jar.dir"/>
|
||||
<mkdir dir="${dist.jar.dir}"/>
|
||||
</target>
|
||||
<target name="-pre-jar">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-do-jar-without-manifest" unless="manifest.available">
|
||||
<j2seproject1:jar/>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
|
||||
<j2seproject1:jar manifest="${manifest.file}"/>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
|
||||
<j2seproject1:jar manifest="${manifest.file}">
|
||||
<j2seproject1:manifest>
|
||||
<j2seproject1:attribute name="Main-Class" value="${main.class}"/>
|
||||
</j2seproject1:manifest>
|
||||
</j2seproject1:jar>
|
||||
<echo>To run this application from the command line without Ant, try:</echo>
|
||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
<pathconvert property="run.classpath.with.dist.jar">
|
||||
<path path="${run.classpath}"/>
|
||||
<map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
|
||||
</pathconvert>
|
||||
<echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
|
||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||
<pathconvert property="run.classpath.without.build.classes.dir">
|
||||
<path path="${run.classpath}"/>
|
||||
<map from="${build.classes.dir.resolved}" to=""/>
|
||||
</pathconvert>
|
||||
<pathconvert pathsep=" " property="jar.classpath">
|
||||
<path path="${run.classpath.without.build.classes.dir}"/>
|
||||
<chainedmapper>
|
||||
<flattenmapper/>
|
||||
<globmapper from="*" to="lib/*"/>
|
||||
</chainedmapper>
|
||||
</pathconvert>
|
||||
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
|
||||
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="${main.class}"/>
|
||||
<attribute name="Class-Path" value="${jar.classpath}"/>
|
||||
</manifest>
|
||||
</copylibs>
|
||||
<echo>To run this application from the command line without Ant, try:</echo>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
<echo>java -jar "${dist.jar.resolved}"</echo>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">
|
||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||
<pathconvert property="run.classpath.without.build.classes.dir">
|
||||
<path path="${run.classpath}"/>
|
||||
<map from="${build.classes.dir.resolved}" to=""/>
|
||||
</pathconvert>
|
||||
<pathconvert pathsep=" " property="jar.classpath">
|
||||
<path path="${run.classpath.without.build.classes.dir}"/>
|
||||
<chainedmapper>
|
||||
<flattenmapper/>
|
||||
<globmapper from="*" to="lib/*"/>
|
||||
</chainedmapper>
|
||||
</pathconvert>
|
||||
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
|
||||
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</copylibs>
|
||||
</target>
|
||||
<target name="-post-jar">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar" description="Build JAR." name="jar"/>
|
||||
<!--
|
||||
=================
|
||||
EXECUTION SECTION
|
||||
=================
|
||||
-->
|
||||
<target depends="init,compile" description="Run a main class." name="run">
|
||||
<j2seproject1:java>
|
||||
<customize>
|
||||
<arg line="${application.args}"/>
|
||||
</customize>
|
||||
</j2seproject1:java>
|
||||
</target>
|
||||
<target name="-do-not-recompile">
|
||||
<property name="javac.includes.binary" value=""/>
|
||||
</target>
|
||||
<target depends="init,-do-not-recompile,compile-single" name="run-single">
|
||||
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||
<j2seproject1:java classname="${run.class}"/>
|
||||
</target>
|
||||
<target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
|
||||
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
|
||||
</target>
|
||||
<!--
|
||||
=================
|
||||
DEBUGGING SECTION
|
||||
=================
|
||||
-->
|
||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
|
||||
<j2seproject1:nbjpdastart name="${debug.class}"/>
|
||||
</target>
|
||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
|
||||
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile" name="-debug-start-debuggee">
|
||||
<j2seproject3:debug>
|
||||
<customize>
|
||||
<arg line="${application.args}"/>
|
||||
</customize>
|
||||
</j2seproject3:debug>
|
||||
</target>
|
||||
<target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
|
||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
|
||||
<j2seproject1:nbjpdastart stopclassname="${main.class}"/>
|
||||
</target>
|
||||
<target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
|
||||
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
|
||||
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||
<j2seproject3:debug classname="${debug.class}"/>
|
||||
</target>
|
||||
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
|
||||
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
|
||||
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
|
||||
</target>
|
||||
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
|
||||
<target depends="init" name="-pre-debug-fix">
|
||||
<fail unless="fix.includes">Must set fix.includes</fail>
|
||||
<property name="javac.includes" value="${fix.includes}.java"/>
|
||||
</target>
|
||||
<target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
|
||||
<j2seproject1:nbjpdareload/>
|
||||
</target>
|
||||
<target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
|
||||
<!--
|
||||
===============
|
||||
JAVADOC SECTION
|
||||
===============
|
||||
-->
|
||||
<target depends="init" name="-javadoc-build">
|
||||
<mkdir dir="${dist.javadoc.dir}"/>
|
||||
<javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
|
||||
<classpath>
|
||||
<path path="${javac.classpath}"/>
|
||||
</classpath>
|
||||
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
|
||||
<filename name="**/*.java"/>
|
||||
</fileset>
|
||||
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||
<include name="**/*.java"/>
|
||||
</fileset>
|
||||
</javadoc>
|
||||
</target>
|
||||
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
|
||||
<nbbrowse file="${dist.javadoc.dir}/index.html"/>
|
||||
</target>
|
||||
<target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
|
||||
<!--
|
||||
=========================
|
||||
JUNIT COMPILATION SECTION
|
||||
=========================
|
||||
-->
|
||||
<target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
|
||||
<mkdir dir="${build.test.classes.dir}"/>
|
||||
</target>
|
||||
<target name="-pre-compile-test">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target if="do.depend.true" name="-compile-test-depend">
|
||||
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
|
||||
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
|
||||
<copy todir="${build.test.classes.dir}">
|
||||
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||
</copy>
|
||||
</target>
|
||||
<target name="-post-compile-test">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
|
||||
<target name="-pre-compile-test-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
|
||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
|
||||
<j2seproject3:javac classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}"/>
|
||||
<copy todir="${build.test.classes.dir}">
|
||||
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||
</copy>
|
||||
</target>
|
||||
<target name="-post-compile-test-single">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
|
||||
<!--
|
||||
=======================
|
||||
JUNIT EXECUTION SECTION
|
||||
=======================
|
||||
-->
|
||||
<target depends="init" if="have.tests" name="-pre-test-run">
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
|
||||
<j2seproject3:junit testincludes="**/*Test.java"/>
|
||||
</target>
|
||||
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
||||
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||
</target>
|
||||
<target depends="init" if="have.tests" name="test-report"/>
|
||||
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
|
||||
<target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
|
||||
<target depends="init" if="have.tests" name="-pre-test-run-single">
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
|
||||
<fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
|
||||
<j2seproject3:junit excludes="" includes="${test.includes}"/>
|
||||
</target>
|
||||
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
|
||||
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||
</target>
|
||||
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
|
||||
<!--
|
||||
=======================
|
||||
JUNIT DEBUGGING SECTION
|
||||
=======================
|
||||
-->
|
||||
<target depends="init,compile-test" if="have.tests" name="-debug-start-debuggee-test">
|
||||
<fail unless="test.class">Must select one file in the IDE or set test.class</fail>
|
||||
<property location="${build.test.results.dir}/TEST-${test.class}.xml" name="test.report.file"/>
|
||||
<delete file="${test.report.file}"/>
|
||||
<mkdir dir="${build.test.results.dir}"/>
|
||||
<j2seproject3:debug classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" classpath="${ant.home}/lib/ant.jar:${ant.home}/lib/ant-junit.jar:${debug.test.classpath}">
|
||||
<customize>
|
||||
<syspropertyset>
|
||||
<propertyref prefix="test-sys-prop."/>
|
||||
<mapper from="test-sys-prop.*" to="*" type="glob"/>
|
||||
</syspropertyset>
|
||||
<arg value="${test.class}"/>
|
||||
<arg value="showoutput=true"/>
|
||||
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter"/>
|
||||
<arg value="formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,${test.report.file}"/>
|
||||
</customize>
|
||||
</j2seproject3:debug>
|
||||
</target>
|
||||
<target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
|
||||
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
|
||||
</target>
|
||||
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
|
||||
<target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
|
||||
<j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
|
||||
</target>
|
||||
<target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
|
||||
<!--
|
||||
=========================
|
||||
APPLET EXECUTION SECTION
|
||||
=========================
|
||||
-->
|
||||
<target depends="init,compile-single" name="run-applet">
|
||||
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
|
||||
<j2seproject1:java classname="sun.applet.AppletViewer">
|
||||
<customize>
|
||||
<arg value="${applet.url}"/>
|
||||
</customize>
|
||||
</j2seproject1:java>
|
||||
</target>
|
||||
<!--
|
||||
=========================
|
||||
APPLET DEBUGGING SECTION
|
||||
=========================
|
||||
-->
|
||||
<target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
|
||||
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
|
||||
<j2seproject3:debug classname="sun.applet.AppletViewer">
|
||||
<customize>
|
||||
<arg value="${applet.url}"/>
|
||||
</customize>
|
||||
</j2seproject3:debug>
|
||||
</target>
|
||||
<target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
|
||||
<!--
|
||||
===============
|
||||
CLEANUP SECTION
|
||||
===============
|
||||
-->
|
||||
<target depends="init" name="deps-clean" unless="no.deps"/>
|
||||
<target depends="init" name="-do-clean">
|
||||
<delete dir="${build.dir}"/>
|
||||
<delete dir="${dist.dir}"/>
|
||||
</target>
|
||||
<target name="-post-clean">
|
||||
<!-- Empty placeholder for easier customization. -->
|
||||
<!-- You can override this target in the ../build.xml file. -->
|
||||
</target>
|
||||
<target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
|
||||
</project>
|
||||
8
nbproject/genfiles.properties
Normal file
8
nbproject/genfiles.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
build.xml.data.CRC32=a8056d46
|
||||
build.xml.script.CRC32=3a7a628a
|
||||
build.xml.stylesheet.CRC32=958a1d3e
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=afb4810b
|
||||
nbproject/build-impl.xml.script.CRC32=7668b6e9
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=5c621a33@1.26.1.45
|
||||
70
nbproject/project.properties
Normal file
70
nbproject/project.properties
Normal file
@@ -0,0 +1,70 @@
|
||||
application.title=wiigee-lib
|
||||
application.vendor=bepo
|
||||
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8
|
||||
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80
|
||||
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/wiigee-lib.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
excludes=
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.source=1.5
|
||||
javac.target=1.5
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}:\
|
||||
${libs.junit.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
jnlp.codebase.type=local
|
||||
jnlp.codebase.url=file:/Users/bepo/develop/java/wiigee/trunk/wiigee-lib/dist
|
||||
jnlp.descriptor=application
|
||||
jnlp.enabled=false
|
||||
jnlp.offline-allowed=false
|
||||
jnlp.signed=false
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
platform.active=default_platform
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project
|
||||
# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
|
||||
# or test-sys-prop.name=value to set system properties for unit tests):
|
||||
run.jvmargs=
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
19
nbproject/project.xml
Normal file
19
nbproject/project.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>wiigee-lib</name>
|
||||
<minimum-ant-version>1.6.5</minimum-ant-version>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
<libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
|
||||
<definitions>lib/nblibraries.properties</definitions>
|
||||
</libraries>
|
||||
</configuration>
|
||||
</project>
|
||||
46
src/org/wiigee/control/Wiigee.java
Normal file
46
src/org/wiigee/control/Wiigee.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.control;
|
||||
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
/**
|
||||
* The mother of all classes. :-) It's just used as parent class
|
||||
* to print version information and later on maybe dynamic configuring
|
||||
* of the whole wiimote system... detecting plugins and devices automatically
|
||||
* maybe. :)
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class Wiigee {
|
||||
|
||||
protected static String version = "1.5.5 alpha";
|
||||
protected static String releasedate = "20090714";
|
||||
|
||||
protected Wiigee() {
|
||||
Log.write("This is wiigee version "+version+" ("+releasedate+")");
|
||||
}
|
||||
|
||||
}
|
||||
234
src/org/wiigee/device/Device.java
Normal file
234
src/org/wiigee/device/Device.java
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
package org.wiigee.device;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.wiigee.logic.*;
|
||||
import org.wiigee.event.*;
|
||||
import org.wiigee.filter.*;
|
||||
|
||||
/**
|
||||
* Abstract representation of a device with very basic functionalities. This
|
||||
* class should be derived from, if anybody plans to add a new class of devices,
|
||||
* like Wiimote or AndroidDevice does. This class mainly consist of filter
|
||||
* management, recognition control and core event control.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class Device {
|
||||
|
||||
// Fixed number values.
|
||||
public static final int MOTION = 0;
|
||||
|
||||
// Buttons for action coordination
|
||||
protected int recognitionbutton;
|
||||
protected int trainbutton;
|
||||
protected int closegesturebutton;
|
||||
|
||||
// Functional
|
||||
protected boolean accelerationEnabled;
|
||||
|
||||
// Filters, can filter the data stream
|
||||
protected Vector<Filter> accfilters = new Vector<Filter>();
|
||||
|
||||
// Listeners, receive generated events
|
||||
protected Vector<AccelerationListener> accelerationlistener = new Vector<AccelerationListener>();
|
||||
protected Vector<ButtonListener> buttonlistener = new Vector<ButtonListener>();
|
||||
|
||||
// Processing unit to analyze the data
|
||||
protected ProcessingUnit processingunit = new TriggeredProcessingUnit();
|
||||
|
||||
public Device(boolean autofiltering) {
|
||||
if (autofiltering) {
|
||||
this.addAccelerationFilter(new IdleStateFilter());
|
||||
this.addAccelerationFilter(new MotionDetectFilter(this));
|
||||
this.addAccelerationFilter(new DirectionalEquivalenceFilter());
|
||||
}
|
||||
this.addAccelerationListener(this.processingunit);
|
||||
this.addButtonListener(this.processingunit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a Filter for processing the acceleration values.
|
||||
* @param filter The Filter instance.
|
||||
*/
|
||||
public void addAccelerationFilter(Filter filter) {
|
||||
this.accfilters.add(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all the accfilters, which are resetable.
|
||||
* Sometimes they have to be resettet if a new gesture starts.
|
||||
*/
|
||||
public void resetAccelerationFilters() {
|
||||
for (int i = 0; i < this.accfilters.size(); i++) {
|
||||
this.accfilters.elementAt(i).reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an AccelerationListener to the Device. Everytime an acceleration
|
||||
* on the Device is performed the AccelerationListener would receive
|
||||
* an event of this action.
|
||||
*
|
||||
* @param listener The Listener.
|
||||
*/
|
||||
public void addAccelerationListener(AccelerationListener listener) {
|
||||
this.accelerationlistener.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a ButtonListener to the Device. Everytime a Button has been
|
||||
* pressed or released, the Listener would be notified about this via
|
||||
* the corresponding Events.
|
||||
*
|
||||
* @param listener The Listener.
|
||||
*/
|
||||
public void addButtonListener(ButtonListener listener) {
|
||||
this.buttonlistener.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a GestureListener to the Device. Everytime a gesture
|
||||
* is performed the GestureListener would receive an event of
|
||||
* this gesture.
|
||||
*
|
||||
* @param listener The Listener.
|
||||
*/
|
||||
public void addGestureListener(GestureListener listener) {
|
||||
this.processingunit.addGestureListener(listener);
|
||||
}
|
||||
|
||||
public int getRecognitionButton() {
|
||||
return this.recognitionbutton;
|
||||
}
|
||||
|
||||
public void setRecognitionButton(int b) {
|
||||
this.recognitionbutton = b;
|
||||
}
|
||||
|
||||
public int getTrainButton() {
|
||||
return this.trainbutton;
|
||||
}
|
||||
|
||||
public void setTrainButton(int b) {
|
||||
this.trainbutton = b;
|
||||
}
|
||||
|
||||
public int getCloseGestureButton() {
|
||||
return this.closegesturebutton;
|
||||
}
|
||||
|
||||
public void setCloseGestureButton(int b) {
|
||||
this.closegesturebutton = b;
|
||||
}
|
||||
|
||||
public ProcessingUnit getProcessingUnit() {
|
||||
return this.processingunit;
|
||||
}
|
||||
|
||||
public void setAccelerationEnabled(boolean enabled) throws IOException {
|
||||
this.accelerationEnabled = enabled;
|
||||
}
|
||||
|
||||
public void loadGesture(String filename) {
|
||||
this.processingunit.loadGesture(filename);
|
||||
}
|
||||
|
||||
public void saveGesture(int id, String filename) {
|
||||
this.processingunit.saveGesture(id, filename);
|
||||
}
|
||||
|
||||
// ###### Event-Methoden
|
||||
/** Fires an acceleration event.
|
||||
* @param vector Consists of three values:
|
||||
* acceleration on X, Y and Z axis.
|
||||
*/
|
||||
public void fireAccelerationEvent(double[] vector) {
|
||||
for (int i = 0; i < this.accfilters.size(); i++) {
|
||||
vector = this.accfilters.get(i).filter(vector);
|
||||
// cannot return here if null, because of time-dependent accfilters
|
||||
}
|
||||
|
||||
// don't need to create an event if filtered away
|
||||
if (vector != null) {
|
||||
// calculate the absolute value for the accelerationevent
|
||||
double absvalue = Math.sqrt((vector[0] * vector[0]) +
|
||||
(vector[1] * vector[1]) + (vector[2] * vector[2]));
|
||||
|
||||
AccelerationEvent w = new AccelerationEvent(this,
|
||||
vector[0], vector[1], vector[2], absvalue);
|
||||
for (int i = 0; i < this.accelerationlistener.size(); i++) {
|
||||
this.accelerationlistener.get(i).accelerationReceived(w);
|
||||
}
|
||||
}
|
||||
|
||||
} // fireaccelerationevent
|
||||
|
||||
/** Fires a button pressed event.
|
||||
* @param button
|
||||
* Integer value of the pressed button.
|
||||
*/
|
||||
public void fireButtonPressedEvent(int button) {
|
||||
ButtonPressedEvent w = new ButtonPressedEvent(this, button);
|
||||
for (int i = 0; i < this.buttonlistener.size(); i++) {
|
||||
this.buttonlistener.get(i).buttonPressReceived(w);
|
||||
}
|
||||
|
||||
if (w.isRecognitionInitEvent() || w.isTrainInitEvent()) {
|
||||
this.resetAccelerationFilters();
|
||||
}
|
||||
}
|
||||
|
||||
/** Fires a button released event.
|
||||
*/
|
||||
public void fireButtonReleasedEvent(int button) {
|
||||
ButtonReleasedEvent w = new ButtonReleasedEvent(this, button);
|
||||
for (int i = 0; i < this.buttonlistener.size(); i++) {
|
||||
this.buttonlistener.get(i).buttonReleaseReceived(w);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a motion start event.
|
||||
*/
|
||||
public void fireMotionStartEvent() {
|
||||
MotionStartEvent w = new MotionStartEvent(this);
|
||||
for (int i = 0; i < this.accelerationlistener.size(); i++) {
|
||||
this.accelerationlistener.get(i).motionStartReceived(w);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a motion stop event.
|
||||
*/
|
||||
public void fireMotionStopEvent() {
|
||||
MotionStopEvent w = new MotionStopEvent(this);
|
||||
for (int i = 0; i < this.accelerationlistener.size(); i++) {
|
||||
this.accelerationlistener.get(i).motionStopReceived(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
79
src/org/wiigee/event/AccelerationEvent.java
Executable file
79
src/org/wiigee/event/AccelerationEvent.java
Executable file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
import org.wiigee.device.*;
|
||||
|
||||
/**
|
||||
* This Event would be generated if an acceleration has been detected.
|
||||
* It contains information about the force applied to the device in each
|
||||
* direction (x, y, z). Further it contains the absolute value of this
|
||||
* vector and the source which generated this event (Device).
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*
|
||||
*/
|
||||
public class AccelerationEvent extends EventObject {
|
||||
|
||||
double X, Y, Z;
|
||||
double absvalue;
|
||||
|
||||
/**
|
||||
* Create an AccelerationEvent with a specific source,
|
||||
* all the three acceleration values and the calculated absolute
|
||||
* value.
|
||||
*
|
||||
* @param source The source which has been accelerated (Wiimote).
|
||||
* @param X The value of acceleration in the x direction.
|
||||
* @param Y The value of acceleration in the y direction.
|
||||
* @param Z The value of acceleration in the z direction.
|
||||
* @param absvalue The absolute value of this acceleration vector.
|
||||
*/
|
||||
public AccelerationEvent(Device source, double X, double Y, double Z, double absvalue) {
|
||||
super(source);
|
||||
this.X=X;
|
||||
this.Y=Y;
|
||||
this.Z=Z;
|
||||
this.absvalue=absvalue;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return X;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return Y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return Z;
|
||||
}
|
||||
|
||||
public double getAbsValue() {
|
||||
return absvalue;
|
||||
}
|
||||
}
|
||||
65
src/org/wiigee/event/AccelerationListener.java
Executable file
65
src/org/wiigee/event/AccelerationListener.java
Executable file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* This interface has to be implemented if the application should react
|
||||
* to pure acceleration data. This could be useful if you want to e.g.
|
||||
* graphically display the acceleration data in your application.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public interface AccelerationListener extends EventListener {
|
||||
|
||||
/**
|
||||
* This method would be called if a Device source has been accelerated.
|
||||
*
|
||||
* @param event The acceleration representation as an event.
|
||||
*/
|
||||
public abstract void accelerationReceived(AccelerationEvent event);
|
||||
|
||||
/**
|
||||
* This method would be called if a Device is in idle state and then a
|
||||
* motion starts or if a Device is in motion and then the motion stops and
|
||||
* the Device is in idle state.
|
||||
*
|
||||
* @param event This is the event which contains if the Wiimote is now
|
||||
* in motion or not.
|
||||
*/
|
||||
public abstract void motionStartReceived(MotionStartEvent event);
|
||||
|
||||
/**
|
||||
* This method would be called if a Device is in motion and then the motion
|
||||
* stops and the Device is in idle state.
|
||||
*
|
||||
* @param event This is the event which contains if the Device is now
|
||||
* in motion or not.
|
||||
*/
|
||||
public abstract void motionStopReceived(MotionStopEvent event);
|
||||
|
||||
|
||||
}
|
||||
84
src/org/wiigee/event/ActionStartEvent.java
Executable file
84
src/org/wiigee/event/ActionStartEvent.java
Executable file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
import org.wiigee.device.Device;
|
||||
|
||||
/**
|
||||
* An ActionStartEvent is an Event where other different events can
|
||||
* be derived from, if they can be considered as an event actually starting
|
||||
* a process like e.g. Training, Recognition, ...
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class ActionStartEvent extends EventObject {
|
||||
|
||||
protected boolean trainbutton;
|
||||
protected boolean recognitionbutton;
|
||||
protected boolean closegesturebutton;
|
||||
|
||||
public ActionStartEvent(Device source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is true if this button press has been done by the
|
||||
* individual defined RecognitionButton which has to be
|
||||
* set during initialization of a Wiimote.
|
||||
*
|
||||
* @return Is this button press initiated by the recognition button.
|
||||
* @see device.Wiimote#setRecognitionButton(int) setRecognitionButton()
|
||||
*/
|
||||
public boolean isRecognitionInitEvent() {
|
||||
return this.recognitionbutton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is true if this button press has been done by the
|
||||
* individual defined TrainButton which has to be
|
||||
* set during initialization of a Wiimote.
|
||||
*
|
||||
* @return Is this button pres initiated by the training button.
|
||||
* @see device.Wiimote#setTrainButton(int) setTrainButton()
|
||||
*/
|
||||
public boolean isTrainInitEvent() {
|
||||
return this.trainbutton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is true if this button press has been done by the
|
||||
* individual defined CloseGestureButton which has to be
|
||||
* set during initialization of a Wiimote.
|
||||
*
|
||||
* @return Is this button press initiated by the close gesture button.
|
||||
* @see device.Wiimote#setCloseGestureButton(int) setCloseGestureButton()
|
||||
*/
|
||||
public boolean isCloseGestureInitEvent() {
|
||||
return this.closegesturebutton;
|
||||
}
|
||||
|
||||
}
|
||||
43
src/org/wiigee/event/ActionStopEvent.java
Executable file
43
src/org/wiigee/event/ActionStopEvent.java
Executable file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import java.util.EventObject;
|
||||
import org.wiigee.device.Device;
|
||||
|
||||
/**
|
||||
* An ActionStopEvent is an Event where other different events can
|
||||
* be derived from, if they can be considered as an event actually stopping
|
||||
* a process like e.g. Training, Recognition, ...
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class ActionStopEvent extends EventObject {
|
||||
|
||||
public ActionStopEvent(Device source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
54
src/org/wiigee/event/ButtonListener.java
Normal file
54
src/org/wiigee/event/ButtonListener.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* This interface has to be implemented if the application should react
|
||||
* to button press/releases.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public interface ButtonListener extends EventListener {
|
||||
|
||||
|
||||
/**
|
||||
* This method would be called if a Device button has been pressed.
|
||||
*
|
||||
* @param event The button representation as an event.
|
||||
*/
|
||||
public abstract void buttonPressReceived(ButtonPressedEvent event);
|
||||
|
||||
/**
|
||||
* This method would be called if a Device button has been released.
|
||||
*
|
||||
* @param event This is actually a meta-event NOT containing which button
|
||||
* has been released.
|
||||
*/
|
||||
public abstract void buttonReleaseReceived(ButtonReleasedEvent event);
|
||||
|
||||
|
||||
}
|
||||
80
src/org/wiigee/event/ButtonPressedEvent.java
Executable file
80
src/org/wiigee/event/ButtonPressedEvent.java
Executable file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import org.wiigee.device.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* This Event would be generated if a button on a wiimote has been
|
||||
* pressed by user. It contains the source (wiimote) and an integer
|
||||
* representation of which button has been pressed. Please note that
|
||||
* there exist enumeration constants in the class, so you don't
|
||||
* have to use this integer values directly.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class ButtonPressedEvent extends ActionStartEvent {
|
||||
|
||||
// Fixed number values.
|
||||
public static final int BUTTON_2 = 1;
|
||||
public static final int BUTTON_1 = 2;
|
||||
public static final int BUTTON_B = 3;
|
||||
public static final int BUTTON_A = 4;
|
||||
public static final int BUTTON_MINUS = 5;
|
||||
public static final int BUTTON_HOME = 8;
|
||||
public static final int BUTTON_LEFT = 9;
|
||||
public static final int BUTTON_RIGHT = 10;
|
||||
public static final int BUTTON_DOWN = 11;
|
||||
public static final int BUTTON_UP = 12;
|
||||
public static final int BUTTON_PLUS = 13;
|
||||
|
||||
int button;
|
||||
|
||||
/**
|
||||
* Create a WiimoteButtonPressedEvent with the Wiimote source whose
|
||||
* Button has been pressed and the integer representation of the button.
|
||||
*
|
||||
* @param source
|
||||
* @param button
|
||||
*/
|
||||
public ButtonPressedEvent(Device source, int button) {
|
||||
super(source);
|
||||
this.button=button;
|
||||
|
||||
if(source.getRecognitionButton()==button) {
|
||||
this.recognitionbutton=true;
|
||||
} else if(source.getTrainButton()==button) {
|
||||
this.trainbutton=true;
|
||||
} else if(source.getCloseGestureButton()==button) {
|
||||
this.closegesturebutton=true;
|
||||
}
|
||||
}
|
||||
|
||||
public int getButton() {
|
||||
return this.button;
|
||||
}
|
||||
|
||||
}
|
||||
49
src/org/wiigee/event/ButtonReleasedEvent.java
Executable file
49
src/org/wiigee/event/ButtonReleasedEvent.java
Executable file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import org.wiigee.device.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* This event would be generated if a button was released.
|
||||
* contains: source (wiimote).
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class ButtonReleasedEvent extends ActionStopEvent {
|
||||
|
||||
int button;
|
||||
|
||||
public ButtonReleasedEvent(Device source, int button) {
|
||||
super(source);
|
||||
this.button = button;
|
||||
}
|
||||
|
||||
public int getButton() {
|
||||
return this.button;
|
||||
}
|
||||
|
||||
}
|
||||
71
src/org/wiigee/event/GestureEvent.java
Executable file
71
src/org/wiigee/event/GestureEvent.java
Executable file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
package org.wiigee.event;
|
||||
|
||||
import org.wiigee.logic.ProcessingUnit;
|
||||
|
||||
/**
|
||||
* This event would be generated if a gesture has been detected.
|
||||
* It contains information about the gesture "name" or type,
|
||||
* the accelerationstreamanalyzer which generated the event (source)
|
||||
* and the probability calculated from the bayes classifier.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class GestureEvent {
|
||||
|
||||
int id;
|
||||
boolean valid;
|
||||
double probability;
|
||||
ProcessingUnit analyzer;
|
||||
|
||||
/** Create a GestureEvent
|
||||
*
|
||||
* @param source The Source, which detected the gesture.
|
||||
* @param id A gesture ID for identifying a gesture.
|
||||
* @param probability The Bayes-Classifier calculated probability.
|
||||
*/
|
||||
public GestureEvent(ProcessingUnit source, boolean valid, int id, double probability) {
|
||||
this.analyzer = source;
|
||||
this.valid = valid;
|
||||
this.id = id;
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
public double getProbability() {
|
||||
return this.probability;
|
||||
}
|
||||
|
||||
public ProcessingUnit getSource() {
|
||||
return this.analyzer;
|
||||
}
|
||||
}
|
||||
47
src/org/wiigee/event/GestureListener.java
Executable file
47
src/org/wiigee/event/GestureListener.java
Executable file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* This is the GestureListener interface which has to be implemented
|
||||
* by any application which should receive recognized gestures.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*
|
||||
*/
|
||||
public interface GestureListener extends EventListener {
|
||||
|
||||
/**
|
||||
* This method would be called if a gesture has been recognized.
|
||||
*
|
||||
* @param event The GestureEvent containing information about
|
||||
* the recognized gesture.
|
||||
*/
|
||||
public abstract void gestureReceived(GestureEvent event);
|
||||
|
||||
}
|
||||
63
src/org/wiigee/event/MotionStartEvent.java
Executable file
63
src/org/wiigee/event/MotionStartEvent.java
Executable file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import org.wiigee.device.Device;
|
||||
|
||||
/**
|
||||
* This Event gets fired, if the Device starts to move.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class MotionStartEvent extends ActionStartEvent {
|
||||
|
||||
public MotionStartEvent(Device source) {
|
||||
super(source);
|
||||
|
||||
if(source.getRecognitionButton()==Device.MOTION) {
|
||||
this.recognitionbutton=true;
|
||||
} else if(source.getTrainButton()==Device.MOTION) {
|
||||
this.trainbutton=true;
|
||||
} else if(source.getCloseGestureButton()==Device.MOTION) {
|
||||
this.closegesturebutton=true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrainInitEvent() {
|
||||
return this.trainbutton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCloseGestureInitEvent() {
|
||||
return this.closegesturebutton;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRecognitionInitEvent() {
|
||||
return this.recognitionbutton;
|
||||
}
|
||||
|
||||
}
|
||||
42
src/org/wiigee/event/MotionStopEvent.java
Executable file
42
src/org/wiigee/event/MotionStopEvent.java
Executable file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.event;
|
||||
|
||||
import org.wiigee.device.Device;
|
||||
|
||||
/**
|
||||
*
|
||||
* This event would be generated if a motion stops.
|
||||
* contains: source.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class MotionStopEvent extends ActionStopEvent {
|
||||
|
||||
public MotionStopEvent(Device source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
70
src/org/wiigee/filter/DirectionalEquivalenceFilter.java
Executable file
70
src/org/wiigee/filter/DirectionalEquivalenceFilter.java
Executable file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.filter;
|
||||
|
||||
/**
|
||||
* This filter removes a vector, if it doesn't differ enough from
|
||||
* the previously retrieved filter.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class DirectionalEquivalenceFilter extends Filter {
|
||||
|
||||
private double sensivity;
|
||||
private double[] reference;
|
||||
|
||||
public DirectionalEquivalenceFilter() {
|
||||
super();
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.sensivity=0.2;
|
||||
this.reference = new double[] {0.0, 0.0, 0.0};
|
||||
}
|
||||
|
||||
public double[] filterAlgorithm(double[] vector) {
|
||||
if(vector[0]<reference[0]-this.sensivity ||
|
||||
vector[0]>reference[0]+this.sensivity ||
|
||||
vector[1]<reference[1]-this.sensivity ||
|
||||
vector[1]>reference[1]+this.sensivity ||
|
||||
vector[2]<reference[2]-this.sensivity ||
|
||||
vector[2]>reference[2]+this.sensivity) {
|
||||
this.reference=vector;
|
||||
return vector;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSensivity(double sensivity) {
|
||||
this.sensivity=sensivity;
|
||||
}
|
||||
|
||||
public double getSensivity() {
|
||||
return this.sensivity;
|
||||
}
|
||||
|
||||
}
|
||||
62
src/org/wiigee/filter/Filter.java
Executable file
62
src/org/wiigee/filter/Filter.java
Executable file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.filter;
|
||||
|
||||
/**
|
||||
* Abstract class to give a definition for a general filter.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public abstract class Filter {
|
||||
|
||||
/***
|
||||
* The actual called method to filter anything. It checks if the vector is
|
||||
* already set to NULL by another filter and won't process it anymore. If it's
|
||||
* not NULL it would be forwarded to the actual implemented method - filterAlgorithm().
|
||||
* @param vector The acceleration vector, encoding: 0/x, 1/y, 2/z
|
||||
* @return a new, filtered acceleration vector, encoded the same way
|
||||
*/
|
||||
public double[] filter(double[] vector) {
|
||||
if(vector==null) {
|
||||
return null;
|
||||
} else {
|
||||
return filterAlgorithm(vector);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* A filter receives a triple of acceleration values within the variable 'vector'.
|
||||
* It's encoded as vector[0]=x, vector[1]=y, vector[2]=z. This is not an object since the
|
||||
* processing of the filter should be really fast, since every acceleration of the wiimote
|
||||
* passes the filter.
|
||||
* @param vector
|
||||
* @param absvalue
|
||||
* @return
|
||||
*/
|
||||
abstract public double[] filterAlgorithm(double[] vector);
|
||||
|
||||
abstract public void reset();
|
||||
|
||||
}
|
||||
71
src/org/wiigee/filter/HighPassFilter.java
Normal file
71
src/org/wiigee/filter/HighPassFilter.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.filter;
|
||||
|
||||
/**
|
||||
*
|
||||
* This filter removes every acceleration that happens slowly or
|
||||
* steadily (like e.g. gravity). Remember: It _passes_ acceleration
|
||||
* with a big variety.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class HighPassFilter extends Filter {
|
||||
|
||||
private double factor;
|
||||
private double[] prevAcc;
|
||||
|
||||
public HighPassFilter() {
|
||||
super();
|
||||
this.factor = 0.1;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public HighPassFilter(double factor) {
|
||||
super();
|
||||
this.factor = factor;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.prevAcc = new double[] {0.0, 0.0, 0.0};
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] filterAlgorithm(double[] vector) {
|
||||
double[] retVal = new double[3];
|
||||
prevAcc[0] = vector[0] * this.factor + this.prevAcc[0] * (1.0 - this.factor);
|
||||
prevAcc[1] = vector[1] * this.factor + this.prevAcc[1] * (1.0 - this.factor);
|
||||
prevAcc[2] = vector[2] * this.factor + this.prevAcc[2] * (1.0 - this.factor);
|
||||
|
||||
retVal[0] = vector[0] - prevAcc[0];
|
||||
retVal[1] = vector[1] - prevAcc[1];
|
||||
retVal[2] = vector[2] - prevAcc[2];
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
86
src/org/wiigee/filter/IdleStateFilter.java
Executable file
86
src/org/wiigee/filter/IdleStateFilter.java
Executable file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.filter;
|
||||
|
||||
/**
|
||||
* Filters if the wiimote is not moved in any way. Be careful in using
|
||||
* this filter together with a HighPassFilter.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class IdleStateFilter extends Filter {
|
||||
|
||||
private double sensivity;
|
||||
|
||||
/**
|
||||
* Since an acceleration sensor usually provides information even
|
||||
* if it doesn't move, this filter removes the data if it's in the
|
||||
* idle state.
|
||||
*/
|
||||
public IdleStateFilter() {
|
||||
super();
|
||||
this.sensivity = 0.1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
// not needed
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] filterAlgorithm(double[] vector) {
|
||||
// calculate values needed for filtering:
|
||||
// absolute value
|
||||
double absvalue = Math.sqrt((vector[0]*vector[0])+
|
||||
(vector[1]*vector[1])+(vector[2]*vector[2]));
|
||||
|
||||
// filter formulaes and return values
|
||||
if(absvalue > 1+this.sensivity ||
|
||||
absvalue < 1-this.sensivity) {
|
||||
return vector;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the absolute value when the wiimote should react to acceleration.
|
||||
* This is a parameter for the first of the two filters: idle state
|
||||
* filter. For example: sensivity=0.2 makes the wiimote react to acceleration
|
||||
* where the absolute value is equal or greater than 1.2g. The default value 0.1
|
||||
* should work well. Only change if you are sure what you're doing.
|
||||
*
|
||||
* @param sensivity
|
||||
* acceleration data values smaller than this value wouldn't be detected.
|
||||
*/
|
||||
public void setSensivity(double sensivity) {
|
||||
this.sensivity = sensivity;
|
||||
}
|
||||
|
||||
public double getSensivity() {
|
||||
return this.sensivity;
|
||||
}
|
||||
|
||||
}
|
||||
67
src/org/wiigee/filter/LowPassFilter.java
Normal file
67
src/org/wiigee/filter/LowPassFilter.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.filter;
|
||||
|
||||
/**
|
||||
*
|
||||
* This filter removes every acceleration that happens fast or
|
||||
* suddenly (like e.g. a short hit). Remember: It _passes_ acceleration
|
||||
* with a slight variety.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class LowPassFilter extends Filter {
|
||||
|
||||
private double factor;
|
||||
private double[] prevAcc;
|
||||
|
||||
public LowPassFilter() {
|
||||
super();
|
||||
this.factor = 0.01;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public LowPassFilter(double factor) {
|
||||
super();
|
||||
this.factor = factor;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.prevAcc = new double[] {0.0, 0.0, 0.0};
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] filterAlgorithm(double[] vector) {
|
||||
double[] retVal = new double[3];
|
||||
retVal[0] = vector[0] * this.factor + this.prevAcc[0] * (1.0 - this.factor);
|
||||
retVal[1] = vector[1] * this.factor + this.prevAcc[1] * (1.0 - this.factor);
|
||||
retVal[2] = vector[2] * this.factor + this.prevAcc[2] * (1.0 - this.factor);
|
||||
this.prevAcc = retVal;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
102
src/org/wiigee/filter/MotionDetectFilter.java
Executable file
102
src/org/wiigee/filter/MotionDetectFilter.java
Executable file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.filter;
|
||||
|
||||
import org.wiigee.device.Device;
|
||||
|
||||
/**
|
||||
* This filter uses time to determine if the wiimote actually is in motion
|
||||
* or not. This filter only works together with the IdleStateFilter.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class MotionDetectFilter extends Filter {
|
||||
|
||||
private int motionchangetime;
|
||||
private boolean nowinmotion;
|
||||
private long motionstartstamp;
|
||||
private Device device;
|
||||
|
||||
/***
|
||||
* Detects wheather the wiimote receives acceleration or not and
|
||||
* raises an event, if the device starts or stops. This is actual a
|
||||
* null filter, not manipulating anything. But looks pretty good in
|
||||
* this datatype since it could be removed easily.
|
||||
*
|
||||
* @param wiimote The Wiimote object which is controlled by the filter.
|
||||
*/
|
||||
public MotionDetectFilter(Device device) {
|
||||
super();
|
||||
this.device=device;
|
||||
this.reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.motionstartstamp=System.currentTimeMillis();
|
||||
this.nowinmotion=false;
|
||||
this.motionchangetime=190;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] filter(double[] vector) {
|
||||
|
||||
if(this.nowinmotion &&
|
||||
(System.currentTimeMillis()-this.motionstartstamp)>=
|
||||
this.motionchangetime) {
|
||||
this.nowinmotion=false;
|
||||
this.device.fireMotionStopEvent();
|
||||
} // fi
|
||||
|
||||
return filterAlgorithm(vector);
|
||||
}
|
||||
|
||||
public double[] filterAlgorithm(double[] vector) {
|
||||
if(vector!=null) {
|
||||
this.motionstartstamp=System.currentTimeMillis();
|
||||
if(!this.nowinmotion) {
|
||||
this.nowinmotion=true;
|
||||
this.motionstartstamp=System.currentTimeMillis();
|
||||
this.device.fireMotionStartEvent();
|
||||
}
|
||||
}
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the time the wiimote has to be in idle state before a new motion change
|
||||
* event appears. The default value 500ms should work well, only change it if you are sure
|
||||
* about what you're doing.
|
||||
* @param time Time in ms
|
||||
*/
|
||||
public void setMotionChangeTime(int time) {
|
||||
this.motionchangetime=time;
|
||||
}
|
||||
|
||||
public int getMotionChangeTime() {
|
||||
return this.motionchangetime;
|
||||
}
|
||||
|
||||
}
|
||||
109
src/org/wiigee/logic/Classifier.java
Normal file
109
src/org/wiigee/logic/Classifier.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
public class Classifier {
|
||||
|
||||
private Vector<GestureModel> gesturemodel; // each gesturetype got its own
|
||||
// gesturemodel in this vector
|
||||
private double lastprob;
|
||||
|
||||
public Classifier() {
|
||||
this.gesturemodel=new Vector<GestureModel>();
|
||||
this.lastprob=0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method recognize a specific gesture, given to the procedure.
|
||||
* For classification a bayes classification algorithm is used.
|
||||
*
|
||||
* @param g gesture to classify
|
||||
*/
|
||||
public int classifyGesture(Gesture g) {
|
||||
//Log.write("Recognizing gesture...");
|
||||
|
||||
// Wert im Nenner berechnen, nach Bayes
|
||||
double sum = 0;
|
||||
for(int i=0; i<this.gesturemodel.size(); i++) {
|
||||
sum+=this.gesturemodel.elementAt(i).getDefaultProbability()*
|
||||
this.gesturemodel.elementAt(i).matches(g);
|
||||
}
|
||||
|
||||
int recognized = -1; // which gesture has been recognized
|
||||
double recogprob = Integer.MIN_VALUE; // probability of this gesture
|
||||
double probgesture = 0; // temporal value for bayes algorithm
|
||||
double probmodel = 0; // temporal value for bayes algorithm
|
||||
for(int i=0; i<this.gesturemodel.size(); i++) {
|
||||
//this.gesturemodel.elementAt(i).print(); // Debug
|
||||
double tmpgesture = this.gesturemodel.elementAt(i).matches(g);
|
||||
double tmpmodel = this.gesturemodel.elementAt(i).getDefaultProbability();
|
||||
|
||||
if(((tmpmodel*tmpgesture)/sum)>recogprob) {
|
||||
probgesture=tmpgesture;
|
||||
probmodel=tmpmodel;
|
||||
recogprob=((tmpmodel*tmpgesture)/sum);
|
||||
recognized=i;
|
||||
}
|
||||
}
|
||||
|
||||
// a gesture could be recognized
|
||||
if(recogprob>0 && probmodel>0 && probgesture>0 && sum>0) {
|
||||
this.lastprob=recogprob;
|
||||
return recognized;
|
||||
} else {
|
||||
// no gesture could be recognized
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public double getLastProbability() {
|
||||
return this.lastprob;
|
||||
}
|
||||
|
||||
public void addGestureModel(GestureModel gm) {
|
||||
this.gesturemodel.add(gm);
|
||||
}
|
||||
|
||||
public GestureModel getGestureModel(int id) {
|
||||
return this.gesturemodel.elementAt(id);
|
||||
}
|
||||
|
||||
public Vector<GestureModel> getGestureModels() {
|
||||
return this.gesturemodel;
|
||||
}
|
||||
|
||||
public int getCountOfGestures() {
|
||||
return this.gesturemodel.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.gesturemodel = new Vector<GestureModel>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
155
src/org/wiigee/logic/Gesture.java
Executable file
155
src/org/wiigee/logic/Gesture.java
Executable file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
import org.wiigee.event.AccelerationEvent;
|
||||
|
||||
/**
|
||||
* This class represents ONE movement trajectory in a
|
||||
* concrete instance.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
|
||||
public class Gesture implements Cloneable {
|
||||
|
||||
/** Min/MaxAcceleration setup manually? */
|
||||
private boolean minmaxmanual;
|
||||
private double minacc;
|
||||
private double maxacc;
|
||||
|
||||
/** The complete trajectory as WiimoteAccelerationEvents
|
||||
* as a vector. It's a vector because we don't want to
|
||||
* loose the chronology of the stored events.
|
||||
*/
|
||||
private Vector<AccelerationEvent> data;
|
||||
|
||||
/**
|
||||
* Create an empty Gesture.
|
||||
*/
|
||||
public Gesture() {
|
||||
this.data = new Vector<AccelerationEvent>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a deep copy of another Gesture object.
|
||||
*
|
||||
* @param original Another Gesture object
|
||||
*/
|
||||
public Gesture(Gesture original) {
|
||||
this.data = new Vector<AccelerationEvent>();
|
||||
Vector<AccelerationEvent> origin = original.getData();
|
||||
for (int i = 0; i < origin.size(); i++) {
|
||||
this.add((AccelerationEvent) origin.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new acceleration event to this gesture.
|
||||
*
|
||||
* @param event The WiimoteAccelerationEvent to add.
|
||||
*/
|
||||
public void add(AccelerationEvent event) {
|
||||
this.data.add(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last acceleration added to this gesture.
|
||||
*
|
||||
* @return the last acceleration event added.
|
||||
*/
|
||||
public AccelerationEvent getLastData() {
|
||||
return (AccelerationEvent) this.data.get(this.data.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the whole chronological sequence of accelerations as
|
||||
* a vector.
|
||||
*
|
||||
* @return chronological sequence of accelerations.
|
||||
*/
|
||||
public Vector<AccelerationEvent> getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first element of the acceleration queue of a gesture
|
||||
*/
|
||||
public void removeFirstData() {
|
||||
this.data.remove(0);
|
||||
}
|
||||
|
||||
public int getCountOfData() {
|
||||
return this.data.size();
|
||||
}
|
||||
|
||||
public void setMaxAndMinAcceleration(double max, double min) {
|
||||
this.maxacc = max;
|
||||
this.minacc = min;
|
||||
this.minmaxmanual = true;
|
||||
}
|
||||
|
||||
public double getMaxAcceleration() {
|
||||
if(!this.minmaxmanual) {
|
||||
double maxacc = Double.MIN_VALUE;
|
||||
for(int i=0; i<this.data.size(); i++) {
|
||||
if(Math.abs(this.data.get(i).getX()) > maxacc) {
|
||||
maxacc=Math.abs(this.data.get(i).getX());
|
||||
}
|
||||
if(Math.abs(this.data.get(i).getY()) > maxacc) {
|
||||
maxacc=Math.abs(this.data.get(i).getY());
|
||||
}
|
||||
if(Math.abs(this.data.get(i).getZ()) > maxacc) {
|
||||
maxacc=Math.abs(this.data.get(i).getZ());
|
||||
}
|
||||
}
|
||||
return maxacc;
|
||||
} else {
|
||||
return this.maxacc;
|
||||
}
|
||||
}
|
||||
|
||||
public double getMinAcceleration() {
|
||||
if(!this.minmaxmanual) {
|
||||
double minacc = Double.MAX_VALUE;
|
||||
for(int i=0; i<this.data.size(); i++) {
|
||||
if(Math.abs(this.data.get(i).getX()) < minacc) {
|
||||
minacc=Math.abs(this.data.get(i).getX());
|
||||
}
|
||||
if(Math.abs(this.data.get(i).getY()) < minacc) {
|
||||
minacc=Math.abs(this.data.get(i).getY());
|
||||
}
|
||||
if(Math.abs(this.data.get(i).getZ()) < minacc) {
|
||||
minacc=Math.abs(this.data.get(i).getZ());
|
||||
}
|
||||
}
|
||||
return minacc;
|
||||
} else {
|
||||
return this.minacc;
|
||||
}
|
||||
}
|
||||
}
|
||||
205
src/org/wiigee/logic/GestureModel.java
Executable file
205
src/org/wiigee/logic/GestureModel.java
Executable file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
import org.wiigee.event.AccelerationEvent;
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
/**
|
||||
* This Class units a Quantizer-Component and an Model-Component.
|
||||
* In this implementation a k-mean-algorithm for quantization and
|
||||
* a hidden markov model as instance for the model has been used.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class GestureModel {
|
||||
|
||||
/** The number of states the hidden markov model consists of */
|
||||
private int numStates;
|
||||
|
||||
/** The number of observations for the hmm and k-mean */
|
||||
private int numObservations;
|
||||
|
||||
/** The quantization component */
|
||||
private Quantizer quantizer;
|
||||
|
||||
/** The statistical model, hidden markov model */
|
||||
private HMM markovmodell;
|
||||
|
||||
/** The default probability of this gesturemodel,
|
||||
* needed for the bayes classifier */
|
||||
private double defaultprobability;
|
||||
|
||||
|
||||
/** Creates a Unit (Quantizer&Model).
|
||||
*
|
||||
* @param id
|
||||
* int representation of a gesture "name"/class.
|
||||
*/
|
||||
public GestureModel() {
|
||||
this.numStates=8; // n=8 states empirical value
|
||||
this.numObservations=14; // k=14 observations empirical value
|
||||
this.markovmodell = new HMM(numStates, numObservations); // init model
|
||||
this.quantizer = new Quantizer(numStates); // init quantizer
|
||||
}
|
||||
|
||||
/**
|
||||
* Trains the model to a set of motion-sequences, representing
|
||||
* different evaluations of a gesture
|
||||
*
|
||||
* @param trainsequence a vector of gestures
|
||||
*/
|
||||
public void train(Vector<Gesture> trainsequence) {
|
||||
// summarize all vectors from the different gestures in one
|
||||
// gesture called sum.
|
||||
double maxacc=0;
|
||||
double minacc=0;
|
||||
Gesture sum = new Gesture();
|
||||
|
||||
for(int i=0; i<trainsequence.size(); i++) {
|
||||
Vector<AccelerationEvent> t = trainsequence.elementAt(i).getData();
|
||||
|
||||
// add the max and min acceleration, we later get the average
|
||||
maxacc+=trainsequence.elementAt(i).getMaxAcceleration();
|
||||
minacc+=trainsequence.elementAt(i).getMinAcceleration();
|
||||
|
||||
// transfer every single accelerationevent of each gesture to
|
||||
// the new gesture sum
|
||||
for(int j=0; j<trainsequence.elementAt(i).getData().size(); j++) {
|
||||
sum.add(t.elementAt(j));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// get the average and set it to the sum gesture
|
||||
sum.setMaxAndMinAcceleration(maxacc/trainsequence.size(), minacc/trainsequence.size());
|
||||
|
||||
// train the centeroids of the quantizer with this master gesture sum.
|
||||
this.quantizer.trainCenteroids(sum);
|
||||
|
||||
// convert gesture vector to a sequence of discrete values
|
||||
Vector<int[]> seqs = new Vector<int[]>();
|
||||
for(int i=0; i<trainsequence.size(); i++) {
|
||||
seqs.add(this.quantizer.getObservationSequence(trainsequence.elementAt(i)));
|
||||
}
|
||||
|
||||
// train the markov model with this derived discrete sequences
|
||||
this.markovmodell.train(seqs);
|
||||
|
||||
// set the default probability for use with the bayes classifier
|
||||
this.setDefaultProbability(trainsequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the probability that a gesture matches to this
|
||||
* gesture model.
|
||||
*
|
||||
* @param gesture a gesture to test.
|
||||
* @return probability that the gesture belongs to this gesture
|
||||
* model.
|
||||
*/
|
||||
public double matches(Gesture gesture) {
|
||||
int[] sequence = quantizer.getObservationSequence(gesture);
|
||||
return this.markovmodell.getProbability(sequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* For debug purposes or very technical interested people. :)
|
||||
*/
|
||||
public void printMap() {
|
||||
Log.write("Gesture Quantizer-Map:");
|
||||
this.quantizer.printMap();
|
||||
}
|
||||
|
||||
/***
|
||||
* For debug purposes or very technical interested people. :)
|
||||
* @return
|
||||
*/
|
||||
public void print() {
|
||||
Log.write("HMM-Print:");
|
||||
this.markovmodell.print();
|
||||
Log.write("Quanzizer-Print:");
|
||||
this.quantizer.printMap();
|
||||
}
|
||||
|
||||
public int getNumStates() {
|
||||
return this.numStates;
|
||||
}
|
||||
|
||||
public int getNumObservations() {
|
||||
return this.numObservations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the model probability for bayes.
|
||||
*
|
||||
* @return
|
||||
* the model probability
|
||||
*/
|
||||
public double getDefaultProbability() {
|
||||
return this.defaultprobability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the bayes classifier needs a model probability for
|
||||
* each model this has to be set once after training. As model
|
||||
* probability the average probability value has been choosen.
|
||||
*
|
||||
* TODO: try lowest or highest model probability as alternative
|
||||
*
|
||||
* @param defsequence the vector of training sequences.
|
||||
*/
|
||||
private void setDefaultProbability(Vector<Gesture> defsequence) {
|
||||
double prob=0;
|
||||
for(int i=0; i<defsequence.size(); i++) {
|
||||
prob+=this.matches(defsequence.elementAt(i));
|
||||
}
|
||||
|
||||
this.defaultprobability=(prob)/defsequence.size();
|
||||
}
|
||||
|
||||
public void setDefaultProbability(double prob) {
|
||||
this.defaultprobability = prob;
|
||||
Log.write("def-prob. set to = "+this.defaultprobability);
|
||||
}
|
||||
|
||||
public Quantizer getQuantizer() {
|
||||
return this.quantizer;
|
||||
}
|
||||
|
||||
public void setQuantizer(Quantizer q) {
|
||||
this.quantizer = q;
|
||||
}
|
||||
|
||||
public HMM getHMM() {
|
||||
return this.markovmodell;
|
||||
}
|
||||
|
||||
public void setHMM(HMM hmm) {
|
||||
this.markovmodell = hmm;
|
||||
}
|
||||
|
||||
}
|
||||
314
src/org/wiigee/logic/HMM.java
Executable file
314
src/org/wiigee/logic/HMM.java
Executable file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Vector;
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
/**
|
||||
* This is a Hidden Markov Model implementation which internally provides
|
||||
* the basic algorithms for training and recognition (forward and backward
|
||||
* algorithm). Since a regular Hidden Markov Model doesn't provide a possibility
|
||||
* to train multiple sequences, this implementation has been optimized for this
|
||||
* purposes using some state-of-the-art technologies described in several papers.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*
|
||||
*/
|
||||
|
||||
public class HMM {
|
||||
/** The number of states */
|
||||
protected int numStates;
|
||||
|
||||
/** The number of observations */
|
||||
protected int numObservations;
|
||||
|
||||
/** The initial probabilities for each state: p[state] */
|
||||
protected double pi[];
|
||||
|
||||
/** The state change probability to switch from state A to
|
||||
* state B: a[stateA][stateB] */
|
||||
protected double a[][];
|
||||
|
||||
/** The probability to emit symbol S in state A: b[stateA][symbolS] */
|
||||
protected double b[][];
|
||||
|
||||
/**
|
||||
* Initialize the Hidden Markov Model in a left-to-right version.
|
||||
*
|
||||
* @param numStates Number of states
|
||||
* @param numObservations Number of observations
|
||||
*/
|
||||
public HMM(int numStates, int numObservations) {
|
||||
this.numStates = numStates;
|
||||
this.numObservations = numObservations;
|
||||
pi = new double[numStates];
|
||||
a = new double[numStates][numStates];
|
||||
b = new double[numStates][numObservations];
|
||||
this.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the Hidden Markov Model to the initial left-to-right values.
|
||||
*
|
||||
*/
|
||||
private void reset() {
|
||||
int jumplimit = 2;
|
||||
|
||||
// set startup probability
|
||||
pi[0] = 1;
|
||||
for(int i=1; i<numStates; i++) {
|
||||
pi[i] = 0;
|
||||
}
|
||||
|
||||
// set state change probabilities in the left-to-right version
|
||||
// NOTE: i now that this is dirty and very static. :)
|
||||
for(int i=0; i<numStates; i++) {
|
||||
for(int j=0; j<numStates; j++) {
|
||||
if(i==numStates-1 && j==numStates-1) { // last row
|
||||
a[i][j] = 1.0;
|
||||
} else if(i==numStates-2 && j==numStates-2) { // next to last row
|
||||
a[i][j] = 0.5;
|
||||
} else if(i==numStates-2 && j==numStates-1) { // next to last row
|
||||
a[i][j] = 0.5;
|
||||
} else if(i<=j && i>j-jumplimit-1) {
|
||||
a[i][j] = 1.0/(jumplimit+1);
|
||||
} else {
|
||||
a[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// emission probability
|
||||
for(int i=0; i<numStates; i++) {
|
||||
for(int j=0; j<numObservations; j++) {
|
||||
b[i][j] = 1.0/(double)numObservations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trains the Hidden Markov Model with multiple sequences.
|
||||
* This method is normally not known to basic hidden markov
|
||||
* models, because they usually use the Baum-Welch-Algorithm.
|
||||
* This method is NOT the traditional Baum-Welch-Algorithm.
|
||||
*
|
||||
* If you want to know in detail how it works please consider
|
||||
* my Individuelles Projekt paper on the wiigee Homepage. Also
|
||||
* there exist some english literature on the world wide web.
|
||||
* Try to search for some papers by Rabiner or have a look at
|
||||
* Vesa-Matti Mäntylä - "Discrete Hidden Markov Models with
|
||||
* application to isolated user-dependent hand gesture recognition".
|
||||
*
|
||||
*/
|
||||
public void train(Vector<int[]> trainsequence) {
|
||||
|
||||
double[][] a_new = new double[a.length][a.length];
|
||||
double[][] b_new = new double[b.length][b[0].length];
|
||||
// re calculate state change probability a
|
||||
for(int i=0; i<a.length; i++) {
|
||||
for(int j=0; j<a[i].length; j++) {
|
||||
double zaehler=0;
|
||||
double nenner=0;
|
||||
|
||||
for(int k=0; k<trainsequence.size(); k++) {
|
||||
int[] sequence = trainsequence.elementAt(k);
|
||||
|
||||
double[][] fwd = this.forwardProc(sequence);
|
||||
double[][] bwd = this.backwardProc(sequence);
|
||||
double prob = this.getProbability(sequence);
|
||||
|
||||
double zaehler_innersum=0;
|
||||
double nenner_innersum=0;
|
||||
|
||||
|
||||
for(int t=0; t<sequence.length-1; t++) {
|
||||
zaehler_innersum+=fwd[i][t]*a[i][j]*b[j][sequence[t+1]]*bwd[j][t+1];
|
||||
nenner_innersum+=fwd[i][t]*bwd[i][t];
|
||||
}
|
||||
zaehler+=(1/prob)*zaehler_innersum;
|
||||
nenner+=(1/prob)*nenner_innersum;
|
||||
} // k
|
||||
|
||||
a_new[i][j] = zaehler/nenner;
|
||||
} // j
|
||||
} // i
|
||||
|
||||
// re calculate emission probability b
|
||||
for(int i=0; i<b.length; i++) { // zustaende
|
||||
for(int j=0; j<b[i].length; j++) { // symbole
|
||||
double zaehler=0;
|
||||
double nenner=0;
|
||||
|
||||
for(int k=0; k<trainsequence.size(); k++) {
|
||||
int[] sequence = trainsequence.elementAt(k);
|
||||
|
||||
double[][] fwd = this.forwardProc(sequence);
|
||||
double[][] bwd = this.backwardProc(sequence);
|
||||
double prob = this.getProbability(sequence);
|
||||
|
||||
double zaehler_innersum=0;
|
||||
double nenner_innersum=0;
|
||||
|
||||
|
||||
for(int t=0; t<sequence.length-1; t++) {
|
||||
if(sequence[t]==j) {
|
||||
zaehler_innersum+=fwd[i][t]*bwd[i][t];
|
||||
}
|
||||
nenner_innersum+=fwd[i][t]*bwd[i][t];
|
||||
}
|
||||
zaehler+=(1/prob)*zaehler_innersum;
|
||||
nenner+=(1/prob)*nenner_innersum;
|
||||
} // k
|
||||
|
||||
b_new[i][j] = zaehler/nenner;
|
||||
} // j
|
||||
} // i
|
||||
|
||||
this.a=a_new;
|
||||
this.b=b_new;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traditional Forward Algorithm.
|
||||
*
|
||||
* @param o the observationsequence O
|
||||
* @return Array[State][Time]
|
||||
*
|
||||
*/
|
||||
protected double[][] forwardProc(int[] o) {
|
||||
double[][] f = new double[numStates][o.length];
|
||||
for (int l = 0; l < f.length; l++) {
|
||||
f[l][0] = pi[l] * b[l][o[0]];
|
||||
}
|
||||
for (int i = 1; i < o.length; i++) {
|
||||
for (int k = 0; k < f.length; k++) {
|
||||
double sum = 0;
|
||||
for (int l = 0; l < numStates; l++) {
|
||||
sum += f[l][i-1] * a[l][k];
|
||||
}
|
||||
f[k][i] = sum * b[k][o[i]];
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the probability that a observation sequence O belongs
|
||||
* to this Hidden Markov Model without using the bayes classifier.
|
||||
* Internally the well known forward algorithm is used.
|
||||
*
|
||||
* @param o observation sequence
|
||||
* @return probability that sequence o belongs to this hmm
|
||||
*/
|
||||
public double getProbability(int[] o) {
|
||||
double prob = 0.0;
|
||||
double[][] forward = this.forwardProc(o);
|
||||
// add probabilities
|
||||
for (int i = 0; i < forward.length; i++) { // for every state
|
||||
prob += forward[i][forward[i].length - 1];
|
||||
}
|
||||
return prob;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Backward algorithm.
|
||||
*
|
||||
* @param o observation sequence o
|
||||
* @return Array[State][Time]
|
||||
*/
|
||||
protected double[][] backwardProc(int[] o) {
|
||||
int T = o.length;
|
||||
double[][] bwd = new double[numStates][T];
|
||||
/* Basisfall */
|
||||
for (int i = 0; i < numStates; i++)
|
||||
bwd[i][T - 1] = 1;
|
||||
/* Induktion */
|
||||
for (int t = T - 2; t >= 0; t--) {
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
bwd[i][t] = 0;
|
||||
for (int j = 0; j < numStates; j++)
|
||||
bwd[i][t] += (bwd[j][t + 1] * a[i][j] * b[j][o[t + 1]]);
|
||||
}
|
||||
}
|
||||
return bwd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prints everything about this model, including
|
||||
* all values. For debug purposes or if you want
|
||||
* to comprehend what happend to the model.
|
||||
*
|
||||
*/
|
||||
public void print() {
|
||||
DecimalFormat fmt = new DecimalFormat();
|
||||
fmt.setMinimumFractionDigits(5);
|
||||
fmt.setMaximumFractionDigits(5);
|
||||
for (int i = 0; i < numStates; i++)
|
||||
Log.write("pi(" + i + ") = " + fmt.format(pi[i]));
|
||||
Log.write("");
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
for (int j = 0; j < numStates; j++)
|
||||
Log.write("a(" + i + "," + j + ") = "
|
||||
+ fmt.format(a[i][j]) + " ");
|
||||
Log.write("");
|
||||
}
|
||||
Log.write("");
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
for (int k = 0; k < numObservations; k++)
|
||||
Log.write("b(" + i + "," + k + ") = "
|
||||
+ fmt.format(b[i][k]) + " ");
|
||||
Log.write("");
|
||||
}
|
||||
}
|
||||
|
||||
public double[] getPi() {
|
||||
return this.pi;
|
||||
}
|
||||
|
||||
public void setPi(double[] pi) {
|
||||
this.pi = pi;
|
||||
}
|
||||
|
||||
public double[][] getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
public void setA(double[][] a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public double[][] getB() {
|
||||
return this.b;
|
||||
}
|
||||
|
||||
public void setB(double[][] b) {
|
||||
this.b=b;
|
||||
}
|
||||
}
|
||||
449
src/org/wiigee/logic/PreciseHMM.java
Executable file
449
src/org/wiigee/logic/PreciseHMM.java
Executable file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
import java.text.*;
|
||||
import java.util.Vector;
|
||||
import java.lang.Math;
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
/**
|
||||
* This is a Hidden Markov Model implementation which internally provides
|
||||
* the basic algorithms for training and recognition (forward and backward
|
||||
* algorithm). Since a regular Hidden Markov Model doesn't provide a possibility
|
||||
* to train multiple sequences, this implementation has been optimized for this
|
||||
* purposes using some state-of-the-art technologies described in several papers.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*
|
||||
*/
|
||||
|
||||
public class PreciseHMM {
|
||||
/** The number of states */
|
||||
private int numStates;
|
||||
|
||||
/** The number of observations */
|
||||
private int sigmaSize;
|
||||
|
||||
/** The initial probabilities for each state: p[state] */
|
||||
public double pi[];
|
||||
|
||||
/** The state change probability to switch from state A to
|
||||
* state B: a[stateA][stateB] */
|
||||
public double a[][];
|
||||
|
||||
/** The probability to emit symbol S in state A: b[stateA][symbolS] */
|
||||
public double b[][];
|
||||
|
||||
/**
|
||||
* Initialize the Hidden Markov Model in a left-to-right version.
|
||||
*
|
||||
* @param numStates Number of states
|
||||
* @param sigmaSize Number of observations
|
||||
*/
|
||||
public PreciseHMM(int numStates, int sigmaSize) {
|
||||
this.numStates = numStates;
|
||||
this.sigmaSize = sigmaSize;
|
||||
pi = new double[numStates];
|
||||
a = new double[numStates][numStates];
|
||||
b = new double[numStates][sigmaSize];
|
||||
this.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the Hidden Markov Model to the initial left-to-right values.
|
||||
*
|
||||
*/
|
||||
private void reset() {
|
||||
int jumplimit = 2;
|
||||
|
||||
// set startup probability
|
||||
pi[0] = 1.0;
|
||||
for(int i=1; i<numStates; i++) {
|
||||
pi[i] = 0;
|
||||
}
|
||||
|
||||
// set state change probabilities in the left-to-right version
|
||||
// NOTE: i now that this is dirty and very static. :)
|
||||
for(int i=0; i<numStates; i++) {
|
||||
for(int j=0; j<numStates; j++) {
|
||||
if(i==numStates-1 && j==numStates-1) { // last row
|
||||
a[i][j] = 1.0;
|
||||
} else if(i==numStates-2 && j==numStates-2) { // next to last row
|
||||
a[i][j] = 0.5;
|
||||
} else if(i==numStates-2 && j==numStates-1) { // next to last row
|
||||
a[i][j] = 0.5;
|
||||
} else if(i<=j && i>j-jumplimit-1) {
|
||||
a[i][j] = 1.0/(jumplimit+1);
|
||||
} else {
|
||||
a[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emission probability
|
||||
for(int i=0; i<numStates; i++) {
|
||||
for(int j=0; j<sigmaSize; j++) {
|
||||
b[i][j] = 1.0/(double)sigmaSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trains the Hidden Markov Model with multiple sequences.
|
||||
* This method is normally not known to basic hidden markov
|
||||
* models, because they usually use the Baum-Welch-Algorithm.
|
||||
* This method is NOT the traditional Baum-Welch-Algorithm.
|
||||
*
|
||||
* If you want to know in detail how it works please consider
|
||||
* my Individuelles Projekt paper on the wiigee Homepage. Also
|
||||
* there exist some english literature on the world wide web.
|
||||
* Try to search for some papers by Rabiner or have a look at
|
||||
* Vesa-Matti Mäntylä - "Discrete Hidden Markov Models with
|
||||
* application to isolated user-dependent hand gesture recognition".
|
||||
*
|
||||
*/
|
||||
public void train(Vector<int[]> trainsequence) {
|
||||
|
||||
double[][] a_new = new double[a.length][a.length];
|
||||
double[][] b_new = new double[b.length][b[0].length];
|
||||
// re calculate state change probability a
|
||||
for(int i=0; i<a.length; i++) {
|
||||
for(int j=0; j<a[i].length; j++) {
|
||||
double zaehler=0;
|
||||
double nenner=0;
|
||||
|
||||
for(int k=0; k<trainsequence.size(); k++) {
|
||||
//this.reset();
|
||||
int[] sequence = trainsequence.elementAt(k);
|
||||
|
||||
double[] sf = this.calculateScalingFactor(sequence);
|
||||
double[][] fwd = this.scaledForwardProc(sequence);
|
||||
double[][] bwd = this.scaledBackwardProc(sequence, sf);
|
||||
|
||||
double zaehler_innersum=0;
|
||||
double nenner_innersum=0;
|
||||
|
||||
for(int t=0; t<sequence.length-1; t++) {
|
||||
zaehler_innersum+=fwd[i][t]*a[i][j]*b[j][sequence[t+1]]*bwd[j][t+1]*sf[t+1];
|
||||
nenner_innersum+=fwd[i][t]*bwd[i][t];
|
||||
}
|
||||
zaehler+=zaehler_innersum;
|
||||
nenner+=nenner_innersum;
|
||||
} // k
|
||||
|
||||
a_new[i][j] = zaehler/nenner;
|
||||
} // j
|
||||
} // i
|
||||
|
||||
// re calculate emission probability b
|
||||
for(int i=0; i<b.length; i++) { // zustaende
|
||||
for(int j=0; j<b[i].length; j++) { // symbole
|
||||
double zaehler=0;
|
||||
double nenner=0;
|
||||
|
||||
for(int k=0; k<trainsequence.size(); k++) {
|
||||
//this.reset();
|
||||
int[] sequence = trainsequence.elementAt(k);
|
||||
|
||||
double[] sf = this.calculateScalingFactor(sequence);
|
||||
double[][] fwd = this.scaledForwardProc(sequence);
|
||||
double[][] bwd = this.scaledBackwardProc(sequence, sf);
|
||||
|
||||
double zaehler_innersum=0;
|
||||
double nenner_innersum=0;
|
||||
|
||||
for(int t=0; t<sequence.length-1; t++) {
|
||||
if(sequence[t]==j) {
|
||||
zaehler_innersum+=fwd[i][t]*bwd[i][t]*sf[t];
|
||||
}
|
||||
nenner_innersum+=fwd[i][t]*bwd[i][t]*sf[t];
|
||||
}
|
||||
zaehler+=zaehler_innersum;
|
||||
nenner+=nenner_innersum;
|
||||
} // k
|
||||
|
||||
b_new[i][j] = zaehler/nenner;
|
||||
} // j
|
||||
} // i
|
||||
|
||||
this.a=a_new;
|
||||
this.b=b_new;
|
||||
}
|
||||
|
||||
|
||||
private double[] calculateScalingFactor(int[] sequence) {
|
||||
// for all indexing: [state][time]
|
||||
double[][] fwd = this.forwardProc(sequence); // normal
|
||||
double[][] help = new double[fwd.length][fwd[0].length];
|
||||
double[][] scaled = new double[fwd.length][fwd[0].length];
|
||||
double[] sf = new double[sequence.length];
|
||||
|
||||
// ************** BASIS *************
|
||||
// Basis, fixed t=0
|
||||
// setup, because needed for further calculations
|
||||
for(int i=0; i<help.length; i++) {
|
||||
help[i][0] = fwd[i][0];
|
||||
}
|
||||
|
||||
// setup initial scaled array
|
||||
double sum0 = 0;
|
||||
for(int i=0; i<help.length; i++) {
|
||||
sum0+=help[i][0];
|
||||
}
|
||||
|
||||
for(int i=0; i<scaled.length; i++) {
|
||||
scaled[i][0] = help[i][0] / sum0;
|
||||
}
|
||||
|
||||
// calculate scaling factor
|
||||
sf[0] = 1/sum0;
|
||||
|
||||
// **************** INDUCTION ***************
|
||||
// end of fixed t = 0
|
||||
// starting with t>1 to sequence.length
|
||||
// induction, further calculations
|
||||
for(int t=1; t<sequence.length; t++) {
|
||||
// calculate help
|
||||
for(int i=0; i<help.length; i++) {
|
||||
for(int j=0; j<this.numStates; j++) {
|
||||
help[i][t]+=scaled[j][t-1]*a[j][i]*b[i][sequence[t]];
|
||||
}
|
||||
}
|
||||
|
||||
double sum = 0;
|
||||
for(int i=0; i<help.length; i++) {
|
||||
sum+=help[i][t];
|
||||
}
|
||||
|
||||
for(int i=0; i<scaled.length; i++) {
|
||||
scaled[i][t] = help[i][t] / sum;
|
||||
}
|
||||
|
||||
// calculate scaling factor
|
||||
sf[t] = 1 / sum;
|
||||
|
||||
} // t
|
||||
|
||||
return sf;
|
||||
} // calculateScalingFactor
|
||||
|
||||
/***
|
||||
* Returns the scaled Forward variable.
|
||||
* TODO: Maybe try out if the other precalculated method is faster.
|
||||
* @param sequence
|
||||
* @return
|
||||
*/
|
||||
private double[][] scaledForwardProc(int[] sequence) {
|
||||
double[][] fwd = this.forwardProc(sequence);
|
||||
double[][] out = new double[fwd.length][fwd[0].length];
|
||||
for(int i=0; i<fwd.length; i++) {
|
||||
for(int t=0; t<sequence.length; t++) {
|
||||
double sum = 0;
|
||||
for(int j=0; j<fwd.length; j++) {
|
||||
sum+=fwd[j][t];
|
||||
}
|
||||
out[i][t] = fwd[i][t] / sum;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private double[][] scaledBackwardProc(int[] sequence, double[] sf) {
|
||||
double[][] bwd = this.backwardProc(sequence);
|
||||
double[][] out = new double[bwd.length][bwd[0].length];
|
||||
for(int i=0; i<bwd.length; i++) {
|
||||
for(int t=0; t<sequence.length; t++) {
|
||||
out[i][t]=1;
|
||||
for(int r=t+1; r<sequence.length; r++) {
|
||||
out[i][t]*=sf[r]*bwd[i][t];
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the probability that a observation sequence O belongs
|
||||
* to this Hidden Markov Model without using the bayes classifier.
|
||||
* Internally the well known forward algorithm is used.
|
||||
*
|
||||
* @param o observation sequence
|
||||
* @return probability that sequence o belongs to this hmm
|
||||
*/
|
||||
public double getProbability(int[] o) {
|
||||
return scaledViterbi(o);
|
||||
//return sProbability(o);
|
||||
/*double prob = 0.0;
|
||||
double[][] forward = this.forwardProc(o);
|
||||
// add probabilities
|
||||
for (int i = 0; i < forward.length; i++) { // for every state
|
||||
prob += forward[i][forward[i].length - 1];
|
||||
}
|
||||
return prob;*/
|
||||
}
|
||||
|
||||
public double sProbability(int[] o) {
|
||||
double prod = 1.0;
|
||||
double[][] fwd = this.scaledForwardProc(o);
|
||||
for(int t=0; t<o.length; t++) {
|
||||
double sum = 0.0;
|
||||
for(int i=0; i<this.numStates; i++) {
|
||||
sum+=fwd[i][t];
|
||||
}
|
||||
sum = 1/sum;
|
||||
prod*=sum;
|
||||
}
|
||||
return 1/prod;
|
||||
}
|
||||
|
||||
public double scaledViterbi(int[] o) {
|
||||
double[][] phi = new double[this.numStates][o.length]; //phi[states][oseq]
|
||||
// init
|
||||
for(int i=0; i<this.numStates; i++) {
|
||||
phi[i][0] = Math.log(pi[i]) + Math.log(b[i][o[0]]);
|
||||
}
|
||||
// induction
|
||||
for(int t=1; t<o.length; t++) {
|
||||
for(int j=0; j<this.numStates; j++) {
|
||||
double max = Double.NEGATIVE_INFINITY;
|
||||
for(int i=0; i<this.numStates; i++) {
|
||||
double val = phi[i][t-1] + Math.log(this.a[i][j]);
|
||||
if(val>max) {
|
||||
max = val;
|
||||
}
|
||||
}
|
||||
|
||||
phi[j][t] = max + Math.log(this.b[j][o[t]]);
|
||||
}
|
||||
}
|
||||
// conclusion
|
||||
double lp = Double.NEGATIVE_INFINITY;
|
||||
for(int i=0; i<this.numStates; i++) {
|
||||
if(phi[i][o.length-1]>lp) {
|
||||
lp = phi[i][o.length-1];
|
||||
}
|
||||
}
|
||||
|
||||
//Log.write("log p = "+lp);
|
||||
//return lp;
|
||||
// we now have log10(p) calculated, transform to p.
|
||||
Log.write("prob = "+Math.exp(lp));
|
||||
return Math.exp(lp);
|
||||
//return Math.pow(10, lp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Traditional Forward Algorithm.
|
||||
*
|
||||
* @param o the observationsequence O
|
||||
* @return Array[State][Time]
|
||||
*
|
||||
*/
|
||||
private double[][] forwardProc(int[] o) {
|
||||
double[][] f = new double[numStates][o.length];
|
||||
for (int l = 0; l < f.length; l++) {
|
||||
f[l][0] = pi[l] * b[l][o[0]];
|
||||
}
|
||||
for (int i = 1; i < o.length; i++) {
|
||||
for (int k = 0; k < f.length; k++) {
|
||||
double sum = 0;
|
||||
for (int l = 0; l < numStates; l++) {
|
||||
sum += f[l][i-1] * a[l][k];
|
||||
}
|
||||
f[k][i] = sum * b[k][o[i]];
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backward algorithm.
|
||||
*
|
||||
* @param o observation sequence o
|
||||
* @return Array[State][Time]
|
||||
*/
|
||||
private double[][] backwardProc(int[] o) {
|
||||
int T = o.length;
|
||||
double[][] bwd = new double[numStates][T];
|
||||
/* Basisfall */
|
||||
for (int i = 0; i < numStates; i++)
|
||||
bwd[i][T - 1] = 1;
|
||||
/* Induktion */
|
||||
for (int t = T - 2; t >= 0; t--) {
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
bwd[i][t] = 0;
|
||||
for (int j = 0; j < numStates; j++)
|
||||
bwd[i][t] += (bwd[j][t + 1] * a[i][j] * b[j][o[t + 1]]);
|
||||
}
|
||||
}
|
||||
return bwd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prints everything about this model, including
|
||||
* all values. For debug purposes or if you want
|
||||
* to comprehend what happend to the model.
|
||||
*
|
||||
*/
|
||||
public void print() {
|
||||
DecimalFormat fmt = new DecimalFormat();
|
||||
fmt.setMinimumFractionDigits(10);
|
||||
fmt.setMaximumFractionDigits(10);
|
||||
for (int i = 0; i < numStates; i++)
|
||||
Log.write("pi(" + i + ") = " + fmt.format(pi[i]));
|
||||
Log.write("");
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
for (int j = 0; j < numStates; j++)
|
||||
Log.write("a(" + i + "," + j + ") = "
|
||||
+ fmt.format(a[i][j]) + " ");
|
||||
Log.write("");
|
||||
}
|
||||
Log.write("");
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
for (int k = 0; k < sigmaSize; k++)
|
||||
Log.write("b(" + i + "," + k + ") = "
|
||||
+ fmt.format(b[i][k]) + " ");
|
||||
Log.write("");
|
||||
}
|
||||
}
|
||||
|
||||
public double[][] getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
public void setA(double[][] a) {
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public double[][] getB() {
|
||||
return this.b;
|
||||
}
|
||||
|
||||
public void setB(double[][] b) {
|
||||
this.b=b;
|
||||
}
|
||||
}
|
||||
72
src/org/wiigee/logic/ProcessingUnit.java
Normal file
72
src/org/wiigee/logic/ProcessingUnit.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.wiigee.event.AccelerationEvent;
|
||||
import org.wiigee.event.ButtonPressedEvent;
|
||||
import org.wiigee.event.ButtonReleasedEvent;
|
||||
import org.wiigee.event.AccelerationListener;
|
||||
import org.wiigee.event.ButtonListener;
|
||||
import org.wiigee.event.GestureEvent;
|
||||
import org.wiigee.event.GestureListener;
|
||||
import org.wiigee.event.MotionStartEvent;
|
||||
import org.wiigee.event.MotionStopEvent;
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
public abstract class ProcessingUnit implements AccelerationListener, ButtonListener {
|
||||
|
||||
// Classifier
|
||||
protected Classifier classifier;
|
||||
|
||||
// Listener
|
||||
private Vector<GestureListener> gesturelistener = new Vector<GestureListener>();
|
||||
|
||||
public ProcessingUnit() {
|
||||
this.classifier = new Classifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an GestureListener to receive GestureEvents.
|
||||
*
|
||||
* @param g
|
||||
* Class which implements GestureListener interface.
|
||||
*/
|
||||
public void addGestureListener(GestureListener g) {
|
||||
this.gesturelistener.add(g);
|
||||
}
|
||||
|
||||
protected void fireGestureEvent(boolean valid, int id, double probability) {
|
||||
GestureEvent w = new GestureEvent(this, valid, id, probability);
|
||||
for (int i = 0; i < this.gesturelistener.size(); i++) {
|
||||
this.gesturelistener.get(i).gestureReceived(w);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void accelerationReceived(AccelerationEvent event);
|
||||
|
||||
public abstract void buttonPressReceived(ButtonPressedEvent event);
|
||||
|
||||
public abstract void buttonReleaseReceived(ButtonReleasedEvent event);
|
||||
|
||||
public abstract void motionStartReceived(MotionStartEvent event);
|
||||
|
||||
public abstract void motionStopReceived(MotionStopEvent event);
|
||||
|
||||
/**
|
||||
* Resets the complete gesturemodel. After reset no gesture is known
|
||||
* to the system.
|
||||
*/
|
||||
public void reset() {
|
||||
if (this.classifier.getCountOfGestures() > 0) {
|
||||
this.classifier.clear();
|
||||
Log.write("### Model reset ###");
|
||||
} else {
|
||||
Log.write("There doesn't exist any data to reset.");
|
||||
}
|
||||
}
|
||||
|
||||
// File IO
|
||||
public abstract void loadGesture(String filename);
|
||||
|
||||
public abstract void saveGesture(int id, String filename);
|
||||
}
|
||||
309
src/org/wiigee/logic/Quantizer.java
Executable file
309
src/org/wiigee/logic/Quantizer.java
Executable file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
import org.wiigee.event.AccelerationEvent;
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
/**
|
||||
* This class implements a quantization component. In this case a
|
||||
* k-mean-algorithm is used. In this case the initial values of the algorithm
|
||||
* are ordered as two intersected circles, representing an abstract globe with
|
||||
* k=14 elements. As a special feature the radius of this globe would be
|
||||
* calculated dynamically before the training of this component.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class Quantizer {
|
||||
|
||||
/** This is the initial radius of this model. */
|
||||
private double radius;
|
||||
|
||||
/** Number of states from the following Hidden Markov Model */
|
||||
private int numStates;
|
||||
|
||||
/** The representation of the so called Centeroids */
|
||||
private double[][] map;
|
||||
|
||||
/** True, if map is already trained. */
|
||||
private boolean maptrained;
|
||||
|
||||
/**
|
||||
* Initialize a empty quantizer. The states variable is necessary since some
|
||||
* algorithms need this value to calculate their values correctly.
|
||||
*
|
||||
* @param numStates
|
||||
* number of hidden markov model states
|
||||
*/
|
||||
public Quantizer(int numStates) {
|
||||
this.numStates = numStates;
|
||||
this.map = new double[14][3];
|
||||
this.maptrained = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trains this Quantizer with a specific gesture. This means that the
|
||||
* positions of the centeroids would adapt to this training gesture. In our
|
||||
* case this would happen with a summarized virtual gesture, containing all
|
||||
* the other gestures.
|
||||
*
|
||||
* @param gesture
|
||||
* the summarized virtual gesture
|
||||
*/
|
||||
public void trainCenteroids(Gesture gesture) {
|
||||
Vector<AccelerationEvent> data = gesture.getData();
|
||||
double pi = Math.PI;
|
||||
this.radius = (gesture.getMaxAcceleration() + gesture
|
||||
.getMinAcceleration()) / 2;
|
||||
Log.write("Using radius: " + this.radius);
|
||||
|
||||
// x , z , y
|
||||
if (!this.maptrained) {
|
||||
this.maptrained = true;
|
||||
this.map[0] = new double[] { this.radius, 0.0, 0.0 };
|
||||
this.map[1] = new double[] { Math.cos(pi / 4) * this.radius, 0.0,
|
||||
Math.sin(pi / 4) * this.radius };
|
||||
this.map[2] = new double[] { 0.0, 0.0, this.radius };
|
||||
this.map[3] = new double[] { Math.cos(pi * 3 / 4) * this.radius,
|
||||
0.0, Math.sin(pi * 3 / 4) * this.radius };
|
||||
this.map[4] = new double[] { -this.radius, 0.0, 0.0 };
|
||||
this.map[5] = new double[] { Math.cos(pi * 5 / 4) * this.radius,
|
||||
0.0, Math.sin(pi * 5 / 4) * this.radius };
|
||||
this.map[6] = new double[] { 0.0, 0.0, -this.radius };
|
||||
this.map[7] = new double[] { Math.cos(pi * 7 / 4) * this.radius,
|
||||
0.0, Math.sin(pi * 7 / 4) * this.radius };
|
||||
|
||||
this.map[8] = new double[] { 0.0, this.radius, 0.0 };
|
||||
this.map[9] = new double[] { 0.0, Math.cos(pi / 4) * this.radius,
|
||||
Math.sin(pi / 4) * this.radius };
|
||||
this.map[10] = new double[] { 0.0,
|
||||
Math.cos(pi * 3 / 4) * this.radius,
|
||||
Math.sin(pi * 3 / 4) * this.radius };
|
||||
this.map[11] = new double[] { 0.0, -this.radius, 0.0 };
|
||||
this.map[12] = new double[] { 0.0,
|
||||
Math.cos(pi * 5 / 4) * this.radius,
|
||||
Math.sin(pi * 5 / 4) * this.radius };
|
||||
this.map[13] = new double[] { 0.0,
|
||||
Math.cos(pi * 7 / 4) * this.radius,
|
||||
Math.sin(pi * 7 / 4) * this.radius };
|
||||
}
|
||||
|
||||
int[][] g_alt = new int[this.map.length][data.size()];
|
||||
int[][] g = new int[this.map.length][data.size()];
|
||||
|
||||
do {
|
||||
// Derive new Groups...
|
||||
g_alt = this.copyarray(g);
|
||||
g = this.deriveGroups(gesture);
|
||||
|
||||
// calculate new centeroids
|
||||
for (int i = 0; i < this.map.length; i++) {
|
||||
double zaehlerX = 0;
|
||||
double zaehlerY = 0;
|
||||
double zaehlerZ = 0;
|
||||
int nenner = 0;
|
||||
for (int j = 0; j < data.size(); j++) {
|
||||
if (g[i][j] == 1) {
|
||||
zaehlerX += data.elementAt(j).getX();
|
||||
zaehlerY += data.elementAt(j).getY();
|
||||
zaehlerZ += data.elementAt(j).getZ();
|
||||
nenner++;
|
||||
}
|
||||
}
|
||||
if (nenner > 1) { // nur wenn der nenner>0 oder >1??? ist muss
|
||||
// was
|
||||
// geaendert werden
|
||||
// Log.write("Setze neuen Centeroid!");
|
||||
this.map[i] = new double[] {(zaehlerX / (double) nenner),
|
||||
(zaehlerY / (double) nenner),
|
||||
(zaehlerZ / (double) nenner) };
|
||||
// Log.write("Centeroid: "+i+": "+newcenteroid[0]+":"+newcenteroid[1]);
|
||||
}
|
||||
} // new centeroids
|
||||
|
||||
} while (!equalarrays(g_alt, g));
|
||||
|
||||
// Debug: Printout groups
|
||||
/*
|
||||
* for (int i = 0; i < n; i++) { for (int j = 0; j < this.data.size();
|
||||
* j++) { Log.write(g[i][j] + "|"); } Log.write(""); }
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods looks up a Gesture to a group matrix, used by the
|
||||
* k-mean-algorithm (traincenteroid method) above.
|
||||
*
|
||||
* @param gesture
|
||||
* the gesture
|
||||
*/
|
||||
public int[][] deriveGroups(Gesture gesture) {
|
||||
Vector<AccelerationEvent> data = gesture.getData();
|
||||
int[][] groups = new int[this.map.length][data.size()];
|
||||
|
||||
// Calculate cartesian distance
|
||||
double[][] d = new double[this.map.length][data.size()];
|
||||
double[] curr = new double[3];
|
||||
double[] vector = new double[3];
|
||||
for (int i = 0; i < this.map.length; i++) { // zeilen
|
||||
double[] ref = this.map[i];
|
||||
for (int j = 0; j < data.size(); j++) { // spalten
|
||||
|
||||
curr[0] = data.elementAt(j).getX();
|
||||
curr[1] = data.elementAt(j).getY();
|
||||
curr[2] = data.elementAt(j).getZ();
|
||||
|
||||
vector[0] = ref[0] - curr[0];
|
||||
vector[1] = ref[1] - curr[1];
|
||||
vector[2] = ref[2] - curr[2];
|
||||
d[i][j] = Math.sqrt((vector[0] * vector[0])
|
||||
+ (vector[1] * vector[1]) + (vector[2] * vector[2]));
|
||||
// Log.write(d[i][j] + "|");
|
||||
}
|
||||
// Log.write("");
|
||||
}
|
||||
|
||||
// look, to which group a value belongs
|
||||
for (int j = 0; j < data.size(); j++) {
|
||||
double smallest = Double.MAX_VALUE;
|
||||
int row = 0;
|
||||
for (int i = 0; i < this.map.length; i++) {
|
||||
if (d[i][j] < smallest) {
|
||||
smallest = d[i][j];
|
||||
row = i;
|
||||
}
|
||||
groups[i][j] = 0;
|
||||
}
|
||||
groups[row][j] = 1; // guppe gesetzt
|
||||
}
|
||||
|
||||
// Debug output
|
||||
/*
|
||||
* for (int i = 0; i < groups.length; i++) { // zeilen for (int j = 0; j
|
||||
* < groups[i].length; j++) { Log.write(groups[i][j] + "|"); }
|
||||
* Log.write(""); }
|
||||
*/
|
||||
|
||||
return groups;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* With this method you can transform a gesture to a discrete symbol
|
||||
* sequence with values between 0 and granularity (number of observations).
|
||||
*
|
||||
* @param gesture
|
||||
* Gesture to get the observationsequence to.
|
||||
*/
|
||||
public int[] getObservationSequence(Gesture gesture) {
|
||||
int[][] groups = this.deriveGroups(gesture);
|
||||
Vector<Integer> sequence = new Vector<Integer>();
|
||||
|
||||
// Log.write("Visible symbol sequence: ");
|
||||
|
||||
for (int j = 0; j < groups[0].length; j++) { // spalten
|
||||
for (int i = 0; i < groups.length; i++) { // zeilen
|
||||
if (groups[i][j] == 1) {
|
||||
// Log.write(" "+ i);
|
||||
sequence.add(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// die sequenz darf nicht zu kurz sein... mindestens so lang
|
||||
// wie die anzahl der zustände. weil sonst die formeln nicht klappen.
|
||||
// english: this is very dirty! it have to be here because if not
|
||||
// too short sequences would cause an error. i've to think about a
|
||||
// better resolution than copying the old value a few time.
|
||||
while (sequence.size() < this.numStates) {
|
||||
sequence.add(sequence.elementAt(sequence.size() - 1));
|
||||
// Log.write(" "+sequence.elementAt(sequence.size()-1));
|
||||
}
|
||||
|
||||
// Log.write("");
|
||||
|
||||
int[] out = new int[sequence.size()];
|
||||
for (int i = 0; i < sequence.size(); i++) {
|
||||
out[i] = sequence.elementAt(i);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the current centeroids-map. Its for debug or technical
|
||||
* interests.
|
||||
*/
|
||||
public void printMap() {
|
||||
Log.write("Centeroids:");
|
||||
for (int i = 0; i < this.map.length; i++) {
|
||||
Log.write(i + ". :" + this.map[i][0] + ":"
|
||||
+ this.map[i][1] + ":" + this.map[i][2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to deepcopy an array.
|
||||
*/
|
||||
private int[][] copyarray(int[][] alt) {
|
||||
int[][] neu = new int[alt.length][alt[0].length];
|
||||
for (int i = 0; i < alt.length; i++) {
|
||||
for (int j = 0; j < alt[i].length; j++) {
|
||||
neu[i][j] = alt[i][j];
|
||||
}
|
||||
}
|
||||
return neu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to look if the two arrays containing the same values.
|
||||
*/
|
||||
private boolean equalarrays(int[][] one, int[][] two) {
|
||||
for (int i = 0; i < one.length; i++) {
|
||||
for (int j = 0; j < one[i].length; j++) {
|
||||
if (!(one[i][j] == two[i][j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return this.radius;
|
||||
}
|
||||
|
||||
public double[][] getHashMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
public void setUpManually(double[][] map, double radius) {
|
||||
this.map = map;
|
||||
this.radius = radius;
|
||||
}
|
||||
}
|
||||
188
src/org/wiigee/logic/TriggeredProcessingUnit.java
Normal file
188
src/org/wiigee/logic/TriggeredProcessingUnit.java
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
import org.wiigee.event.*;
|
||||
import org.wiigee.util.Log;
|
||||
|
||||
/**
|
||||
* This class analyzes the AccelerationEvents emitted from a Wiimote
|
||||
* and further creates and manages the different models for each type
|
||||
* of gesture.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*/
|
||||
public class TriggeredProcessingUnit extends ProcessingUnit {
|
||||
|
||||
// gesturespecific values
|
||||
private Gesture current; // current gesture
|
||||
|
||||
private Vector<Gesture> trainsequence;
|
||||
|
||||
// State variables
|
||||
private boolean learning, analyzing;
|
||||
|
||||
public TriggeredProcessingUnit() {
|
||||
super();
|
||||
this.learning=false;
|
||||
this.analyzing=false;
|
||||
this.current=new Gesture();
|
||||
this.trainsequence=new Vector<Gesture>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Since this class implements the WiimoteListener this procedure is
|
||||
* necessary. It contains the filtering (directional equivalence filter)
|
||||
* and adds the incoming data to the current motion, we want to train
|
||||
* or recognize.
|
||||
*
|
||||
* @param event The acceleration event which has to be processed by the
|
||||
* directional equivalence filter and which has to be added to the current
|
||||
* motion in recognition or training process.
|
||||
*/
|
||||
public void accelerationReceived(AccelerationEvent event) {
|
||||
if(this.learning || this.analyzing) {
|
||||
this.current.add(event); // add event to gesture
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is from the WiimoteListener interface. A button press
|
||||
* is used to control the data flow inside the structures.
|
||||
*
|
||||
*/
|
||||
public void buttonPressReceived(ButtonPressedEvent event) {
|
||||
this.handleStartEvent(event);
|
||||
}
|
||||
|
||||
public void buttonReleaseReceived(ButtonReleasedEvent event) {
|
||||
this.handleStopEvent(event);
|
||||
}
|
||||
|
||||
public void motionStartReceived(MotionStartEvent event) {
|
||||
// this.handleStartEvent(event);
|
||||
}
|
||||
|
||||
public void motionStopReceived(MotionStopEvent event) {
|
||||
// this.handleStopEvent(event);
|
||||
}
|
||||
|
||||
public void handleStartEvent(ActionStartEvent event) {
|
||||
|
||||
// TrainButton = record a gesture for learning
|
||||
if((!this.analyzing && !this.learning) &&
|
||||
event.isTrainInitEvent()) {
|
||||
Log.write("Training started!");
|
||||
this.learning=true;
|
||||
}
|
||||
|
||||
// RecognitionButton = record a gesture for recognition
|
||||
if((!this.analyzing && !this.learning) &&
|
||||
event.isRecognitionInitEvent()) {
|
||||
Log.write("Recognition started!");
|
||||
this.analyzing=true;
|
||||
}
|
||||
|
||||
// CloseGestureButton = starts the training of the model with multiple
|
||||
// recognized gestures, contained in trainsequence
|
||||
if((!this.analyzing && !this.learning) &&
|
||||
event.isCloseGestureInitEvent()) {
|
||||
|
||||
if(this.trainsequence.size()>0) {
|
||||
Log.write("Training the model with "+this.trainsequence.size()+" gestures...");
|
||||
this.learning=true;
|
||||
|
||||
GestureModel m = new GestureModel();
|
||||
m.train(this.trainsequence);
|
||||
m.print();
|
||||
this.classifier.addGestureModel(m);
|
||||
|
||||
this.trainsequence=new Vector<Gesture>();
|
||||
this.learning=false;
|
||||
} else {
|
||||
Log.write("There is nothing to do. Please record some gestures first.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleStopEvent(ActionStopEvent event) {
|
||||
if(this.learning) { // button release and state=learning, stops learning
|
||||
if(this.current.getCountOfData()>0) {
|
||||
Log.write("Finished recording (training)...");
|
||||
Log.write("Data: "+this.current.getCountOfData());
|
||||
Gesture gesture = new Gesture(this.current);
|
||||
this.trainsequence.add(gesture);
|
||||
this.current=new Gesture();
|
||||
this.learning=false;
|
||||
} else {
|
||||
Log.write("There is no data.");
|
||||
Log.write("Please train the gesture again.");
|
||||
this.learning=false; // ?
|
||||
}
|
||||
}
|
||||
|
||||
else if(this.analyzing) { // button release and state=analyzing, stops analyzing
|
||||
if(this.current.getCountOfData()>0) {
|
||||
Log.write("Finished recording (recognition)...");
|
||||
Log.write("Compare gesture with "+this.classifier.getCountOfGestures()+" other gestures.");
|
||||
Gesture gesture = new Gesture(this.current);
|
||||
|
||||
int recognized = this.classifier.classifyGesture(gesture);
|
||||
if(recognized!=-1) {
|
||||
double recogprob = this.classifier.getLastProbability();
|
||||
this.fireGestureEvent(true, recognized, recogprob);
|
||||
Log.write("######");
|
||||
Log.write("Gesture No. "+recognized+" recognized: "+recogprob);
|
||||
Log.write("######");
|
||||
} else {
|
||||
this.fireGestureEvent(false, 0, 0.0);
|
||||
Log.write("######");
|
||||
Log.write("No gesture recognized.");
|
||||
Log.write("######");
|
||||
}
|
||||
|
||||
this.current=new Gesture();
|
||||
this.analyzing=false;
|
||||
} else {
|
||||
Log.write("There is no data.");
|
||||
Log.write("Please recognize the gesture again.");
|
||||
this.analyzing=false; // ?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadGesture(String filename) {
|
||||
GestureModel g = org.wiigee.util.FileIO.readFromFile(filename);
|
||||
this.classifier.addGestureModel(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveGesture(int id, String filename) {
|
||||
org.wiigee.util.FileIO.writeToFile(this.classifier.getGestureModel(id), filename);
|
||||
}
|
||||
|
||||
}
|
||||
233
src/org/wiigee/util/FileIO.java
Normal file
233
src/org/wiigee/util/FileIO.java
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* wiigee - accelerometerbased gesture recognition
|
||||
* Copyright (C) 2007, 2008, 2009 Benjamin Poppinga
|
||||
*
|
||||
* Developed at University of Oldenburg
|
||||
* Contact: wiigee@benjaminpoppinga.de
|
||||
*
|
||||
* This file is part of wiigee.
|
||||
*
|
||||
* wiigee is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
package org.wiigee.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import org.wiigee.logic.GestureModel;
|
||||
import org.wiigee.logic.HMM;
|
||||
import org.wiigee.logic.Quantizer;
|
||||
|
||||
/**
|
||||
* This is a static class to support saving and loading complete gestures. I've
|
||||
* choosen not to use some kind of XML, because the big multidimensional arrays
|
||||
* would cause a huge senseless amount of xml-data. So KISS: Keep It Simple,
|
||||
* Stupid! ;) Comma-separated-vectors with some control data.
|
||||
*
|
||||
* @author Benjamin 'BePo' Poppinga
|
||||
*
|
||||
*/
|
||||
public class FileIO {
|
||||
|
||||
public static void writeToFile(GestureModel m, String name) {
|
||||
try {
|
||||
// initialize file and get values
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(name+".txt"));
|
||||
int numStates = m.getNumStates();
|
||||
int numObservations = m.getNumObservations();
|
||||
double defaultProbability = m.getDefaultProbability();
|
||||
Quantizer quantizer = m.getQuantizer();
|
||||
HMM hmm = m.getHMM();
|
||||
|
||||
out.write("# numStates:");
|
||||
out.newLine();
|
||||
out.write(Integer.toString(numStates));
|
||||
out.newLine();
|
||||
|
||||
out.write("# numObservations:");
|
||||
out.newLine();
|
||||
out.write(Integer.toString(numObservations));
|
||||
out.newLine();
|
||||
|
||||
out.write("# defaultProbability:");
|
||||
out.newLine();
|
||||
out.write(Double.toString(defaultProbability));
|
||||
out.newLine();
|
||||
|
||||
out.write("# Quantizer: Radius");
|
||||
out.newLine();
|
||||
out.write(Double.toString(quantizer.getRadius()));
|
||||
out.newLine();
|
||||
out.write("# Quantizer: MAP");
|
||||
out.newLine();
|
||||
double[][] map = quantizer.getHashMap();
|
||||
for(int v=0; v<map.length; v++) {
|
||||
double[] d = map[v];
|
||||
out.write(Double.toString(d[0])+", "+Double.toString(d[1])+", "+Double.toString(d[2]));
|
||||
out.newLine();
|
||||
}
|
||||
|
||||
out.write("# HMM: PI");
|
||||
out.newLine();
|
||||
double[] pi = hmm.getPi();
|
||||
for (int i=0; i<numStates; i++) {
|
||||
if(i==numStates-1) {
|
||||
out.write(Double.toString(pi[i]));
|
||||
out.newLine();
|
||||
} else {
|
||||
out.write(Double.toString(pi[i])+", ");
|
||||
}
|
||||
}
|
||||
|
||||
out.write("# HMM: A");
|
||||
out.newLine();
|
||||
double[][] a = hmm.getA();
|
||||
for(int i=0; i<numStates; i++) {
|
||||
for(int j=0; j<numStates; j++) {
|
||||
if(j==numStates-1) {
|
||||
out.write(Double.toString(a[i][j]));
|
||||
out.newLine();
|
||||
} else {
|
||||
out.write(Double.toString(a[i][j])+", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.write("# HMM: B");
|
||||
out.newLine();
|
||||
double[][] b = hmm.getB();
|
||||
for(int i=0; i<numStates; i++) {
|
||||
for(int j=0; j<numObservations; j++) {
|
||||
if(j==numObservations-1) {
|
||||
out.write(Double.toString(b[i][j]));
|
||||
out.newLine();
|
||||
} else {
|
||||
out.write(Double.toString(b[i][j])+", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.write("# END");
|
||||
|
||||
// close file
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
System.out.println("Error: Write to File!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static GestureModel readFromFile(String name) {
|
||||
try {
|
||||
// initialize file and create values
|
||||
BufferedReader in = new BufferedReader(new FileReader(name+".txt"));
|
||||
int numStates = 0;
|
||||
int numObservations = 0;
|
||||
double defaultprobability = 0;
|
||||
double radius = 0;
|
||||
double[][] map = new double[numObservations][3];
|
||||
double[] pi = new double[numStates];
|
||||
double[][] a = new double[numStates][numStates];
|
||||
double[][] b = new double[numStates][numObservations];
|
||||
|
||||
String line;
|
||||
int position = 0;
|
||||
while(in.ready()) {
|
||||
line = in.readLine();
|
||||
if(!line.startsWith("#")) { // isn't a comment
|
||||
switch (position++) {
|
||||
case 0:
|
||||
numStates = Integer.parseInt(line);
|
||||
break;
|
||||
case 1:
|
||||
numObservations = Integer.parseInt(line);
|
||||
break;
|
||||
case 2:
|
||||
defaultprobability = Double.parseDouble(line);
|
||||
break;
|
||||
case 3:
|
||||
radius = Double.parseDouble(line);
|
||||
break;
|
||||
case 4:
|
||||
map = new double[numObservations][3];
|
||||
for(int i=0; i<numObservations; i++) {
|
||||
String s[] = line.split(", ");
|
||||
double[] d = new double[] { Double.parseDouble(s[0]),
|
||||
Double.parseDouble(s[1]),
|
||||
Double.parseDouble(s[2]) };
|
||||
map[i] = d;
|
||||
line = in.ready() ? in.readLine() : "";
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
pi = new double[numStates];
|
||||
String pi_row[] = line.split(", ");
|
||||
for(int i=0; i<numStates; i++) {
|
||||
pi[i] = Double.parseDouble(pi_row[i]);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
a = new double[numStates][numStates];
|
||||
for(int i=0; i<numStates; i++) {
|
||||
String a_row[] = line.split(", ");
|
||||
for(int j=0; j<numStates; j++) {
|
||||
a[i][j] = Double.parseDouble(a_row[j]);
|
||||
}
|
||||
line = in.ready() ? in.readLine() : "";
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
b = new double[numStates][numObservations];
|
||||
for(int i=0; i<numStates; i++) {
|
||||
String b_row[] = line.split(", ");
|
||||
for(int j=0; j<numObservations; j++) {
|
||||
b[i][j] = Double.parseDouble(b_row[j]);
|
||||
}
|
||||
line = in.ready() ? in.readLine() : "";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
System.out.println("SWITCH EMPTY!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GestureModel ret = new GestureModel();
|
||||
ret.setDefaultProbability(defaultprobability);
|
||||
|
||||
Quantizer quantizer = new Quantizer(numStates);
|
||||
quantizer.setUpManually(map, radius);
|
||||
ret.setQuantizer(quantizer);
|
||||
|
||||
HMM hmm = new HMM(numStates, numObservations);
|
||||
hmm.setPi(pi);
|
||||
hmm.setA(a);
|
||||
hmm.setB(b);
|
||||
ret.setHMM(hmm);
|
||||
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error: Read from File!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null; // bad error case
|
||||
}
|
||||
|
||||
}
|
||||
43
src/org/wiigee/util/Log.java
Normal file
43
src/org/wiigee/util/Log.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package org.wiigee.util;
|
||||
|
||||
public class Log {
|
||||
|
||||
public static final int OFF = -1;
|
||||
public static final int NORMAL = 0;
|
||||
public static final int DEBUG = 1;
|
||||
|
||||
public static final int PRINT = 0;
|
||||
public static final int FILE = 1;
|
||||
|
||||
public static int level = Log.NORMAL;
|
||||
public static int mode = Log.PRINT;
|
||||
|
||||
public static void setLevel(int n) {
|
||||
level = n;
|
||||
}
|
||||
|
||||
public static void write(String s) {
|
||||
write(Log.NORMAL, s, null);
|
||||
}
|
||||
|
||||
public static void write(String s, Object o) {
|
||||
write(Log.NORMAL, s, o);
|
||||
}
|
||||
|
||||
public static void write(int n, String s, Object o) {
|
||||
if(level>=n) {
|
||||
if(mode==Log.PRINT) {
|
||||
// console output enabled
|
||||
if(o!=null) {
|
||||
System.out.println(o.getClass()+": "+s);
|
||||
} else {
|
||||
System.out.println(s);
|
||||
}
|
||||
} else if(mode==Log.FILE) {
|
||||
// file output enabled
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
128
test/org/wiigee/logic/ClassifierTest.java
Normal file
128
test/org/wiigee/logic/ClassifierTest.java
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
import junit.framework.TestCase;
|
||||
import org.wiigee.device.Device;
|
||||
import org.wiigee.event.AccelerationEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author bepo
|
||||
*/
|
||||
public class ClassifierTest extends TestCase {
|
||||
|
||||
public ClassifierTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of classifyGesture method, of class Classifier.
|
||||
*/
|
||||
public void testClassifyGesture() {
|
||||
|
||||
// create a pseudo-device
|
||||
Device d = new Device(true);
|
||||
|
||||
// create 3 gestures
|
||||
Gesture g0 = new Gesture();
|
||||
Gesture g1 = new Gesture();
|
||||
Gesture g2 = new Gesture();
|
||||
|
||||
g0.add(new AccelerationEvent(d, 0.0, 0.0, 0.0, 0.0));
|
||||
g0.add(new AccelerationEvent(d, 1.0, 1.0, 1.0, 0.0));
|
||||
g0.add(new AccelerationEvent(d, 2.0, 2.0, 2.0, 0.0));
|
||||
g0.add(new AccelerationEvent(d, 1.0, 1.0, 1.0, 0.0));
|
||||
|
||||
g1.add(new AccelerationEvent(d, -1.0, 1.0, -1.0, 0.0));
|
||||
g1.add(new AccelerationEvent(d, -1.0, 3.0, -1.0, 0.0));
|
||||
g1.add(new AccelerationEvent(d, -1.0, 1.0, -1.0, 0.0));
|
||||
g1.add(new AccelerationEvent(d, -1.0, 3.0, -1.0, 0.0));
|
||||
|
||||
g2.add(new AccelerationEvent(d, -2.0, -2.0, -2.0, -2.0));
|
||||
g2.add(new AccelerationEvent(d, -2.0, -2.0, -2.0, -2.0));
|
||||
g2.add(new AccelerationEvent(d, -2.0, -2.0, -2.0, -2.0));
|
||||
g2.add(new AccelerationEvent(d, -2.0, -2.0, -2.0, -2.0));
|
||||
|
||||
// create 3 gesturesets with 1 gesture each
|
||||
Vector<Gesture> gs0 = new Vector<Gesture>();
|
||||
Vector<Gesture> gs1 = new Vector<Gesture>();
|
||||
Vector<Gesture> gs2 = new Vector<Gesture>();
|
||||
gs0.add(g0);
|
||||
gs1.add(g1);
|
||||
gs2.add(g2);
|
||||
|
||||
// create three gesturemodels and train these
|
||||
GestureModel gm0 = new GestureModel();
|
||||
GestureModel gm1 = new GestureModel();
|
||||
GestureModel gm2 = new GestureModel();
|
||||
gm0.train(gs0);
|
||||
gm1.train(gs1);
|
||||
gm2.train(gs2);
|
||||
|
||||
// create a classifier and add gesturemodels
|
||||
Classifier classifier = new Classifier();
|
||||
classifier.addGestureModel(gm0);
|
||||
classifier.addGestureModel(gm1);
|
||||
classifier.addGestureModel(gm2);
|
||||
|
||||
// classify gesture
|
||||
int result0 = classifier.classifyGesture(g0);
|
||||
int result1 = classifier.classifyGesture(g1);
|
||||
int result2 = classifier.classifyGesture(g2);
|
||||
|
||||
if((result0 != 0) ||
|
||||
(result1 != 1) ||
|
||||
(result2 != 2)) {
|
||||
fail("Wrong gesture classified.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test of addGestureModel method, of class Classifier.
|
||||
*/
|
||||
public void testAddGestureModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getGestureModel method, of class Classifier.
|
||||
*/
|
||||
public void testGetGestureModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getGestureModels method, of class Classifier.
|
||||
*/
|
||||
public void testGetGestureModels() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of getCountOfGestures method, of class Classifier.
|
||||
*/
|
||||
public void testGetCountOfGestures() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of clear method, of class Classifier.
|
||||
*/
|
||||
public void testClear() {
|
||||
}
|
||||
|
||||
}
|
||||
73
test/org/wiigee/logic/HMMTest.java
Normal file
73
test/org/wiigee/logic/HMMTest.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
|
||||
package org.wiigee.logic;
|
||||
|
||||
import java.util.Vector;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author bepo
|
||||
*/
|
||||
public class HMMTest extends TestCase {
|
||||
|
||||
public HMMTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Probabilistic test of the train method, of class HMM.
|
||||
*/
|
||||
public void testTrain() {
|
||||
System.out.println("train");
|
||||
|
||||
HMM instance = new HMM(8, 14);
|
||||
|
||||
// setup a trainsequence
|
||||
Vector<int[]> trainsequence = new Vector<int[]>();
|
||||
trainsequence.add(new int[] { 0, 1, 2, 1, 6, 4, 3, 2});
|
||||
trainsequence.add(new int[] { 0, 1, 2, 2, 6, 3, 3, 1});
|
||||
trainsequence.add(new int[] { 0, 1, 2, 2, 6, 3, 2, 2});
|
||||
|
||||
// setup a failing trainsequence
|
||||
int[] fail = new int[] { 5, 5, 5, 5, 5, 5, 5, 5};
|
||||
|
||||
// train the hmm
|
||||
instance.train(trainsequence);
|
||||
|
||||
double probA = instance.getProbability(trainsequence.elementAt(0));
|
||||
double probB = instance.getProbability(trainsequence.elementAt(1));
|
||||
double probC = instance.getProbability(trainsequence.elementAt(2));
|
||||
double probFAIL = instance.getProbability(fail);
|
||||
|
||||
System.out.println("probA = "+probA);
|
||||
System.out.println("probB = "+probB);
|
||||
System.out.println("probC = "+probC);
|
||||
System.out.println("probFAIL = "+probFAIL);
|
||||
|
||||
if((probA <= 1.0E-10) ||
|
||||
(probB <= 1.0E-10) ||
|
||||
(probC <= 1.0E-10)) {
|
||||
fail("Probabilities to low to be accurate.");
|
||||
}
|
||||
|
||||
if(probFAIL > 0.0) {
|
||||
fail("Fake probability to high.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user