Do not reuse cid files.
This can cause improper cleanup logic.
Fixes #746

Signed-off-by: Tully Foote <22715502305f5acc3bd5bf22a9c406e70a1e1348@osrfoundation.org>

<project>
  <actions/>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <keepDependencies>false</keepDependencies>
  <properties>
@(SNIPPET(
    'property_log-rotator',
    days_to_keep=100,
    num_to_keep=100,
))@
@(SNIPPET(
    'property_job-priority',
    priority=30,
))@
@(SNIPPET(
    'property_requeue-job',
))@
@(SNIPPET(
    'property_parameters-definition',
    parameters=[
        {
            'type': 'boolean',
            'name': 'dry_run',
            'description': 'Skip the actual reconfiguration but show the diffs',
        },
    ],
))@
  </properties>
@(SNIPPET(
    'scm_git',
    url=ros_buildfarm_repository.url,
    branch_name=ros_buildfarm_repository.version or 'master',
    relative_target_dir='ros_buildfarm',
    refspec=None,
))@
  <scmCheckoutRetryCount>2</scmCheckoutRetryCount>
  <assignedNode>agent_on_master</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
@(SNIPPET(
    'trigger_timer',
    spec='0 23 * * *',
))@
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
@(SNIPPET(
    'builder_system-groovy',
    command=
"""// USE PARAMETER FOR BUILD DESCRIPTION
repository_names = build.buildVariableResolver.resolve('repository_names')
if (repository_names) {
  build.setDescription(repository_names)
}
""",
    script_file=None,
))@
@(SNIPPET(
    'builder_shell_docker-info',
))@
@(SNIPPET(
    'builder_shell_key-files',
    script_generating_key_files=script_generating_key_files,
))@
@[for ci_build_name in ci_build_names]@
@{ cid_filename = '$WORKSPACE/docker_generate_ci_jobs/docker__%s.cid' % (ci_build_name) }@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'rm -fr $WORKSPACE/docker_generate_ci_jobs',
        'rm -fr $WORKSPACE/reconfigure_jobs',
        'mkdir -p $WORKSPACE/docker_generate_ci_jobs',
        'mkdir -p $WORKSPACE/reconfigure_jobs',
        '',
        '# monitor all subprocesses and enforce termination',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/subprocess_reaper.py' +
        ' $$ --cid-file %s > $WORKSPACE/docker_generate_ci_jobs/subprocess_reaper.log 2>&1 &' % (cid_filename),
        '# sleep to give python time to startup',
        'sleep 1',
        '',
        '# generate Dockerfile, build and run it',
        '# generating the Dockerfiles for the actual CI tasks',
        'echo "# BEGIN SECTION: Generate Dockerfile - reconfigure jobs for %s"' % (ci_build_name),
        'export PYTHONPATH=$WORKSPACE/ros_buildfarm:$PYTHONPATH',
        'if [ "$dry_run" = "true" ]; then DRY_RUN_FLAG="--dry-run"; fi',
        'if [ "$repository_names" != "" ]; then REPOSITORY_NAMES_FLAG="--repository-names $repository_names"; fi',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/ci/run_ci_reconfigure_job.py' +
        ' ' + config_url +
        ' ' + rosdistro_name +
        ' ' + ci_build_name +
        ' ' + ' '.join(repository_args) +
        ' --groovy-script /tmp/reconfigure_jobs/reconfigure_jobs.groovy' +
        ' --dockerfile-dir $WORKSPACE/docker_generate_ci_jobs' +
        ' $DRY_RUN_FLAG' +
        ' $REPOSITORY_NAMES_FLAG',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - reconfigure jobs for %s"' % (ci_build_name),
        'cd $WORKSPACE/docker_generate_ci_jobs',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/misc/docker_pull_baseimage.py',
        'docker build --force-rm -t ci_reconfigure_jobs .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - reconfigure jobs for %s"' % (ci_build_name),
        '# -e=GIT_BRANCH= is required since Jenkins leaves the wc in detached state',
        'docker run' +
        ' --rm ' +
        ' --cidfile=%s' % (cid_filename) +
        ' -e=GIT_BRANCH=$GIT_BRANCH' +
        ' --net=host' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm:ro' +
        ' -v %s:%s:ro' % (credentials_src, credentials_dst) +
        ' -v $WORKSPACE/reconfigure_jobs:/tmp/reconfigure_jobs' +
        ' ci_reconfigure_jobs',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_system-groovy',
    command=None,
    script_file='$WORKSPACE/reconfigure_jobs/reconfigure_jobs.groovy',
))@
@[end for]@
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_mailer',
    recipients=recipients,
    dynamic_recipients=[],
    send_to_individuals=False,
))@
  </publishers>
  <buildWrappers>
@(SNIPPET(
    'build-wrapper_timestamper',
))@
  </buildWrappers>
</project>

<project>
  <actions/>
  <description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
  <keepDependencies>false</keepDependencies>
  <properties>
@(SNIPPET(
    'property_log-rotator',
    days_to_keep=100,
    num_to_keep=100,
))@
@(SNIPPET(
    'property_job-priority',
    priority=30,
))@
@(SNIPPET(
    'property_requeue-job',
))@
@(SNIPPET(
    'property_parameters-definition',
    parameters=[
        {
            'type': 'boolean',
            'name': 'dry_run',
            'description': 'Skip the actual reconfiguration but show the diffs',
        },
    ],
))@
  </properties>
@(SNIPPET(
    'scm_git',
    url=ros_buildfarm_repository.url,
    branch_name=ros_buildfarm_repository.version or 'master',
    relative_target_dir='ros_buildfarm',
    refspec=None,
))@
  <scmCheckoutRetryCount>2</scmCheckoutRetryCount>
  <assignedNode>agent_on_master</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
@(SNIPPET(
    'trigger_timer',
    spec='0 23 * * *',
))@
  </triggers>
  <concurrentBuild>false</concurrentBuild>
  <builders>
@(SNIPPET(
    'builder_system-groovy',
    command=
"""// USE PARAMETER FOR BUILD DESCRIPTION
repository_names = build.buildVariableResolver.resolve('repository_names')
if (repository_names) {
  build.setDescription(repository_names)
}
""",
    script_file=None,
))@
@(SNIPPET(
    'builder_shell_docker-info',
))@
@(SNIPPET(
    'builder_shell_key-files',
    script_generating_key_files=script_generating_key_files,
))@
@[for ci_build_name in ci_build_names]@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'rm -fr $WORKSPACE/docker_generate_ci_jobs',
        'rm -fr $WORKSPACE/reconfigure_jobs',
        'mkdir -p $WORKSPACE/docker_generate_ci_jobs',
        'mkdir -p $WORKSPACE/reconfigure_jobs',
        '',
        '# monitor all subprocesses and enforce termination',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/subprocess_reaper.py $$ --cid-file $WORKSPACE/docker_generate_ci_jobs/docker.cid > $WORKSPACE/docker_generate_ci_jobs/subprocess_reaper.log 2>&1 &',
        '# sleep to give python time to startup',
        'sleep 1',
        '',
        '# generate Dockerfile, build and run it',
        '# generating the Dockerfiles for the actual CI tasks',
        'echo "# BEGIN SECTION: Generate Dockerfile - reconfigure jobs for %s"' % (ci_build_name),
        'export PYTHONPATH=$WORKSPACE/ros_buildfarm:$PYTHONPATH',
        'if [ "$dry_run" = "true" ]; then DRY_RUN_FLAG="--dry-run"; fi',
        'if [ "$repository_names" != "" ]; then REPOSITORY_NAMES_FLAG="--repository-names $repository_names"; fi',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/ci/run_ci_reconfigure_job.py' +
        ' ' + config_url +
        ' ' + rosdistro_name +
        ' ' + ci_build_name +
        ' ' + ' '.join(repository_args) +
        ' --groovy-script /tmp/reconfigure_jobs/reconfigure_jobs.groovy' +
        ' --dockerfile-dir $WORKSPACE/docker_generate_ci_jobs' +
        ' $DRY_RUN_FLAG' +
        ' $REPOSITORY_NAMES_FLAG',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - reconfigure jobs for %s"' % (ci_build_name),
        'cd $WORKSPACE/docker_generate_ci_jobs',
        'python3 -u $WORKSPACE/ros_buildfarm/scripts/misc/docker_pull_baseimage.py',
        'docker build --force-rm -t ci_reconfigure_jobs .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - reconfigure jobs for %s"' % (ci_build_name),
        '# -e=GIT_BRANCH= is required since Jenkins leaves the wc in detached state',
        'docker run' +
        ' --rm ' +
        ' --cidfile=$WORKSPACE/docker_generate_ci_jobs/docker.cid' +
        ' -e=GIT_BRANCH=$GIT_BRANCH' +
        ' --net=host' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm:ro' +
        ' -v %s:%s:ro' % (credentials_src, credentials_dst) +
        ' -v $WORKSPACE/reconfigure_jobs:/tmp/reconfigure_jobs' +
        ' ci_reconfigure_jobs',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_system-groovy',
    command=None,
    script_file='$WORKSPACE/reconfigure_jobs/reconfigure_jobs.groovy',
))@
@[end for]@
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_mailer',
    recipients=recipients,
    dynamic_recipients=[],
    send_to_individuals=False,
))@
  </publishers>
  <buildWrappers>
@(SNIPPET(
    'build-wrapper_timestamper',
))@
  </buildWrappers>
</project>


[GladiatorTool] backup

[GladiatorTool] backup

macro _ReplaceInBufRegex( hbuf, oldPattern, newPattern )
{
  lnStart         = 0;
  lnLim           = GetBufLineCount( hbuf );
  fMatchCase      = 0;
  fRegExp         = 1;
  fWholeWordsOnly = 0;
  fConfirm        = 1;

  ReplaceInBuf( hbuf, oldPattern, newPattern, lnStart, lnLim,
                fMatchCase, fRegExp, fWholeWordsOnly, fConfirm );
}

macro RefactorGetData( )
{
  hbuf = GetCurrentBuf( );
  sel  = GetBufSelText( hbuf );

  if ( sel == nil )
  {
    return;
  }

  oldPattern = "\\(.*=.*\\)\\(@sel@\\)\\(.*;.*\\)";
  newPattern = "\\1\\Get@sel@()\\3";

  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  AppendBufLine( hbuf, "void Get@sel@( void )" );
  AppendBufLine( hbuf, "{" );
  AppendBufLine( hbuf, "  return @sel@;" );
  AppendBufLine( hbuf, "}" );
}

macro RefactorSetData( )
{
  hbuf = GetCurrentBuf( );
  sel  = GetBufSelText( hbuf );

  if ( sel == nil )
  {
    return;
  }

  oldPattern = "\\(\\w*@sel@\\w*=\\)\\(.*\\)\\(;\\)";
  newPattern = "\\Set@sel@(\\2\\)";

  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  AppendBufLine( hbuf, "void Set@sel@( var )" );
  AppendBufLine( hbuf, "{" );
  AppendBufLine( hbuf, "  @sel@ = var;" );
  AppendBufLine( hbuf, "}" );
}

macro RefactorExtractMethod( )
{
  hbuf = GetCurrentBuf( );
  hwnd = GetCurrentWnd( );
  sel  = GetWndSel( hwnd );

  // Create extracted fucntion
  AppendBufLine( hbuf, "void extractedfunction( void )" );
  AppendBufLine( hbuf, "{" );
  iLine = sel.lnFirst;
  while ( iLine <= sel.lnLast )
  {
    szLine = GetBufLine( hbuf, iLine );
    AppendBufLine( hbuf, szLine );
    iLine = iLine + 1;
  }
  AppendBufLine( hbuf, "}" );

  iLine = sel.lnFirst; // Save line number

  cut; // Delete origin code block

  // Call extracted function
  InsBufLine( hbuf, iLine, "extractedfunction( );" );
}

macro RefactorMisraConstU( )
{
  hbuf = GetCurrentBuf( );

  // Constant like 0xff, 0x10, white space at the end
  oldPattern = "\\(\\w0[xX][0-9a-fA-F]+\\)\\([\\w;,]\\)";
  newPattern = "\\1\\U\\2\\";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant like 0xff, 0x10, white space at the end
  oldPattern = "\\(\\w0[xX][0-9a-fA-F]+\\)\\w";
  newPattern = "\\1\\U\\s";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant like 0xff, 0x10, and at the end of the line
  oldPattern = "\\(\\w0[xX][0-9a-fA-F]+$\\)";
  // Add u at the end
  newPattern = "\\1\\U";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant like 10, 356, ; or , at the end
  oldPattern = "\\(\\w[0-9]+\\)\\([;,]\\)";
  newPattern = "\\1\\U\\2\\";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant white space at the end
  oldPattern = "\\(\\w[0-9]+\\)\\w";
  newPattern = "\\1\\U\\s";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant at the end of the line
  oldPattern = "\\(\\w[0-9]+$\\)";
  // Add u at the end
  newPattern = "\\1\\U";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );
}

// Add Bracket for define, for example
// Before:  #define XXX YYY ZZZ
// After :  #define XXX ( YYY ZZZ )
macro RefactorDefineAddBracket( )
{
  hbuf = GetCurrentBuf( );

  oldPattern = "\\(\\#define\\w+.+\\w+\\)\\(.+[^)]$\\)";
  newPattern = "\\1\\( \\2\\ )";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );
}

macro _ReplaceInBufRegex( hbuf, oldPattern, newPattern )
{
  lnStart         = 0;
  lnLim           = GetBufLineCount( hbuf );
  fMatchCase      = 0;
  fRegExp         = 1;
  fWholeWordsOnly = 0;
  fConfirm        = 1;

  ReplaceInBuf( hbuf, oldPattern, newPattern, lnStart, lnLim,
                fMatchCase, fRegExp, fWholeWordsOnly, fConfirm );
}

macro RefactorGetData( )
{
  hbuf = GetCurrentBuf( );
  sel  = GetBufSelText( hbuf );

  if ( sel == nil )
  {
    return;
  }

  oldPattern = "\\(.*=.*\\)\\(@sel@\\)\\(.*;.*\\)";
  newPattern = "\\1\\Get@sel@()\\3";

  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  AppendBufLine( hbuf, "void Get@sel@( void )" );
  AppendBufLine( hbuf, "{" );
  AppendBufLine( hbuf, "  return @sel@;" );
  AppendBufLine( hbuf, "}" );
}

macro RefactorSetData( )
{
  hbuf = GetCurrentBuf( );
  sel  = GetBufSelText( hbuf );

  if ( sel == nil )
  {
    return;
  }

  oldPattern = "\\(\\w*@sel@\\w*=\\)\\(.*\\)\\(;\\)";
  newPattern = "\\Set@sel@(\\2\\)";

  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  AppendBufLine( hbuf, "void Set@sel@( var )" );
  AppendBufLine( hbuf, "{" );
  AppendBufLine( hbuf, "  @sel@ = var;" );
  AppendBufLine( hbuf, "}" );
}

macro RefactorExtractMethod( )
{
  hbuf = GetCurrentBuf( );
  hwnd = GetCurrentWnd( );
  sel  = GetWndSel( hwnd );

  // Create extracted fucntion
  AppendBufLine( hbuf, "void extractedfunction( void )" );
  AppendBufLine( hbuf, "{" );
  iLine = sel.lnFirst;
  while ( iLine <= sel.lnLast )
  {
    szLine = GetBufLine( hbuf, iLine );
    AppendBufLine( hbuf, szLine );
    iLine = iLine + 1;
  }
  AppendBufLine( hbuf, "}" );

  iLine = sel.lnFirst; // Save line number

  cut; // Delete origin code block

  // Call extracted function
  InsBufLine( hbuf, iLine, "extractedfunction( );" );
}

macro RefactorMisraConstU( )
{
  hbuf = GetCurrentBuf( );

  // Constant like 0xff, 0x10, white space at the end
  oldPattern = "\\(\\w0[xX][0-9a-fA-F]+\\)\\([\\w;,]\\)";
  newPattern = "\\1\\u\\2\\";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant like 0xff, 0x10, white space at the end
  oldPattern = "\\(\\w0[xX][0-9a-fA-F]+\\)\\w";
  newPattern = "\\1\\u\\s";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant like 0xff, 0x10, and at the end of the line
  oldPattern = "\\(\\w0[xX][0-9a-fA-F]+$\\)";
  // Add u at the end
  newPattern = "\\1\\u";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant like 10, 356, ; or , at the end
  oldPattern = "\\(\\w[0-9]+\\)\\([;,]\\)";
  newPattern = "\\1\\u\\2\\";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant white space at the end
  oldPattern = "\\(\\w[0-9]+\\)\\w";
  newPattern = "\\1\\u\\s";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );

  // Constant at the end of the line
  oldPattern = "\\(\\w[0-9]+$\\)";
  // Add u at the end
  newPattern = "\\1\\u";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );
}

// Add Bracket for define, for example
// Before:  #define XXX YYY ZZZ
// After :  #define XXX ( YYY ZZZ )
macro RefactorDefineAddBracket( )
{
  hbuf = GetCurrentBuf( );

  oldPattern = "\\(\\#define\\w+.+\\w+\\)\\(.+[^)]$\\)";
  newPattern = "\\1\\( \\2\\ )";
  _ReplaceInBufRegex( hbuf, oldPattern, newPattern );
}


move devel jobs to slaves labeled with 'buildslave'

<project>
	<actions/>
	<description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
@(SNIPPET(
    'log-rotator',
    days_to_keep=100,
    num_to_keep=100,
))@
	<keepDependencies>false</keepDependencies>
	<properties>
@[if job_priority is not None]@
@(SNIPPET(
    'property_job-priority',
    priority=job_priority,
))@
@[end if]@
	</properties>
@(SNIPPET(
    'scm',
    repo_spec=source_repo_spec,
    path='catkin_workspace/src/%s' % source_repo_spec.name
))@
	<assignedNode>buildslave</assignedNode>
	<canRoam>false</canRoam>
	<disabled>false</disabled>
	<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
	<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
	<triggers>
@(SNIPPET(
    'trigger_poll',
    spec='H * * * *',
))@
	</triggers>
	<concurrentBuild>true</concurrentBuild>
	<builders>
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Clone custom rosdistro"',
        'rm -fr rosdistro',
        'git clone https://github.com/dirk-thomas/ros-infrastructure_rosdistro.git rosdistro',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Clone ros_buildfarm"',
        'rm -fr ros_buildfarm',
        'git clone https://github.com/dirk-thomas/ros_buildfarm.git ros_buildfarm',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        '# generate key files',
        'echo "# BEGIN SECTION: Generate key files"',
    ] + script_generating_key_files + [
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        '# generate Dockerfile, build and run it',
        '# generating the Dockerfiles for the actual build tasks',
        'echo "# BEGIN SECTION: Generate Dockerfile 1"',
        'mkdir -p $WORKSPACE/docker_generating_devel_dockers',
        'export PYTHONPATH=$WORKSPACE/ros_buildfarm:$PYTHONPATH',
        '$WORKSPACE/ros_buildfarm/scripts/devel/run_devel_job.py' +
        ' --rosdistro-index-url %s' % rosdistro_index_url +
        ' --rosdistro-name %s' % rosdistro_name +
        ' --source-build-name %s' % source_build_name +
        ' --repo-name %s' % source_repo_spec.name +
        ' --os-name %s' % os_name +
        ' --os-code-name %s' % os_code_name +
        ' --arch %s' % arch +
        ' ' + ' '.join(apt_mirror_args) +
        ' --workspace-root $WORKSPACE/catkin_workspace' +
        ' --dockerfile-dir $WORKSPACE/docker_generating_devel_dockers',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - generating docker tasks"',
        'cd $WORKSPACE/docker_generating_devel_dockers',
        'docker build -t devel .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - generating docker tasks"',
        'mkdir -p $WORKSPACE/docker_build_and_install',
        'mkdir -p $WORKSPACE/docker_build_and_test',
        'docker run' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm' +
        ' -v $WORKSPACE/catkin_workspace:/tmp/catkin_workspace' +
        ' -v $WORKSPACE/docker_build_and_install:/tmp/docker_build_and_install' +
        ' -v $WORKSPACE/docker_build_and_test:/tmp/docker_build_and_test' +
        ' devel',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Build Dockerfile - build and install"',
        '# build and run build_and_install Dockerfile',
        'cd $WORKSPACE/docker_build_and_install',
        'docker build -t build_and_install .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - build and install"',
        'docker run' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm' +
        ' -v $WORKSPACE/catkin_workspace:/tmp/catkin_workspace' +
        ' build_and_install',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Build Dockerfile - build and test"',
        '# build and run build_and_test Dockerfile',
        'cd $WORKSPACE/docker_build_and_test',
        'docker build -t build_and_test .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - build and test"',
        'docker run' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm' +
        ' -v $WORKSPACE/catkin_workspace:/tmp/catkin_workspace' +
        ' build_and_test',
        'echo "# END SECTION"',
    ]),
))@
	</builders>
	<publishers>
@(SNIPPET(
    'publisher_junit',
    test_results='catkin_workspace/build_isolated/**/*.xml',
))@
@(SNIPPET(
    'publisher_mailer',
    recipients=recipients,
    send_to_individuals=True,
))@
	</publishers>
	<buildWrappers>
@[if timeout_minutes is not None]@
@(SNIPPET(
    'build-wrapper_build-timeout',
    timeout_minutes=timeout_minutes,
))@
@[end if]@
	</buildWrappers>
</project>

<project>
	<actions/>
	<description>Generated at @ESCAPE(now_str) from template '@ESCAPE(template_name)'</description>
@(SNIPPET(
    'log-rotator',
    days_to_keep=100,
    num_to_keep=100,
))@
	<keepDependencies>false</keepDependencies>
	<properties>
@[if job_priority is not None]@
@(SNIPPET(
    'property_job-priority',
    priority=job_priority,
))@
@[end if]@
	</properties>
@(SNIPPET(
    'scm',
    repo_spec=source_repo_spec,
    path='catkin_workspace/src/%s' % source_repo_spec.name
))@
	<assignedNode>master</assignedNode>
	<canRoam>false</canRoam>
	<disabled>false</disabled>
	<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
	<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
	<triggers>
@(SNIPPET(
    'trigger_poll',
    spec='H * * * *',
))@
	</triggers>
	<concurrentBuild>true</concurrentBuild>
	<builders>
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Clone custom rosdistro"',
        'rm -fr rosdistro',
        'git clone https://github.com/dirk-thomas/ros-infrastructure_rosdistro.git rosdistro',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Clone ros_buildfarm"',
        'rm -fr ros_buildfarm',
        'git clone https://github.com/dirk-thomas/ros_buildfarm.git ros_buildfarm',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        '# generate key files',
        'echo "# BEGIN SECTION: Generate key files"',
    ] + script_generating_key_files + [
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        '# generate Dockerfile, build and run it',
        '# generating the Dockerfiles for the actual build tasks',
        'echo "# BEGIN SECTION: Generate Dockerfile 1"',
        'mkdir -p $WORKSPACE/docker_generating_devel_dockers',
        'export PYTHONPATH=$WORKSPACE/ros_buildfarm:$PYTHONPATH',
        '$WORKSPACE/ros_buildfarm/scripts/devel/run_devel_job.py' +
        ' --rosdistro-index-url %s' % rosdistro_index_url +
        ' --rosdistro-name %s' % rosdistro_name +
        ' --source-build-name %s' % source_build_name +
        ' --repo-name %s' % source_repo_spec.name +
        ' --os-name %s' % os_name +
        ' --os-code-name %s' % os_code_name +
        ' --arch %s' % arch +
        ' ' + ' '.join(apt_mirror_args) +
        ' --workspace-root $WORKSPACE/catkin_workspace' +
        ' --dockerfile-dir $WORKSPACE/docker_generating_devel_dockers',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Build Dockerfile - generating docker tasks"',
        'cd $WORKSPACE/docker_generating_devel_dockers',
        'docker build -t devel .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - generating docker tasks"',
        'mkdir -p $WORKSPACE/docker_build_and_install',
        'mkdir -p $WORKSPACE/docker_build_and_test',
        'docker run' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm' +
        ' -v $WORKSPACE/catkin_workspace:/tmp/catkin_workspace' +
        ' -v $WORKSPACE/docker_build_and_install:/tmp/docker_build_and_install' +
        ' -v $WORKSPACE/docker_build_and_test:/tmp/docker_build_and_test' +
        ' devel',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Build Dockerfile - build and install"',
        '# build and run build_and_install Dockerfile',
        'cd $WORKSPACE/docker_build_and_install',
        'docker build -t build_and_install .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - build and install"',
        'docker run' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm' +
        ' -v $WORKSPACE/catkin_workspace:/tmp/catkin_workspace' +
        ' build_and_install',
        'echo "# END SECTION"',
    ]),
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Build Dockerfile - build and test"',
        '# build and run build_and_test Dockerfile',
        'cd $WORKSPACE/docker_build_and_test',
        'docker build -t build_and_test .',
        'echo "# END SECTION"',
        '',
        'echo "# BEGIN SECTION: Run Dockerfile - build and test"',
        'docker run' +
        ' -v $WORKSPACE/ros_buildfarm:/tmp/ros_buildfarm' +
        ' -v $WORKSPACE/catkin_workspace:/tmp/catkin_workspace' +
        ' build_and_test',
        'echo "# END SECTION"',
    ]),
))@
	</builders>
	<publishers>
@(SNIPPET(
    'publisher_junit',
    test_results='catkin_workspace/build_isolated/**/*.xml',
))@
@(SNIPPET(
    'publisher_mailer',
    recipients=recipients,
    send_to_individuals=True,
))@
	</publishers>
	<buildWrappers>
@[if timeout_minutes is not None]@
@(SNIPPET(
    'build-wrapper_build-timeout',
    timeout_minutes=timeout_minutes,
))@
@[end if]@
	</buildWrappers>
</project>


Fix axes to not rely on being fully connected to function correctly.

/* axes.em
 *
 * Author: Will Monroe
 *
 * Restrict an object's motion to take place along a certain axis while
 * dragging.
 *
 * [currently: creates a single axis as its own entity, which can be dragged
 * in any direction and is not attached to another presence]
 */
system.require('std/graphics/graphics.em');

