Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}
h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
.tabSelected {color:[[ColorPalette::PrimaryDark]];
background:[[ColorPalette::TertiaryPale]];
border-left:1px solid [[ColorPalette::TertiaryLight]];
border-top:1px solid [[ColorPalette::TertiaryLight]];
border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}
#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}
#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
.tiddler .defaultCommand {font-weight:bold;}
.shadow .title {color:[[ColorPalette::TertiaryDark]];}
.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}
.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}
.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}
.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}
.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
.imageLink, #displayArea .imageLink {background:transparent;}
.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}
#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}
body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}
hr {height:1px;}
a {text-decoration:none;}
dt {font-weight:bold;}
ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}
.txtOptionInput {width:11em;}
#contentWrapper .chkOptionInput {border:0;}
.externalLink {text-decoration:underline;}
.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}
.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}
/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
#mainMenu .tiddlyLinkExisting,
#mainMenu .tiddlyLinkNonExisting,
#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}
.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}
#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}
.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}
#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}
.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}
.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}
.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}
#contentWrapper {display:block;}
#splashScreen {display:none;}
#displayArea {margin:1em 17em 0 14em;}
.toolbar {text-align:right; font-size:.9em;}
.tiddler {padding:1em 1em 0;}
.missing .viewer,.missing .title {font-style:italic;}
.title {font-size:1.6em; font-weight:bold;}
.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}
.tiddler .button {padding:0.2em 0.4em;}
.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}
.footer {font-size:.9em;}
.footer li {display:inline;}
.annotation {padding:0.5em; margin:0.5em;}
* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}
.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}
.fieldsetFix {border:0; padding:0; margin:1px 0px;}
.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}
* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser
Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])
<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]
----
Also see [[AdvancedOptions]]
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #d9c89e
PrimaryMid: #6e6259
PrimaryDark: #c50
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
The [[Open Source physics engine, ODE,|http://sourceforge.net/projects/opende/]] is a nice tool. It allows you to build models and simulate physical phenomena. I have been working to add new functionality by creating additional constraint options for the system. These are described below.
!!!~LMPlus
ODE provides a joint known as an [[LMotor|http://ode-wiki.org/wiki/index.php?title=Manual:_All#Linear_Motor]]. This joint allows you to constrain the relative velocity of the center of mass of two bodies. It does not, however, allow you to specify limits on the distance possible between two bodies or to constrain the bodies relative to some point besides the center of mass. The ~LMPlus joint allows this.
[img(auto,30em+)[LMPlus Constraint:Planar mode|images/lmPlusPlanarLabeled.jpg]] [img(auto,30em+)[LMPlus Constraint:Cylinder mode|images/lmPlusCylinderLabeled.jpg]] [img(auto,30em+)[LMPlus Constraint:Spherical mode|images/lmPlusSphericalLabeled.jpg]]
This simple demo video shows these different constraint modes being used to keep a set of spheres attached to a fixed volume defined relative to other bodies. The planar mode can constrain a point to a line, a plane, or a box. The cylinder mode can constrain a point to remain within a cylinder volume (or a cylindrical shell). Likewise, the spherical mode constrains a point relative to one body to remain within a spherical shell relative to a point defined with respect to another body.
<html><iframe width="420" height="315" src="http://www.youtube.com/embed/VQ02NOP6lYI" frameborder="0" allowfullscreen></iframe></html>
!!!~AMPlus
The [[AMotor|http://ode-wiki.org/wiki/index.php?title=Manual:_All#Angular_Motor]] joint in ODE allows you to constrain the relative angular velocity of two bodies around some axis. However, it has no notion of current angle unless you set it to use //Euler// mode, in which case, you must use all three degrees of freedom and a particular way. The ~AMPlus joint provides a well-defined single axis of rotation for both angular velocity control and joint limits. There are two modes: //Cone// and //Projection//.
[img(auto,30em+)[AMPlus Constraint:Cone mode|images/armConeLimitLabel.png]] [img(auto,30em+)[AMPlus Constraint:Cone mode|images/armProjectionLimitLabel.png]]
In //Cone// mode, the user specifies a reference axis for each body in the joint. The angle of the joint is then the angle between those two reference axes. The axis of rotation is the orthogonal axis. This constraint works poorly when the angle is zero or π, but works very well when the angle is π/2. It works reasonably well in-between.
In //Projection// mode, the user specifies a reference axis for each body and a third axis to define a plane. The angle of the joint is then projected onto the reference plane and measured around the third axis. This allows us to define angles from -π to π. This projection obviously performs poorly as one of the two reference axes becomes parallel to the third axis. However, it works well in general.
With the ~AMPlus constraint, one can recreate the other joint constraints. For example, the universal joint requires that two references be kept perpendicular (//Cone// mode) and then provides actuation around those two reference axes (two constraints in //Projection// mode).
!!!Rolling Friction
[<img(auto,10em+)[Rolling friction|images/rollingPrev.jpg]]I recently submitted [[a patch that provides optional rolling friction|https://sourceforge.net/p/opende/patches/184/]] for contact constraints. This models loss of energy in a rolling body from hysteresis and slippage and makes it so a rolling body can come to a rest, even on a slope. Without it, bodies will roll forever. They will slide down slopes, even if you set the maximum angular velocity to zero and the sliding friction to infinity.<html><br clear=all></html>
!!!~QServo
When you want to control the relative orientation of two bodies, sometimes it is not possible to independently actuate individual angular degrees of freedom. The ~QServo allows you to specify a desired relative orientation as a quaternion. The servo then uses internal torques to achieve that target orientation. This joint has not been submitted yet. It needs some usability work.
!!!~QLimit
Similarly, some joint limits are not easily specified in terms of a single degree of freedom. The ~QLimit specifies constraints on the relative quaternion between two bodies. You specify a reference quaternion and limits on the inner-product between the relative orientation of the bodies and the reference quaternion. This joint has not been submitted yet. It makes all kinds of sense to me to frame angular constraints in quaternion space, but others do not find it as useful.
[img[elements/bullet.png]] Office Hours
Fridays, 2-3 pm
GDC 1.302 (Tutorial Lab)
[img[elements/bullet.png]] Phone
| Office: | (512) 232-9135 |
| Lab: | (512) 232-7447 |
[img[elements/bullet.png]] Mail
Computer Science Dept.
1 University Station D9500
Austin, Texas 78712
[img[elements/bullet.png]] E-mail
jcooper[img[images/adend.png]]
UT Austin Courses:
|C S 391L |Machine Learning |[[Ray Mooney|http://userweb.cs.utexas.edu/~mooney/]] |
|C S 395T |Computer Vision |[[Kristen Grauman|http://userweb.cs.utexas.edu/~grauman/]] |
|C S 395T |Computation Orchestration |[[Jayadev Misra|http://userweb.cs.utexas.edu/~misra/]] |
|C S 395T |Object Recognition |[[Kristen Grauman|http://userweb.cs.utexas.edu/~grauman/]] |
|C S 388G |Algorithms: Techniques and Theory |[[Vijaya Ramachandran|http://userweb.cs.utexas.edu/~vlr/]] |
|C S 384G |Computer Graphics |[[Don Fussell|http://userweb.cs.utexas.edu/~fussell/]] |
|C S 380P |Parallel Systems |[[Calvin Lin|http://userweb.cs.utexas.edu/~lin/]] |
|C S 388L |Intro to Mathematical Logic |[[Vladimir Lifschitz|http://userweb.cs.utexas.edu/~vl/]] |
|PSY 394U |Perception and Action |[[Mary Hayhoe|http://www.cps.utexas.edu/Research/Hayhoe/hayhoe.html]] |
BYU Courses:
|C S 670 |~Multi-Agent Systems |[[Mike Goodrich|http://cs.byu.edu/faculty/goodrich_michael_a]] |
|C S 678 |Advanced Neural Networks |[[Tony Martinez|http://cs.byu.edu/faculty/martinez_tony]] |
|PSYCH 361 |Principles of Learning |Paul Robinson |
|PSYCH 375 |Cognition |[[Mark Allen|http://psychology.byu.edu/Faculty/MAllen/Home.dhtml]] |
|NEURO 205 |Neurobiology |[[Mike Brown|http://pdbio.byu.edu/DepartmentInformation/FacultyandStaff/tabid/393/ctl/FacultyProfile/mid/835/FacultyID/149/Default.aspx ]] |
|PSYCH 350 |Intro to Social Psychology |[[Cardell Jacobson|http://fhssfaculty.byu.edu/Faculty/ckj/]] |
|PSYCH 370 |Sensation and Perception |[[Scott Steffensen|http://psychology.byu.edu/Faculty/SSteffensen/Home.dhtml]] |
|C S 601R |Advanced Multi-agent Systems |[[Mike Goodrich|http://cs.byu.edu/faculty/goodrich_michael_a]] |
|C S 650 |Computer Vision 1 |[[Brian Morse|http://cs.byu.edu/faculty/morse_bryan]] |
|C S 601R |Computational Biology |[[Mark Clement|http://cs.byu.edu/faculty/clement_mark]], [[Quinn Snell|http://cs.byu.edu/faculty/snell_quinn]]|
|C S 655 |Advanced Computer Graphics |[[Parris Egbert|http://cs.byu.edu/faculty/egbert_parris]] |
|C S 677 |Bayesian Methods in C S |[[Kevin Seppi|http://cs.byu.edu/faculty/seppi_kevin]] |
!![[University of Texas at Austin|http://www.utexas.edu/]] - [[Department of Computer Science|http://www.cs.utexas.edu/]]
Advisor: [[Dr. Dana Ballard|http://www.cs.utexas.edu/~dana/]]
Research Lab: Embodied Cognition Lab (part of the [[Center for Perceptual Systems|http://www.cps.utexas.edu/]])
Dissertation Topic: Hierarchies of Abstractions for Modeling of Human Movement Generation (currently in candidacy)
!![[Brigham Young University|http://home.byu.edu]] - [[Computer Science Department|http://cs.byu.edu/]]
Master's Advisor: [[Dr. Michael Goodrich|http://faculty.cs.byu.edu/~mike/]]
Research Lab: [[Human-Centered Machine Intelligence|https://facwiki.cs.byu.edu/HCMI/index.php/Main_Page]]
Thesis Topic: [[Supporting Flight Control for UAV-Assisted Wilderness Search and Rescue Through Human Centered Interface Design|http://contentdm.lib.byu.edu/ETD/image/etd2140.pdf]]
[[Relevant courses|Coursework]] that have helped shape my thinking.
/%
!info
|Name|HideTiddlerTags|
|Source|http://www.TiddlyTools.com/#HideTiddlerTags|
|Version|2.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|hide a tiddler's 'tagged' and 'tagging' displays (if any)|
Usage:
<<<
{{{
<<tiddler HideTiddlerTags>>
<<tiddler HideTiddlerTags with: TiddlerTitle>>
}}}
<<<
!end
!show
<<tiddler {{
var title="$1";
if (title=='$'+'1') {
var here=story.findContainingTiddler(place);
if (here) title=here.getAttribute('tiddler');
}
var t=story.getTiddler(title); if (t) {
var e=t.getElementsByTagName('*');
for (var i=0; i<e.length; i++)
if (hasClass(e[i],'tagging')||hasClass(e[i],'tagged'))
e[i].style.display='none';
}
'';}}>>
!end
%/<<tiddler {{
var src='HideTiddlerTags';
src+(tiddler&&tiddler.title==src?'##info':'##show');}}
with: [[$1]]>>
/%
!info
|Name|HideTiddlerTitle|
|Source|http://www.TiddlyTools.com/#HideTiddlerTitle|
|Version|2.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|transclusion|
|Description|hide a tiddler's title and subtitle (date and author)|
Usage:
<<<
{{{
<<tiddler HideTiddlerTitle>>
<<tiddler HideTiddlerTitle with: TiddlerTitle>>
}}}
<<<
!end
!show
<<tiddler {{
var title="$1";
if (title=='$'+'1')
title=(story.findContainingTiddler(place)||place).getAttribute('tiddler')||'';
var t=story.getTiddler(title); if (t) {
var e=t.getElementsByTagName('*');
for (var i=0; i<e.length; i++)
if (hasClass(e[i],'title')||hasClass(e[i],'subtitle')) e[i].style.display='none';
}
'';}}>>
!end
%/<<tiddler {{
var src='HideTiddlerTitle';
src+(tiddler&&tiddler.title==src?'##info':'##show');}}
with: [[$1]]>>
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.2a|
|Date:|27-Jun-2011|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
Warning: the showWhen and hideWhen macros will blindly eval paramString.
This could be used to execute harmful javascript from a tiddler.
(TODO: Make some effort to sanitize paramString. Perhaps disallow the equals sign?)
***/
//{{{
window.hideWhenLastTest = false;
window.removeElementWhen = function(test,place) {
window.hideWhenLastTest = test;
if (test) {
jQuery(place).empty()
place.parentNode.removeChild(place);
}
};
merge(config.macros,{
hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( eval(paramString), place );
}},
showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !eval(paramString), place );
}},
hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place );
}},
showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place );
}},
hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAny(params), place );
}},
showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAny(params), place );
}},
hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place );
}},
showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place );
}},
hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place );
}},
showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place );
}},
hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title == params[0], place );
}},
showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title != params[0], place );
}},
'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !window.hideWhenLastTest, place );
}}
});
//}}}
[<img(20em+,auto)[Joseph L Cooper|images/josephlcooper.jpg]] I am a ~PhD candidate in the [[Department of Computer Science|http://www.cs.utexas.edu/]] at [[the University of Texas at Austin|http://www.utexas.edu/]] studying the computational basis of human behavior with [[Dr. Dana Ballard|http://www.cs.utexas.edu/~dana/]]. I have been focusing on hierarchical models of motor control based on feedback and abstraction. Understanding how humans control their bodies can produce life-like character animation and improved control algorithms for humanoid robots. It also has potential uses in intelligent prosthetics or for early diagnosis of neural disorders that affect motor patterns such as Parkinsons, ataxia, schizophrenia, or dementia. Read more on my [[Research page|Research]].
I am currently working to complete my doctoral research with the intent to graduate in May 2013. I expect to eventually take up teaching and researching as a professor at the university level in order to continue working to model human behavior and intelligence. [[My CV can be found here|jc_cv.pdf]].
I keep a [[blog of discoveries and ideas|http://lost-found-wandering.blogspot.com/]] that I feel are worth sharing.
I earned Bachelor's and Master's degrees at [[Brigham Young University|http://www.byu.edu/]] studying in the [[Computer Science Department|http://www.cs.byu.edu/]]. I completed my Master's work under [[Dr. Michael Goodrich|http://faculty.cs.byu.edu/~mike/]]. My thesis involved designing, creating, and testing an interface for controlling small, camera-equipped Unmanned Aerial Vehicles (~UAVs). The project was directed at assisting Wilderness Search and Rescue volunteers in their rescue efforts by creating an intuitive tool for rapidly acquiring imagery of an area. More information about this project is available at the [[BYU WiSAR project page|https://facwiki.cs.byu.edu/WiSAR/index.php/Main_Page]].@@clear:both;display:block; @@
| <html><iframe width="420" height="315" src="http://www.youtube.com/embed/VALU8ecbsvc" frameborder="0" allowfullscreen></iframe></html> |After building two simple humanoids model in ODE, I constrained the first to kinematically follow my movements (translated from the motion capture data) and then constrained the second to dynamically follow the joint angles of the first. The joints in the dynamic model are seriously over-powered, but even so, creating a programmatic controller that would make the model stand up would not be trivial. By using the human feedback controller loop, I was able to get the agent to stand in a matter of minutes. This video shows my second attempt. It worked on my first attempt too; I just didn't have a camera out. So this is not something that requires a lot training either..<html><br><br></html>I am currently working to see if this technique can be used to create new movements for a simulated soccer-robot. |
/***
|Name|ImageSizePlugin|
|Source|http://www.TiddlyTools.com/#ImageSizePlugin|
|Version|1.2.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|adds support for resizing images|
This plugin adds optional syntax to scale an image to a specified width and height and/or interactively resize the image with the mouse.
!!!!!Usage
<<<
The extended image syntax is:
{{{
[img(w+,h+)[...][...]]
}}}
where ''(w,h)'' indicates the desired width and height (in CSS units, e.g., px, em, cm, in, or %). Use ''auto'' (or a blank value) for either dimension to scale that dimension proportionally (i.e., maintain the aspect ratio). You can also calculate a CSS value 'on-the-fly' by using a //javascript expression// enclosed between """{{""" and """}}""". Appending a plus sign (+) to a dimension enables interactive resizing in that dimension (by dragging the mouse inside the image). Use ~SHIFT-click to show the full-sized (un-scaled) image. Use ~CTRL-click to restore the starting size (either scaled or full-sized).
<<<
!!!!!Examples
<<<
{{{
[img(100px+,75px+)[images/meow2.jpg]]
}}}
[img(100px+,75px+)[images/meow2.jpg]]
{{{
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img( 1%+,+)[images/meow.gif]]
}}}
[<img(34%+,+)[images/meow.gif]]
[<img(21% ,+)[images/meow.gif]]
[<img(13%+, )[images/meow.gif]]
[<img( 8%+, )[images/meow.gif]]
[<img( 5% , )[images/meow.gif]]
[<img( 3% , )[images/meow.gif]]
[<img( 2% , )[images/meow.gif]]
[img( 1%+,+)[images/meow.gif]]
{{tagClear{
}}}
<<<
!!!!!Revisions
<<<
2011.09.03 [1.2.3] bypass addStretchHandlers() if no '+' suffix is used (i.e., not resizable)
2010.07.24 [1.2.2] moved tip/dragtip text to config.formatterHelpers.imageSize object to enable customization
2009.02.24 [1.2.1] cleanup width/height regexp, use '+' suffix for resizing
2009.02.22 [1.2.0] added stretchable images
2008.01.19 [1.1.0] added evaluated width/height values
2008.01.18 [1.0.1] regexp for "(width,height)" now passes all CSS values to browser for validation
2008.01.17 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImageSizePlugin= {major: 1, minor: 2, revision: 3, date: new Date(2011,9,3)};
//}}}
//{{{
var f=config.formatters[config.formatters.findByField("name","image")];
f.match="\\[[<>]?[Ii][Mm][Gg](?:\\([^,]*,[^\\)]*\\))?\\[";
f.lookaheadRegExp=/\[([<]?)(>?)[Ii][Mm][Gg](?:\(([^,]*),([^\)]*)\))?\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg;
f.handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var floatLeft=lookaheadMatch[1];
var floatRight=lookaheadMatch[2];
var width=lookaheadMatch[3];
var height=lookaheadMatch[4];
var tooltip=lookaheadMatch[5];
var src=lookaheadMatch[6];
var link=lookaheadMatch[7];
// Simple bracketted link
var e = w.output;
if(link) { // LINKED IMAGE
if (config.formatterHelpers.isExternalLink(link)) {
if (config.macros.attach && config.macros.attach.isAttachment(link)) {
// see [[AttachFilePluginFormatters]]
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title = config.macros.attach.linkTooltip + link;
} else
e = createExternalLink(w.output,link);
} else
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
addClass(e,"imageLink");
}
var img = createTiddlyElement(e,"img");
if(floatLeft) img.align="left"; else if(floatRight) img.align="right";
if(width||height) {
var x=width.trim(); var y=height.trim();
var stretchW=(x.substr(x.length-1,1)=='+'); if (stretchW) x=x.substr(0,x.length-1);
var stretchH=(y.substr(y.length-1,1)=='+'); if (stretchH) y=y.substr(0,y.length-1);
if (x.substr(0,2)=="{{")
{ try{x=eval(x.substr(2,x.length-4))} catch(e){displayMessage(e.description||e.toString())} }
if (y.substr(0,2)=="{{")
{ try{y=eval(y.substr(2,y.length-4))} catch(e){displayMessage(e.description||e.toString())} }
img.style.width=x.trim(); img.style.height=y.trim();
if (stretchW||stretchH) config.formatterHelpers.addStretchHandlers(img,stretchW,stretchH);
}
if(tooltip) img.title = tooltip;
// GET IMAGE SOURCE
if (config.macros.attach && config.macros.attach.isAttachment(src))
src=config.macros.attach.getAttachment(src); // see [[AttachFilePluginFormatters]]
else if (config.formatterHelpers.resolvePath) { // see [[ImagePathPlugin]]
if (config.browser.isIE || config.browser.isSafari) {
img.onerror=(function(){
this.src=config.formatterHelpers.resolvePath(this.src,false);
return false;
});
} else
src=config.formatterHelpers.resolvePath(src,true);
}
img.src=src;
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
config.formatterHelpers.imageSize={
tip: 'SHIFT-CLICK=show full size, CTRL-CLICK=restore initial size',
dragtip: 'DRAG=stretch/shrink, '
}
config.formatterHelpers.addStretchHandlers=function(e,stretchW,stretchH) {
e.title=((stretchW||stretchH)?this.imageSize.dragtip:'')+this.imageSize.tip;
e.statusMsg='width=%0, height=%1';
e.style.cursor='move';
e.originalW=e.style.width;
e.originalH=e.style.height;
e.minW=Math.max(e.offsetWidth/20,10);
e.minH=Math.max(e.offsetHeight/20,10);
e.stretchW=stretchW;
e.stretchH=stretchH;
e.onmousedown=function(ev) { var ev=ev||window.event;
this.sizing=true;
this.startX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
this.startY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
this.startW=this.offsetWidth;
this.startH=this.offsetHeight;
return false;
};
e.onmousemove=function(ev) { var ev=ev||window.event;
if (this.sizing) {
var s=this.style;
var currX=!config.browser.isIE?ev.pageX:(ev.clientX+findScrollX());
var currY=!config.browser.isIE?ev.pageY:(ev.clientY+findScrollY());
var newW=(currX-this.offsetLeft)/(this.startX-this.offsetLeft)*this.startW;
var newH=(currY-this.offsetTop )/(this.startY-this.offsetTop )*this.startH;
if (this.stretchW) s.width =Math.floor(Math.max(newW,this.minW))+'px';
if (this.stretchH) s.height=Math.floor(Math.max(newH,this.minH))+'px';
clearMessage(); displayMessage(this.statusMsg.format([s.width,s.height]));
}
return false;
};
e.onmouseup=function(ev) { var ev=ev||window.event;
if (ev.shiftKey) { this.style.width=this.style.height=''; }
if (ev.ctrlKey) { this.style.width=this.originalW; this.style.height=this.originalH; }
this.sizing=false;
clearMessage();
return false;
};
e.onmouseout=function(ev) { var ev=ev||window.event;
this.sizing=false;
clearMessage();
return false;
};
}
//}}}
<<option chkAnimate>> Enable Animations
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
</div>
</div>
<div id='siteMenu' class='siteMenu' refresh='content' tiddler='SiteMenu' style='clear:both'></div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div macro="hideWhen readOnly">
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
| <html><iframe width="420" height="315" src="http://www.youtube.com/embed/Ypxl8VFNlRE" frameborder="0" allowfullscreen></iframe></html> |A somewhat surprising discovery was that if you just attach a simulated character model to motion capture markers (simulated as infinite point masses) through joint constraints, the model follows the correct trajectory. You can then constrain the model to reproduce the kinematic trajectory using internal dynamics and the solver finds, in real-time, a dynamic solution that accounts for gravity, momentum, and contact constraints. Exactly reproducing the original trajectory still requires small residual external torques, but these can be applied at bodies in contact with the environment. <html><br><br></html>The markers need to be mapped onto the model, but the mapping is very forgiving, allowing you to easily [[retarget the markers to a different model|http://www.youtube.com/watch?v=ysTuu247-oo]]. You also do not need very many markers to get reasonable behavior if you apply "joint stiffness" constraints to the model to bias it toward a prior pose. [[More about this on my blog|http://lost-found-wandering.blogspot.com/2012/12/physics-based-skeleton-fit-inverse.html]].<html><h3>Paper</h3></html>J. L. Cooper and D. Ballard. [[Realtime, Physics-Based Marker Following|http://www.springerlink.com/content/dw80789343584574/]]. //Motion in Games 2012, Lecture Notes in Computer Science//, M. Kallmann and K. Bekris (Eds.): pp 350-361, 2012. |
!!!Journal Articles
G. Diaz, J. L. Cooper, M. Hayhoe, and C. Rothkopf. Saccades to future ball location reveal memory-based prediction in a natural interception task. //Journal of Vision//, Accepted, 2012.
M. A. Goodrich, B. S. Morse, C. Engh, J. L. Cooper, and J. A. Adams. Towards using Unmanned Aerial Vehicles (~UAVs) in Wilderness Search and Rescue: Lessons from field trials. //Interaction Studies//, 10(3), pp 455-481, 2009.
J. A. Adams, C. M. Humphrey, M. A. Goodrich, J. L. Cooper, B. S. Morse, C. Engh and N. Rasmussen. Cognitive Task Analysis for Developing UAV Wilderness Search Support. //Journal of Cognitive Engineering and Decision Making//, 3(1), pp 1-26, 2009.
M. A. Goodrich, B. S. Morse, Damon Gerhardt, J. L. Cooper, M. Quigley, J. A. Adams, and C. Humphrey. Supporting Wilderness Search and Rescue using a ~Camera-Equipped Mini UAV. //Journal of Field Robotics//, 25 (1-2), pp 89-110, 2008. The paper is [[available for free from Wiley InterScience|http://www3.interscience.wiley.com/cgi-bin/fulltext/117865012/PDFSTART]].
!!!Conference Papers
J. L. Cooper and D. Ballard. [[Realtime, Physics-Based Marker Following|http://www.springerlink.com/content/dw80789343584574/]]. //Motion in Games 2012, Lecture Notes in Computer Science//, M. Kallmann and K. Bekris (Eds.): pp 350-361, 2012.
J. L. Cooper and M. A. Goodrich. [[Towards Combining UAV and Sensor Operator Roles in UAV-Enabled Visual Search|http://faculty.cs.byu.edu/~mike/mikeg/papers/p351-cooper.pdf]]. In //Proceedings of ACM/IEEE International Conference on ~Human-Robot Interaction//, March 2008, Amsterdam, The Netherlands. (Best student paper award).
M. A. Goodrich, J. L. Cooper, J. A. Adams, C. Humphrey, R. Zeeman, and Brian G. Buss. Using a ~Mini-UAV to Support Wilderness Search and Rescue Practices for ~Human-Robot Teaming. In //Proceedings of the IEEE International Conference on Safety, Security and Rescue Robotics//, 2007. A draft of the paper is available [[here|http://faculty.cs.byu.edu/~mike/mikeg/papers/GoodrichSSRRCameraReady.pdf]].
J. L. Cooper and M. A. Goodrich. Integrating critical interface elements for intuitive single-display aviation control of ~UAVs. //Proceedings of SPIE -- Volume 6226. Enhanced and Synthetic Vision 2006//, Jacques G. Verly, Jeff J. Guell, Editors. [[Abstract and paper download available from SPIE.|http://spiedl.aip.org/getabs/servlet/GetabsServlet?prog=normal&id=PSISDG00622600000162260B000001&idtype=cvips&gifs=yes]]
!!!Thesis
J. L. Cooper. [[Supporting Flight Control for UAV-Assisted Wilderness Search and Rescue Through Human Centered Interface Design|http://www.cs.utexas.edu/~jcooper/Thesis.pdf]]. M.S. Thesis, Brigham Young University, 2008.
!!!Conference and Workshop Presentations
G. Diaz, J. L. Cooper, M. Hayhoe. Internal models for predictive saccades in a natural interception task. //[[22nd meeting of the Society for the Neural Control of Movement|http://ncm-society.org/upload/docs/Program%20-%20Satellite%20Meetings/2012_NCM_Satellite_Meeting_Program_2012_03_05.pdf]]//, Venice, Italy, April 2012.
J. L. Cooper, M. A. Goodrich, D. Gerhardt, and B. Morse. Appropriate Spatiotemporal Scope of Automation and Interface Elements in ~UAV-Assisted Wilderness Search and Rescue. Human Factors of ~UAVs Workshop, Chandler, AZ, May 2007.
M. A. Goodrich and J. L. Cooper, "~Mini-UAV User Interface Elements: Trade-offs and Validation." Human Factors of ~UAVs Workshop, Mesa, AZ, May 2006.
M. A. Goodrich, M. Quigley, J. L. Cooper, and B. Barber, "Portable ~Mini-UAV Control Interfaces for the ~Non-Pilot." Human Factors of ~UAVs Workshop, Mesa, AZ, May 2005.
| <html><iframe width="420" height="315" src="http://www.youtube.com/embed/R3_iq9Q_U6M" frameborder="0" allowfullscreen></iframe></html> |As a first step toward building our own balancing agents, I reproduced Marc Raibert's hoppers as described in "Legged Robots that Balance" using the ODE simulator. The book is well-written and the models basically worked as soon as I finished translating the text-descriptions into ODE code. |
My research as a ~PhD student in Computer Science is on hierarchical motor control. We know that the brain is composed of separate logical units (neurons) in a complex hierarchical structure. I seek to understand, in part, what this hierarchy is doing. Humans accomplish a task by repeatedly breaking it into sub-tasks. Memory and mental simulation, as well as vestibular, tactile, proprioceptive, and visual input, inform the brain and body on how well a task is progressing at multiple levels of abstraction. The brain and body use this feedback to produce control signals to the muscles to drive the body toward accomplishing the goals.
[>img[vrRacquetballSmall.jpg][vrRacquetball.jpg]]The neural mechanisms underlying this process are not well-understood, but we know that it allows humans to solve a remarkably varied set of problems. In order to get a glimpse into this phenomenon, we use two general tools: forward modeling and reverse engineering. Both techniques rely on each other.
Forward modeling involves taking some description of a simple motor task and trying to build a simulated system that accomplishes it. Reverse engineering involves taking data from humans performing a task (both the inputs to the human and outputs from the human to the extent possible) and then trying to find patterns within the data. Ideally, both methods work in a loop where we capture data and build a model from observations on those data. Then we test the model to see how well it matches other data, just like in most machine learning applications.
With a [[PhaseSpace|http://phasespace.com/]] motion capture system, a good graphics card, and several head-mounted displays ([[nVis SX111|http://www.nvisinc.com/product.php?id=48]] and [[V8 hmd|http://www.virtualresearch.com/products/v8.htm]]), we have the tools we need to build compelling, interactive, virtual scenarios. We then carefully control the visual and auditory inputs received by the human and record the motion that the human generates in response. We also use [[32-channel wireless EMG|http://www.myopac.com/]] to read muscle activation, eye-tracking cameras ([[1|http://www.asleyetracking.com/Site/]],[[2|http://www.arringtonresearch.com/]]) to follow gaze, Wii-fit [[balance boards|https://github.com/rpavlik/wiiuse/]] to measure forces, Wii remotes with the motion-plus plugin for inertial measurements, and microphones for auditory data.
Once we have the data, building useful models can be tricky. I am working to decompose task-driven movements into abstract feedback models that can still accomplish the task when conditions have changed. The toy domain that I work in is virtual racquetball. This is convenient because it involves a relatively small closed environment with few objects, but it still involves multiple interacting agents and interesting, highly dynamic movements. Playing racquetball is also an interesting task. We are working toward developing a controller that drives a simulated character with valid, internal forces to play virtual racquetball with a human. This involves addressing a number of interesting problems along the way.<html><br clear=all></html>
!!!Projects
| [img(auto,10em)[Physics based skeleton fit, inverse kinematics, retargeting, and inverse dynamics|images/odeIKID.jpg][Physics based model control]] | [img(auto,10em)[Physically simulated virtual environments|images/vrPreview.jpg][Virtual Environments]] | [img(auto,10em)[Human feedback for Humanoid standing control|images/standPreview.jpg][Human feedback for Humanoid standing control]] |
| Physics based fit, IK, and ID | Virtual Environments | Human feedback control |
| [img(auto,10em)[Constraints in ODE Physics Engine|images/lmPlusPreview.jpg][Constraints in ODE Physics Engine]] | [img(auto,10em)[Raibert-style hopping models|images/hopperPreview.jpg][Raibert-style hopping models]] | [img(auto,10em)[Implicit computation of gyroscopic forces|images/gyroPreview.jpg][http://www.youtube.com/watch?v=RHqyKfxWNpY]] |
|New ODE constraints | Simple model controllers | [[Implicit gyro forces|http://lost-found-wandering.blogspot.com/2013/01/gyroscopic-forces-in-ode.html]] |
| [img(auto,10em)[Intuitive UAV Interface|images/uavUIpreview.jpg][http://www.youtube.com/watch?v=aKTUH_vigi0]] |
| [[Intuitive UAV Control|http://www.cs.utexas.edu/~jcooper/Thesis.pdf]] |
Other
|[img(auto,10em)[3d breakout game|images/gamePreview.jpg][http://www.youtube.com/watch?v=h6BA6DD0A64]] |
| 3d breakout game<html><br></html>24hr coding event |
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>
/%
%/ {{indent{ [img[Home|elements/home.jpg][Home]] [img[Research|elements/research.jpg][Research]] [img[School|elements/school.jpg][Formal Education]] [img[Publications|elements/publications.jpg][Publications and Presentations]]/%
%/ [img[While I'm not at school|elements/personal.jpg][Personal Life]] [img[Link to contact info|elements/contact.jpg][Contact Information]]}}}
@@font-family:"Times New Roman",Georgia,Serif;Joseph L. Cooper@@
/***
!Spacing stuff /%==================================================%/
***/
/*{{{*/
.header
{ background:transparent; padding:.3em .3em; border-bottom:1px solid; position:static; }
.headerShadow, .headerForeground
{ padding:1em 2.5em 1em 5.5em; }
.header a, .header .button, .header .tiddlyLinkExisting, .header .tiddlyLinkNonExisting
{ font-weight: normal; font-style: normal; }
.header .externalLink,
.siteSubtitle a, .siteSubtitle .button, .siteSubtitle .tiddlyLinkExisting, .siteSubtitle .tiddlyLinkNonExisting
{ font-style:italic; text-decoration:none; }
.header table
{ border-collapse: collapse !important; }
#displayArea {margin:1em 17em 0 5em; max-width:1000px; }
.tiddler
{ padding: 0 1em 1em 1em; }
.button, .button:hover, .button:active,
.viewer .button, .viewer .button:hover, .viewer .button:active
{ background:transparent; border:0; }
.toolbar
{ float:right; display:inline; padding-bottom:0; visibility:visible; }
.selected .toolbar
{ visibility:visible; }
.toolbar .button, .toolbar a
{ border:1px solid transparent; background:transparent; margin:0px 1px; padding:0px .2em; -moz-border-radius:.5em; }
.toolbar
{color:[[ColorPalette::TertiaryLight]];}
.toolbar a
{color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar
{color:[[ColorPalette::Foreground]];}
.selected .toolbar, .selected .toolbar .button, .selected .toolbar a
{ color:#006; }
.toolbar .button:hover, .toolbar a:hover
{ border:1px solid #69c !important; background:#006 !important; color:#fff !important; }
.tagging, .tagged
{ background-color: #ccc; border: 1px solid; }
.selected .tagging, .selected .tagged
{ background-color:#eee; border: 1px solid #999; }
.tagging, .tagged
{ -moz-border-radius:1em; }
.subtitle
{ font-size:90%; }
.editor input, .editor textarea
{ font-size: 8pt;}
.editor select
{ font-size: 8pt; border:1px solid; }
.title
{ font-size: 2em; line-height:120%; }
.viewer
{ font-size: 9pt; padding: 0.7em; }
.viewer pre, .viewer code, .viewer blockquote
{ font-size:8pt; text-align:left; }
.viewer pre
{ background:#ffe; border:1px solid; }
.viewer table, .viewer table tr, .viewer table td
{ border:1px solid; }
.viewer hr {
margin: 1px; padding:1px;
border:0;
border-top: solid 1px #666;
color: #666;
}
.viewer img {
margin: 1px 5px;
}
.viewer blockquote {
line-height: 1.5em;
padding-left: 1em;
margin-left: 1em;
border-left: 1px dotted;
}
.viewer td { vertical-align: top; }
/*}}}*/
/***
!Textures /%==================================================%/
/*{{{*/
body
{ background-image: url('images/parchment.jpg'); }
.tagging, .tagged
{ background-color: transparent; border: 1px solid #ccc; }
.selected .tagging, .selected .tagged
{ background-image: url('images/parchment.jpg'); background-color:#edb; border: 1px solid #999; }
.menubox
{ background-image: url('images/parchment_gray.jpg'); background-color:#fff; }
.viewer
{ background-image: url('images/parchment_gray.jpg'); background-color:#fff; border: 1px solid #999;
/*}}}*/
/***
|Name|ToggleTopButton|
|Source|http://www.TiddlyTools.com/#ToggleTopButton|
|Version|0.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|adds a floating "scroll to top" button in the lower right corner of the window. |
***/
//{{{
window.showTopButton=function(show) {
// remove existing "top" button (if any)
var e=document.getElementById("scrollToTopButton"); if (e) e.parentNode.removeChild(e);
if (config.browser.isIE) return; // IE doesn't do FIXED... do nothing.
if (!show) return; // hiding button... we're done.
// create a link that scrolls to the top of page
e=createTiddlyElement(null,"A",null,null,"Return to top");
e.id="scrollToTopButton";
e.title="scroll to top of page";
e.onclick=function(){window.scrollTo(0,0)};
// make it hover in the bottom right corner of the window
var s=e.style;
s.position="fixed";
s.zIndex="1001"; // hopefully, this will be on top of ALL other elements!
s.bottom="1em";
s.right="3em";
s.cursor="pointer";
s.backgroundColor="#eee";
s.color="#009";
s.border="1px solid";
s.padding="0 1em";
s.MozBorderRadius="1em";
s.fontSize="7pt";
document.body.insertBefore(e,null);
}
if (config.options.chkShowTopButton==undefined) config.options.chkShowTopButton=true;
window.showTopButton(config.options.chkShowTopButton);
//}}}
|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|
|~WebToolbar|closeTiddler closeOthers jump permalink references|
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
<!--{{{-->
<div macro="showWhen readOnly">
<!- - cut-down toolbar for web users - ->
<div class='toolbar' macro='toolbar [[ToolbarCommands::WebToolbar]]'></div>
</div>
<div macro="hideWhen readOnly">
<!- - regular toolbar for editor - ->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
</div>
<div class='title' macro='view title'></div>
<div class='subtitle'></div>
<div class='tagging' macro='tagging'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
| <html><iframe width="420" height="315" src="http://www.youtube.com/embed/XS8qBvT3Htk" frameborder="0" allowfullscreen></iframe></html> |When I first arrived in the lab, Dr. Ballard had purchased a Phasespace motion capture system but no one was using it. I took on the task of using it to produce a virtual environment for interactive experiments. Tracking a head-mounted display with markers, I could render a physically simulated 3d world in stereo. With a tracked glove, I could interact with that world. Early versions of the environment used uniformly colored objects and walls. When I asked another person to put on the helmet a try to touch something, they had a very hard time.<html><br><br></html>Eventually I added several depth cues and people could function just fine. Detailed textures give a sense of depth because they become blurry at a distance. Projected shadow volumes are surprisingly important. As an object approaches its own shadow, it becomes clear that a collision is imminent. Familiar reference objects provide a lot of help. Instead of using only abstract cubes and spheres, if I have familiar objects, people can compare other objects to them to estimate size and distance..<html><br><br></html>I then incorporated EMG, eye-tracking cameras, force-plates, and inertial measurements. All of these sensors could produce data that could be used to influence the simulation in real-time. We also designed and executed psychophysical experiments using the environment to learn more about movement, balance, and attention. |