Revision: 8007
http://playerstage.svn.sourceforge.net/playerstage/?rev=8007&view=rev
Author: asadat
Date: 2009-07-13 20:05:09 +0000 (Mon, 13 Jul 2009)
Log Message:
-----------
the visualization applet is added
Modified Paths:
--------------
code/websim/CMakeLists.txt
code/websim/src/req_sim.cc
code/websim/src/websim.cc
code/websim/src/websim.hh
Added Paths:
-----------
code/websim/viz/
code/websim/viz/Main.java
code/websim/viz/ReadMe
code/websim/viz/java.policy.applet
code/websim/viz/visualization.html
Modified: code/websim/CMakeLists.txt
===================================================================
--- code/websim/CMakeLists.txt 2009-07-13 16:53:48 UTC (rev 8006)
+++ code/websim/CMakeLists.txt 2009-07-13 20:05:09 UTC (rev 8007)
@@ -1,5 +1,4 @@
project(WebSim)
-
SET( V_MAJOR 1 )
SET( V_MINOR 0 )
SET( V_BUGFIX 0 )
@@ -148,4 +147,18 @@
"make"
"make install")
+INSTALL (FILES README.txt COPYING.txt DESTINATION .)
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "WebSim")
+#SET(CPACK_PACKAGE_DESCRIPTION_FILE "/home/abbas/websim/README.txt")
+SET(CPACK_RESOURCE_FILE_LICENSE "/home/abbas/websim/COPYING.txt")
+SET(CPACK_RESOURCE_FILE_README "/home/abbas/websim/README.txt")
+SET(CPACK_PACKAGE_VERSION_MAJOR "0")
+SET(CPACK_PACKAGE_VERSION_MINOR "1")
+SET(CPACK_PACKAGE_VERSION_PATCH "0")
+SET(CPACK_PACKAGE_VERSION "0.1")
+SET(CPACK_PACKAGE_VENDOR "Richard Vaughan")
+SET(CPACK_NSIS_DISPLAY_NAME "WebSim 0.1")
+
+
+INCLUDE(CPack)
Modified: code/websim/src/req_sim.cc
===================================================================
--- code/websim/src/req_sim.cc 2009-07-13 16:53:48 UTC (rev 8006)
+++ code/websim/src/req_sim.cc 2009-07-13 20:05:09 UTC (rev 8007)
@@ -1,4 +1,5 @@
#include "websim.hh"
+#include <stdlib.h>
using namespace websim;
const double TICK_INTERVAL = 1.0;
@@ -40,6 +41,14 @@
if(prop == "viz")
return HandleSimVisualizationRequest( action, format, kv, response );
+ if(prop == "applet"){
+
+
+
+
+ return true;
+ }
+
response = "ERROR: Unknown property " + prop + " for sim. Candidates are:
clock factory greet tree.";
return false;
}
@@ -49,12 +58,14 @@
struct evkeyvalq* kv,
std::string& response)
{
+
response =
"<HTML><HEAD><TITLE>Websim Visualization</TITLE></HEAD>"
"<BODY><iframe id=\"visualization\" frameborder=0 width=\"1000\"
height=\"1000\" "
"src=\"viz.html\"></iframe></BODY></HTML>";
return true;
+
}
bool WebSim::HandleSimHomepageRequest( std::string action,
Modified: code/websim/src/websim.cc
===================================================================
--- code/websim/src/websim.cc 2009-07-13 16:53:48 UTC (rev 8006)
+++ code/websim/src/websim.cc 2009-07-13 20:05:09 UTC (rev 8007)
@@ -38,6 +38,7 @@
const std::string WebSim::package = "WebSim";
const std::string WebSim::version = "0.1";
+
std::string Time::String()
{
std::string seconds = boost::lexical_cast<std::string>(sec);
@@ -305,7 +306,6 @@
response_string = "OK";
}
- //puts(response.c_str());
evbuffer_add_printf(eb, "%s\n", response.c_str());
evhttp_send_reply(req, response_code, response_string.c_str(), eb);
@@ -330,6 +330,7 @@
// We require 3 path components: model/property/action
StringSplit(bare_uri, uri_parts, "/");
+
//check if the web page is requested
if(uri_parts.size()==2){
Modified: code/websim/src/websim.hh
===================================================================
--- code/websim/src/websim.hh 2009-07-13 16:53:48 UTC (rev 8006)
+++ code/websim/src/websim.hh 2009-07-13 20:05:09 UTC (rev 8007)
@@ -105,9 +105,11 @@
*/
virtual bool ClockRunFor( double seconds )=0;
+ /** Create a model of the specified type */
virtual bool CreateModel(const std::string& name,
const
std::string& type,
std::string& response) = 0;
+ /** Delete the specified model */
virtual bool DeleteModel(const std::string& name,
std::string& response) = 0;
@@ -665,10 +667,8 @@
{
public:
Pose pos;
- double range;
- double bearing;
int id;
- Fiducial():range(0),bearing(0),id(-1){}
+ Fiducial():id(-1){}
};
Added: code/websim/viz/Main.java
===================================================================
--- code/websim/viz/Main.java (rev 0)
+++ code/websim/viz/Main.java 2009-07-13 20:05:09 UTC (rev 8007)
@@ -0,0 +1,1212 @@
+/**
+ This program is for visualizing the webstage data. Requests for model tree,
robots and their devices are sent to a server and the xml responses are parsed
and visualized in this applet. The program will be run via an HTML page.
+*/
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.tree.TreePath;
+import java.net.URLConnection;
+import java.net.URL;
+import org.w3c.dom.Document;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.xml.sax.*;
+import javax.swing.tree.*;
+import java.util.*;
+import org.xml.sax.helpers.*;
+import javax.xml.parsers.*;
+
+/**
+ * This is the main class. 2 panels and an applet are created. "treepanel"
contains a scrollpanel which has the model tree in it. "values" contains the
checkboxes that
+ * determine which features should show up on the screen. The text field in
"values" panel, determines the server address. The default server address is
"192.168.1.210:8000".
+ * "mixture" is a Stage-like applet by which robots and their devices can be
monitored.
+ *
+ * Parts of the code are from
"http://www.developer.com/net/vb/article.php/626261"
+ */
+public class Main extends Applet implements Runnable{
+
+ Panel treepanel;
+ Panel values;
+ //Panel leftPanel;
+ StageApplet mixture;
+ private TextField host_address_textfield;
+ private Button submitButton;
+
+ private final JCheckBoxMenuItem check1=new JCheckBoxMenuItem("position",
true) ;
+ private final JCheckBoxMenuItem check2=new JCheckBoxMenuItem("laser",
true) ;
+ private final JCheckBoxMenuItem check3=new JCheckBoxMenuItem("sonar",
false) ;
+ private final JCheckBoxMenuItem check4=new JCheckBoxMenuItem("fiducial",
false) ;
+ private final JCheckBoxMenuItem check5=new JCheckBoxMenuItem("sayings",
false) ;
+
+ JTree tree;
+ JScrollPane scrollPanel;
+
+ public void init()
+ {
+ BorderLayout thisBorderLayout=new BorderLayout();
+ thisBorderLayout.setHgap(20);
+ setLayout(thisBorderLayout);
+ this.setSize(new Dimension(900,900));
+
+
+ try{
+ mixture = (StageApplet)addApplet("StageApplet");
+ mixture.mainApp=this;
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+
+ host_address_textfield = new TextField("192.168.1.210:8000");
+ host_address_textfield.setSize(100,25);
+
+ submitButton = new Button("Send Request");
+ submitButton.setSize(100,25);
+ submitButton.addActionListener(new ActionListener(){public void
actionPerformed(ActionEvent evt) {
+ try {
+ mixture.host_address = host_address_textfield.getText();
+ mixture.address_changed=true;
+ }
+ catch (Exception e){
+ System.out.println("Error reading host address: "
+e.getMessage());
+ }}});
+
+ check1.addActionListener(new ActionListener(){public void
actionPerformed(ActionEvent evt) {
+ if(check1.getSelectedObjects()!=null)
+ mixture.show_position=true;
+ else
+ mixture.show_position=false;
+ }});
+ check2.addActionListener(new ActionListener(){public void
actionPerformed(ActionEvent evt) {
+ if(check2.getSelectedObjects()!=null)
+ mixture.show_laser=true;
+ else
+ mixture.show_laser=false;
+ }});
+ check3.addActionListener(new ActionListener(){public void
actionPerformed(ActionEvent evt) {
+ if(check3.getSelectedObjects()!=null)
+ mixture.show_sonar=true;
+ else
+ mixture.show_sonar=false;
+ }});
+ check4.addActionListener(new ActionListener(){public void
actionPerformed(ActionEvent evt) {
+ if(check4.getSelectedObjects()!=null)
+ mixture.show_fiducial=true;
+ else
+ mixture.show_fiducial=false;
+ }});
+ check5.addActionListener(new ActionListener(){public void
actionPerformed(ActionEvent evt) {
+ if(check5.getSelectedObjects()!=null)
+ mixture.show_sayings=true;
+ else
+ mixture.show_sayings=false;
+ }});
+
+ values = new Panel();
+ FlowLayout layout=new FlowLayout();
+ values.setLayout(layout);
+
+
+ values.add(host_address_textfield);
+ values.add(submitButton);
+ check1.setSize(100,25);
+ check2.setSize(100,25);
+ check3.setSize(100,25);
+ check4.setSize(100,25);
+ values.add(check1);
+ values.add(check2);
+ values.add(check3);
+ values.add(check4);
+
+ //leftPanel =new Panel();
+ //leftPanel.setLayout(new BorderLayout());
+ add(values,BorderLayout.NORTH);
+
+ //add(leftPanel,BorderLayout.WEST);
+
+ add(mixture);
+// mixture.start();
+
+ treepanel=new Panel();
+ tree = mixture.tree;
+
+
+ if(tree!=null)
+ scrollPanel=new JScrollPane(tree);
+ else
+ scrollPanel=new JScrollPane();
+
+ scrollPanel.setPreferredSize(new Dimension(200,600));
+ treepanel.add(scrollPanel, BorderLayout.CENTER);
+
+
+ treepanel.setVisible(true);
+ treepanel.setLocation(100,400);
+ treepanel.setPreferredSize(new Dimension(200,600));
+ //leftPanel.add(treepanel,BorderLayout.CENTER);
+ add(treepanel,BorderLayout.WEST);
+
+ }
+
+
+ public void run(){
+ repaint();
+ }
+
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ public void paint(Graphics g){
+
+ super.paint(g);
+ }
+
+ public Vector applets = new Vector();
+
+ public void addApplet( Applet applet ) {
+ // Create a new, "artificial" stub for the subapplet
+ AppletStub stub = new MultiAppletStub( this );
+ // Give it to the subapplet to use
+ applet.setStub( stub );
+ // Start up the subapplet
+ applet.init();
+ // Finally, store it in our list
+ applets.addElement( applet );
+ }
+
+ public Applet addApplet( String className )
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException {
+ // Create an instance of the named applet
+ Class clas = Class.forName( className );
+ Applet applet = (Applet)clas.newInstance();
+ // Add it to the system
+ addApplet( applet );
+ // Return it, in case the caller wants to access the Applet
+ // object directly
+ return applet;
+ }
+
+ public void start() {
+ for (Enumeration e=applets.elements(); e.hasMoreElements();) {
+ ((Applet)e.nextElement()).start();
+ }
+ }
+
+ public void stop() {
+ for (Enumeration e=applets.elements(); e.hasMoreElements();) {
+ ((Applet)e.nextElement()).stop();
+ }
+ }
+
+ public void destroy() {
+ for (Enumeration e=applets.elements(); e.hasMoreElements();) {
+ ((Applet)e.nextElement()).destroy();
+ }
+ }
+
+ public void appletResize( int width, int height ) {
+
+ }
+ }
+
+ class MultiAppletStub implements AppletStub
+ {
+ private Applet applet;
+
+ public MultiAppletStub( Applet applet ) {
+ this.applet = applet;
+ }
+
+ public boolean isActive() {
+ return applet.isActive();
+ }
+
+ public URL getDocumentBase() {
+ return applet.getDocumentBase();
+ }
+
+ public URL getCodeBase() {
+ return applet.getCodeBase();
+ }
+
+ public String getParameter( String name ) {
+ return applet.getParameter( name );
+ }
+
+ public AppletContext getAppletContext() {
+ return applet.getAppletContext();
+ }
+
+ public void appletResize( int width, int height ) {
+ }
+ }
+
+ /**
+ * This is the Stage-like applet class. It sends a request for the model
tree, and for each of the robots in that tree, will send out requests for each
of their devices
+ * indicated in the model tree. Then based on the check boxes selected in
the main applet, corresponding features of the robots would be drawn.
+ */
+ class StageApplet extends Applet implements Runnable{
+
+ Main mainApp;
+
+ int frame;
+ int delay;
+ //Size and coordinates of the map.
+ int boardSize=512, boardX=100, boardY=100;
+ Thread animator;
+
+ Image scrnBuf;
+ Graphics scrnG;
+ Dimension dim;
+
+ boolean address_changed=false;
+
+ //The server address, default address is "192.168.1.210:8000"
+ String host_address="192.168.1.210:8000";
+
+ String time="";
+ //Based on the checkboxes in the main applet, these variables will
be true or false meaning whether that feature should be drawn or not.
+ boolean show_position=true, show_laser=true, show_sonar=false,
show_fiducial=false, show_sayings=false;
+
+ //Content handler for the model tree.
+ TreeSink sink2;
+ //Content handler for position and device requests.
+ Sink sink;
+ //All the robots indicated in the model tree.
+ ArrayList<Robot> robots;
+ TreeBuilder jsamp;
+ //The model tree.
+ JTree tree;
+
+ TreePath[] paths;
+ Object[][] pathComponents;
+
+ XMLReader reader,reader2;
+
+ public void addNotify() {
+ super.addNotify();
+ robots=new ArrayList<Robot>();
+ scrnBuf = createImage(1000, 1000);
+ if(scrnBuf==null){
+ System.out.println("Image Null");
+ }
+ scrnG = scrnBuf.getGraphics();
+ sink2=new TreeSink(this);
+ sink=new Sink();
+ try{
+ reader2 = XML.makeXMLReader();
+
+ reader2.setContentHandler( sink2 );
+ reader2.parse( new InputSource( new
URL("http://"+host_address+"/sim/tree/get?format=xml").openStream() ));
+ jsamp=new TreeBuilder();
+ tree=jsamp.makeTree(sink2.arraylist, 1,0);
+
+ reader = XML.makeXMLReader();
+ reader.setContentHandler( sink );
+ }catch(Exception e){
+ e.printStackTrace();
+ scrnG.drawString(e.getMessage(), 5, 130);
+ }
+ }
+
+ public void init() {
+ super.init();
+ try{
+ dim=this.getSize();
+ boardSize=Math.min(dim.height, dim.width)-200;
+
+ }catch(Exception e){
+ e.printStackTrace();
+ scrnG.drawString(e.getMessage(), 5, 120);
+ }
+ int fps=10;
+ delay = (fps > 0) ? (1000 / fps) : 300;
+
+
+ }
+
+
+ public void start() {
+ try{
+ /*reader2 = XML.makeXMLReader();
+ reader2.setContentHandler( sink2 );
+ reader2.parse( new InputSource( new
URL("http://"+host_address+"/sim/tree/get?format=xml").openStream() ));
+ jsamp=new TreeBuilder();
+ tree=jsamp.makeTree(sink2.arraylist, 1,0);
+
+ reader = XML.makeXMLReader();
+ reader.setContentHandler( sink );*/
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ animator = new Thread(this);
+ animator.start();
+ }
+
+ public void run() {
+
+ // Remember the starting time
+ long tm = System.currentTimeMillis();
+ while (Thread.currentThread() == animator) {
+ // Display the next frame of animation.
+ repaint();
+
+ // Delay depending on how far we are behind.
+ try {
+ tm += delay;
+ Thread.sleep(Math.max(0, tm -
System.currentTimeMillis()));
+ } catch (InterruptedException e) {
+ break;
+ }
+
+ // Advance the frame
+ frame++;
+ }
+ }
+
+ public void stop() {
+ animator = null;
+ }
+
+ public void paint(Graphics g) {
+ if(address_changed){
+ if(robots!=null)
+ robots.clear();
+ if(sink2.arraylist!=null)
+ sink2.arraylist.clear();
+ try{
+ reader2.parse( new InputSource( new
URL("http://"+host_address+"/sim/tree/get?format=xml").openStream() ));
+ jsamp=new TreeBuilder();
+ tree=jsamp.makeTree(sink2.arraylist,
1,0);
+ reader = XML.makeXMLReader();
+ reader.setContentHandler( sink );
+
+ if(tree!=null){
+ mainApp.tree=tree;
+
mainApp.scrollPanel.setViewportView(tree);
+
mainApp.treepanel.add(mainApp.scrollPanel, BorderLayout.CENTER);
+
mainApp.treepanel.setVisible(true);
+ }
+
mainApp.add(mainApp.treepanel,BorderLayout.WEST);
+ mainApp.run();
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ address_changed=false;
+ }
+ scrnG.clearRect(0, 0, dim.height, dim.width);
+ dim=this.getSize();
+ boardSize=Math.min(dim.height, dim.width)-200;
+ boardX=dim.width/7;
+ boardY=dim.height/8;
+ scrnG.setColor(new Color(110,110,110));
+ scrnG.fillRect(boardX-100, boardY-100, boardSize+200,
boardSize+200);
+ scrnG.setColor(Color.white);
+ scrnG.fillRect(boardX, boardY, boardSize, boardSize);
+ scrnG.setColor(Color.black);
+// String response=getResponseText();
+ scrnG.drawString(sink.time, boardX-40,
boardY+boardSize+60);
+
+ //For each of the robots,
+ for(int s=0;s<robots.size();s++){
+
+ if(robots.get(s)==null){
+ robots.remove(s);
+ s--;
+ }
+ Robot current=robots.get(s);
+
current.selected=current.laserSelected=current.sonarSelected=current.fiducialSelected=false;
+ //Determine if the robot and/or any of its devices are
selected on the tree
+ if(paths!=null && pathComponents!=null){
+ for(int is=0;is<pathComponents.length;is++){
+ for(int
js=0;js<pathComponents[is].length;js++){
+
if(pathComponents[is][js].toString().contains(current.name)){
+
if(paths[is].getLastPathComponent().toString().equals(current.name))
+
current.selected=true;
+
if(paths[is].getLastPathComponent().toString().contains("laser"))
+
current.laserSelected=true;
+
if(paths[is].getLastPathComponent().toString().contains("ranger"))
+
current.sonarSelected=true;
+
if(paths[is].getLastPathComponent().toString().contains("fiducial"))
+
current.fiducialSelected=true;
+ }
+ }
+ }
+ }
+ try{
+ //Send the request for pva
+ InputStream pva_input_stream=new URL (
"http://"+host_address+"/"+current.name+"/pva/get?format=xml").openStream ( );
+ reader.parse( new InputSource( pva_input_stream
));
+// Send the request for laser
+ InputStream laser_input_stream=new URL (
"http://"+host_address+"/"+current.laserName/*.replace('.',
'/')*/+"/data/get?format=xml").openStream ( );
+ reader.parse( new InputSource(
laser_input_stream ));
+// Send the request for ranger
+ InputStream sonar_input_stream=new URL (
"http://"+host_address+"/"+current.sonarName/*.replace('.',
'/')*/+"/data/get?format=xml").openStream ( );
+ reader.parse( new InputSource(
sonar_input_stream ));
+// Send the request for fiducial
+ InputStream fiducial_input_stream=new URL (
"http://"+host_address+"/"+current.fiducialName/*.replace('.',
'/')*/+"/data/get?format=xml").openStream ( );
+ reader.parse( new InputSource(
fiducial_input_stream ));
+ current.laser_fov=sink.robot.laser_fov;
+ current.laser_resol=sink.robot.laser_resol;
+ current.sonar_fov=sink.robot.sonar_fov;
+
current.laser_sampleCount=sink.robot.laser_sampleCount;
+
current.sonar_sampleCount=sink.robot.sonar_sampleCount;
+ current.pose=sink.robot.pose;
+ current.samples=sink.robot.samples;
+ current.sonar=sink.robot.sonar;
+ current.sonar_pairs=sink.robot.sonar_pairs;
+ current.fiducial=sink.robot.fiducial;
+
current.fiducial_sampleCount=sink.robot.fiducial_sampleCount;
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ if(current!=null && current.pose!=null){
+ // If the checkbox for position is selected in the main
applet, draw the robots.
+ if(show_position)
+
drawRobot(current.pose.x,current.pose.y,current.pose.a,current);
+ //If the checkbox for laser is selected in the main
applet, draw the laser beams.
+ if(show_laser && current.hasLaser)
+ drawLaser(current);
+ //If the checkbox for ranger is selected in the main
applet, draw the sonar beams.
+ if(show_sonar && current.hasRanger)
+ drawSonar(current);
+ //If the checkbox for fiducial is selected in the main
applet, draw the fiducials.
+ if(show_fiducial && current.hasFiducial &&
current.fiducial!=null)
+ drawFiducial(current);
+
+ }
+ else{
+ scrnG.drawString( "Robot Null", 5,140);
+ super.paint(g);
+ }
+ }
+ g.drawImage(scrnBuf, 0 , 0 , this);
+ }
+
+ public void update(Graphics g) {
+ paths=null;
+ pathComponents=null;
+ if(tree!=null)
+ paths=tree.getSelectionPaths();
+ if(paths!=null && paths.length>0){
+ pathComponents=new Object[paths.length][];
+ for(int i=0;i<paths.length;i++)
+ pathComponents[i]=paths[i].getPath();
+ }
+ paint(g);
+
+
+ }
+
+
+ public String getResponseText(){
+
+ try{
+ String
urlstr="http://"+host_address+"/position:0/pva/get?format=xml";
+ URL url = new URL(urlstr);
+ URLConnection urlconn = url.openConnection();
+
+ Document doc = null;
+ try {
+
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(urlconn.getInputStream()));
+ StringBuilder sb = new StringBuilder();
+
+ String line = null;
+ try {
+ while ((line = reader.readLine()) != null) {
+ sb.append(line + "\n");
+ }
+
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+
+ return (sb.toString());
+
+ } catch (Exception e) {
+
+ return e.toString();
+ }
+ } catch (Exception e){
+ return "Problem accessing the response text.";
+ }
+ }
+
+
+ public void drawRobot(double x,double y, double a, Robot robot){
+ int[] verx=new int[4];
+ int[] very=new int[4];
+ int head_x,head_y,center_x,center_y;
+// 0:0.25,0.25 1:0.25,-0.25 2:-0.25,-0.25 3:-0.25,0.25
+
verx[0]=(int)((Math.cos(-a)*0.25+Math.sin(-a)*0.25+x)*(double)((double)boardSize/16.0));
+
verx[1]=(int)((Math.cos(-a)*0.25+Math.sin(-a)*(-0.25)+x)*(double)((double)boardSize/16.0));
+
verx[2]=(int)((Math.cos(-a)*(-0.25)+Math.sin(-a)*(-0.25)+x)*(double)((double)boardSize/16.0));
+
verx[3]=(int)((Math.cos(-a)*(-0.25)+Math.sin(-a)*0.25+x)*(double)((double)boardSize/16.0));
+
very[0]=(int)((-Math.sin(-a)*0.25+Math.cos(-a)*0.25+y)*(double)((double)boardSize/16.0));
+
very[1]=(int)((-Math.sin(-a)*0.25+Math.cos(-a)*(-0.25)+y)*(double)((double)boardSize/16.0));
+
very[2]=(int)((-Math.sin(-a)*(-0.25)+Math.cos(-a)*(-0.25)+y)*(double)((double)boardSize/16.0));;
+
very[3]=(int)((-Math.sin(-a)*(-0.25)+Math.cos(-a)*0.25+y)*(double)((double)boardSize/16.0));
+ for(int i=0;i<4;i++){
+ verx[i]=verx[i]+boardSize/2+boardX;
+ very[i]=-very[i]+boardSize/2+boardY;
+ }
+
center_x=(int)(x*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
center_y=(int)(-y*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+
head_x=(int)((Math.cos(-a)*0.5+x)*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
head_y=(int)(-(-Math.sin(-a)*0.5+y)*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+ Polygon poly=new Polygon(verx,very,4);
+ scrnG.setColor(Color.red);
+ scrnG.fillPolygon(poly);
+ //If robot is selected on the model tree, draw a highlighted
square around it.
+ if(robot.selected){
+ int[] selx=new int[4];
+ int[] sely=new int[4];
+
selx[0]=(int)((Math.cos(-a)*0.5+Math.sin(-a)*0.5+x)*(double)((double)boardSize/16.0));
+
selx[1]=(int)((Math.cos(-a)*0.5+Math.sin(-a)*(-0.5)+x)*(double)((double)boardSize/16.0));
+
selx[2]=(int)((Math.cos(-a)*(-0.5)+Math.sin(-a)*(-0.5)+x)*(double)((double)boardSize/16.0));
+
selx[3]=(int)((Math.cos(-a)*(-0.5)+Math.sin(-a)*0.5+x)*(double)((double)boardSize/16.0));
+
sely[0]=(int)((-Math.sin(-a)*0.5+Math.cos(-a)*0.5+y)*(double)((double)boardSize/16.0));
+
sely[1]=(int)((-Math.sin(-a)*0.5+Math.cos(-a)*(-0.5)+y)*(double)((double)boardSize/16.0));
+
sely[2]=(int)((-Math.sin(-a)*(-0.5)+Math.cos(-a)*(-0.5)+y)*(double)((double)boardSize/16.0));;
+
sely[3]=(int)((-Math.sin(-a)*(-0.5)+Math.cos(-a)*0.5+y)*(double)((double)boardSize/16.0));
+ for(int i=0;i<4;i++){
+ selx[i]=selx[i]+boardSize/2+boardX;
+ sely[i]=-sely[i]+boardSize/2+boardY;
+ }
+ Polygon selpoly=new Polygon(selx,sely,4);
+ scrnG.setColor(new
Color((float)0,(float)1,(float)1,(float)0.5));
+ scrnG.fillPolygon(selpoly);
+ }
+ scrnG.setColor(Color.BLACK);
+ scrnG.drawLine(verx[0],very[0],verx[1],very[1]);
+ scrnG.drawLine(center_x,center_y,head_x,head_y);
+ }
+
+ public void drawLaser(Robot robot){
+ //If the laser device is selected on the model tree, highlight
it, otherwise draw it normally.
+ if(robot.laserSelected)
+ scrnG.setColor(new
Color((float)0,(float)0,(float)1,(float)0.75));
+ else
+ scrnG.setColor(new
Color((float)0,(float)0,(float)1,(float)0.25));
+ double fov=robot.laser_fov;
+ double[] samples=robot.getLaserRange();
+ int sampleCount=samples.length;
+ double[] xs= new double[sampleCount+1];
+ double[] ys= new double[sampleCount+1];
+ double[] xprimes= new double[sampleCount+1];
+ double[] yprimes= new double[sampleCount+1];
+ int[] int_xprimes= new int[sampleCount+1];
+ int[] int_yprimes= new int[sampleCount+1];
+ double bearing = robot.pose.a;
+
+ xs[0]=0.0;
+ ys[0]=0.0;
+ for(int s=0;s<sampleCount;s++){
+ double ray_angle = (s * (fov /
(sampleCount-1))) - fov/2.0;
+ xs[s+1] =(samples[s] * Math.cos(ray_angle) );
+ ys[s+1] =(samples[s] * Math.sin(ray_angle) );
+ }
+ xprimes[0]=robot.pose.x;
+ yprimes[0]=robot.pose.y;
+// Rotates Counter-Clockwise with (-bearing)
+ for(int s=0;s<sampleCount;s++){
+ xprimes[s+1] =
Math.cos(-bearing)*xs[s+1]+Math.sin(-bearing)*ys[s+1]+xprimes[0];
+ yprimes[s+1] =
-Math.sin(-bearing)*xs[s+1]+Math.cos(-bearing)*ys[s+1]+yprimes[0];
+ }
+ for(int i=0;i<sampleCount+1;i++){
+
int_xprimes[i]=(int)(xprimes[i]*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
int_yprimes[i]=(int)(-yprimes[i]*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+ }
+
scrnG.fillPolygon(int_xprimes,int_yprimes,sampleCount+1);
+ }
+
+ public void drawSonar(Robot robot){
+ //If the ranger device is selected on the model tree, highlight
it, otherwise draw it normally.
+ if(robot.sonarSelected)
+ scrnG.setColor(new
Color((float)0,(float)1,(float)0.75));
+ else
+ scrnG.setColor(Color.green);
+ for(int i=0;i<robot.sonar_sampleCount;i++){
+ int startx,starty,endx,endy;
+
startx=(int)(robot.sonar_pairs[i].start.x*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
starty=(int)(-robot.sonar_pairs[i].start.y*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+
endx=(int)(robot.sonar_pairs[i].end.x*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
endy=(int)(-robot.sonar_pairs[i].end.y*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+ scrnG.drawLine(startx,starty,endx,endy);
+ }
+ }
+
+ public void drawFiducial(Robot robot){
+ //If the fiducial device is selected on the model tree,
highlight it, otherwise draw it normally.
+ if(robot.fiducialSelected)
+ scrnG.setColor(new
Color((float)0.15,(float)0.15,(float)0.15));
+ else
+ scrnG.setColor(Color.gray);
+ for(int i=0;i<robot.fiducial_sampleCount;i++){
+ int startx,starty,endx,endy;
+
startx=(int)(robot.pose.x*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
starty=(int)(-robot.pose.y*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+
endx=(int)((robot.pose.x+robot.fiducial[i].x)*(double)((double)boardSize/16.0))+boardSize/2+boardX;
+
endy=(int)(-(robot.pose.y+robot.fiducial[i].y)*(double)((double)boardSize/16.0))+boardSize/2+boardY;
+ scrnG.drawLine(startx,starty,endx,endy);
+ scrnG.drawString(new
Integer(robot.fiducial[i].id).toString() ,endx, endy);
+ }
+ }
+
+
+ public double toDouble(String s){
+ double ans=0;
+ boolean minusFlag=false;
+ if(s.startsWith("-")){
+ minusFlag=true;
+ s=s.substring(1);
+ }
+ int dotLocation=s.length();
+ for(int i=0;i<s.length();i++){
+ if((s.charAt(i)<'0' ||s.charAt(i)>'9') && s.charAt(i)!='.' )
+ break;
+ if(s.charAt(i)=='.'){
+ dotLocation=i;
+ continue;
+ }
+ if(i<dotLocation){
+ ans*=10;
+ ans+=((int)s.charAt(i)-'0');
+ }
+ else
+
ans+=(double)((double)((int)s.charAt(i)-'0')/Math.pow(10.0,i-dotLocation));
+ }
+
+ if(minusFlag)
+ ans=-ans;
+ return ans;
+ }
+
+ }
+
+
+ /**
+ * This class build a JTree based on the xml format of the tree. The xml
parser builds an arraylist of the models and their depth in the tree which will
be passed to this
+ * class. Then this class will recursively build the tree.
+
+ * Parts of the code are from
"http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-JTree.html"
+ */
+ class TreeBuilder extends JPanel {
+
+ public TreeBuilder() {
+
+ }
+
+ public JTree makeTree(ArrayList list, int level, int index){
+ DefaultMutableTreeNode root = processHierarchy(list,level,index);
+ JTree tree = new JTree(root);
+ return tree;
+ }
+
+ int staticIndex=0;
+ private DefaultMutableTreeNode processHierarchy(ArrayList list, int level,
int index) {
+ DefaultMutableTreeNode node =
+ new
DefaultMutableTreeNode(((ObjectLevelPair)list.get(index)).obj);
+ DefaultMutableTreeNode child;
+ for(int i=index+1; i<list.size(); i++) {
+ ObjectLevelPair nodeSpecifier = (ObjectLevelPair)list.get(i);
+ if (nodeSpecifier.level>((ObjectLevelPair)list.get(index)).level){
+ child = processHierarchy(list,nodeSpecifier.level,i);
+ nodeSpecifier.level=0;
+ node.add(child);
+ }
+ else if(nodeSpecifier.level==0)
+ continue;
+ else
+ break;
+ }
+ return(node);
+ }
+ }
+
+ /**
+ * This is a class used for building the tree.
+ */
+ class ObjectLevelPair {
+ Object obj;
+ int level;
+ public ObjectLevelPair(Object argobj, int arglevel){
+ obj=argobj;
+ level=arglevel;
+ }
+
+ }
+
+ /**
+ * A pair of double values.
+ */
+ class Pair {
+ double x,y;
+ Pair(){
+ x=0.0;
+ y=0.0;
+ }
+ Pair(double argx,double argy){
+ x=argx;
+ y=argy;
+ }
+
+ }
+
+
+
+ /**
+ * This is a Robot class. Fields correspond to the devices and models a
robot can have.
+ */
+ class Robot{
+
+ //PVA
+ Pose pose;
+ //Laser samples
+ LaserSample[] samples;
+ //Sonar ranges
+ double[] sonar;
+ //Laser configurations
+ double laser_fov, laser_resol, sonar_fov;
+ int laser_sampleCount;
+ int sonar_sampleCount;
+ int fiducial_sampleCount;
+ //Start and end ponits of Sonar beams
+ SonarSample[] sonar_pairs;
+ //Fiducials detected
+ FiducialSample[] fiducial;
+ //Names of robot and its devices
+ String name, laserName,sonarName,fiducialName;
+ //Flags indicating if robot has any of these devices
+ boolean hasLaser, hasRanger, hasFiducial;
+ //Flags indicating if robot or any of these devices are selected on the
model tree
+ boolean selected, laserSelected, sonarSelected, fiducialSelected;
+
+ Robot(){
+ name="r";
+ laserName="laser:0";
+ sonarName="ranger:0";
+ fiducialName="fiducial:0";
+ hasLaser=false;
+ hasRanger=false;
+ hasFiducial=false;
+ selected=false;
+ laserSelected=false;
+ sonarSelected=false;
+ fiducialSelected=false;
+ pose=new Pose();
+ laser_sampleCount=30;
+ samples=new LaserSample[laser_sampleCount];
+ sonar_sampleCount=10;
+ sonar=new double[sonar_sampleCount];
+ sonar_pairs=new SonarSample[sonar_sampleCount];
+ laser_fov=3.1416;
+ sonar_fov=6.2832;
+ laser_resol=1.0;
+ for(int i=0;i<laser_sampleCount;i++){
+ samples[i]=new LaserSample();
+ samples[i].range=1.0;
+ }
+ for(int i=0;i<sonar_sampleCount;i++){
+ sonar[i]=2.2;
+ sonar_pairs[i]=new SonarSample();
+ }
+ fiducial_sampleCount=0;
+ }
+
+ //Returns pva of the robot.
+ public Pose getPosition(){
+ return this.pose;
+ }
+ public void setPose(double argx,double argy,double argz,double
argr,double argp,double arga){
+ pose.a=arga;
+ pose.r=argr;
+ pose.p=argp;
+ pose.x=argx;
+ pose.y=argy;
+ pose.z=argz;
+ }
+
+ //Returns laser samples of the robot.
+ public LaserSample[] getLaser(){
+ return this.samples;
+ }
+
+ //Returns laser ranges of the robot.
+ public double[] getLaserRange(){
+ double[] ranges=new double[samples.length];
+ for(int i=0;i<samples.length;i++){
+ ranges[i]=samples[i].range;
+ }
+ return ranges;
+ }
+
+ //Returns sonar samples of the robot.
+ public double[] getSonar(){
+ return this.sonar;
+ }
+
+ public void print(){
+ System.out.println("pose:");
+ System.out.println("x:"+pose.x+" y:"+pose.y+" z:"+pose.z+"
r:"+pose.r+" p:"+pose.p+" a:"+pose.a);
+ }
+
+
+
+ }
+
+ /**
+ * A Class corresponding to the PVA of the robot, indicating x,y,z
positions ans r,p,a, angles.
+ */
+ class Pose{
+ double a,r,p,x,y,z;
+ Pose(){
+ a=r=p=x=y=z=0.0;
+ }
+ Pose(double argx,double argy,double argz,double argr,double
argp,double arga){
+ a=arga;
+ r=argr;
+ p=argp;
+ x=argx;
+ y=argy;
+ z=argz;
+ }
+ }
+ /**
+ * A Class corresponding to the Laser of the robot, indicating intensity
and range of the laser beam.
+ */
+ class LaserSample{
+ double intensity;
+ double range;
+ LaserSample(){
+ intensity=range=0.0;
+ }
+ }
+ /**
+ * A Class corresponding to the Sonar of the robot, indicating start and
end point of the sonar beam.
+ */
+ class SonarSample{
+ Pair start,end;
+ SonarSample(){
+ start=new Pair();
+ end=new Pair();
+ }
+ SonarSample(double startx,double starty,double endx,double
endy){
+ start=new Pair(startx,starty);
+ end=new Pair(endx,endy);
+ }
+ }
+ /**
+ * A Class corresponding to the Fiducial of the robot, indicating range,
bearing, and id of the fiducial.
+ */
+ class FiducialSample{
+ double x,y;
+ int id;
+ FiducialSample(){
+ x=0;
+ y=0;
+ id=0;
+ }
+ FiducialSample(double xarg,double yarg,int idarg){
+ x=xarg;
+ y=yarg;
+ id=idarg;
+ }
+ }
+
+
+ /**
+ * This is a Content Handler for xml parser. This Content Handler parses
the xml responses for Position, Laser, Ranger, and Fiducial requests. It has a
robot field and
+ * whenever a property is parsed, the corresponding fields in the robot are
(re)assigned.
+ *
+ * Parts of the code are from:
http://www-inf.int-evry.fr/cours/WebServices/XML/sax.html
+ */
+ class Sink
+ extends DefaultHandler
+ implements ContentHandler
+
+ {
+ String time="Time: ";
+ Robot robot=new Robot();
+ final private static void print
+ ( final String context, final String text )
+ { System.out.println( context + ": \"" + text + "\"." ); }
+
+ public void startElement
+ ( final String namespace, final String localname,
+ final String type, final Attributes attrs )
+ {
+ try{
+ time="Time: "+attrs.getValue("Time");
+ if(attrs.getValue("Type").toLowerCase().equals("pva")){
+ String pose=attrs.getValue("Pose");
+ String x,y,z,r,p,a;
+ String[] vals=pose.split(",");
+ x = vals[0];
+ y = vals[1];
+ z = vals[2];
+ r = vals[3];
+ p = vals[4];
+ a = vals[5];
+
+ double x_val,y_val,z_val,r_val,p_val,a_val;
+ x_val=Double.parseDouble(x);
+ y_val=Double.parseDouble(y);
+ z_val=Double.parseDouble(z);
+ r_val=Double.parseDouble(r);
+ p_val=Double.parseDouble(p);
+ a_val=Double.parseDouble(a);
+ robot.setPose(x_val,y_val,z_val,r_val,p_val,a_val);
+
+ }
+ if(attrs.getValue("Type").toLowerCase().equals("laser")){
+ String res,fov,sam;
+ res = attrs.getValue("Resolution");
+ fov = attrs.getValue("FOV");
+ sam = attrs.getValue("Samples");
+ double res_val,fov_val;
+ String[] tokens=sam.split(",");
+ double[] samples=new double[tokens.length];
+ robot.laser_sampleCount=tokens.length;
+ robot.samples=new LaserSample[tokens.length];
+ for(int i=0;i<tokens.length;i++){
+ samples[i]=Double.parseDouble(tokens[i]);
+ robot.samples[i]=new LaserSample();
+ robot.samples[i].range=samples[i];
+ }
+ res_val=Double.parseDouble(res);
+ fov_val=Double.parseDouble(fov);
+ robot.laser_fov=fov_val;
+ robot.laser_resol=res_val;
+
+ }
+ if(attrs.getValue("Type").toLowerCase().equals("ranger")){
+ String pos,sam;
+ sam = attrs.getValue("Samples");
+ String[] tokens=sam.split(",");
+ robot.sonar_sampleCount=tokens.length;
+ robot.sonar=new double[tokens.length];
+ robot.sonar_pairs=new SonarSample[tokens.length];
+ double[] samples=new double[tokens.length];
+ pos= attrs.getValue("Positions");
+ pos=pos.replaceAll(" \\(", "");
+ String[] posetokens=pos.split("\\)");
+ for(int i=0;i<tokens.length;i++){
+ String[] poses=posetokens[2*i].split(",");
+ String[] angles=posetokens[2*i+1].split(",");
+ double
startx,starty,angle,endx,endy,startx1,starty1;
+ samples[i]=Double.parseDouble(tokens[i]);
+ robot.sonar[i]=samples[i];
+ startx1=Double.parseDouble(poses[0]);
+ starty1=Double.parseDouble(poses[1]);
+
startx=Math.cos(-robot.pose.a)*startx1+Math.sin(-robot.pose.a)*starty1+robot.pose.x;
+ starty=
-Math.sin(-robot.pose.a)*startx1+Math.cos(-robot.pose.a)*starty1+robot.pose.y;
+ angle=Double.parseDouble(angles[2]);
+
endx=startx+Math.cos(angle+robot.pose.a)*samples[i];
+
endy=starty+Math.sin(angle+robot.pose.a)*samples[i];
+ robot.sonar_pairs[i]=new
SonarSample(startx,starty,endx,endy);
+ }
+
+ }
+ if(attrs.getValue("Type").toLowerCase().equals("fiducial")){
+ robot.fiducial=null;
+ robot.fiducial_sampleCount=0;
+ String fids;
+ fids = attrs.getValue("Targets");
+ if(!fids.equals("")){
+ fids=fids.replaceAll("\\)\\(", ",");
+ fids=fids.replaceAll("\\(", "");
+ fids=fids.replaceAll("\\)", "");
+ String[] fidtokens=fids.split(",");
+ robot.fiducial_sampleCount=fidtokens.length/7;
+ robot.fiducial= new
FiducialSample[fidtokens.length/7];
+ for(int i=0;i<fidtokens.length/7;i++){
+ robot.fiducial[i]=new FiducialSample();
+
robot.fiducial[i].x=Double.parseDouble(fidtokens[i*7]);
+
robot.fiducial[i].y=Double.parseDouble(fidtokens[i*7+1]);
+
robot.fiducial[i].id=Integer.parseInt(fidtokens[i*7+6]);
+ }
+ }
+
+
+ }
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+
+
+
+
+ public void endElement
+ ( final String namespace, final String localname,
+ final String type )
+ throws SAXException
+ {
+
+ }
+
+ final public void characters
+ ( final char[] ch, final int start, final int len )
+ { final String text = new String( ch, start, len );
+ final String text1 = text.trim();
+ if( text1.length() > 0 )print( "characters ", text1 ); }
+
+ public Robot getRobot(){
+ return robot;
+ }
+
+ }
+
+
+ /**
+ * This is a Content Handler for xml parser. This Content Handler parses
the xml tree returned by the server. Based on the models that exist in the
tree,
+ * corresponding models (robots, lasers, rangers, fiducials) are created.
+ *
+ * Parts of the code are from:
"http://www-inf.int-evry.fr/cours/WebServices/XML/sax.html"
+ */
+ class TreeSink
+ extends DefaultHandler
+ implements ContentHandler
+
+ {
+ //int xposition=600, yposition=250;
+ Robot robot=new Robot();
+ StageApplet np;
+ TreeBuilder tree;
+ int level=0;
+ ArrayList<ObjectLevelPair> arraylist;
+
+ TreeSink(StageApplet nparg){
+ np=nparg;
+ tree=new TreeBuilder();
+ arraylist=new ArrayList<ObjectLevelPair>();
+ }
+
+ final private static void print
+ ( final String context, final String text )
+ { System.out.println( context + ": \"" + text + "\"." ); }
+
+ public void startElement
+ ( final String namespace, final String localname,
+ final String type, final Attributes attrs )
+ {
+
+ level++;
+ String model_type=attrs.getValue("Type");
+ if(model_type!=null){
+ if(model_type.toLowerCase().equals("position")){
+ String name=attrs.getValue("Name");
+ if(name.indexOf('.')!=-1)
+ name=name.substring(0,name.indexOf('.'));
+ if(np.robots.size()<1 ||
!np.robots.get(np.robots.size()-1).name.equals(name)){
+ Robot r=new Robot();
+ r.name=name;
+ np.robots.add(r);
+ }
+ }
+ if(model_type.toLowerCase().equals("laser")){
+ String name=attrs.getValue("Name");
+ if(np.robots.size()<1 ||
!np.robots.get(np.robots.size()-1).name.equals(name.substring(0,name.indexOf('.')))){
+ Robot r=new Robot();
+ r.name=name.substring(1,name.lastIndexOf('.'));
+ np.robots.add(r);
+ }
+ np.robots.get(np.robots.size()-1).hasLaser=true;
+ np.robots.get(np.robots.size()-1).laserName=name;
+ }
+ if(model_type.toLowerCase().equals("ranger")){
+ String name=attrs.getValue("Name");
+ if(np.robots.size()<1 ||
!np.robots.get(np.robots.size()-1).name.equals(name.substring(0,name.indexOf('.')))){
+ Robot r=new Robot();
+ r.name=name.substring(1,name.lastIndexOf('.'));
+ np.robots.add(r);
+ }
+ np.robots.get(np.robots.size()-1).hasRanger=true;
+ np.robots.get(np.robots.size()-1).sonarName=name;
+ }
+ if(model_type.toLowerCase().equals("fiducial")){
+ String name=attrs.getValue("Name");
+ if(np.robots.size()<1 ||
!np.robots.get(np.robots.size()-1).name.equals(name.substring(0,name.indexOf('.')))){
+ Robot r=new Robot();
+ r.name=name.substring(1,name.lastIndexOf('.'));
+ np.robots.add(r);
+ }
+ np.robots.get(np.robots.size()-1).hasFiducial=true;
+ np.robots.get(np.robots.size()-1).fiducialName=name;
+ }
+
+ try{
+ arraylist.add(new
ObjectLevelPair((attrs.getValue("Name").lastIndexOf('.')>0?attrs.getValue("Name").substring(attrs.getValue("Name").lastIndexOf('.')+1):attrs.getValue("Name")),level));
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+ else{
+ arraylist.add(new ObjectLevelPair(type,level));
+ }
+ }
+
+
+
+
+ public void endElement
+ ( final String namespace, final String localname,
+ final String type )
+ throws SAXException
+ {
+
+ level--;
+
+ }
+
+ final public void characters
+ ( final char[] ch, final int start, final int len )
+ { final String text = new String( ch, start, len );
+ final String text1 = text.trim();
+ if( text1.length() > 0 )print( "characters ", text1 ); }
+
+ public Robot getRobot(){
+ return robot;
+ }
+
+ }
+
+ /**
+ * This class creates a new XML reader.
+ *
+ * code from: "http://www-inf.int-evry.fr/cours/WebServices/XML/sax.html"
+ */
+ final class XML
+
+ {
+
+ final public static XMLReader makeXMLReader()
+ throws Exception
+ { final SAXParserFactory saxParserFactory =
SAXParserFactory.newInstance();
+ final SAXParser saxParser = saxParserFactory.newSAXParser();
+ final XMLReader parser = saxParser.getXMLReader();
+ return parser;
+ }
+ }
+
+
+
+
+
+
+
+
+
Added: code/websim/viz/ReadMe
===================================================================
--- code/websim/viz/ReadMe (rev 0)
+++ code/websim/viz/ReadMe 2009-07-13 20:05:09 UTC (rev 8007)
@@ -0,0 +1,3 @@
+ The HTML page calls "Main.class" to be run. The applet will contain a
textfield, that indicates the server address. The default value for it is set
to "192.168.1.210:8000". The server address can be changed by editing this text
field and then pressing the "Send Request" button.
+ On the left side of the panel, the model tree will show up. This tree
contains all the models existing in the world. The parent of each node in the
tree corresponds to its parent model in the world. Models can be selected or
unselected on the tree by clicking on them. Selecting a model highlights it in
the visualization panel. Several Models can be selected by holding "ctrl".
+ There are 4 checkboxes on the top of the page: Position, Laser, Sonar,
and Fiducial. Selecting or unselecting each of them will result in those
features being drawn or not. By default, position and laser are selected
meaning the robots and their laser beams are drawn initially.
Added: code/websim/viz/java.policy.applet
===================================================================
--- code/websim/viz/java.policy.applet (rev 0)
+++ code/websim/viz/java.policy.applet 2009-07-13 20:05:09 UTC (rev 8007)
@@ -0,0 +1,7 @@
+/* AUTOMATICALLY GENERATED ON Tue Apr 16 17:20:59 EDT 2002*/
+/* DO NOT EDIT */
+
+grant {
+ permission java.security.AllPermission;
+};
+
Added: code/websim/viz/visualization.html
===================================================================
--- code/websim/viz/visualization.html (rev 0)
+++ code/websim/viz/visualization.html 2009-07-13 20:05:09 UTC (rev 8007)
@@ -0,0 +1,14 @@
+<HTML>
+<HEAD>
+ <TITLE>Websim Visualization</TITLE>
+</HEAD>
+<BODY>
+ <CENTER>
+ <APPLET CODE="Main.class" WIDTH="1000" HEIGHT="1000" id="TheApplet">
+ </APPLET>
+ </CENTER>
+
+
+</BODY>
+</HTML>
+
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit