00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 package com.generalrobotix.ui.item;
00019
00020 import javax.media.j3d.Geometry;
00021 import javax.media.j3d.IndexedTriangleArray;
00022 import javax.media.j3d.QuadArray;
00023 import javax.media.j3d.Shape3D;
00024 import javax.media.j3d.Switch;
00025 import javax.media.j3d.TransparencyAttributes;
00026 import javax.media.j3d.TriangleFanArray;
00027 import javax.vecmath.Point3f;
00028
00029 import jp.go.aist.hrp.simulator.SensorInfo;
00030 import jp.go.aist.hrp.simulator.CameraPackage.CameraParameter;
00031 import jp.go.aist.hrp.simulator.CameraPackage.CameraType;
00032
00033 import com.generalrobotix.ui.GrxPluginManager;
00034 import com.generalrobotix.ui.view.tdview.SceneGraphModifier;
00035 import com.generalrobotix.ui.view.vsensor.Camera_impl;
00036
00040 @SuppressWarnings({ "serial", "unchecked" })
00041 public class GrxSensorItem extends GrxShapeTransformItem implements Comparable {
00042 public String type_;
00043 public int id_;
00044 private float[] specValues_;
00045 private String specFile_;
00046
00047
00048 private Camera_impl camera_ = null;
00049 private Switch switchVisibleArea_ = null;
00050
00051 public static final String[] sensorType = { "Vision", "RateGyro" , "Acceleration" , "Force" , "Range" };
00052 protected static final String[] sensorTypeComboItem_ = sensorType;
00053 protected static final String[] cameraTypeComboItem_ = new String[] { "NONE", "COLOR" , "MONO" , "DEPTH" , "COLOR_DEPTH" , "MONO_DEPTH" };
00054
00060 public GrxSensorItem(String name, GrxPluginManager manager, GrxModelItem model, SensorInfo info) {
00061 super(name, manager, model);
00062 if(info != null){
00063 type_ = info.type;
00064 id_ = info.id;
00065 specValues_ = info.specValues;
00066 specFile_ = info.specFile;
00067 translation(info.translation);
00068 rotation(info.rotation);
00069 int n = info.shapeIndices.length;
00070 for(int i=0; i<n; i++)
00071 addTransformedShapeIndex(info.shapeIndices[i]);
00072 buildShapeTransforms(info.inlinedShapeTransformMatrices);
00073 }else{
00074 id_ = -1;
00075 type_ = new String("Force");
00076 specValues_ = new float[]{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f};
00077 translation(new double[]{0.0, 0.0, 0.0});
00078 rotation(new double[]{0.0, 0.0, 1.0, 0.0});
00079 }
00080
00081 initMenu();
00082
00083 setProperty("type", type_);
00084 setProperty("id", String.valueOf(id_));
00085 setProperty("alwaysVisible", "false");
00086 setIcon("camera.png");
00087
00088 if (type_.equals("Vision")) {
00089 CameraParameter prm = new CameraParameter();
00090 prm.defName = new String(name);
00091 prm.sensorName = new String(name);
00092 prm.sensorId = id_;
00093
00094 prm.frontClipDistance = (float)specValues_[0];
00095 prm.backClipDistance = (float)specValues_[1];
00096 prm.fieldOfView = (float)specValues_[2];
00097 try {
00098 prm.type = CameraType.from_int((int)specValues_[3]);
00099 } catch (Exception e) {
00100 prm.type = CameraType.NONE;
00101 }
00102 prm.width = (int)specValues_[4];
00103 prm.height = (int)specValues_[5];
00104 prm.frameRate = (float)specValues_[6];
00105
00106 setDbl("frontClipDistance", prm.frontClipDistance, 4);
00107 setDbl("backClipDistance", prm.backClipDistance, 4);
00108 setDbl("fieldOfView", prm.fieldOfView, 6);
00109 if (prm.type == CameraType.NONE){
00110 setProperty("cameraType", "NONE");
00111 }else if (prm.type == CameraType.COLOR){
00112 setProperty("cameraType", "COLOR");
00113 }else if (prm.type == CameraType.MONO){
00114 setProperty("cameraType", "MONO");
00115 }else if (prm.type == CameraType.COLOR_DEPTH){
00116 setProperty("cameraType", "COLOR_DEPTH");
00117 }else if (prm.type == CameraType.MONO_DEPTH){
00118 setProperty("cameraType", "MONO_DEPTH");
00119 }else if (prm.type == CameraType.DEPTH){
00120 setProperty("cameraType", "DEPTH");
00121 }
00122 setInt("width", prm.width);
00123 setInt("height", prm.height);
00124 setDbl("frameRate", prm.frameRate);
00125 boolean offScreen = false;
00126 camera_ = new Camera_impl(prm, offScreen);
00127
00128 tg_.addChild(camera_.getBranchGroup());
00129 switchVisibleArea_ = SceneGraphModifier._makeSwitchNode(_createShapeOfVisibleArea());
00130 tg_.addChild(switchVisibleArea_);
00131 }else if(type_.equals("RateGyro")){
00132 float[] max = new float[3];
00133 max[0] = specValues_[0];
00134 max[1] = specValues_[1];
00135 max[2] = specValues_[2];
00136 setFltAry("maxAngularVelocity", max);
00137 }else if(type_.equals("Acceleration")){
00138 float[] max = new float[3];
00139 max[0] = specValues_[0];
00140 max[1] = specValues_[1];
00141 max[2] = specValues_[2];
00142 setFltAry("maxAcceleration", max);
00143 }else if(type_.equals("Force")){
00144 float[] maxf = new float[3];
00145 maxf[0] = specValues_[0];
00146 maxf[1] = specValues_[1];
00147 maxf[2] = specValues_[2];
00148 float[] maxt = new float[3];
00149 maxt[0] = specValues_[3];
00150 maxt[1] = specValues_[4];
00151 maxt[2] = specValues_[5];
00152 setFltAry("maxForce", maxf);
00153 setFltAry("maxTorque", maxt);
00154 }else if(type_.equals("Range")){
00155 setFlt("scanAngle", specValues_[0]);
00156 setFlt("scanStep", specValues_[1]);
00157 setFlt("scanRate", specValues_[2]);
00158 setFlt("maxDistance", specValues_[3]);
00159 switchVisibleArea_ = SceneGraphModifier._makeSwitchNode(_createShapeOfVisibleArea());
00160 tg_.addChild(switchVisibleArea_);
00161 }
00162
00163 }
00164
00165 public int compareTo(Object o) {
00166 if (o instanceof GrxSensorItem) {
00167 GrxSensorItem s = (GrxSensorItem) o;
00168 if (getOrder(type_) < getOrder(s.type_))
00169 return -1;
00170 else{
00171 if (id_ < s.id_)
00172 return -1;
00173 }
00174 }
00175 return 1;
00176 }
00177
00183 private int getOrder(String type) {
00184 if (type.equals("Force"))
00185 return 0;
00186 else if (type.equals("RateGyro"))
00187 return 1;
00188 else if (type.equals("Acceleration"))
00189 return 2;
00190 else if (type.equals("Vision"))
00191 return 3;
00192 else if (type.equals("Range"))
00193 return 4;
00194 else
00195 return -1;
00196
00197 }
00198
00203 void id(String value){
00204 Short id = getShort(value);
00205 if (id != null && id_ != id){
00206 id_ = id;
00207 setShort("id", id);
00208 if (model_ != null) model_.notifyModified();
00209 }
00210 }
00211
00218 public boolean propertyChanged(String property, String value) {
00219 if (property.equals("name")){
00220 rename(value);
00221 }else if(property.equals("translation")){
00222 translation(value);
00223 }else if(property.equals("rotation")){
00224 rotation(value);
00225 }else if(property.equals("id")){
00226 id(value);
00227 }else if(property.equals("type")){
00228 type(value);
00229 }else if(property.equals("cameraType")){
00230 cameraType(value);
00231 }else if(property.equals("alwaysVisible")){
00232 if (value.startsWith("true")){
00233 setProperty("alwaysVisible", "true");
00234 setVisibleArea(true);
00235 }else{
00236 setProperty("alwaysVisible", "false");
00237 setVisibleArea(false);
00238 }
00239 }else if(property.equals("frameRate")){
00240 setProperty("frameRate", value);
00241 if (model_ != null) model_.notifyModified();
00242 }else{
00243 return false;
00244 }
00245 return true;
00246 }
00247
00248 public void type(String type){
00249 if (type_.equals(type)) return;
00250
00251 if (type.equals("Vision")){
00252 if (specValues_ == null || specValues_.length != 7){
00253 specValues_ = new float[7];
00254 _removeSensorSpecificProperties();
00255 setProperty("frontClipDistance", "0.01");
00256 setProperty("backClipDistance", "10.0");
00257 setProperty("fieldOfView", "0.0785398");
00258 setProperty("cameraType", "COLOR");
00259 setProperty("width", "320");
00260 setProperty("height", "240");
00261 setProperty("frameRate", "30.0");
00262 }
00263 specValues_[0] = getFlt("frontClipDistance", null);
00264 specValues_[1] = getFlt("backClipDistance", null);
00265 specValues_[2] = getFlt("fieldOfView", null);
00266 if (getStr("cameraType", "NONE").equals("NONE")){
00267 specValues_[3] = CameraType._NONE;
00268 }else if(getStr("cameraType", "NONE").equals("COLOR")){
00269 specValues_[3] = CameraType._COLOR;
00270 }else if(getStr("cameraType", "NONE").equals("MONO")){
00271 specValues_[3] = CameraType._MONO;
00272 }else if(getStr("cameraType", "NONE").equals("DEPTH")){
00273 specValues_[3] = CameraType._DEPTH;
00274 }else if(getStr("cameraType", "NONE").equals("COLOR_DEPTH")){
00275 specValues_[3] = CameraType._COLOR_DEPTH;
00276 }else if(getStr("cameraType", "NONE").equals("MONO_DEPTH")){
00277 specValues_[3] = CameraType._MONO_DEPTH;
00278 }else{
00279 setProperty("cameraType", "NONE");
00280 }
00281 specValues_[4] = getInt("width", null);
00282 specValues_[5] = getInt("height", null);
00283 specValues_[6] = getFlt("frameRate", null);
00284
00285
00286 }else if(type.equals("RateGyro")){
00287 if (specValues_ == null || specValues_.length != 3 || getProperty("maxAngularVelocity")==null){
00288 specValues_ = new float[]{-1.0f, -1.0f, -1.0f};
00289 _removeSensorSpecificProperties();
00290 setFltAry("maxAngularVelocity", specValues_);
00291 }
00292 specValues_ = getFltAry("maxAngularVelocity", null);
00293 }else if(type.equals("Acceleration")){
00294 if (specValues_ == null || specValues_.length != 3 || getProperty("maxAcceleration")==null){
00295 specValues_ = new float[]{-1.0f, -1.0f, -1.0f};
00296 _removeSensorSpecificProperties();
00297 setFltAry("maxAcceleration", specValues_);
00298 }
00299 specValues_ = getFltAry("maxAcceleration", null);
00300 }else if(type.equals("Force")){
00301 if (specValues_ == null || specValues_.length != 6){
00302 specValues_ = new float[]{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f};
00303 _removeSensorSpecificProperties();
00304 setFltAry("maxForce", new float[]{-1.0f, -1.0f, -1.0f});
00305 setFltAry("maxTorque", new float[]{-1.0f, -1.0f, -1.0f});
00306 }
00307 float[] maxf = getFltAry("maxForce", null);
00308 float[] maxt = getFltAry("maxTorque", null);
00309 specValues_[0] = maxf[0];
00310 specValues_[1] = maxf[1];
00311 specValues_[2] = maxf[2];
00312 specValues_[3] = maxt[0];
00313 specValues_[4] = maxt[1];
00314 specValues_[5] = maxt[2];
00315 }else if(type.equals("Range")){
00316 if (specValues_ == null || specValues_.length != 3){
00317 specValues_ = new float[]{3.14159f, 0.1f, 10.0f, 10.0f};
00318 _removeSensorSpecificProperties();
00319 setFlt("scanAngle", 3.14159f);
00320 setFlt("scanStep", 0.1f);
00321 setFlt("scanRate", 10.0f);
00322 setFlt("maxDistance", 10.0f);
00323 }
00324 specValues_[0] = getFlt("scanAngle", 3.14159f);
00325 specValues_[1] = getFlt("scanStep", 0.1f);
00326 specValues_[2] = getFlt("scanRate", 10.0f);
00327 }else{
00328 System.out.println("GrxSensorItem.propertyChanged() : unknown sensor type : "+type_);
00329 return;
00330 }
00331 type_ = type;
00332 setProperty("type", type);
00333 if (model_ != null) model_.notifyModified();
00334 }
00335 private void _removeSensorSpecificProperties() {
00336
00337 remove("maxForce");
00338 remove("maxTorque");
00339
00340 remove("maxAngularVelocity");
00341
00342 remove("maxAcceleration");
00343
00344 remove("frontClipDistance");
00345 remove("backClipDistance");
00346 remove("fieldOfView");
00347 remove("width");
00348 remove("height");
00349 remove("frameRate");
00350 remove("cameraType");
00351
00352 remove("scanAngle");
00353 remove("scanStep");
00354 remove("scanRate");
00355 remove("maxDistance");
00356 }
00357
00362 public GrxSensorItem clone(){
00363 GrxSensorItem ret = (GrxSensorItem)super.clone();
00364
00365
00366
00367
00368 return ret;
00369 }
00370
00376 private Point3f[] _distances2points(double[] distances){
00377 if (type_.equals("Range")){
00378 float step = specValues_[1];
00379 int half = distances.length/2;
00380 float maxD = getFlt("maxDistance", 10.0f);
00381 Point3f[] p3f = new Point3f[distances.length*2+1];
00382 p3f[0] = new Point3f(0,0,0);
00383 double startAngle = -step*half-step/2;
00384 for(int i=0; i<distances.length; i++){
00385 double distance = distances[i];
00386 if(distance==0)
00387 distance = maxD;
00388 p3f[2*i+1] = new Point3f(
00389 (float)(-distance*Math.sin(startAngle)),
00390 0.0f,
00391 (float)(-distance*Math.cos(startAngle)));
00392 startAngle += step;
00393 p3f[2*i+2] = new Point3f(
00394 (float)(-distance*Math.sin(startAngle)),
00395 0.0f,
00396 (float)(-distance*Math.cos(startAngle)));
00397 }
00398 return p3f;
00399 }else{
00400 return null;
00401 }
00402 }
00407 public void updateShapeOfVisibleArea(double[] distances){
00408 if (type_.equals("Range")){
00409 Point3f[] p3f = _distances2points(distances);
00410 if (p3f == null) return;
00411 Shape3D shapeNode = (Shape3D)switchVisibleArea_.getChild(0);
00412 Geometry gm = (Geometry)shapeNode.getGeometry(0);
00413 if (gm instanceof TriangleFanArray){
00414 TriangleFanArray tri = (TriangleFanArray)gm;
00415 tri.setCoordinates(0, p3f);
00416 }
00417 }
00418 }
00423 private Shape3D _createShapeOfVisibleArea() {
00424 if (type_.equals("Range")){
00425 double scanAngle = specValues_[0];
00426 double step = specValues_[1];
00427 float d = specValues_[3];
00428 int length = (int)(scanAngle/step);
00429 int half = (int)(length/2);
00430 Point3f[] p3f = new Point3f[length*2+1];
00431 p3f[0] = new Point3f(0,0,0);
00432 double startAngle = -step*half-step/2;
00433 for(int i=0; i<length; i++){
00434 p3f[2*i+1] = new Point3f(
00435 (float)(-d*Math.sin(startAngle)),
00436 0.0f,
00437 (float)(-d*Math.cos(startAngle)));
00438 startAngle += step;
00439 p3f[2*i+2] = new Point3f(
00440 (float)(-d*Math.sin(startAngle)),
00441 0.0f,
00442 (float)(-d*Math.cos(startAngle)));
00443 }
00444 int[] stripVertexCounts = { p3f.length };
00445 TriangleFanArray tri = new TriangleFanArray(p3f.length,
00446 TriangleFanArray.COORDINATES,
00447 stripVertexCounts);
00448 tri.setCapability(QuadArray.ALLOW_COORDINATE_READ);
00449 tri.setCapability(QuadArray.ALLOW_COORDINATE_WRITE);
00450 tri.setCoordinates(0, p3f);
00451 javax.media.j3d.Appearance app = new javax.media.j3d.Appearance();
00452 app.setTransparencyAttributes(
00453 new TransparencyAttributes(TransparencyAttributes.FASTEST, 0.5f)
00454 );
00455 Shape3D s3d = new Shape3D(tri, app);
00456 s3d.setCapability(Shape3D.ALLOW_GEOMETRY_READ);
00457 s3d.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
00458 return s3d;
00459 }
00460 if (camera_ == null) return null;
00461
00462 CameraParameter prm = camera_.getCameraParameter();
00463
00464 float enlarge = 0.001f;
00465 float f = (float)prm.backClipDistance*(1.0f+enlarge);
00466 float n = (float)prm.frontClipDistance*(1.0f-enlarge);
00467 double theta = prm.fieldOfView;
00468 float aspect = ((float)prm.height)/prm.width;
00469 float nx = (float)Math.tan(theta/2)*n;
00470 float ny = nx*aspect;
00471 float fx = (float)Math.tan(theta/2)*f;
00472 float fy = fx*aspect;
00473
00474 Point3f[] p3f = {
00475 new Point3f(nx,ny,-n),
00476 new Point3f(-nx,ny,-n),
00477 new Point3f(-nx,-ny,-n),
00478 new Point3f(nx,-ny,-n),
00479 new Point3f(fx,fy,-f),
00480 new Point3f(-fx,fy,-f),
00481 new Point3f(-fx,-fy,-f),
00482 new Point3f(fx,-fy,-f),
00483 };
00484
00485 int vertIndices[] = {0,1,2,0,2,3,1,0,4,1,4,5,0,3,7,0,7,4,5,2,1,5,6,2,6,7,3,6,3,2,5,4,7,5,7,6};
00486 IndexedTriangleArray tri =
00487 new IndexedTriangleArray(p3f.length,
00488 IndexedTriangleArray.COORDINATES,
00489 vertIndices.length);
00490
00491 tri.setCoordinates(0, p3f);
00492 tri.setCoordinateIndices(0,vertIndices);
00493 javax.media.j3d.Appearance app = new javax.media.j3d.Appearance();
00494 app.setTransparencyAttributes(
00495 new TransparencyAttributes(TransparencyAttributes.FASTEST, 0.5f)
00496 );
00497 Shape3D s3d = new Shape3D(tri, app);
00498 return s3d;
00499 }
00500
00505 public void setVisibleArea(boolean b) {
00506 if (switchVisibleArea_ != null){
00507 switchVisibleArea_.setWhichChild(b? Switch.CHILD_ALL:Switch.CHILD_NONE);
00508 }
00509 }
00510
00511 public boolean isVisible(){
00512 return switchVisibleArea_ != null && switchVisibleArea_.getWhichChild() == Switch.CHILD_ALL;
00513 }
00514
00521 public void setFocused(boolean b){
00522 if (b)
00523 resizeBoundingBox();
00524 super.setFocused(b);
00525 if (isFalse("alwaysVisible")) setVisibleArea(b);
00526 }
00527
00528 public boolean isCamera(){
00529 if(camera_ != null)
00530 return true;
00531 else
00532 return false;
00533 }
00534
00535 public Camera_impl getCamera(){
00536 if(isCamera())
00537 return camera_;
00538 else
00539 return null;
00540 }
00541
00542 private void cameraType(String cameraType){
00543 String old = getStr("cameraType", "NONE");
00544 if(!type_.equals("Vision") || old.equals(cameraType)) return;
00545
00546 if(cameraType.equals("NONE")){
00547 specValues_[3] = CameraType._NONE;
00548 }else if(cameraType.equals("COLOR")){
00549 specValues_[3] = CameraType._COLOR;
00550 }else if(cameraType.equals("MONO")){
00551 specValues_[3] = CameraType._MONO;
00552 }else if(cameraType.equals("DEPTH")){
00553 specValues_[3] = CameraType._DEPTH;
00554 }else if(cameraType.equals("COLOR_DEPTH")){
00555 specValues_[3] = CameraType._COLOR_DEPTH;
00556 }else if(cameraType.equals("MONO_DEPTH")){
00557 specValues_[3] = CameraType._MONO_DEPTH;
00558 }else{
00559 System.out.println("GrxSensorItem.propertyChanged() : unknown camera type : " + cameraType);
00560 return;
00561 }
00562 setProperty("cameraType", cameraType);
00563 if (model_ != null) model_.notifyModified();
00564 }
00565
00566 @Override
00567 public ValueEditType GetValueEditType(String key) {
00568 if(key.matches("type")) {
00569 return new ValueEditCombo(sensorTypeComboItem_);
00570 }else if(type_.equals("Vision") && key.equals("cameraType")){
00571 return new ValueEditCombo(cameraTypeComboItem_);
00572 }
00573 if(key.matches("alwaysVisible")){
00574 return new ValueEditCombo(booleanComboItem_);
00575 }
00576 return super.GetValueEditType(key);
00577 }
00578 }