(function() {

     var redAxisMesh = 'meerkat:///wmonroe4/red_axis.dae/optimized/red_axis.dae';

     function axesScript(args) {
         system.require('std/movement/movableremote.em');
         system.require('std/movement/units.em');
         system.require('std/core/repeatingTimer.em');

         var moveMeshes = {x: 'meerkat:///wmonroe4/red_axis.dae/optimized/red_axis.dae',
                           y: 'meerkat:///wmonroe4/green_axis.dae/optimized/green_axis.dae',
                           z: 'meerkat:///wmonroe4/blue_axis.dae/optimized/blue_axis.dae'};
         var rotateMeshes = {x: 'meerkat:///wmonroe4/red_gimbal.dae/optimized/red_gimbal.dae',
                           y: 'meerkat:///wmonroe4/green_gimbal.dae/optimized/green_gimbal.dae',
                           z: 'meerkat:///wmonroe4/blue_gimbal.dae/optimized/blue_gimbal.dae'};
         var orientations = {x: new util.Quaternion(<0, 0, -1>, Math.PI / 2),
                             y: new util.Quaternion(),
                             z: new util.Quaternion(<1, 0, 0>, Math.PI / 2)};
         var axisMeshes = moveMeshes;
         var mode = 'move';
         var axes = {};
         var axisIDs = {};
         var movable = null;
         var updateTimer;
         var UPDATE_PERIOD = 1 * u.s;
         var ROTATE_FACTOR = 0.02;

         function onPresenceConnected(presence) {
             if(presence.mesh.slice(-12) != 'red_axis.dae')
                 return;

             setPosition << [{'request':'movable':},
                             {'position'::}];
             setOrientation << [{'request':'movable':},
                                {'orient'::}];
             setScale << [{'request':'movable':},
                          {'scale'::}];

             follow << [{'request':'axes':},
                               {'id'::}];
             toggleRotateMode << [{'request':'axes':},
                                  {'mode':'toggle':}];
             snapLocal << [{'request':'axes':},
                           {'snap':'local':}];
             snapGlobal << [{'request':'axes':},
                           {'snap':'global':}];
             forwardScriptRequest << [{'request':'script':}];
             onRedConnected(presence);
         }

         function onRedConnected(presence) {
             presence.modelOrientation = orientations.x;
             axes.x = presence;
             axisIDs[presence.toString()] = true;
             system.createPresence('meerkat:///wmonroe4/green_axis.dae/optimized/green_axis.dae',
                                   onGreenConnected);
         }

         function onGreenConnected(presence) {
             presence.modelOrientation = orientations.y;
             axes.y = presence;
             axisIDs[presence.toString()] = true;
             system.createPresence('meerkat:///wmonroe4/blue_axis.dae/optimized/blue_axis.dae',
                                   onBlueConnected);
         }

         function onBlueConnected(presence) {
             presence.modelOrientation = orientations.z;
             axes.z = presence;
             axisIDs[presence.toString()] = true;
             follow();
             updateTimer = new std.core.RepeatingTimer(UPDATE_PERIOD,
                                                       function() { follow(); });
             {axes: 'created'} >> args.avatar >> [];
         }

         function setPosition(msg, sender) {
             var axis = system.self.orientation.mul(
                     system.self.modelOrientation.mul(<0, 1, 0>));
             var delta = axis.scale(axis.dot(msg.position - system.self.position));
             if(mode == 'move') {
                 system.self.position = system.self.position + delta;

                 for(var a in axes)
                     axes[a].position = system.self.position;
                 if(movable)
                     movable.setPosition(system.self.position);
             } else /* mode == 'rotate' */ {
                 var quatDelta = new util.Quaternion(delta.normal(),
                                                     delta.length() * ROTATE_FACTOR /
                                                     system.self.scale);

                 system.self.orientation = quatDelta.mul(system.self.orientation);

                 for(var a in axes)
                     axes[a].orientation = system.self.orientation;
                 if(movable)
                     movable.setOrientation(system.self.orientation);
             }
             msg.makeReply({}) >> [];
         }

         function setOrientation(msg, sender) {
             /* Quaternions mess everything up!  By all means, try to fix this
              * code if you're brave.  Right now I've just made moving become
              * rotating when in rotate mode. (See above).
              */
             /*
             var axis = system.self.orientation.mul(
                     system.self.modelOrientation.mul(<0, 1, 0>));
             system.__debugPrint('axis: ' + std.core.pretty(axis) + '\n');
             var target = msg.orient.mul(<0, 1, 0>);
             system.__debugPrint('target: ' + std.core.pretty(target) + '\n');
             var corrAxis = target.cross(axis);
             system.__debugPrint('corr: ' + std.core.pretty(corrAxis) + '\n');
             var correction = (new util.Quaternion(corrAxis.x, corrAxis.y,
                                                  corrAxis.z, 1 +
                                                  target.dot(axis))).normal();
             var newOrient = correction.mul(msg.orient);
             system.__debugPrint('new y: ' + std.core.pretty(newOrient.mul(<0, 1, 0>)) + '\n\n');
             system.self.orientation = newOrient.mul(system.self.
                                       modelOrientation.inverse());
              */

             system.self.orientation = msg.orient.mul(system.self.
                                       modelOrientation.inverse());
             for(a in axes)
                 axes[a].orientation = system.self.orientation;
             if(movable)
                 movable.setOrientation(system.self.orientation);

             msg.makeReply({}) >> [];
         }

         function setScale(msg, sender) {
             system.self.scale = msg.scale;
             for(var a in axes)
                 axes[a].scale = system.self.scale;
             if(movable)
                 movable.setScale(system.self.scale / 2);
             msg.makeReply({}) >> [];
         }

         function follow(msg, sender) {
             if(typeof(msg) === 'undefined') {
                 if(movable) {
                     msg = {id: movable._remote.toString()};
                 } else {
                     msg = {id: ''};
                 }
             }

             if(msg.id !== '') {
                 if(msg.id in axisIDs)
                     // selecting an axis shouldn't make it follow itself!
                     return;

                 if(!movable || movable._remote.toString() != msg.id)
                     movable = new std.movement.MovableRemote(
                             system.createVisible(msg.id));

                 for(var a in axes) {
                     axes[a].mesh = axisMeshes[a];
                     axes[a].position = movable.getPosition();
                     axes[a].orientation = movable.getOrientation();
                     axes[a].scale = movable.getScale() * 2;
                 }
             } else {
                 movable = null;
                 for(var a in axes) {
                     axes[a].mesh = '';
                 }
             }
         }

         function toggleRotateMode(msg, sender) {
             mode = (mode == 'move' ? 'rotate' : 'move');
             axisMeshes = (mode == 'move' ? moveMeshes : rotateMeshes);
             for(var a in axes)
                 if(axes[a].mesh != '')
                     axes[a].mesh = axisMeshes[a];
         }

         function snapLocal(msg, sender) {
             for(var a in axes)
                 axes[a].modelOrientation = orientations[a];

             follow();
         }

         function snapGlobal(msg, sender) {
             if(!movable)
                 return;

             for(var a in axes)
                 axes[a].modelOrientation = movable.getOrientation().inverse().
                                            mul(orientations[a]);

             follow();
         }

         function forwardScriptRequest(msg, sender) {
             if(!movable)
                 return;

             msg >> movable._remote >> [];
         }

         system.onPresenceConnected(onPresenceConnected);
     }

     std.graphics.Graphics.prototype.onAxesCreated = function(msg, sender) {
         this._axesVisible = sender;
     };

     std.graphics.Graphics.prototype.createAxes = function(self) {
         std.core.bind(this.onAxesCreated, this) << [{'axes':'created':}];

         system.createEntityScript(<0, 0, 0>, axesScript,
                                   {avatar: self},
                                   self.queryAngle, redAxisMesh, 1);
     };

     std.graphics.Graphics.prototype._axes = {};

     std.graphics.Graphics.prototype._axes.follow = function(vis) {
         if (!this._axesVisible) return;
         if(vis)
             {request: 'axes', id: vis.toString()} >> this._axesVisible >> [];
         else
             {request: 'axes', id: ''} >> this._axesVisible >> [];
     };

     std.graphics.Graphics.prototype._axes.toggleRotateMode = function() {
         if (!this._axesVisible) return;
         {request: 'axes', mode: 'toggle'} >> this._axesVisible >> [];
     };

     std.graphics.Graphics.prototype._axes.snapLocal = function() {
         if (!this._axesVisible) return;
         {request: 'axes', snap: 'local'} >> this._axesVisible >> [];
     }

     std.graphics.Graphics.prototype._axes.snapGlobal = function() {
         if (!this._axesVisible) return;
         {request: 'axes', snap: 'global'} >> this._axesVisible >> [];
     }

})();

/* axes.em
 *
 * Author: Will Monroe
 *
 * Restrict an object's motion to take place along a certain axis while
 * dragging.
 *
 * [currently: creates a single axis as its own entity, which can be dragged
 * in any direction and is not attached to another presence]
 */
system.require('std/graphics/graphics.em');

(function() {

     var redAxisMesh = 'meerkat:///wmonroe4/red_axis.dae/optimized/red_axis.dae';

     function axesScript(args) {
         system.require('std/movement/movableremote.em');
         system.require('std/movement/units.em');
         system.require('std/core/repeatingTimer.em');

         var moveMeshes = {x: 'meerkat:///wmonroe4/red_axis.dae/optimized/red_axis.dae',
                           y: 'meerkat:///wmonroe4/green_axis.dae/optimized/green_axis.dae',
                           z: 'meerkat:///wmonroe4/blue_axis.dae/optimized/blue_axis.dae'};
         var rotateMeshes = {x: 'meerkat:///wmonroe4/red_gimbal.dae/optimized/red_gimbal.dae',
                           y: 'meerkat:///wmonroe4/green_gimbal.dae/optimized/green_gimbal.dae',
                           z: 'meerkat:///wmonroe4/blue_gimbal.dae/optimized/blue_gimbal.dae'};
         var orientations = {x: new util.Quaternion(<0, 0, -1>, Math.PI / 2),
                             y: new util.Quaternion(),
                             z: new util.Quaternion(<1, 0, 0>, Math.PI / 2)};
         var axisMeshes = moveMeshes;
         var mode = 'move';
         var axes = {};
         var axisIDs = {};
         var movable = null;
         var updateTimer;
         var UPDATE_PERIOD = 1 * u.s;
         var ROTATE_FACTOR = 0.02;

         function onPresenceConnected(presence) {
             if(presence.mesh.slice(-12) != 'red_axis.dae')
                 return;

             setPosition << [{'request':'movable':},
                             {'position'::}];
             setOrientation << [{'request':'movable':},
                                {'orient'::}];
             setScale << [{'request':'movable':},
                          {'scale'::}];

             follow << [{'request':'axes':},
                               {'id'::}];
             toggleRotateMode << [{'request':'axes':},
                                  {'mode':'toggle':}];
             snapLocal << [{'request':'axes':},
                           {'snap':'local':}];
             snapGlobal << [{'request':'axes':},
                           {'snap':'global':}];
             forwardScriptRequest << [{'request':'script':}];
             onRedConnected(presence);
         }

         function onRedConnected(presence) {
             presence.modelOrientation = orientations.x;
             axes.x = presence;
             axisIDs[presence.toString()] = true;
             system.createPresence('meerkat:///wmonroe4/green_axis.dae/optimized/green_axis.dae',
                                   onGreenConnected);
         }

         function onGreenConnected(presence) {
             presence.modelOrientation = orientations.y;
             axes.y = presence;
             axisIDs[presence.toString()] = true;
             system.createPresence('meerkat:///wmonroe4/blue_axis.dae/optimized/blue_axis.dae',
                                   onBlueConnected);
         }

         function onBlueConnected(presence) {
             presence.modelOrientation = orientations.z;
             axes.z = presence;
             axisIDs[presence.toString()] = true;
             follow();
             updateTimer = new std.core.RepeatingTimer(UPDATE_PERIOD,
                                                       function() { follow(); });
             {axes: 'created'} >> args.avatar >> [];
         }

         function setPosition(msg, sender) {
             var axis = system.self.orientation.mul(
                     system.self.modelOrientation.mul(<0, 1, 0>));
             var delta = axis.scale(axis.dot(msg.position - system.self.position));
             if(mode == 'move') {
                 system.self.position = system.self.position + delta;

                 for(var a in axes)
                     axes[a].position = system.self.position;
                 if(movable)
                     movable.setPosition(system.self.position);
             } else /* mode == 'rotate' */ {
                 var quatDelta = new util.Quaternion(delta.normal(),
                                                     delta.length() * ROTATE_FACTOR /
                                                     system.self.scale);

                 system.self.orientation = quatDelta.mul(system.self.orientation);

                 for(var a in axes)
                     axes[a].orientation = system.self.orientation;
                 if(movable)
                     movable.setOrientation(system.self.orientation);
             }
             msg.makeReply({}) >> [];
         }

         function setOrientation(msg, sender) {
             /* Quaternions mess everything up!  By all means, try to fix this
              * code if you're brave.  Right now I've just made moving become
              * rotating when in rotate mode. (See above).
              */
             /*
             var axis = system.self.orientation.mul(
                     system.self.modelOrientation.mul(<0, 1, 0>));
             system.__debugPrint('axis: ' + std.core.pretty(axis) + '\n');
             var target = msg.orient.mul(<0, 1, 0>);
             system.__debugPrint('target: ' + std.core.pretty(target) + '\n');
             var corrAxis = target.cross(axis);
             system.__debugPrint('corr: ' + std.core.pretty(corrAxis) + '\n');
             var correction = (new util.Quaternion(corrAxis.x, corrAxis.y,
                                                  corrAxis.z, 1 +
                                                  target.dot(axis))).normal();
             var newOrient = correction.mul(msg.orient);
             system.__debugPrint('new y: ' + std.core.pretty(newOrient.mul(<0, 1, 0>)) + '\n\n');
             system.self.orientation = newOrient.mul(system.self.
                                       modelOrientation.inverse());
              */

             system.self.orientation = msg.orient.mul(system.self.
                                       modelOrientation.inverse());
             for(a in axes)
                 axes[a].orientation = system.self.orientation;
             if(movable)
                 movable.setOrientation(system.self.orientation);

             msg.makeReply({}) >> [];
         }

         function setScale(msg, sender) {
             system.self.scale = msg.scale;
             for(var a in axes)
                 axes[a].scale = system.self.scale;
             if(movable)
                 movable.setScale(system.self.scale / 2);
             msg.makeReply({}) >> [];
         }

         function follow(msg, sender) {
             if(typeof(msg) === 'undefined') {
                 if(movable) {
                     msg = {id: movable._remote.toString()};
                 } else {
                     msg = {id: ''};
                 }
             }

             if(msg.id !== '') {
                 if(msg.id in axisIDs)
                     // selecting an axis shouldn't make it follow itself!
                     return;

                 if(!movable || movable._remote.toString() != msg.id)
                     movable = new std.movement.MovableRemote(
                             system.createVisible(msg.id));

                 for(var a in axes) {
                     axes[a].mesh = axisMeshes[a];
                     axes[a].position = movable.getPosition();
                     axes[a].orientation = movable.getOrientation();
                     axes[a].scale = movable.getScale() * 2;
                 }
             } else {
                 movable = null;
                 for(var a in axes) {
                     axes[a].mesh = '';
                 }
             }
         }

         function toggleRotateMode(msg, sender) {
             mode = (mode == 'move' ? 'rotate' : 'move');
             axisMeshes = (mode == 'move' ? moveMeshes : rotateMeshes);
             for(var a in axes)
                 if(axes[a].mesh != '')
                     axes[a].mesh = axisMeshes[a];
         }

         function snapLocal(msg, sender) {
             for(var a in axes)
                 axes[a].modelOrientation = orientations[a];

             follow();
         }

         function snapGlobal(msg, sender) {
             if(!movable)
                 return;

             for(var a in axes)
                 axes[a].modelOrientation = movable.getOrientation().inverse().
                                            mul(orientations[a]);

             follow();
         }

         function forwardScriptRequest(msg, sender) {
             if(!movable)
                 return;

             msg >> movable._remote >> [];
         }

         system.onPresenceConnected(onPresenceConnected);
     }

     std.graphics.Graphics.prototype.onAxesCreated = function(msg, sender) {
         if(typeof(this._axes) === 'undefined')
             this._axes = {};

         this._axes.follow = function(vis) {
             if(vis)
                 {request: 'axes', id: vis.toString()} >> sender >> [];
             else
                 {request: 'axes', id: ''} >> sender >> [];
         };

         this._axes.toggleRotateMode = function() {
             {request: 'axes', mode: 'toggle'} >> sender >> [];
         };

         this._axes.snapLocal = function() {
             {request: 'axes', snap: 'local'} >> sender >> [];
         }

         this._axes.snapGlobal = function() {
             {request: 'axes', snap: 'global'} >> sender >> [];
         }
     };

     std.graphics.Graphics.prototype.createAxes = function(self) {
         std.core.bind(this.onAxesCreated, this) << [{'axes':'created':}];

         system.createEntityScript(<0, 0, 0>, axesScript,
                                   {avatar: self},
                                   self.queryAngle, redAxisMesh, 1);
     };

})();


change accessor so pres.getOrientation(pres.setOrientation(q)) results in a quaternion equal to q

/*  Sirikata
 *  presence.em
 *
 *  Copyright (c) 2011, Bhupesh Chandra
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Add functions to the prototype for presence */

(function() {
     // Just a cache, but the underlying system will also store copies
     // and give us the existing one. This is necessary to make reset
     // transparent.
     var sims = {};

     system.__presence_constructor__.prototype.runSimulation = function(name) {
         if (!sims[this]) sims[this] = {};
         if (!sims[this][name]) sims[this][name] = this._runSimulation(name);
         return sims[this][name];
     };
 })();

system.__presence_constructor__.prototype.getSimulation =
    system.__presence_constructor__.prototype.runSimulation;

system.__presence_constructor__.prototype.onProxAdded =
function (funcToCallback,onExisting)
{
    var cb_handle = system.__sys_register_onProxAdded(this,funcToCallback,onExisting);
    // Return a callback handle with just a clear method
    return {
        'clear' : std.core.bind(this._delProxAdded, this, cb_handle)
    };
};

system.__presence_constructor__.prototype.onProxRemoved =
function (funcToCallback)
{
    var cb_handle = system.__sys_register_onProxRemoved(this,funcToCallback);
    // Return a callback handle with just a clear method
    return {
        'clear' : std.core.bind(this._delProxRemoved, this, cb_handle)
    };
};

system.__presence_constructor__.prototype._delProxAdded =
function (idToDelete)
{
    system.__sys_register_delProxAdded(this,idToDelete);
};

system.__presence_constructor__.prototype._delProxRemoved =
function (idToDelete)
{
    system.__sys_register_delProxRemoved(this,idToDelete);
};

system.__presence_constructor__.prototype.proxResultSet = {};

