TrendGraphModel.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, AIST, the University of Tokyo and General Robotix Inc.
00003  * All rights reserved. This program is made available under the terms of the
00004  * Eclipse Public License v1.0 which accompanies this distribution, and is
00005  * available at http://www.eclipse.org/legal/epl-v10.html
00006  * Contributors:
00007  * General Robotix Inc.
00008  * National Institute of Advanced Industrial Science and Technology (AIST) 
00009  */
00010 package com.generalrobotix.ui.view.graph;
00011 
00012 import java.util.*;
00013 
00014 import javax.vecmath.AxisAngle4d;
00015 import javax.vecmath.Matrix3d;
00016 
00017 import com.generalrobotix.ui.GrxTimeSeriesItem;
00018 import com.generalrobotix.ui.grxui.Activator;
00019 import com.generalrobotix.ui.item.GrxWorldStateItem;
00020 import com.generalrobotix.ui.item.GrxWorldStateItem.WorldStateEx;
00021 import com.generalrobotix.ui.item.GrxWorldStateItem.CharacterStateEx;
00022 import com.generalrobotix.ui.util.GrxDebugUtil;
00023 import com.generalrobotix.ui.view.graph.LogManager.LogHeader;
00024 
00031 public class TrendGraphModel
00032 {
00033         private TrendGraph[] trendGraph_;
00034         
00035     public  static final double TIME_SCALE = 1000000;   // タイムカウントの倍率(1μsec)
00036     private static final double MAX_DIV = 10;   // 時間軸の最大分割数
00037     private static final double LOG10 = Math.log(10);
00038 
00039     private long stepTimeCount_;    // 時間刻み幅(カウント)
00040 
00041     private double stepTime_;       // 時間刻み幅(秒)
00042     private double totalTime_;      // 総時間(秒)
00043     private double currentTime_;    // 現在時刻(秒)
00044 
00045     private double timeRange_;      // 時間レンジ(秒)
00046     private double markerPos_;      // 現在時刻マーカ位置(0.0から1.0で指定)
00047 
00048     private double baseTime_;       // グラフ左端時刻(秒)
00049 
00050     public int sampleCount_;   // グラフサンプル数
00051     public long baseCount_;    // データ開始位置
00052 
00053     private AxisInfo timeAxisInfo_; // 時間軸情報
00054 
00055     private HashMap<String, Integer > dataItemCount_; // データアイテムカウンタ
00056                                     // (どのデータ系列にいくつのデータアイテムが割り当てられているか)
00057 
00058     private HashMap<String, DataModel> dataModelMap_;   // データモデル一覧
00059     private DataModel[] dataModelArray_;    // データモデル一覧
00060     private HashMap<String, AttitudeDataModel> attitudeDataModelMap_;   
00061     
00062     private GrxWorldStateItem world_ = null;
00063 
00064     private boolean markerFixed_;   // 現在時刻マーカ固定フラグ
00065     private double fixedMarkerPos_; // 固定マーカ位置
00066 
00067    //private int mode_;  // モード
00068     private GraphPanel gPanel_= null;
00069     
00070     private long prevLogSize_ = -1;    
00071     
00075     public TrendGraphModel(int numGraph) {
00076         
00077         // 軸情報生成
00078         timeAxisInfo_ = new AxisInfo(0,0);
00079         timeAxisInfo_.min = 0;
00080         timeAxisInfo_.minLimitEnabled = true;
00081         timeAxisInfo_.maxLimitEnabled = true;
00082         timeAxisInfo_.unitXOfs = 12;
00083         timeAxisInfo_.unitYOfs = 0;
00084         timeAxisInfo_.unitLabel = "(sec)";
00085         timeAxisInfo_.markerColor = Activator.getDefault().getColor( "markerColor" );
00086         timeAxisInfo_.markerVisible = true;
00087 
00088         dataItemCount_ = new HashMap<String, Integer >();
00089         dataModelMap_ = new HashMap<String, DataModel>();
00090         attitudeDataModelMap_ = new HashMap<String, AttitudeDataModel>();
00091         dataModelArray_ = null;
00092       
00093         trendGraph_ = new TrendGraph[numGraph];
00094         for (int i = 0; i < trendGraph_.length; i ++) {
00095             StringBuffer graphName = new StringBuffer("Graph");
00096             graphName.append(i);
00097             trendGraph_[i] = new TrendGraph(this, graphName.toString());
00098         }
00099     }
00100 
00101     public int getNumGraph() {
00102         return trendGraph_.length;
00103     }
00104 
00105     public TrendGraph getTrendGraph(int index) {
00106         return trendGraph_[index];
00107     }
00108 
00109     public String getTrendGraphName(int index) {
00110         if (index < 0 || index >= trendGraph_.length) {
00111             throw new ArrayIndexOutOfBoundsException();
00112         }
00113         StringBuffer graphName = new StringBuffer("Graph");
00114         graphName.append(index);
00115         return graphName.toString();
00116     }
00117     
00118     public void worldTimeChanged(Time time) {
00119         setCurrentTime(time.getUtime());
00120         for (int i = 0; i < trendGraph_.length; i ++) {
00121             trendGraph_[i].repaint();
00122         }
00123     }
00124    
00125     // -----------------------------------------------------------------
00126     // メソッド
00132     public AxisInfo getTimeAxisInfo() {
00133         return timeAxisInfo_;
00134     }
00135 
00141     public void setStepTime(
00142         long stepTime
00143     ) {
00144         stepTimeCount_ = stepTime;
00145         stepTime_ = stepTimeCount_ / TIME_SCALE;
00146 
00147         sampleCount_ = (int)Math.floor(timeRange_ / stepTime_) + 2;  // サンプル数(前後2サンプルを追加)
00148         baseCount_ = Math.round(baseTime_ / stepTime_); //- 1; // データ開始位置
00149         
00150         // 全データ系列の更新
00151         Iterator<DataModel> itr = dataModelMap_.values().iterator();
00152         while (itr.hasNext()) {
00153             DataModel dm = (DataModel)itr.next();
00154             dm.dataSeries.setSize(sampleCount_);
00155             dm.dataSeries.setXStep(stepTime_);
00156             dm.dataSeries.setXOffset(baseCount_);
00157         }
00158         Iterator<AttitudeDataModel> itr0 = attitudeDataModelMap_.values().iterator();
00159         while (itr0.hasNext()) {
00160                 AttitudeDataModel ad = itr0.next();
00161                 for(int i=0; i<3; i++){
00162                         if(ad.rpySeries[i]!=null){
00163                                 ad.rpySeries[i].setSize(sampleCount_);
00164                                 ad.rpySeries[i].setXStep(stepTime_);
00165                                 ad.rpySeries[i].setXOffset(baseCount_);
00166                         }
00167                 }
00168         }
00169     }
00170 
00176     public void setTotalTime(double totalTime) {
00177         totalTime_ = totalTime;
00178         timeAxisInfo_.max = totalTime_; 
00179     }
00180 
00187     public void setRangeAndPos(
00188         double timeRange,
00189         double markerPos
00190     ) {
00191         timeRange_ = timeRange;
00192         fixedMarkerPos_ = markerPos;
00193         timeAxisInfo_.extent = timeRange_;
00194         _updateDiv();
00195         
00196         init();
00197     }
00198 
00204     public double getTimeRange() {
00205         return timeRange_;
00206     }
00207 
00213     public double getMarkerPos() {
00214         return fixedMarkerPos_;
00215     }
00216 
00222     public double getStepTime() {
00223         return stepTime_;
00224     }
00225 
00231     public double getTotalTime() {
00232         return totalTime_;
00233     }
00234 
00240     public void setCurrentTime(long currentTime) {
00241         currentTime_ = currentTime / TIME_SCALE;
00242 
00243         long oldBaseCount = baseCount_;
00244         long totalCount = Math.round(totalTime_ / stepTime_);
00245         markerFixed_ = (timeRange_ * fixedMarkerPos_ < totalTime_);
00246         if (markerFixed_) { 
00247             markerPos_ = fixedMarkerPos_;
00248             baseTime_ = currentTime_ - timeRange_ * markerPos_; // グラフ左端位置
00249             baseCount_ = Math.round(baseTime_ / stepTime_); // - 1; // データ開始位置
00250         } else {
00251             markerPos_ = currentTime_ / timeRange_;
00252             baseTime_ = 0;
00253             baseCount_ = 0;
00254         }
00255         
00256         timeAxisInfo_.markerPos = markerPos_;
00257         timeAxisInfo_.base = baseTime_;
00258                
00259         if (dataModelArray_ == null) {
00260             return;
00261         }
00262         
00263         if(totalCount==0)
00264                 return;
00265         
00266         // データを読み直す
00267         
00268         int diff = (int)(baseCount_ - oldBaseCount);
00269 
00270         // 全データ系列の移動
00271         Iterator<DataModel> itr = dataModelMap_.values().iterator();
00272         while (itr.hasNext()) {
00273             DataSeries ds = ((DataModel)itr.next()).dataSeries;
00274             ds.shift(diff);
00275         }
00276         Iterator<AttitudeDataModel> itr0 = attitudeDataModelMap_.values().iterator();
00277         while (itr0.hasNext()) {
00278                 AttitudeDataModel ad = itr0.next();
00279                 for(int i=0; i<3; i++){
00280                         if(ad.rpySeries[i]!=null){
00281                                 ad.rpySeries[i].shift(diff);
00282                         }
00283                 }
00284         }
00285         
00286         if(prevLogSize_ < totalCount)
00287         {
00288             int yet = (int)(baseCount_ + sampleCount_ - prevLogSize_);
00289             if(diff < yet)
00290                 diff = yet;
00291         }
00292         prevLogSize_ = totalCount;
00293 
00294         if (diff > 0) {
00295            if (diff >= sampleCount_) {
00296                 _getData(baseCount_, 0, sampleCount_);
00297             } else {
00298                 _getData(baseCount_, sampleCount_ - diff, diff);
00299             }
00300         } else {
00301             if (-diff >= sampleCount_) {
00302                 _getData(baseCount_, 0, sampleCount_);
00303             } else {
00304                 _getData(baseCount_, 0, -diff);
00305             }
00306         }
00307     }
00308 
00315     public DataSeries addDataItem(
00316         DataItem dataItem
00317     ) {
00318         DataSeries ds;
00319         DataModel dm;
00320 
00321         String key = dataItem.toString();
00322         Integer l = dataItemCount_.get(key);
00323         if (l == null) {    // 初めてのデータアイテム?
00324             if(key.contains("attitude")){
00325                 AttitudeDataModel attitudeDataModel = attitudeDataModelMap_.get(dataItem.getAttributePath());
00326                 if(attitudeDataModel==null){
00327                         attitudeDataModel = new AttitudeDataModel();
00328                     attitudeDataModelMap_.put(dataItem.getAttributePath(),attitudeDataModel);
00329                 }
00330                 ds = new DataSeries(sampleCount_, baseCount_ * stepTime_, stepTime_ );
00331                 attitudeDataModel.setRPYSeries(dataItem.index, ds);
00332                 for(int i=0; i<4; i++){
00333                         DataItem di = new DataItem(dataItem.object, dataItem.node, dataItem.attribute, i, "");
00334                         if(dataModelMap_.get(di.toString())==null){
00335                                 DataSeries dataSeries = new DataSeries(sampleCount_, baseCount_ * stepTime_, stepTime_ );
00336                                 dm = new DataModel(di, dataSeries);
00337                                 dataModelMap_.put(di.toString(), dm);
00338                                 attitudeDataModel.setAxisAngleSeries(i,dataSeries);
00339                         }
00340                 }
00341                 dataItemCount_.put(key, new Integer(1));  
00342             }else{
00343                     dataItemCount_.put(key, new Integer(1));
00344                     ds = new DataSeries(
00345                         sampleCount_,
00346                         baseCount_ * stepTime_, // baseTime_, ★これではダメ
00347                         stepTime_
00348                     );
00349                     dm = new DataModel(dataItem, ds);
00350                     dataModelMap_.put(key, dm);
00351             }
00352             dataModelArray_ = new DataModel[dataModelMap_.size()];
00353             dataModelMap_.values().toArray(dataModelArray_);
00354         } else {
00355                 dataItemCount_.put(key, ++l);
00356                 if(key.contains("attitude"))
00357                         ds = attitudeDataModelMap_.get(dataItem.getAttributePath()).rpySeries[dataItem.index];
00358                 else
00359                         ds = ((DataModel)dataModelMap_.get(key)).dataSeries;
00360         }
00361 
00362         initGetData();
00363         prevLogSize_ = -1;
00364         return ds;
00365     }
00366 
00372     public void removeDataItem(
00373         DataItem dataItem
00374     ) {
00375         String key = dataItem.toString();
00376         Integer l = dataItemCount_.get(key);   // カウント取得
00377         dataItemCount_.put(key, --l);    // カウントを減らす
00378         if(key.contains("attitude")){
00379                 if( l<= 0 ){
00380                         dataItemCount_.remove(key);
00381                         attitudeDataModelMap_.get(dataItem.getAttributePath()).setRPYSeries(dataItem.index, null);
00382                 }
00383                 AttitudeDataModel attitudeDataModel = attitudeDataModelMap_.get(dataItem.getAttributePath());
00384                 if(attitudeDataModel.isDisused()){
00385                         attitudeDataModelMap_.remove(dataItem.getAttributePath());
00386                         for(int i=0; i<4; i++)
00387                                 dataModelMap_.remove(dataItem.getAttributePath()+"."+i);
00388                         int size = dataModelMap_.size();
00389                     if (size <= 0) {
00390                         dataModelArray_ = null;
00391                     } else {
00392                         dataModelArray_ = new DataModel[size];
00393                         dataModelMap_.values().toArray(dataModelArray_);
00394                     }
00395                 }
00396         }else{
00397                 if (l <= 0) {    // データ系列に対応するデータアイテムがなくなった?
00398                     dataItemCount_.remove(key); // カウント除去
00399                     dataModelMap_.remove(key); // データ系列除去
00400                     int size = dataModelMap_.size();
00401                     if (size <= 0) {
00402                         dataModelArray_ = null;
00403                     } else {
00404                         dataModelArray_ = new DataModel[size];
00405                         dataModelMap_.values().toArray(dataModelArray_);
00406                     }
00407                 }
00408         }
00409         initGetData();
00410         prevLogSize_ = -1;
00411     }
00412 
00413     // -----------------------------------------------------------------
00414     // プライベートメソッド
00419     private void _updateDiv() {
00420         double sMin = timeAxisInfo_.extent / MAX_DIV;
00421         int eMin = (int)Math.floor(Math.log(sMin) / LOG10);
00422         double step = 0;
00423         String format = "0";
00424         int e = eMin;
00425         boolean found = false;
00426         while (!found) {
00427             int m = 1;
00428             for (int i = 1; i <= 3; i++) {
00429                 step = m * Math.pow(10.0, e);
00430                 if (sMin <= step) { // && step <= sMax) {
00431                     if (e < 0) {
00432                         char[] c = new char[-e + 2];
00433                         c[0] = '0';
00434                         c[1] = '.';
00435                         for (int j = 0; j < -e; j++) {
00436                             c[j + 2] = '0';
00437                         }
00438                         format = new String(c);
00439                     }
00440                     found = true;
00441                     break;
00442                 }
00443                 m += (2 * i - 1);
00444             }
00445             e++;
00446         }
00447         timeAxisInfo_.tickEvery = step;
00448         timeAxisInfo_.labelEvery = step;
00449         timeAxisInfo_.gridEvery = step;
00450         timeAxisInfo_.labelFormat = format;
00451     }
00452 
00453     public void setWorldState(GrxWorldStateItem world) {
00454         world_ = world;
00455         init();
00456     }
00457     
00458     //  初期化関数  //
00459     private void init(){
00460         baseTime_ = 0;
00461         currentTime_ = 0;
00462         baseCount_ = 0;
00463         prevLogSize_ = -1;
00464         if(world_ != null){
00465                 Double time = ((GrxTimeSeriesItem)world_).getTime(world_.getLogSize()-1);
00466                 if(time != null)
00467                         setTotalTime(time);
00468                 else
00469                         setTotalTime(0);
00470                 try {
00471                                 double step = world_.getDbl("logTimeStep", 0.001);
00472                                 setStepTime((long)(1000000*step));
00473                         } catch (Exception e) {
00474                                 GrxDebugUtil.printErr("Couldn't parse log step time.", e);
00475                         }
00476                         initGetData();
00477         }else{
00478                 setTotalTime(0);
00479                 setStepTime(1000);
00480         }
00481     }
00482     
00483     public void initGetData(){
00484         if(dataModelArray_ != null && world_ != null)
00485                 if (world_.isUseDsik()){
00486                     world_.logger_.initGetData(dataModelArray_);
00487                 }
00488     }
00489     
00490     private void _getData(long origin, int offset, int count){
00491         if(world_ == null){
00492             return;
00493         } else if (world_.isUseDsik()){
00494             world_.logger_.getData(origin, offset, count);
00495         }else{
00496                 int changePos = world_.getChangePosition();
00497                 int counter = changePos - ((int)origin + offset);
00498         
00499                 // ログの記録方式がメモリ方式からファイル方式へスイッチした場合処理
00500                 if( changePos >= 0 ){
00501                     if( counter <= 0 ){
00502                         world_.logger_.getData(-offset-counter, offset, count, dataModelArray_);
00503                         return;
00504                     }
00505                     //ログの記録方式がファイル方式とメモリ方式で混在する場合の境界処理
00506                     if( counter <= count ){
00507                         count -= counter;  
00508                         world_.logger_.getData(-offset-counter, offset + counter, count, dataModelArray_);
00509                         count = counter;  
00510                     }
00511                 }
00512                 
00513                 WorldStateEx refWorld = world_.getValue( (int)origin + offset );
00514                 if(refWorld == null){
00515                     for(int h = 0; h < dataModelArray_.length; ++h){
00516                         DataSeries ds = dataModelArray_[h].dataSeries;
00517                         double[] dbArray = ds.getData();
00518                         int localOffset = (ds.getHeadPos() + offset) % dbArray.length;
00519                         for (int i = 0; i < count; ++i, ++localOffset){
00520                             if(localOffset +i >= dbArray.length){
00521                                     localOffset = 0;
00522                             }
00523                             dbArray[localOffset] = Double.NaN;
00524                         }                
00525                     }            
00526                 } else {
00527                     // メモリーデータから表示したいラインの要素を抽出する処理
00528                     for(int h = 0; h < dataModelArray_.length; ++h){
00529                         long recNo = origin + offset; // レコード番号
00530                         DataItem localDataItem = dataModelArray_[h].dataItem;
00531                         CharacterStateEx refCharacter = refWorld.get(localDataItem.object);
00532                         CharacterStateEx localCharacter = refCharacter;
00533                         DataSeries ds = dataModelArray_[h].dataSeries;
00534                         double[] dbArray = ds.getData();
00535                         int localOffset = (ds.getHeadPos() + offset) % dbArray.length;
00536                         int index = world_.logger_.getIndex(localDataItem.object,
00537                                 localDataItem.node + "." + localDataItem.attribute + (localDataItem.index >= 0 ? "." + localDataItem.index : "") );
00538                         ArrayList<Integer> arryLength = new ArrayList<Integer>();
00539                         arryLength.add(refCharacter.position.length * 7);
00540                         arryLength.add(arryLength.get(0) + refCharacter.sensorState.q.length);
00541                         arryLength.add(arryLength.get(1) + refCharacter.sensorState.u.length);
00542                         if(refCharacter.sensorState.force.length == 0){
00543                             arryLength.add( arryLength.get(2));
00544                         } else {
00545                             arryLength.add( arryLength.get(2) +
00546                                             refCharacter.sensorState.force.length * refCharacter.sensorState.force[0].length);
00547                         }
00548         
00549                         if(refCharacter.sensorState.rateGyro.length == 0){
00550                             arryLength.add( arryLength.get(3));
00551                         } else {
00552                             arryLength.add( arryLength.get(3) +
00553                                             refCharacter.sensorState.rateGyro.length * refCharacter.sensorState.rateGyro[0].length);
00554                         }
00555                         
00556                         if(refCharacter.sensorState.accel.length == 0){
00557                             arryLength.add( arryLength.get(4));
00558                         } else {
00559                             arryLength.add( arryLength.get(4) +
00560                                             refCharacter.sensorState.accel.length * refCharacter.sensorState.accel[0].length);
00561                         }
00562                         if(refCharacter.sensorState.range.length == 0){
00563                             arryLength.add( arryLength.get(5));
00564                         } else {
00565                             arryLength.add( arryLength.get(5) +
00566                                             refCharacter.sensorState.range.length * refCharacter.sensorState.range[0].length);
00567                         }
00568         
00569                         for (int i = 0; i < count; ++i, ++recNo, ++localOffset){
00570                             if(localOffset >= dbArray.length){
00571                                     localOffset = 0;
00572                             }
00573                             if(recNo < 0 || recNo >= world_.getLogSize() || localCharacter == null){
00574                                 dbArray[localOffset] = Double.NaN;
00575                                 continue;
00576                             }
00577                             if (index <= arryLength.get(0)){
00578                                 
00579                                 
00580                             } else if  (index <= arryLength.get(2)){
00581                                 if( (index - 1) % 2 == 0 ){
00582                                     dbArray[localOffset] = localCharacter.sensorState.q[(index - arryLength.get(0) - 1)/2];
00583                                 } else {
00584                                     dbArray[localOffset] = localCharacter.sensorState.u[(index - arryLength.get(0) - 2)/2];
00585                                 }
00586                             } else if  (index <= arryLength.get(3) && localCharacter.sensorState.force.length > 0){
00587                                 int dim1 = (index - arryLength.get(2) - 1) / localCharacter.sensorState.force[0].length ;
00588                                 int dim2 = (index - arryLength.get(2) - 1) % localCharacter.sensorState.force[0].length ;
00589                                 dbArray[localOffset] = localCharacter.sensorState.force[dim1][dim2];  
00590                     
00591                             } else if  (index <= arryLength.get(4) && localCharacter.sensorState.rateGyro.length > 0){
00592                                 int dim1 = (index - arryLength.get(3) - 1) / localCharacter.sensorState.rateGyro[0].length ;
00593                                 int dim2 = (index - arryLength.get(3) - 1) % localCharacter.sensorState.rateGyro[0].length ;
00594                                 dbArray[localOffset] = localCharacter.sensorState.rateGyro[dim1][dim2];     
00595                             } else if  (index <= arryLength.get(5) && localCharacter.sensorState.accel.length > 0){
00596                                 int dim1 = (index - arryLength.get(4) - 1) / localCharacter.sensorState.accel[0].length ;
00597                                 int dim2 = (index - arryLength.get(4) - 1) % localCharacter.sensorState.accel[0].length ;
00598                                 dbArray[localOffset] = localCharacter.sensorState.accel[dim1][dim2];     
00599                             } else if(localCharacter.sensorState.range.length > 0) {
00600                                 int dim1 = (index - arryLength.get(5) - 1) / localCharacter.sensorState.range[0].length ;
00601                                 int dim2 = (index - arryLength.get(5) - 1) % localCharacter.sensorState.range[0].length ;
00602                                 dbArray[localOffset] = localCharacter.sensorState.range[dim1][dim2];     
00603                             }
00604                             localCharacter = world_.getValue( (int)recNo ).get(localDataItem.object);
00605                         }
00606                     }                    
00607                 }
00608         }
00609         
00610         //姿勢データをロール、ピッチ、ヨーに変換  //
00611         Iterator<AttitudeDataModel> it = attitudeDataModelMap_.values().iterator();
00612         while(it.hasNext()){
00613                 AttitudeDataModel attitudeDataModel = it.next();
00614                 double[][] aa = new double[4][];
00615                 int[] aapos = new int[4];
00616                 int[] aaSize = new int[4];
00617                 for(int i=0; i<4; i++){
00618                         DataSeries ds = attitudeDataModel.axisAngleSeries[i];
00619                         aaSize[i] = ds.getSize();
00620                         aapos[i] = (ds.getHeadPos() + offset) % aaSize[i];
00621                         aa[i] = attitudeDataModel.axisAngleSeries[i].getData();
00622                 }
00623                 double[][] rpy = {null, null, null};
00624                 int[] rpypos = new int[3];
00625                 int[] rpySize = new int[3];
00626                 for(int i=0; i<3; i++){
00627                         DataSeries ds = attitudeDataModel.rpySeries[i];
00628                         if(ds!=null){
00629                                 rpySize[i] = ds.getSize();
00630                                 rpypos[i] = (ds.getHeadPos() + offset) % rpySize[i];
00631                                 rpy[i] = attitudeDataModel.rpySeries[i].getData();
00632                         }
00633                 }
00634                 for (int i = 0; i < count; i++) {
00635                 if(aa[0][aapos[0]] == Double.NaN || aa[1][aapos[1]] == Double.NaN || aa[2][aapos[2]] == Double.NaN || aa[3][aapos[3]] == Double.NaN){
00636                         if(rpy[0]!=null) rpy[0][rpypos[0]] = Double.NaN;
00637                         if(rpy[1]!=null) rpy[1][rpypos[1]] = Double.NaN;
00638                         if(rpy[2]!=null) rpy[2][rpypos[2]] = Double.NaN;
00639                 }else
00640                         AxisAngleToRPY(aa, rpy, aapos, rpypos);    
00641                 for(int j=0; j<4; j++){
00642                         if(aapos[j] < aaSize[j]-1)
00643                         aapos[j]++;
00644                     else
00645                         aapos[j]=0;
00646                 }
00647                 for(int j=0; j<3; j++){
00648                         if(rpypos[j] < rpySize[j]-1)
00649                         rpypos[j]++;
00650                     else
00651                         rpypos[j]=0;
00652                 }
00653                 }
00654         }
00655     }
00656     
00657     public void updateGraph(){
00658         if(world_!=null){
00659                 Double time = world_.getTime();
00660                 if(time!=null)
00661                         setCurrentTime(new Time(time).getUtime());
00662                 else
00663                         setCurrentTime(0);
00664         }else
00665                 setCurrentTime(0);
00666         gPanel_.redraw(gPanel_.getLocation().x,gPanel_.getLocation().y,gPanel_.getSize().x,gPanel_.getSize().y,true);
00667     }
00668 
00669         public void clearDataItem() {           
00670                 for (int i = 0; i < getNumGraph(); i++) {
00671                         TrendGraph t = getTrendGraph(i);
00672                         t.clearDataItem();
00673                 }
00674         }
00675 
00676         public void setPanel(GraphPanel gPanel) {
00677                 gPanel_ = gPanel;
00678                 
00679         }
00680 
00681         private void AxisAngleToRPY(double[][] aa, double[][] rpy, int[] aapos, int[] rpypos){
00682                 Matrix3d m = new Matrix3d();
00683                 m.set(new AxisAngle4d(aa[0][aapos[0]], aa[1][aapos[1]], aa[2][aapos[2]], aa[3][aapos[3]]));
00684                 
00685                 // hrpUtil/TVmet3d.cpp   からコピー  //
00686                 double roll, pitch, yaw;    
00687                 if ((Math.abs(m.m00)<Math.abs(m.m20)) && (Math.abs(m.m10)<Math.abs(m.m20))) {
00688                 double sp = -m.m20;
00689                 if (sp < -1.0) {
00690                     sp = -1;
00691                 } else if (sp > 1.0) {
00692                     sp = 1;
00693                 }
00694                 pitch = Math.asin(sp); // -pi/2< p < pi/2
00695                 
00696                 roll = Math.atan2(sp*m.m01+m.m12,  // -cp*cp*sr*cy
00697                              sp*m.m02-m.m11); // -cp*cp*cr*cy
00698                 
00699                 if (m.m00>0.0) { // cy > 0
00700                     if(roll < 0.0)
00701                         roll += Math.PI;
00702                     else
00703                         roll -= Math.PI;
00704                 }
00705                 double sr=Math.sin(roll), cr=Math.cos(roll);
00706                 if (sp > 0.0) {
00707                     yaw = Math.atan2(sr*m.m11+cr*m.m12, //sy*sp
00708                                 sr*m.m01+cr*m.m02);//cy*sp
00709                 } else {
00710                     yaw = Math.atan2(-sr*m.m11-cr*m.m12,
00711                                 -sr*m.m01-cr*m.m02);
00712                 }
00713             } else {
00714                 yaw = Math.atan2(m.m10, m.m00);
00715                 double sa = Math.sin(yaw);
00716                 double ca = Math.cos(yaw);
00717                 pitch = Math.atan2(-m.m20, ca*m.m00+sa*m.m10);
00718                 roll = Math.atan2(sa*m.m02-ca*m.m12, -sa*m.m01+ca*m.m11);
00719             }
00720                 
00721                 if(rpy[0]!=null) rpy[0][rpypos[0]] = roll;
00722                 if(rpy[1]!=null) rpy[1][rpypos[1]] = pitch;
00723                 if(rpy[2]!=null) rpy[2][rpypos[2]] = yaw;
00724         }
00725 
00726         private class AttitudeDataModel{
00727                 private DataSeries[] rpySeries = {null, null, null};
00728                 private DataSeries[] axisAngleSeries = {null, null, null, null};
00729                 
00730                 public AttitudeDataModel(){
00731                 }
00732                 
00733                 private void setAxisAngleSeries(int i, DataSeries dataSeries){
00734                         axisAngleSeries[i] = dataSeries;
00735                 }
00736                 
00737                 private void setRPYSeries(int i, DataSeries dataSeries){
00738                         rpySeries[i] = dataSeries;
00739                 }
00740                 
00741                 private boolean isDisused(){
00742                         return rpySeries[0]==null && rpySeries[1]==null && rpySeries[2]==null ;
00743                 }
00744         }
00745 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Sun Apr 2 2017 03:43:57