|
Last Modified Sunday 07th 2005f August 2005 10:02 Quick GuideA quick programming guide for Simbad simulator. Plan
Create your own robot controllerYou need very few things to build and test your own robot controller:
Your main program:This is your main class and its purpose is to launch Simbad with your environment description. You can just copy the code below and specify the name of your EnvironmentDescription class (here MyEnv). import simbad.gui.Simbad; public class MyProg { public static void main(String[] args) { Simbad frame = new Simbad(new MyEnv() ,false); } } Your environment description:Then you need to describe the components of your environment. In the example below we indicate that want only one robot and one Arch (Arch is one of the prebuild objects such as Wall or Box). The robot class MyRobot is the one you provide. import simbad.sim.*; import javax.vecmath.Vector3d; public class MyEnv extends EnvironmentDescription { public MyEnv(){ add(new Arch(new Vector3d(3,0,-3),this)); add(new MyRobot(new Vector3d(0, 0, 0),"my robot")); } } Your Robot class:You may then describe your robot controller with the MyRobot class. MyRobot is derived from the Agent class and you must override the two methods initBehavior and performBehavior.
import simbad.sim.*; import javax.vecmath.Vector3d; public class MyRobot extends Agent { public MyRobot (Vector3d position, String name) { super(position,name); } public void initBehavior() {} public void performBehavior() { if (collisionDetected()) { // stop the robot setTranslationalVelocity(0.0); setRotationalVelocity(0); } else { // progress at 0.5 m/s setTranslationalVelocity(0.5); // frequently change orientation if ((getCounter() % 100)==0) setRotationalVelocity(Math.PI/2 * (0.5 - Math.random())); } } } Compile and runTo compile your program you need to specifiy the directory containing simbad arborescence on the classpath (you can also set your CLASSPATH variable). javac -classpath simbad-1.0 MyProg.java MyEnv.java MyRobot.java
And you may run the program with the following command: java -classpath simbad-1.0:. MyProg
The simulatorThe simulator loopOn each simulation steps the simulator performs the following operations for each agent (robot) alive in the world.
As real devices, sensors and actuators may not be updated on each frame depending on their update rate. Normal modeIn normal mode (default) the simulation steps are triggered by a timer event 20 times per second. So the real time (seen by the user) and virtual time (seen by each robot) coincide and inter step delay is 1/20=0.05 s. However, the timer can be speeded up or slowed down by intermediary of simbad User interface. If, for instance, the timer is speeded 10 times, the simulator will perform 200 simulation steps per second in real time but from the view point of the robot 10 seconds of virtual time elapse during one second of real time. This enables to preserve time dependant values and units whatever is the real time speed. Special background modeFor intensive simulations, as often required by Genetic Algorithms and Generate and Test schemes in general, Simbad provides a special background mode. In this mode, the simulation steps are performed at the fastest speed available on your hardware. The 3D world is rendered very rarely for monitoring purpose and use no or very small part of the cpu power. In background mode the user interface inputs are disabled. Simbad is known to achieve 16000 simulation steps per second on a Pentium 4 PC at 2.8 GHz. Notice however that for the present time only sonars and bumpers are available in this mode. Camera will be available soon in background mode. import simbad.gui.Simbad; public class MyProg { public static void main(String[] args) { // Launch Simbad in background mode Simbad frame = new Simbad(new MyEnv() ,false); } } The robot APIStatus API.The robot's status can be accessed via the following methods inherited from Agent class.
Movements API.You can control the robot movements by specifing rotational and translational velocities.
This is the default kinematic model - however you can also use a differential drive kinematic and control left and right wheel velocities. See the demo in class simbad.demo.DifferentialDriveDemo. The SensorsYou can equip your robot with the following sensors:
The RobotFactory class provides methods to easily add sensors.
Adding and using Sonar SensorsTo use sonars you must first add them to the robot. This is done in the Robot constructor and the most simple way is by using the RobotFactory class to obtain a RangeSensorBelt object. The example below adds a 8 sonars belt to the robot, the sonars are organised counter clock wise, starting at angle 0 in front of the robot. Each sonar provides a range measurement information in meters and a hit state which value is true only if an obstacle is situated on the sonar ray. To access to each sonar sensor individualy you can use hasHit and getMeasurement methods. The example below prints the state of all sonars every 20 frames. public class Robot extends Agent { RangeSensorBelt sonars; public Robot(Vector3d position, String name) { super(position, name); sonars = RobotFactory.addSonarBeltSensor(this,8); } public void performBehavior() { //every 20 frames if (getCounter()%20==0){ // print each sonars measurement for (int i=0;i< sonars.getNumSensors();i++) { double range = sonars.getMeasurement(i); double angle = sonars.getAngle(i); boolean hit = sonars.hasHit(i); System.out.println("Sonar at angle "+ angle + "measured range ="+range+ " has hit something:"+hit); } } } } The RangeSensorBelt Class also provide methods for obtaining averaged measurements in the eight angular quadrants around the robot : getFrontQuadrantMeasurement, getFrontLeftQuadrantMeasurement ,getLeftQuadrantMeasurement etc ... More information is given in RangeSensorBelt api doc. Adding and using Bumpers SensorsAdding and using Bumbers is very similar to sonars except that we can only use hit information and no range measurement. To use bumpers you must again add them with the RobotFactory class and obtain a RangeSensorBelt object. The example below adds a 8 bumpers belt to the robot, the bumpers are organised counter clock wise, starting at angle 0 in front of the robot. To access to each bumper sensor individualy you can use hasHit method.The example below prints the state of all bumpers every 20 frames. public class Robot extends Agent { RangeSensorBelt bumpers; public Robot(Vector3d position, String name) { super(position, name); bumpers = RobotFactory.addBumperBeltSensor(this,8); } public void performBehavior() { //every 20 frames if (getCounter()%20==0){ // print each bumper state for (int i=0;i< bumpers.getNumSensors();i++) { double angle = bumpers.getAngle(i); boolean hit = bumpers.hasHit(i); System.out.println("Bumpers at angle "+ angle + " has hit something:"+hit); } } } } More information is given in RangeSensorBelt api. Adding and using a Camera SensorSimbad provides a 2D camera sensor which can be settled on the top of the robot (or anywhere else). The 3d world is rendered by the Java3d engine onto the camera image at the desired frequence. The default camera has a 100x100 pixels resolution and a refresh rate of 3 images per second (in virtual time). It can be added by using again the RobotFactory class in the robot constructor. It is also necessary to reserve space for future image capture and this has to be compatible with the actual camera format. To reserve space for a java BufferedImage one may call CameraSensor createCompatibleImage method. One may also obtained a luminance image by calling createCompatibleSensorMatrix to reserve a SensorMatrix object. To obtain the camera image you have only to call copyVisionImage method and your BufferedImage will be updated. You may then process it as you want with BufferedImage standard API (with getRGB method for instance), you may also use the java advanced imaging framework JAI. However remember that performBehavior is called very frequently (20 times per second by default), so calling copyVisionImage and processing image every frame could be very costly. public class Robot extends Agent { CameraSensor camera; BufferedImage cameraImage; public Robot(Vector3d position, String name) { super(position, name); // add a camera on top of the robot camera = RobotFactory.addCameraSensor(this); // reserve space for image capture cameraImage = camera.createCompatibleImage(); } public void performBehavior() { ....... your code // get camera image camera.copyVisionImage(cameraImage); // process image ... use BufferedImage api } } The ActuatorsThe 3D world |