Object.defineProperty(system.__presence_constructor__.prototype, "position",
                      {
                          get: function() { return this.getPosition(); },
                          set: function() { return this.setPosition.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "queryAngle",
                      {
                          get: function() { return this.getQueryAngle(); },
                          set: function() { return this.setQueryAngle.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "velocity",
                      {
                          get: function() { return this.getVelocity(); },
                          set: function() { return this.setVelocity.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "orientation",
                      {
                          get: function() { return this.getOrientation(); },
                          set: function() { return this.setOrientation.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "orientationVel",
                      {
                          get: function() { return this.getOrientationVel(); },
                          set: function() { return this.setOrientationVel.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "scale",
                      {
                          get: function() { return this.getScale(); },
                          set: function() { return this.setScale.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "mesh",
                      {
                          get: function() { return this.getMesh(); },
                          set: function() { return this.setMesh.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "physics",
                      {
                          get: function() { return this.getPhysics(); },
                          set: function() { return this.updatePhysics.apply(this, arguments); },
                          enumerable: true
                      }
);

system.__presence_constructor__.prototype.__prettyPrintFieldsData__ = [
    "position", "velocity",
    "orientation", "orientationVel",
    "scale", "mesh", "physics"
];
system.__presence_constructor__.prototype.__prettyPrintFields__ = function() {
    return this.__prettyPrintFieldsData__;
};

system.__presence_constructor__.prototype.__getType = function()
{
  return 'presence';
};

{
  /** @namespace presence */
  var presence = function()
  {
    /**@function
       @description Returns the position of the presence
       @return the vector corresponding to the position of the presence
       @type util.Vec3
    */
    presence.prototype.getPosition = function(){}

    /**@function
       @description sets the position of the presence to a new value
       @param newpos  The new position of the presence to set to

    */

    presence.prototype.setPosition = function(/** util.Vec3 */ newpos){}

    /**@function
       @description sets the velocity of the presence to a new value
       @param newvel  The new velocity of the presence to set to

    */

    presence.prototype.setVelocity = function(/** util.Vec3 */ newvel){}

      /**
       @function
       Disconnects presence from space.  Emerson presence object still exists, but its isConnected field
       evaluates to false.
       */
      presence.prototype.disconnect = function()
      {
      };

     /**
      @param {string} sporef,
      @param {vec3} pos,
      @param {vec3} vel,
      @param {string} posTime,
      @param {quaternion} orient,
      @param {quaternion} orientVel,
      @param {string} orientTime,
      @param {string} mesh,
      @param {number} scale,
      @param {boolean} isCleared ,
      @param {uint32} contextId,
      @param {boolean} isConnected,
      @param {function,null} connectedCallback,
      @param {boolean} isSuspended,
      @param {vec3} suspendedVelocity,
      @param {quaternion} suspendedOrientationVelocity,
      @param {float} solidAngleQuery
      */
      presence.prototype.getAllData = function()
      {
      };

    /**@function
       @description Returns the velocity of the presence
       @return the vector corresponding to the velocity of the presence
       @type util.Vec3
    */

    presence.prototype.getVelocity = function(){}

    /**@function
       @description sets the orientation of the presence to a new value
       @param newvel  The new orientation of the presence to set to
    */
    presence.prototype.setOrientation = function(/** util.Quaternion */ newpos){}

    /**@function
       @description Returns the orientation of the presence
       @return the quaternion corresponding to the  of the presence
       @type util.Quaternion
    */

    presence.prototype.getOrientation = function(){}

    /**@function
       @description sets the orientation velocity (both angular velocity and the axis of rotation)
          of the presence to a new value
       @param newvel  The new orientation velocity of the presence to set to
    */

    presence.prototype.setOrientationVel = function(/** util.Quaternion */ newvel){}

    /**@function
       @description Returns the orientation velocity of the presence
       @return the quaternion corresponding to the  orientation velocity of the presence
       @type util.Quaternion
    */

    presence.prototype.getOrientationVel = function(){}

    /**@function
       @description scales of the mesh of the presence to a new value
       @param scale the factor by which to scale the mesh
    */

    presence.prototype.setScale = function(/**Number */ scale){}

    /**@function
       @description Returns the factor by which the mesh has been scaled from the original size
       @return  the factor by which the mesh has been scaled from the original size
       @type Number
    */

    presence.prototype.getScale = function(){}

    /**@function
       @description sets the mesh of the presence
       @param newmesh The url for the mesh to set to
    */

    presence.prototype.setMesh = function(/**String */ newmesh){}

     /**@function
       @description Returns the mesh of the presence
       @return  the url for the mesh of the presence
       @type String
    */

    presence.prototype.getMesh = function(){}

    presence.prototype.getAnimationList = function(){}

      /** @function
       @description Allows a scripter to set a callback to execute
       when visibles are added to the proximity set.  Setting
       onExisting to true, allows scripter to set a callback for any
       visibles added to the proximity set or that already exist in
       the set.
       @param {function} cb Callback function to execute on proximity events.
       @param {bool} (optional) onExisting If true, cb will execute
       over all existing visibles in result set as well as all future
       visibles added to set.
       @return {object} Can call clear on this object to de-register
       cb.
       */
      presence.prototype.onProxAdded = function(){ };

      /**@function
       @description Allws a scirpter to set a callback that executes
       when visibles are removed from the proximity set.
       @param {function} cb Callback function to execute when visible
       leaves this presence's proximity result set.
       @return {object} Can call clear on this object to de-register cb.
       */
      presence.prototype.onProxRemoved = function(){ };

    /**@function
       @description Sets the solid angle query that is issued from this presence.
       @param newQueryAngle Pinto should return this presence prox
       results for presences that are larger than newQueryAngle.
    */
    presence.prototype.setQueryAngle = function(/** float */ newQueryAngle){};

    /**@function
       @description Returns the solid angle that pinto is using to
       provide prox results for this presence.
    */
    presence.prototype.getQueryAngle = function(){};

      /** @function
       *  @description Returns the (decoded) physics settings of the presence.
       *  @type Object
       */
      presence.prototype.getPhysics = function() {};

      /** @function
       *  @description Sets the physics parameters for the
       *               presence. Unspecified values will use the
       *               defaults even if they were previously
       *               specified.
       *  @param newphys The new physics settings for the object
       */
      presence.prototype.setPhysics = function(/**Object */ newphys) {};

      /** @function
       *  @description Updates the physics parameters for the presence. Unspecified values use their previous setting.
       *  @param newphys The new physics settings for the object.
       */
      presence.prototype.updatePhysics = function(/**Object */ newphys) {};

      /** @function
       @return Returns the identifier for the space that the presence is in.
       @type String
       */
      presence.prototype.getSpaceID = function(){};

      /** @function
       @return Returns the identifier for the presence in the space that it's in.
       @type String
       */
      presence.prototype.getPresenceID = function(){};

      /** @function
       *  @description Requests that the mesh for this model is
       *  downloaded and parsed, making it available for operations
       *  like raytracing and getting precise bounding box
       *  information.
       *  @param {function} cb callback to invoke when loading is
       *  complete. The callback takes no parameters.
       *
       */
      presence.prototype.loadMesh = function(cb) {};
  };

}

(function() {

     // Models may come in with improper orientation. We provide a
     // modelOrientation setting (field + getter/setter) to adjust this
     // orientation. Most importantly, this gets transparently multiplied into
     // orientations you specify so that all motion appears 'natural' once you
     // set the proper model orientation, i.e. forward is always negative z, up
     // is always positive y, etc.

     var presence = system.__presence_constructor__;

     // Default value == identity
     presence.prototype.__modelOrientation = new util.Quaternion();

     presence.prototype.getModelOrientation = function() {
         return this.__modelOrientation;
     };
     presence.prototype.setModelOrientation = function(v) {
         // Extract orientation, making sure we get *current*
         // orientation out before updating
         var curorient = this.getOrientation();

         this.__modelOrientation = v;

         // And now we can set orientation again, which should
         // transparently multiply in our new value
         this.setOrientation(curorient);
     };

     Object.defineProperty(system.__presence_constructor__.prototype, "modelOrientation",
                           {
                               get: function() { return this.getModelOrientation(); },
                               set: function() { return this.setModelOrientation.apply(this, arguments); },
                               enumerable: true
                           }
                          );

     // Override get/setOrientation so they automatically take into account the modelOrientation.

     var orig_getOrientation = presence.prototype.getOrientation;
     var orig_setOrientation = presence.prototype.setOrientation;

     presence.prototype.getOrientation = function() {
         // Provide orientation without model orientation
         return orig_getOrientation.apply(this).mul(this.modelOrientation.inv());
     };

     presence.prototype.setOrientation = function(v) {
         // Multiply in additional transformation
         orig_setOrientation.apply(this, [v.mul(this.modelOrientation.neg())]);
     };

})();

(function() {

      // Physics is stored as an opaque string. This takes care of
      // encoding and decoding that string. Currently the only
      // supported type is JSON encoding.

      var decodePhysics = function(phy) {
          if (phy.length == 0) return {};
          return JSON.parse(phy);
      };

      var encodePhysics = function(phy) {
          return JSON.stringify(phy);
      };

      var valid_physics_fields = ['treatment', 'bounds', 'mass'];
      var orig_get_physics = system.__presence_constructor__.prototype.getPhysics;
      var orig_set_physics = system.__presence_constructor__.prototype.setPhysics;

      system.__presence_constructor__.prototype.getPhysics = function() {
          return decodePhysics( orig_get_physics.apply(this) );
      };

      system.__presence_constructor__.prototype.setPhysics = function(update) {
          var raw = {};
          for(var i in valid_physics_fields) {
              if (valid_physics_fields[i] in update)
                  raw[valid_physics_fields[i]] = update[valid_physics_fields[i]];
          }
          return orig_set_physics.apply(this, [encodePhysics(raw)]);
      };

      system.__presence_constructor__.prototype.updatePhysics = function(update) {
          var raw = this.getPhysics();
          for(var i in valid_physics_fields) {
              if (valid_physics_fields[i] in update)
                  raw[valid_physics_fields[i]] = update[valid_physics_fields[i]];
          }
          return orig_set_physics.apply(this, [encodePhysics(raw)]);
      };

     // FIXME we shouldn't need __origLoadMesh but getting at the
     // real, internal system object requires us to route through
     // system right now
     system.__presence_constructor__.prototype.__origLoadMesh = system.__presence_constructor__.prototype.loadMesh;
     system.__presence_constructor__.prototype.loadMesh = function(cb) {
         system.__loadPresenceMesh(this, cb);
     };
     // No need to override unloadMesh since it takes no special parameters

     var __origMeshBounds = system.__presence_constructor__.prototype.meshBounds;
     var __origUntransformedMeshBounds = system.__presence_constructor__.prototype.untransformedMeshBounds;
     var decodeBBox = function(raw) {
         return new util.BBox(raw[0], raw[1]);
     };
     system.__presence_constructor__.prototype.meshBounds = function() {
         return decodeBBox(__origMeshBounds.apply(this));
     };
     system.__presence_constructor__.prototype.untransformedMeshBounds = function() {
         return decodeBBox(__origUntransformedMeshBounds.apply(this));
     };

     // The basic raytrace is in *completely untransformed* mesh space, meaning
     // not even the translate/rotate/scale of the presence/visible is
     // included. Wrappers provide those types of raytracing.
     var __origRaytrace = system.__presence_constructor__.prototype.raytrace;
     system.__presence_constructor__.prototype.__raytrace = function(start, dir) {
         return __origRaytrace.apply(this, arguments);
     };

})();

/*  Sirikata
 *  presence.em
 *
 *  Copyright (c) 2011, Bhupesh Chandra
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Add functions to the prototype for presence */

(function() {
     // Just a cache, but the underlying system will also store copies
     // and give us the existing one. This is necessary to make reset
     // transparent.
     var sims = {};

     system.__presence_constructor__.prototype.runSimulation = function(name) {
         if (!sims[this]) sims[this] = {};
         if (!sims[this][name]) sims[this][name] = this._runSimulation(name);
         return sims[this][name];
     };
 })();

system.__presence_constructor__.prototype.getSimulation =
    system.__presence_constructor__.prototype.runSimulation;

system.__presence_constructor__.prototype.onProxAdded =
function (funcToCallback,onExisting)
{
    var cb_handle = system.__sys_register_onProxAdded(this,funcToCallback,onExisting);
    // Return a callback handle with just a clear method
    return {
        'clear' : std.core.bind(this._delProxAdded, this, cb_handle)
    };
};

system.__presence_constructor__.prototype.onProxRemoved =
function (funcToCallback)
{
    var cb_handle = system.__sys_register_onProxRemoved(this,funcToCallback);
    // Return a callback handle with just a clear method
    return {
        'clear' : std.core.bind(this._delProxRemoved, this, cb_handle)
    };
};

system.__presence_constructor__.prototype._delProxAdded =
function (idToDelete)
{
    system.__sys_register_delProxAdded(this,idToDelete);
};

system.__presence_constructor__.prototype._delProxRemoved =
function (idToDelete)
{
    system.__sys_register_delProxRemoved(this,idToDelete);
};

system.__presence_constructor__.prototype.proxResultSet = {};

Object.defineProperty(system.__presence_constructor__.prototype, "position",
                      {
                          get: function() { return this.getPosition(); },
                          set: function() { return this.setPosition.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "queryAngle",
                      {
                          get: function() { return this.getQueryAngle(); },
                          set: function() { return this.setQueryAngle.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "velocity",
                      {
                          get: function() { return this.getVelocity(); },
                          set: function() { return this.setVelocity.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "orientation",
                      {
                          get: function() { return this.getOrientation(); },
                          set: function() { return this.setOrientation.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "orientationVel",
                      {
                          get: function() { return this.getOrientationVel(); },
                          set: function() { return this.setOrientationVel.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "scale",
                      {
                          get: function() { return this.getScale(); },
                          set: function() { return this.setScale.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "mesh",
                      {
                          get: function() { return this.getMesh(); },
                          set: function() { return this.setMesh.apply(this, arguments); },
                          enumerable: true
                      }
);

Object.defineProperty(system.__presence_constructor__.prototype, "physics",
                      {
                          get: function() { return this.getPhysics(); },
                          set: function() { return this.updatePhysics.apply(this, arguments); },
                          enumerable: true
                      }
);

system.__presence_constructor__.prototype.__prettyPrintFieldsData__ = [
    "position", "velocity",
    "orientation", "orientationVel",
    "scale", "mesh", "physics"
];
system.__presence_constructor__.prototype.__prettyPrintFields__ = function() {
    return this.__prettyPrintFieldsData__;
};

system.__presence_constructor__.prototype.__getType = function()
{
  return 'presence';
};

{
  /** @namespace presence */
  var presence = function()
  {
    /**@function
       @description Returns the position of the presence
       @return the vector corresponding to the position of the presence
       @type util.Vec3
    */
    presence.prototype.getPosition = function(){}

    /**@function
       @description sets the position of the presence to a new value
       @param newpos  The new position of the presence to set to

    */

    presence.prototype.setPosition = function(/** util.Vec3 */ newpos){}

    /**@function
       @description sets the velocity of the presence to a new value
       @param newvel  The new velocity of the presence to set to

    */

    presence.prototype.setVelocity = function(/** util.Vec3 */ newvel){}

      /**
       @function
       Disconnects presence from space.  Emerson presence object still exists, but its isConnected field
       evaluates to false.
       */
      presence.prototype.disconnect = function()
      {
      };

     /**
      @param {string} sporef,
      @param {vec3} pos,
      @param {vec3} vel,
      @param {string} posTime,
      @param {quaternion} orient,
      @param {quaternion} orientVel,
      @param {string} orientTime,
      @param {string} mesh,
      @param {number} scale,
      @param {boolean} isCleared ,
      @param {uint32} contextId,
      @param {boolean} isConnected,
      @param {function,null} connectedCallback,
      @param {boolean} isSuspended,
      @param {vec3} suspendedVelocity,
      @param {quaternion} suspendedOrientationVelocity,
      @param {float} solidAngleQuery
      */
      presence.prototype.getAllData = function()
      {
      };

    /**@function
       @description Returns the velocity of the presence
       @return the vector corresponding to the velocity of the presence
       @type util.Vec3
    */

    presence.prototype.getVelocity = function(){}

    /**@function
       @description sets the orientation of the presence to a new value
       @param newvel  The new orientation of the presence to set to
    */
    presence.prototype.setOrientation = function(/** util.Quaternion */ newpos){}

    /**@function
       @description Returns the orientation of the presence
       @return the quaternion corresponding to the  of the presence
       @type util.Quaternion
    */

    presence.prototype.getOrientation = function(){}

    /**@function
       @description sets the orientation velocity (both angular velocity and the axis of rotation)
          of the presence to a new value
       @param newvel  The new orientation velocity of the presence to set to
    */

    presence.prototype.setOrientationVel = function(/** util.Quaternion */ newvel){}

    /**@function
       @description Returns the orientation velocity of the presence
       @return the quaternion corresponding to the  orientation velocity of the presence
       @type util.Quaternion
    */

    presence.prototype.getOrientationVel = function(){}

    /**@function
       @description scales of the mesh of the presence to a new value
       @param scale the factor by which to scale the mesh
    */

    presence.prototype.setScale = function(/**Number */ scale){}

    /**@function
       @description Returns the factor by which the mesh has been scaled from the original size
       @return  the factor by which the mesh has been scaled from the original size
       @type Number
    */

    presence.prototype.getScale = function(){}

    /**@function
       @description sets the mesh of the presence
       @param newmesh The url for the mesh to set to
    */

    presence.prototype.setMesh = function(/**String */ newmesh){}

     /**@function
       @description Returns the mesh of the presence
       @return  the url for the mesh of the presence
       @type String
    */

    presence.prototype.getMesh = function(){}

    presence.prototype.getAnimationList = function(){}

      /** @function
       @description Allows a scripter to set a callback to execute
       when visibles are added to the proximity set.  Setting
       onExisting to true, allows scripter to set a callback for any
       visibles added to the proximity set or that already exist in
       the set.
       @param {function} cb Callback function to execute on proximity events.
       @param {bool} (optional) onExisting If true, cb will execute
       over all existing visibles in result set as well as all future
       visibles added to set.
       @return {object} Can call clear on this object to de-register
       cb.
       */
      presence.prototype.onProxAdded = function(){ };

      /**@function
       @description Allws a scirpter to set a callback that executes
       when visibles are removed from the proximity set.
       @param {function} cb Callback function to execute when visible
       leaves this presence's proximity result set.
       @return {object} Can call clear on this object to de-register cb.
       */
      presence.prototype.onProxRemoved = function(){ };

    /**@function
       @description Sets the solid angle query that is issued from this presence.
       @param newQueryAngle Pinto should return this presence prox
       results for presences that are larger than newQueryAngle.
    */
    presence.prototype.setQueryAngle = function(/** float */ newQueryAngle){};

    /**@function
       @description Returns the solid angle that pinto is using to
       provide prox results for this presence.
    */
    presence.prototype.getQueryAngle = function(){};

      /** @function
       *  @description Returns the (decoded) physics settings of the presence.
       *  @type Object
       */
      presence.prototype.getPhysics = function() {};

      /** @function
       *  @description Sets the physics parameters for the
       *               presence. Unspecified values will use the
       *               defaults even if they were previously
       *               specified.
       *  @param newphys The new physics settings for the object
       */
      presence.prototype.setPhysics = function(/**Object */ newphys) {};

      /** @function
       *  @description Updates the physics parameters for the presence. Unspecified values use their previous setting.
       *  @param newphys The new physics settings for the object.
       */
      presence.prototype.updatePhysics = function(/**Object */ newphys) {};

      /** @function
       @return Returns the identifier for the space that the presence is in.
       @type String
       */
      presence.prototype.getSpaceID = function(){};

      /** @function
       @return Returns the identifier for the presence in the space that it's in.
       @type String
       */
      presence.prototype.getPresenceID = function(){};

      /** @function
       *  @description Requests that the mesh for this model is
       *  downloaded and parsed, making it available for operations
       *  like raytracing and getting precise bounding box
       *  information.
       *  @param {function} cb callback to invoke when loading is
       *  complete. The callback takes no parameters.
       *
       */
      presence.prototype.loadMesh = function(cb) {};
  };

}

(function() {

     // Models may come in with improper orientation. We provide a
     // modelOrientation setting (field + getter/setter) to adjust this
     // orientation. Most importantly, this gets transparently multiplied into
     // orientations you specify so that all motion appears 'natural' once you
     // set the proper model orientation, i.e. forward is always negative z, up
     // is always positive y, etc.

     var presence = system.__presence_constructor__;

     // Default value == identity
     presence.prototype.__modelOrientation = new util.Quaternion();

     presence.prototype.getModelOrientation = function() {
         return this.__modelOrientation;
     };
     presence.prototype.setModelOrientation = function(v) {
         // Extract orientation, making sure we get *current*
         // orientation out before updating
         var curorient = this.getOrientation();

         this.__modelOrientation = v;

         // And now we can set orientation again, which should
         // transparently multiply in our new value
         this.setOrientation(curorient);
     };

     Object.defineProperty(system.__presence_constructor__.prototype, "modelOrientation",
                           {
                               get: function() { return this.getModelOrientation(); },
                               set: function() { return this.setModelOrientation.apply(this, arguments); },
                               enumerable: true
                           }
                          );

     // Override get/setOrientation so they automatically take into account the modelOrientation.

     var orig_getOrientation = presence.prototype.getOrientation;
     var orig_setOrientation = presence.prototype.setOrientation;

     presence.prototype.getOrientation = function() {
         // Provide orientation without model orientation
         return orig_getOrientation.apply(this).mul(this.modelOrientation.inv());
     };

     presence.prototype.setOrientation = function(v) {
         // Multiply in additional transformation
         orig_setOrientation.apply(this, [v.mul(this.modelOrientation)]);
     };

})();

(function() {

      // Physics is stored as an opaque string. This takes care of
      // encoding and decoding that string. Currently the only
      // supported type is JSON encoding.

      var decodePhysics = function(phy) {
          if (phy.length == 0) return {};
          return JSON.parse(phy);
      };

      var encodePhysics = function(phy) {
          return JSON.stringify(phy);
      };

      var valid_physics_fields = ['treatment', 'bounds', 'mass'];
      var orig_get_physics = system.__presence_constructor__.prototype.getPhysics;
      var orig_set_physics = system.__presence_constructor__.prototype.setPhysics;

      system.__presence_constructor__.prototype.getPhysics = function() {
          return decodePhysics( orig_get_physics.apply(this) );
      };

      system.__presence_constructor__.prototype.setPhysics = function(update) {
          var raw = {};
          for(var i in valid_physics_fields) {
              if (valid_physics_fields[i] in update)
                  raw[valid_physics_fields[i]] = update[valid_physics_fields[i]];
          }
          return orig_set_physics.apply(this, [encodePhysics(raw)]);
      };

      system.__presence_constructor__.prototype.updatePhysics = function(update) {
          var raw = this.getPhysics();
          for(var i in valid_physics_fields) {
              if (valid_physics_fields[i] in update)
                  raw[valid_physics_fields[i]] = update[valid_physics_fields[i]];
          }
          return orig_set_physics.apply(this, [encodePhysics(raw)]);
      };

     // FIXME we shouldn't need __origLoadMesh but getting at the
     // real, internal system object requires us to route through
     // system right now
     system.__presence_constructor__.prototype.__origLoadMesh = system.__presence_constructor__.prototype.loadMesh;
     system.__presence_constructor__.prototype.loadMesh = function(cb) {
         system.__loadPresenceMesh(this, cb);
     };
     // No need to override unloadMesh since it takes no special parameters

     var __origMeshBounds = system.__presence_constructor__.prototype.meshBounds;
     var __origUntransformedMeshBounds = system.__presence_constructor__.prototype.untransformedMeshBounds;
     var decodeBBox = function(raw) {
         return new util.BBox(raw[0], raw[1]);
     };
     system.__presence_constructor__.prototype.meshBounds = function() {
         return decodeBBox(__origMeshBounds.apply(this));
     };
     system.__presence_constructor__.prototype.untransformedMeshBounds = function() {
         return decodeBBox(__origUntransformedMeshBounds.apply(this));
     };

     // The basic raytrace is in *completely untransformed* mesh space, meaning
     // not even the translate/rotate/scale of the presence/visible is
     // included. Wrappers provide those types of raytracing.
     var __origRaytrace = system.__presence_constructor__.prototype.raytrace;
     system.__presence_constructor__.prototype.__raytrace = function(start, dir) {
         return __origRaytrace.apply(this, arguments);
     };

})();


Add env variable THOR_DESCRIPTION_PACKAGE #804

#!/bin/sh

@[if DEVELSPACE]@
export THOR_SCRIPTS=@(PROJECT_SOURCE_DIR)/scripts
@[else]@
export THOR_SCRIPTS=@(CMAKE_INSTALL_PREFIX)/@(CATKIN_PACKAGE_SHARE_DESTINATION)/scripts
@[end if]@

# set THOR_* environment variables
alias l_vt_hand='. l_vt_hand'
alias r_vt_hand='. r_vt_hand'
alias l_thor_mang_hand='. l_thor_mang_hand'
alias r_thor_mang_hand='. r_thor_mang_hand'

# include THOR_scripts hooks
#if [ -d $THOR_SCRIPTS ]; then
#  . $THOR_SCRIPTS/functions.sh
#  . $THOR_SCRIPTS/robot.sh ""

#  _THOR_include "$THOR_SCRIPTS/setup.d/*.sh"
#  _THOR_include "$THOR_SCRIPTS/$HOSTNAME/setup.d/*.sh"

#  if [ -r "$THOR_SCRIPTS/$HOSTNAME/setup.sh" ]; then
#      echo "Including $THOR_SCRIPTS/$HOSTNAME/setup.sh..." >&2
#      . "$THOR_SCRIPTS/$HOSTNAME/setup.sh"
#  fi
#fi

# export additional ROS_PACKAGE_PATH for indigo
if [ "$ROS_DISTRO" = "indigo" ]; then
    export ROS_BOOST_LIB_DIR_NAME=/usr/lib/x86_64-linux-gnu
    export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$ROS_WORKSPACE/../external
fi

# export some variables
export PATH=$THOR_SCRIPTS/helper:$PATH
export ROS_WORKSPACE=$THOR_ROOT/src
export THOR_MOTION_HOSTNAME="thor-motion"
export THOR_PERCEPTION_HOSTNAME="thor-perception"
export THOR_ONBOARD_HOSTNAME="thor-motion" #need to be thor-motion because on same machine
export THOR_FIELD_HOSTNAME="thor-field"
export ROBOT_HOSTNAMES="thor-motion thor-perception thor-onboard thor-field"
export ROBOT_USER="thor"
export THOR_ROBOT_TYPE="thor_mang_hands"
export LEFT_HAND_TYPE="l_vt_hand"
export RIGHT_HAND_TYPE="r_vt_hand"
export THOR_DESCRIPTION_PACKAGE="thor_mang_tud_description"

# adding ssh keys
if [ -d "$THOR_ROOT/.ssh/" ] && [ "$(ls -A $THOR_ROOT/.ssh/)" ]; then
    #echo "Adding ssh keys from '$THOR_ROOT/.ssh/':"
    for f in $THOR_ROOT/.ssh/*; do
        ssh-add $f
    done
fi

#!/bin/sh

@[if DEVELSPACE]@
export THOR_SCRIPTS=@(PROJECT_SOURCE_DIR)/scripts
@[else]@
export THOR_SCRIPTS=@(CMAKE_INSTALL_PREFIX)/@(CATKIN_PACKAGE_SHARE_DESTINATION)/scripts
@[end if]@

# set THOR_* environment variables
alias l_vt_hand='. l_vt_hand'
alias r_vt_hand='. r_vt_hand'
alias l_thor_mang_hand='. l_thor_mang_hand'
alias r_thor_mang_hand='. r_thor_mang_hand'

# include THOR_scripts hooks
#if [ -d $THOR_SCRIPTS ]; then
#  . $THOR_SCRIPTS/functions.sh
#  . $THOR_SCRIPTS/robot.sh ""

#  _THOR_include "$THOR_SCRIPTS/setup.d/*.sh"
#  _THOR_include "$THOR_SCRIPTS/$HOSTNAME/setup.d/*.sh"

#  if [ -r "$THOR_SCRIPTS/$HOSTNAME/setup.sh" ]; then
#      echo "Including $THOR_SCRIPTS/$HOSTNAME/setup.sh..." >&2
#      . "$THOR_SCRIPTS/$HOSTNAME/setup.sh"
#  fi
#fi

# export additional ROS_PACKAGE_PATH for indigo
if [ "$ROS_DISTRO" = "indigo" ]; then
    export ROS_BOOST_LIB_DIR_NAME=/usr/lib/x86_64-linux-gnu
    export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$ROS_WORKSPACE/../external
fi

# export some variables
export PATH=$THOR_SCRIPTS/helper:$PATH
export ROS_WORKSPACE=$THOR_ROOT/src
export THOR_MOTION_HOSTNAME="thor-motion"
export THOR_PERCEPTION_HOSTNAME="thor-perception"
export THOR_ONBOARD_HOSTNAME="thor-motion" #need to be thor-motion because on same machine
export THOR_FIELD_HOSTNAME="thor-field"
export ROBOT_HOSTNAMES="thor-motion thor-perception thor-onboard thor-field"
export ROBOT_USER="thor"
export THOR_ROBOT_TYPE="thor_mang_hands"
export LEFT_HAND_TYPE="l_vt_hand"
export RIGHT_HAND_TYPE="r_vt_hand"

# adding ssh keys
if [ -d "$THOR_ROOT/.ssh/" ] && [ "$(ls -A $THOR_ROOT/.ssh/)" ]; then
    #echo "Adding ssh keys from '$THOR_ROOT/.ssh/':"
    for f in $THOR_ROOT/.ssh/*; do
        ssh-add $f
    done
fi