Difference between revisions of "Sbot Common Interface"

From IridiaWiki
Jump to navigationJump to search
 
(27 intermediate revisions by 2 users not shown)
Line 9: Line 9:
   
   
; Everyone shares a common build environment. We can stop reinventing the wheel.
+
; Everyone shares a common build environment and repository. We can stop reinventing the wheel.
* All controllers stored in common repository. Can easily browse other people's code.
+
* Easy to browse (and use) other people's code.
 
* Share and jointly improve tools - eg. scripts for copying files to sbots
 
* Share and jointly improve tools - eg. scripts for copying files to sbots
 
* All extra libraries included in common interface - toolchain, sboteyelib etc.
 
* All extra libraries included in common interface - toolchain, sboteyelib etc.
Line 26: Line 26:
 
#*make controller=describe_circle
 
#*make controller=describe_circle
 
#Copy binary to sbot and run it
 
#Copy binary to sbot and run it
#*tools/sbot_file_copy/describe_circle <sbotnumber>
+
#*./tools/sbot_file_copy/copy_binary_to_sbot.sh describe_circle <sbot number>
 
#*ssh root@sbot<sbotnumber>
 
#*ssh root@sbot<sbotnumber>
 
#*cd /tmp
 
#*cd /tmp
 
#*./describe_circle
 
#*./describe_circle
 
#Compile twodee and run an example controller
 
#Compile twodee and run an example controller
#*cd twodee
+
#*cd sbotci/twodee
 
#*./bootstrap.sh
 
#*./bootstrap.sh
 
#*./configure
 
#*./configure
 
#*make
 
#*make
 
#*./twodee -e10003 --experiment-parameters controller=describe_circle
 
#*./twodee -e10003 --experiment-parameters controller=describe_circle
 
   
 
==Write your own common interface controller==
 
==Write your own common interface controller==
Line 48: Line 47:
 
*ControlStep()
 
*ControlStep()
 
*Stop()
 
*Stop()
Everything else is done for yo.
+
Everything else is done for you.
   
   
Your code needs to live in the directory sbotci/controllers/<your_name>/<controllername>
+
Your code needs to live in the directory sbotci/controllers/<your_name>/<controllername>
   
 
If these directories do not exist you will have to create them and add them to svn with the svn add command.
 
If these directories do not exist you will have to create them and add them to svn with the svn add command.
   
  +
;NB Do not svn commit the following test controller, or everyone will have a go_straight
The easiest way to get started is probable to copy one of the examples in the sbotci/controllers/generic directory into your own directory ( sbotci/controllers/<your_name>/ )/
 
  +
controller and the system will get confused.
* cd sbotci/controllers/<your_name>
 
* cp -r ../describe_circle ./my_test_controller
 
   
;To compile your controller on the real sbot
+
===Create a test controller===
 
*mkdir -p sbotci/controllers/<your_name>/go_straight
  +
*Create the following three files (containing the associated text you get when you click on the wiki link) in your new go_straight controller directory
  +
  +
[[go_straight_controller.cpp]] [[go_straight_controller.h]] [[controller_factory.cpp]]
  +
  +
  +
===To compile your controller on the real sbot===
 
* cd sbotci/real_sbot
 
* cd sbotci/real_sbot
* make controller=my_test_controller
+
* make controller=go_straight
  +
<br>
   
;To compile your controller in twodee
+
===To compile your controller in twodee (steps necessary only the first time)===
  +
;1. Mirror the directory structure in sbotci/controllers/<your_name>/go_straight in sbotci/twodee/controllers/ci_controllers/<your_name>/go_straight
* Anders - can you fill this in. Thx.
 
  +
* mkdir -p sbotci/controllers/ci_controllers/<your_name>/go_straight
  +
* cd sbotci/controllers/ci_controllers/<your_name>/go_straight
  +
* ln -s describe_circle_controller.cpp ../../../../../go_straight_controller.cpp
  +
* ln -s describe_circle_controller.cpp ../../../../../go_straight_controller.h
   
  +
  +
;2. Create a Makefile.am in sbotci/twodee/controllers/ci_controllers/<your_name>/go_straight/
  +
* sed -e 's/describe_circle/go_straight/g' ../../generic/describe_circle/Makefile.am > Makefile.am
  +
  +
  +
;3. Update the Makefile.am in sbotci/twodee/controllers/ci_controllers so that SUBDIRS= includes the newly created sub-directory.
  +
  +
  +
;4. Add two lines to sbotci/twodee/configure.ac so that a Makefile is output in directories:
  +
#sbotci/twodee/controllers/ci_controllers/<your_name>/
  +
#sbotci/twodee/controllers/ci_controllers/<your_name>/go_straight
  +
  +
  +
;5. Modify sbotci/twodee/Makefile.am so that it references lib_go_straight_controller.a
  +
  +
  +
;6. Edit sbotci/twodee/experiments/debugcommoninterfaceexperiment.cpp
  +
*Reference your controller in the two relevant places.
  +
<br>
  +
  +
===Logging in the Common interface===
  +
Each controller has a pre-instantiated CCILogger logging class object called m_pcCILogger.
  +
  +
; To set an output logging file.
  +
*If you do not set a logging file, all output will go only to stderr. Otherwise to logging file and stderr.
  +
*Note that in simulation, each controller has its own associated sbot and logging object. You will need to ensure each sbot gets its own logging file:
  +
char rgchSbotName[64];
  +
m_pcCISBot->GetSbotName( rgchSbotName, 64 );
  +
m_pcCILogger->SetLogFileName( rgchSbotName );
  +
  +
; To set the current log prefix - all output lines will be prefixed with this string
  +
* This is an easy way to see which bit of your code is generating logging output
  +
m_pcCILogger->SetLogPrefix( "TEMP PREFIX" );
  +
  +
; To log a message
  +
m_pcCILogger->LogMsg( "%s, "d", pchSomeString, nSomeInteger );
   
 
==How to make your simulator compatible with the common interface==
 
==How to make your simulator compatible with the common interface==
  +
In order to implement the common interface for another simulator, you need to implement the common s-bot interface, the sensor factory and any sensors that can be made compatible with your simulator (or that you can be bothered implementing). The s-bot common interface, which consists of the set of methods through which an s-bot is controlled, does not need to be fully implemented. Any function that you do not implement will simply not have an effect, except from an error message to stderr. To start off you might only implement the method, which sets the speed of the treels. This will allow you to run for instance the describe_circle behavior. For more advanced controllers using sensors and other actuators you will of course have to implement the corresponding methods of the s-bot interface.
Anders - do you feel like having a crack at this one too.
 
  +
  +
=== The s-bot common interface ===
  +
The s-bot common interface is a super class specificing the interface for reading sensory inputs and for controlling s-bots. For the real s-bots specialization, all methods have been implemented so that the s-bot API is called, while in TwoDee another specialization in which the simulated robots are controlled instead.
  +
  +
''Example of the SetSpeed method, which sets the speed of the left and the right treel:''
  +
<pre>
  +
// Super class implementation (print an error saying that the function is not implemented):
  +
void CCISBot::SetSpeed(int left, int right)
  +
{
  +
FUNCTION_NOT_IMPLEMENTED
  +
}
  +
</pre>
  +
<pre>
  +
// Real s-bot implementation (write to the real s-bot API):
  +
void CRealSBot::SetSpeed(int left, int right)
  +
{
  +
sbot_c::setSpeed(left,right);
  +
}
  +
</pre>
  +
<pre>
  +
// TwoDee implementation (check inputs, convert to TwoDee's units and set the speed of the TwoDee s-bot):
  +
void CTwoDeeCommonInterfaceSbot::SetSpeed(int left, int right)
  +
{
  +
if (abs(left) > CI_MAX_SBOT_SPEED || abs(right) > CI_MAX_SBOT_SPEED)
  +
{
  +
ERROR3("Trying to set speed to (%d,%d) max(min) is %d", left, right, CI_MAX_SBOT_SPEED);
  +
}
  +
  +
// Notice CI_MAX_SBOT_SPEED != CSbot::MAX_SBOT_SPEED
  +
m_pcTwoDeeSbot->SetWheelSpeed(((float) left / CI_MAX_SBOT_SPEED) * m_pcTwoDeeSbot->MAX_SBOT_SPEED,
  +
((float) right / CI_MAX_SBOT_SPEED) * m_pcTwoDeeSbot->MAX_SBOT_SPEED);
  +
}
  +
</pre>
  +
  +
=== The sensor factory common interface ===
  +
The sensor factory allows for implementing complex sensors, like the camera, in simulators. The sensor factory is a class, which controllers can ask to create instances of sensors.
  +
  +
=== How the common interface was implemented in TwoDee ===
  +
In TwoDee the common-interface is really just a controller like every other controller. Whenever a common interface controller writes actuator outputs to the s-bot common interface, the TwoDee implementation translates the calls to control the simulated s-bot. Likewise, when a common interface controller reads the state of a sensor, TwoDee queries the corresponding simulated sensor and translates whatever input/output to the appropriate units.
  +
  +
  +
[[media:Image-Common_interface_class_diag.png|Common Interface Class Diagram (sort of)]]
   
[[Media:Image:Common_interface_class_diag.png|Common Interface (sort of) Class Diagram]]
+
[[media:Image-common_interface_directory_structure.png|Common Interface Directory Structure]]

Latest revision as of 10:38, 2 May 2006

What is the common interface, and why should we use it?

Write Controller Once, instead of modifying for each platform.
  • Save time - no code rewrites. Maintain just one version of your code
  • When developing in simulation, you can do frequent reality checks on real robots.


Why common interface.png


Everyone shares a common build environment and repository. We can stop reinventing the wheel.
  • Easy to browse (and use) other people's code.
  • Share and jointly improve tools - eg. scripts for copying files to sbots
  • All extra libraries included in common interface - toolchain, sboteyelib etc.


Common Interface QuickStart

  1. Install subversion.
    • apt-get install subversion
  2. Checkout common interface from repository
    • svn checkout svn+ssh://<your iridia username>@iridia.ulb.ac.be/usr/local/share/svn_repositories/sbotci
  3. Compile one of the example controllers for the real robot
    • cd sbotci/real_sbot
    • ./build_scripts/build_support_libs.sh (build toolchain, sboteyelib etc)
    • make controller=describe_circle
  4. Copy binary to sbot and run it
    • ./tools/sbot_file_copy/copy_binary_to_sbot.sh describe_circle <sbot number>
    • ssh root@sbot<sbotnumber>
    • cd /tmp
    • ./describe_circle
  5. Compile twodee and run an example controller
    • cd sbotci/twodee
    • ./bootstrap.sh
    • ./configure
    • make
    • ./twodee -e10003 --experiment-parameters controller=describe_circle

Write your own common interface controller

You will need to familiarise yourself with the basics of source code control using svn. If you are already familiar with cvs this is a piece of cake, as svn commands are by in large a superset of cvs commands.

When you write your common interface controller, you basically have to implement three functions

  • Init()
  • ControlStep()
  • Stop()

Everything else is done for you.


Your code needs to live in the directory sbotci/controllers/<your_name>/<controllername>

If these directories do not exist you will have to create them and add them to svn with the svn add command.

NB Do not svn commit the following test controller, or everyone will have a go_straight

controller and the system will get confused.

Create a test controller

  • mkdir -p sbotci/controllers/<your_name>/go_straight
  • Create the following three files (containing the associated text you get when you click on the wiki link) in your new go_straight controller directory

go_straight_controller.cpp go_straight_controller.h controller_factory.cpp


To compile your controller on the real sbot

  • cd sbotci/real_sbot
  • make controller=go_straight


To compile your controller in twodee (steps necessary only the first time)

1. Mirror the directory structure in sbotci/controllers/<your_name>/go_straight in sbotci/twodee/controllers/ci_controllers/<your_name>/go_straight
  • mkdir -p sbotci/controllers/ci_controllers/<your_name>/go_straight
  • cd sbotci/controllers/ci_controllers/<your_name>/go_straight
  • ln -s describe_circle_controller.cpp ../../../../../go_straight_controller.cpp
  • ln -s describe_circle_controller.cpp ../../../../../go_straight_controller.h


2. Create a Makefile.am in sbotci/twodee/controllers/ci_controllers/<your_name>/go_straight/
  • sed -e 's/describe_circle/go_straight/g' ../../generic/describe_circle/Makefile.am > Makefile.am


3. Update the Makefile.am in sbotci/twodee/controllers/ci_controllers so that SUBDIRS= includes the newly created sub-directory.


4. Add two lines to sbotci/twodee/configure.ac so that a Makefile is output in directories
  1. sbotci/twodee/controllers/ci_controllers/<your_name>/
  2. sbotci/twodee/controllers/ci_controllers/<your_name>/go_straight


5. Modify sbotci/twodee/Makefile.am so that it references lib_go_straight_controller.a


6. Edit sbotci/twodee/experiments/debugcommoninterfaceexperiment.cpp
  • Reference your controller in the two relevant places.


Logging in the Common interface

Each controller has a pre-instantiated CCILogger logging class object called m_pcCILogger.

To set an output logging file.
  • If you do not set a logging file, all output will go only to stderr. Otherwise to logging file and stderr.
  • Note that in simulation, each controller has its own associated sbot and logging object. You will need to ensure each sbot gets its own logging file:
   char rgchSbotName[64];
   m_pcCISBot->GetSbotName( rgchSbotName, 64 );
   m_pcCILogger->SetLogFileName( rgchSbotName );
To set the current log prefix - all output lines will be prefixed with this string
  • This is an easy way to see which bit of your code is generating logging output
m_pcCILogger->SetLogPrefix( "TEMP PREFIX" );
To log a message
m_pcCILogger->LogMsg( "%s, "d", pchSomeString, nSomeInteger );

How to make your simulator compatible with the common interface

In order to implement the common interface for another simulator, you need to implement the common s-bot interface, the sensor factory and any sensors that can be made compatible with your simulator (or that you can be bothered implementing). The s-bot common interface, which consists of the set of methods through which an s-bot is controlled, does not need to be fully implemented. Any function that you do not implement will simply not have an effect, except from an error message to stderr. To start off you might only implement the method, which sets the speed of the treels. This will allow you to run for instance the describe_circle behavior. For more advanced controllers using sensors and other actuators you will of course have to implement the corresponding methods of the s-bot interface.

The s-bot common interface

The s-bot common interface is a super class specificing the interface for reading sensory inputs and for controlling s-bots. For the real s-bots specialization, all methods have been implemented so that the s-bot API is called, while in TwoDee another specialization in which the simulated robots are controlled instead.

Example of the SetSpeed method, which sets the speed of the left and the right treel:

// Super class implementation (print an error saying that the function is not implemented):
void CCISBot::SetSpeed(int left, int right) 
{ 
    FUNCTION_NOT_IMPLEMENTED 
}
// Real s-bot implementation (write to the real s-bot API):
void CRealSBot::SetSpeed(int left, int right) 
{ 
    sbot_c::setSpeed(left,right); 
}
// TwoDee implementation (check inputs, convert to TwoDee's units and set the speed of the TwoDee s-bot):
void CTwoDeeCommonInterfaceSbot::SetSpeed(int left, int right) 
{ 
    if (abs(left) > CI_MAX_SBOT_SPEED  || abs(right) > CI_MAX_SBOT_SPEED)
    {
        ERROR3("Trying to set speed to (%d,%d) max(min) is %d", left, right, CI_MAX_SBOT_SPEED);
    }
    
    // Notice CI_MAX_SBOT_SPEED != CSbot::MAX_SBOT_SPEED
    m_pcTwoDeeSbot->SetWheelSpeed(((float) left / CI_MAX_SBOT_SPEED) * m_pcTwoDeeSbot->MAX_SBOT_SPEED, 
                                  ((float) right / CI_MAX_SBOT_SPEED) * m_pcTwoDeeSbot->MAX_SBOT_SPEED);
}

The sensor factory common interface

The sensor factory allows for implementing complex sensors, like the camera, in simulators. The sensor factory is a class, which controllers can ask to create instances of sensors.

How the common interface was implemented in TwoDee

In TwoDee the common-interface is really just a controller like every other controller. Whenever a common interface controller writes actuator outputs to the s-bot common interface, the TwoDee implementation translates the calls to control the simulated s-bot. Likewise, when a common interface controller reads the state of a sensor, TwoDee queries the corresponding simulated sensor and translates whatever input/output to the appropriate units.


Common Interface Class Diagram (sort of)

Common Interface Directory Structure