LogManager.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  */
00018 package com.generalrobotix.ui.view.graph;
00019 
00020 import java.util.*;
00021 import java.io.*;
00022 import java.util.zip.*;
00023 
00024 import jp.go.aist.hrp.simulator.CollisionPoint;
00025 
00038 public class LogManager {
00039     //--------------------------------------------------------------------
00040     // 定数
00041     public static final String COLLISION_LOG_NAME = "CollisionData.col";
00042     public static final String COLLISION_LOG_DAT_NAME = "CollisionData.dat";
00043     private static final String POSTFIX = ".tmp";
00044     private static final int COLLISION_DATA_SIZE = 6 * 4 + 1 * 8;
00045     private static final String NONAME_OBJECT = "_noname";
00046 
00047     //--------------------------------------------------------------------
00048     // インスタンス変数
00049     private Hashtable<String, LogHeader> header_;
00050     private Hashtable<String, DataOutputStream> writeFile_;
00051     private Hashtable<String, RandomAccessFile> readFile_;
00052     private Map<String, Map<String, Integer> > indexMapMap_;
00053     private CollisionLogHeader collisionLog_;
00054     private Time time_;
00055     private DataOutputStream collisionOut_ = null;
00056     private RandomAccessFile collisionIn_ = null;
00057     private DataOutputStream collisionDatOut_ = null;
00058     private RandomAccessFile collisionDatIn_ = null;
00059     private String collisionLogPath_ = new String(COLLISION_LOG_NAME);
00060     private String collisionLogDatPath_ = new String(COLLISION_LOG_DAT_NAME);
00061 
00062         private String tmpdir;
00063 
00064     //--------------------------------------------------------------------
00065     // 公開メソッド
00066     public static void main(String[] args) {
00067         LogManager log = new LogManager();
00068         log.init();
00069         try {
00070             log.addLogObject("test", new String[] {
00071                     "test1", "float", "test2", "float[3]"
00072             });
00073         } catch (LogFileFormatException ex) {
00074             ex.printStackTrace();
00075         }
00076     }
00077 
00078     public LogManager(){
00079         
00080     }
00081     
00082     public LogManager(LogManager logger) {
00083         String tmpdir = System.getProperty("TEMP");
00084         if (logger != null) {
00085             if(tmpdir != null)
00086                 setTempDir(tmpdir);
00087             _initTempInstance(logger);
00088         }
00089     }
00090 
00094     public void init() {
00095         header_ = new Hashtable<String, LogHeader>();
00096         indexMapMap_ = new HashMap<String, Map<String, Integer>>();
00097         time_ = new Time();
00098         closeReads();
00099     }
00100 
00104     public void closeReads() {
00105         try{
00106             closeAsRead();
00107             closeCollisionLogAsRead();
00108         } catch (IOException ex){
00109             ex.printStackTrace();
00110         } catch (Exception ex){
00111             ex.printStackTrace();
00112         }
00113     }
00114     
00118     public void closeWrites() {
00119         try{
00120             closeAsWrite();
00121             closeCollisionLogAsWrite();
00122         } catch (IOException ex){
00123             ex.printStackTrace();
00124         } catch (Exception ex){
00125             ex.printStackTrace();
00126         }
00127     }
00128 
00129 
00130     private String getTempFilePath(String objectName) {
00131         // String tmpdir = System.getProperty("TEMP");
00132         if (tmpdir != null) {
00133             return tmpdir + File.separator + objectName + POSTFIX;
00134         } else {
00135             return objectName + POSTFIX;
00136         }
00137     }
00138     
00139     public String getIntegrationMethodStr(){
00140         Enumeration elements = header_.elements();
00141         if (!elements.hasMoreElements()) return "";
00142         LogHeader header = (LogHeader)elements.nextElement();
00143         return int2StrIntegrationMethod(header.method_);
00144     }
00145 
00149     public void getSimulationTime(SimulationTime time) {
00150         // ヘッダのシミュレーション時間に関する項目はすべてのオブジェクトに
00151         // 共通のはずだから、1つだけヘッダ情報を取り出してSimulationTime
00152         // に変換
00153         Enumeration elements = header_.elements();
00154         if (!elements.hasMoreElements()) return;
00155         LogHeader header = (LogHeader)elements.nextElement();
00156         //time.totalTime_.setUtime(header.totalTime_);
00157         time.totalTime_.setUtime(header.endTime_ - header.startTime_);
00158         time.startTime_.setUtime(header.startTime_);
00159         time.timeStep_.setUtime(header.timeStep_);
00160     }
00161     
00166     public void addLogObject(String objectName, String[] format) throws LogFileFormatException {
00167         LogHeader header = new LogHeader(objectName, format);
00168         header_.put(objectName, header);
00169         _makeIndexMapMap(header);
00170     }
00171 
00175     public void initCollisionLog(SimulationTime time) {
00176         collisionLog_ = new CollisionLogHeader(time);
00177     }
00178 
00179     public void extendTime(SimulationTime time){
00180         collisionLog_.totalTime_ = time.totalTime_.getUtime();
00181     }
00182     
00188     public void openAsWrite(SimulationTime time, String method) throws IOException {
00189         writeFile_ = new Hashtable<String, DataOutputStream>();
00190         for (Enumeration elements = header_.elements(); elements.hasMoreElements();) {
00191             try {
00192                 LogHeader header = (LogHeader) elements.nextElement();
00193                 header.totalTime_ = time.totalTime_.getUtime();
00194                 header.startTime_ = time.startTime_.getUtime();
00195                 header.timeStep_ = time.timeStep_.getUtime();
00196                 header.endTime_ = 0;
00197                 header.method_ = str2IntIntegrationMethod(method);
00198                 header.numRecords_ = 0;
00199                 // ヘッダの書込み
00200                 DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(getTempFilePath(header.objectName_))));
00201 
00202                 header.output(out);
00203                 writeFile_.put(header.objectName_, out);
00204             } catch (IOException ex) {
00205                 for (Enumeration elms = writeFile_.elements(); elms.hasMoreElements();) {
00206                     DataOutputStream out = (DataOutputStream) elms.nextElement();
00207                     out.close();
00208                 }
00209                 throw ex;
00210             }
00211         }
00212     }
00213 
00217     public double closeAsWrite() throws IOException {
00218         if(writeFile_ == null)
00219             return 0;
00220         for (Enumeration elements = header_.elements(); elements.hasMoreElements();) {
00221             LogHeader header = (LogHeader) elements.nextElement();
00222             DataOutputStream out = (DataOutputStream) writeFile_.get(header.objectName_);
00223             out.close();
00224 
00225             // ヘッダに終了時間を書き込む
00226             header.endTime_ = time_.getUtime();
00227             RandomAccessFile file = new RandomAccessFile(getTempFilePath(header.objectName_), "rw");
00228             header.outEndTime(file); // 終了時間までシーク
00229             file.close();
00230         }
00231         writeFile_ = null;
00232         return time_.getDouble();
00233     }
00234 
00235     public void openAsRead() throws IOException, FileOpenFailException {
00236         readFile_ = new Hashtable<String, RandomAccessFile>();
00237         for (Enumeration elements = header_.elements(); elements.hasMoreElements();) {
00238             LogHeader header = (LogHeader) elements.nextElement();
00239             RandomAccessFile file = null;
00240             try{
00241                 file = new RandomAccessFile(getTempFilePath(header.objectName_), "r");
00242             }catch (IOException ex){
00243                 throw new FileOpenFailException(ex.getMessage());
00244             }
00245             readFile_.put(header.objectName_, file);
00246         }
00247     }
00248 
00249     public void closeAsRead() throws IOException {
00250         if (readFile_ == null)
00251             return;
00252         for (Enumeration elements = readFile_.elements(); elements.hasMoreElements();) {
00253             RandomAccessFile file = (RandomAccessFile) elements.nextElement();
00254             file.close();
00255         }
00256         readFile_ = null;
00257     }
00258 
00259     public void openCollisionLogAsWrite() throws IOException {
00260         collisionOut_ = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(collisionLogPath_)));
00261         collisionDatOut_ = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(collisionLogDatPath_)));
00262         collisionLog_.currentPos_ = 0;
00263         collisionLog_.position_.clear();
00264         collisionLog_.position_.add(0);
00265         collisionLog_.numRecords_ = 0;
00266         collisionLog_.createLogHeader(collisionOut_);
00267     }
00268 
00269     public void openCollisionLogAsRead() throws IOException, FileNotFoundException {
00270         collisionIn_ = new RandomAccessFile(collisionLogPath_, "r");
00271         collisionDatIn_ = new RandomAccessFile(collisionLogDatPath_, "r");
00272     }
00273 
00274     public void closeCollisionLogAsRead() throws IOException {
00275         if ( collisionDatIn_ != null ){
00276             collisionDatIn_.close();
00277             collisionDatIn_ = null;
00278         }
00279         if ( collisionIn_ != null ){
00280             collisionIn_.close();
00281             collisionIn_ = null;
00282         }
00283     }
00284 
00285     public void closeCollisionLogAsWrite() throws IOException {
00286         if(collisionOut_ == null || collisionDatOut_ == null )
00287             return;
00288         collisionDatOut_.close();
00289         collisionOut_.close();
00290         collisionDatOut_ = null;
00291         collisionOut_ = null;
00292 
00293         // recordSize_を書き込む
00294         collisionLog_.endTime_ = time_.getUtime();
00295         try {
00296             RandomAccessFile file = new RandomAccessFile(collisionLogPath_, "rw");
00297             collisionLog_.outTimesAndRecalculation(file);
00298             collisionLog_.outPositions(file);
00299             file.close();
00300         } catch (FileNotFoundException ex) {
00301             throw new IOException();
00302         }
00303     }
00304 
00305     public String[] getDataFormat(String objectName) {
00306         LogHeader header = (LogHeader) header_.get(objectName);
00307         if (header == null)
00308             return null;
00309 
00310         int size = header.dataFormat_.length / 2;
00311         String[] format = new String[size];
00312         for (int i = 0; i < size; i++) {
00313             format[i] = header.dataFormat_[i * 2];
00314         }
00315         return format;
00316     }
00317 
00318     public void setTime(Time time) {
00319         time_.set(time);
00320     }
00321 
00322     public void put(String objectName, float[] data) throws LogFileOutputException, IOException {
00323         LogHeader header = (LogHeader) header_.get(objectName);
00324 
00325         if (data.length == (header.recordSize_ / LogHeader.FLOAT_DATA_SIZE)) {
00326             try {
00327                 DataOutputStream out = (DataOutputStream) writeFile_.get(objectName);
00328                 for (int i = 0; i < data.length; i++) {
00329                     out.writeFloat(data[i]);
00330                 }
00331                 out.flush();
00332             } catch (IOException ex) {
00333                 closeAsWrite();
00334                 throw ex;
00335             }
00336             header.numRecords_++;
00337         } else {
00338             throw new LogFileOutputException("data length error.");
00339         }
00340     }
00341     
00342     public void putCollisionPointData(CollisionPoint[] data) throws IOException {
00343         // int frameNum = (int)(time_.getUtime() / collisionLog_.timeStep_);
00344         // System.out.println("putCollisionPointData(): frameNum=" +
00345         // frameNum+":"+time_.getUtime()+":"+collisionLog_.timeStep_);
00346 
00347         for (int i = 0; i < data.length; i++) {
00348             collisionDatOut_.writeFloat((float) data[i].normal[0]);
00349             collisionDatOut_.writeFloat((float) data[i].normal[1]);
00350             collisionDatOut_.writeFloat((float) data[i].normal[2]);
00351             collisionDatOut_.writeFloat((float) data[i].position[0]);
00352             collisionDatOut_.writeFloat((float) data[i].position[1]);
00353             collisionDatOut_.writeFloat((float) data[i].position[2]);
00354             collisionDatOut_.writeDouble(data[i].idepth);
00355         }
00356         collisionDatOut_.flush();
00357         collisionLog_.currentPos_ += data.length * COLLISION_DATA_SIZE;
00358         collisionLog_.position_.add(collisionLog_.currentPos_);
00359         collisionLog_.numRecords_++;
00360     }
00361 
00362     public void jointLogs() throws IOException {
00363         String srcDir = tmpdir;
00364         
00365         long leftSize = 0;
00366         byte[] buffer = new byte[1024 * 1024];
00367         
00368         // 各モデルログファイルの結合処理
00369         for (Enumeration elements = header_.elements(); elements.hasMoreElements();) {
00370             LogHeader header = (LogHeader) elements.nextElement();
00371             String srcFilePath = new String( srcDir + File.separator + header.objectName_ + POSTFIX);
00372             File srcFile = new File(srcFilePath);
00373             FileInputStream srcInStream = new FileInputStream(srcFile);
00374             srcInStream.skip(header.headerSize_);
00375             leftSize = srcFile.length() - header.headerSize_;
00376             header.numRecords_ += leftSize / header.recordSize_; 
00377             DataOutputStream destOutStream = writeFile_.get(header.objectName_);
00378             while (leftSize > 0) {
00379                 int readSize = srcInStream.read(buffer);
00380                 destOutStream.write(buffer, 0, readSize);
00381                 leftSize -= readSize;
00382             }
00383             srcInStream.close();
00384         }
00385         
00386         // collisionLogの結合
00387         File col = new File(srcDir + File.separator + COLLISION_LOG_NAME);
00388         DataInputStream inCol = new DataInputStream(new FileInputStream(col));
00389         CollisionLogHeader localColLog = new CollisionLogHeader();
00390         
00391         try{
00392             localColLog.input(inCol);
00393         } catch ( LogFileFormatException ex){
00394             ex.printStackTrace();
00395         } catch ( IOException ex){
00396             throw ex;
00397         } finally {
00398             inCol.close();
00399         }
00400         
00401         collisionLog_.joinCollisionLogHeader(localColLog);
00402 
00403         // collisionLogDatの結合
00404         File colData = new File(srcDir + File.separator + COLLISION_LOG_DAT_NAME);
00405         FileInputStream fileInStream = new FileInputStream(colData);
00406         leftSize = colData.length();
00407         while (leftSize > 0) {
00408             int readSize = fileInStream.read(buffer);
00409             collisionDatOut_.write(buffer, 0, readSize);
00410             leftSize -= readSize;
00411         }
00412         fileInStream.close();
00413     }
00414 
00415     
00416     public void separateLogs(final int changePos) throws IOException {
00417         String srcDir = tmpdir;
00418                 
00419         long leftSize = 0;
00420         byte[] buffer = new byte[1024 * 1024];
00421         
00422         // 各モデルログファイルの分離処理
00423         for (Enumeration elements = header_.elements(); elements.hasMoreElements();) {
00424             LogHeader header = (LogHeader) elements.nextElement();
00425             String srcFilePath = new String( srcDir + File.separator + header.objectName_ + POSTFIX);
00426             File srcFile = new File(srcFilePath);
00427             FileInputStream srcInStream = new FileInputStream(srcFile);
00428             srcInStream.skip(header.headerSize_ + header.recordSize_ * changePos);
00429             leftSize = srcFile.length() - header.headerSize_ - header.recordSize_ * changePos;
00430             DataOutputStream destOutStream = writeFile_.get(header.objectName_);
00431             while (leftSize > 0) {
00432                 int readSize = srcInStream.read(buffer);
00433                 destOutStream.write(buffer, 0, readSize);
00434                 leftSize -= readSize;
00435             }
00436             srcInStream.close();
00437         }
00438         
00439         // this_.collisionLogの分離
00440         File col = new File(srcDir + File.separator + COLLISION_LOG_NAME);
00441         DataInputStream inCol = new DataInputStream(new FileInputStream(col));
00442         CollisionLogHeader localColLog = new CollisionLogHeader();
00443         
00444         try{
00445             localColLog.input(inCol);
00446         } catch ( LogFileFormatException ex){
00447             ex.printStackTrace();
00448         } catch ( IOException ex){
00449             throw ex;
00450         } finally {
00451             inCol.close();
00452         }
00453         
00454         collisionLog_.separateCollisionLogHeader(localColLog,changePos);
00455 
00456         // this_.collisionLogDatの分離
00457         final int offset = collisionLog_.position_.get(changePos);
00458         File colData = new File(srcDir + File.separator + COLLISION_LOG_DAT_NAME);
00459         FileInputStream fileInStream = new FileInputStream(colData);
00460         fileInStream.skip( offset );
00461         leftSize = colData.length() - offset;
00462         while (leftSize > 0) {
00463             int readSize = fileInStream.read(buffer);
00464             collisionDatOut_.write(buffer, 0, readSize);
00465             leftSize -= readSize;
00466         }
00467         fileInStream.close();
00468     }
00469 
00476     public void save(String fileName, String prjFileName) throws IOException {
00477         try {
00478             ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(new File(fileName)));
00479 
00480             // 各ログファイルを追加
00481             for (Enumeration elements = header_.elements(); elements.hasMoreElements();) {
00482                 LogHeader header = (LogHeader) elements.nextElement();
00483                 _addFileToZipEntry(zip, new File( getTempFilePath(header.objectName_) ) );
00484                 zip.closeEntry();
00485                 // logFile.delete();
00486             }
00487 
00488             // プロジェクトファイルの追加
00489             _addFileToZipEntry(zip, new File(prjFileName) );
00490 
00491             // 干渉情報ログを追加
00492             _addFileToZipEntry(zip, new File(collisionLogPath_) );
00493             _addFileToZipEntry(zip, new File(collisionLogDatPath_) );
00494 
00495             zip.flush();
00496             zip.closeEntry();
00497             zip.close();
00498         } catch (IOException ex) {
00499             throw ex;
00500         }
00501     }
00502 
00503     private void _addFileToZipEntry(ZipOutputStream zip, File file)
00504         throws IOException{
00505         if (file.exists()) {
00506             FileInputStream fileInStream = new FileInputStream(file);
00507 
00508             byte[] buffer = new byte[1024 * 1024];
00509 
00510             String zipPath = _getRelativePath(file.getPath());
00511             ZipEntry zipEntry = new ZipEntry(zipPath);
00512             zip.putNextEntry(zipEntry);
00513 
00514             long leftSize = file.length();
00515             while (leftSize > 0) {
00516                 int readSize = fileInStream.read(buffer);
00517                 zip.write(buffer, 0, readSize);
00518                 leftSize -= readSize;
00519             }
00520             fileInStream.close();
00521         }
00522     }
00523 
00524     private String _getRelativePath(String path)
00525     {
00526         if (tmpdir != null) {
00527             String abs_path = (new File(path)).getAbsolutePath();
00528             String tmp_abs_path = (new File(tmpdir)).getAbsolutePath();
00529             if(abs_path.startsWith(tmp_abs_path)){
00530                 String ret = abs_path.substring(tmp_abs_path.length());
00531                 if(ret.startsWith(File.separator)){
00532                     ret = ret.substring(File.separator.length());
00533                 }
00534                 return(ret);
00535             }
00536         }
00537         return path;
00538     }
00539     
00540     public void load(String fileName, String prjFile) throws FileOpenFailException, LogFileFormatException {
00541         init();
00542 
00543         // zipファイルのエントリ数を取得、プロジェクトファイルがあるかどうか
00544         // チェックする。
00545         try {
00546             ZipFile zipFile = new ZipFile(fileName);
00547             int entrySize = zipFile.size();
00548             // TODO temporary comment for GRXUI
00549             /*
00550              * if (zipFile.getEntry(prjFile) == null) { throw new
00551              * LogFileFormatException(); } zipFile.close();
00552              */
00553             // zipを展開する
00554             ZipInputStream zip = new ZipInputStream(new FileInputStream(fileName));
00555             byte[] buffer = new byte[1024];
00556             for (int i = 0; i < entrySize; i++) {
00557                 String entry = zip.getNextEntry().getName();
00558                 if(!(new File(entry)).isAbsolute()){
00559                     entry = tmpdir + File.separator + entry;
00560                 }
00561 
00562                 FileOutputStream out = new FileOutputStream(entry);
00563                 while (zip.available() == 1) {
00564                     int readSize = zip.read(buffer, 0, 1024);
00565                     if (readSize < 0)
00566                         break;
00567                     out.write(buffer, 0, readSize);
00568                 }
00569                 out.close();
00570 
00571                 if (entry.equals(prjFile) ||
00572                     entry.contains(new File(collisionLogDatPath_).getName()) ) {
00573                     continue;
00574                 }
00575 
00576                 DataInputStream in;
00577 
00578                 if (entry.contains(new File(collisionLogPath_).getName())) {
00579                     try {
00580                         in = new DataInputStream(new FileInputStream(entry));
00581                         collisionLog_ = new CollisionLogHeader();
00582                         collisionLog_.input(in);
00583                         in.close();
00584                     } catch (LogFileFormatException ex) {
00585                         zip.close();
00586                         throw ex;
00587                     }
00588                 } else {
00589                     try {
00590                         in = new DataInputStream(new FileInputStream(entry));
00591                         LogHeader header = new LogHeader();
00592                         header.input(in);
00593                         header_.put(header.objectName_, header);
00594                         in.close();
00595                         if (header.getVersion() <= 100) {
00596                             File file = new File(entry);
00597                             header.setFileSize(file.length());
00598                         }
00599                         header.calcUnitSize();
00600                         _makeIndexMapMap(header);
00601                     } catch (LogFileFormatException ex) {
00602                         zip.close();
00603                         throw ex;
00604                     }
00605                 }
00606             }
00607             zip.close();
00608         } catch (IOException ex) {
00609             ex.printStackTrace();
00610             throw new FileOpenFailException();
00611         }
00612     }
00613 
00614     public void saveCSV(String fileName, String ObjectName) throws FileOpenFailException {
00615         try {
00616             LogHeader header = (LogHeader) header_.get(ObjectName);
00617             if (header == null) {
00618                 throw new FileOpenFailException();
00619             }
00620             final long nLine = (new File(getTempFilePath(header.objectName_)).length() - header.headerSize_) / header.recordSize_;
00621             DataInputStream in = new DataInputStream(new FileInputStream(getTempFilePath(header.objectName_)));
00622             PrintWriter out = new PrintWriter(new FileWriter(fileName));
00623 
00624             out.println("Software Version, " + String.valueOf(header.version_[0]) + "." + String.valueOf(header.version_[1]) + "." + String.valueOf(header.version_[2]) + "." + String.valueOf(header.version_[3]));
00625             out.println("Header Size[byte], " + header.headerSize_);
00626             out.println("Simulation Total Time[s], " + (double) header.totalTime_ / 1000000.0);
00627             out.println("Simulation Start Time[s], " + (double) header.startTime_ / 1000000.0);
00628             out.println("Simulation End Time[s], " + (nLine > 0 ? get(ObjectName, nLine - 1)[0] : 0 ));
00629             out.println("TimeStep[s], " + (double) header.timeStep_ / 1000000.0);
00630 
00631             String methodStr = int2StrIntegrationMethod(header.method_);
00632             if(!methodStr.equals("")){
00633                 out.println("Integration Method, " + methodStr);
00634             } else {
00635                 out.println("Integration Method, " + header.method_);
00636             }
00637             out.println("Record Size[byte], " + header.recordSize_);
00638 
00639             for (int i = 0; i < header.dataFormat_.length / 2; i++) {
00640                 String fmt = header.dataFormat_[i * 2 + 1];
00641                 int start = fmt.indexOf('[') + 1;
00642                 int end = fmt.indexOf(']');
00643                 int len = 1;
00644                 if (start > 0)
00645                     len = Integer.parseInt(fmt.substring(start, end));
00646                 if (len == 1) {
00647                     out.print(header.dataFormat_[i * 2]);
00648                     if (i != header.dataFormat_.length / 2 - 1)
00649                         out.print(",");
00650                 } else {
00651                     for (int j = 0; j < len; j++) {
00652                         out.print(header.dataFormat_[i * 2] + "[" + j + "]");
00653                         if (!(i == header.dataFormat_.length / 2 - 1 && j == len - 1))
00654                             out.print(",");
00655                     }
00656                 }
00657             }
00658             out.println();
00659             in.skip(header.headerSize_);
00660             for (long i = 0; i < nLine; i++) {
00661                 for (long j = 0; j < header.recordSize_ / LogHeader.FLOAT_DATA_SIZE - 1; j++) {
00662                     out.print(in.readFloat() + ",");
00663                 }
00664                 // 最後の一個
00665                 out.println(in.readFloat());
00666             }
00667             out.close();
00668             in.close();
00669 
00670         } catch (IOException ex) {
00671             ex.printStackTrace();
00672             throw new FileOpenFailException();
00673         }
00674     }
00675 
00676     public boolean existRecord(int recordNum) {
00677         Enumeration elements = header_.elements();
00678         while (elements.hasMoreElements()) {
00679             LogHeader header = (LogHeader) elements.nextElement();
00680             if (header.numRecords_ <= recordNum) {
00681                 // System.out.println("object=" + header.objectName_ + "
00682                 // numRecords=" + header.numRecords_);
00683                 return false;
00684             }
00685         }
00686 
00687         if (collisionLog_.numRecords_ <= recordNum) {
00688             // System.out.println("recordNum=" + recordNum);
00689             // System.out.println("numRecords=" + collisionLog_.numRecords_);
00690             return false;
00691             // return true;
00692         } else {
00693             return true;
00694         }
00695     }
00696 
00697     public int getLogObjectNum() {
00698         return header_.size();
00699     }
00700 
00701     public int getDataLength(String objectName) {
00702         LogHeader header = (LogHeader) header_.get(objectName);
00703         return header.recordSize_ / LogHeader.FLOAT_DATA_SIZE;
00704     }
00705 
00718     public void getData(long origin, int offset, int count, DataModel[] dataModelArray) {
00719         if (readFile_ == null) {
00720             return;
00721         }
00722 
00723         // 読み出し準備
00724         int numItems = dataModelArray.length; // アイテム数取得
00725         ArrayList<String> objList = new ArrayList<String>(); // オブジェクト名のリスト
00726         HashMap<String, ArrayList<DataSeries>> dsListMap = new HashMap<String, ArrayList<DataSeries>>(); // データ系列リストのマップ
00727         HashMap<String, ArrayList<Object>> indexListMap = new HashMap<String, ArrayList<Object>>(); // 添字リストのマップ
00728         HashMap<String, ArrayList<Integer>> posListMap = new HashMap<String, ArrayList<Integer>>(); // 配列書込位置リストのマップ
00729         HashMap<String, ArrayList<Integer>> sizeListMap = new HashMap<String, ArrayList<Integer>>(); // 配列サイズリストのマップ
00730         for (int i = 0; i < numItems; i++) { // アイテム数分ループ
00731             DataItem di = dataModelArray[i].dataItem; // データアイテム
00732             DataSeries ds = dataModelArray[i].dataSeries; // データ系列
00733             String obj = di.object; // オブジェクト名
00734             if (obj == null || obj.equals("")) { // オブジェクト名なし?
00735                 obj = NONAME_OBJECT; // 無名オブジェクト
00736             }
00737 
00738             // 添字取得(node.attribute.index)
00739             // System.out.println(i+":"+obj+":"+di.node+":"+di.attribute+" ::
00740             // "+indexMapMap_);
00741             Object ind = ((Map) indexMapMap_.get(obj)).get(di.node + "." + di.attribute + (di.index >= 0 ? "." + di.index : ""));
00742 
00743             // データ系列リスト取得
00744             ArrayList<DataSeries> dsList = dsListMap.get(obj);
00745             // 添字リスト取得
00746             ArrayList<Object> indList = indexListMap.get(obj);
00747             // 配列書込位置リスト取得
00748             ArrayList<Integer> posList = posListMap.get(obj);
00749             // 配列長リスト取得
00750             ArrayList<Integer> sizeList = sizeListMap.get(obj);
00751             if (dsList == null) { // 初めてのオブジェクト?
00752                 objList.add(obj); // オブジェクトリストに追加
00753                 dsList = new ArrayList<DataSeries>(); // データ系列リスト生成
00754                 indList = new ArrayList<Object>(); // 添字リスト生成
00755                 posList = new ArrayList<Integer>(); // 配列書込位置リスト生成
00756                 sizeList = new ArrayList<Integer>(); // 配列長リスト生成
00757                 dsListMap.put(obj, dsList); // データ系列リストマップに追加
00758                 indexListMap.put(obj, indList); // 添字リストマップに追加
00759                 posListMap.put(obj, posList); // 配列書込位置リストマップに追加
00760                 sizeListMap.put(obj, sizeList); // 配列長リストマップに追加
00761             }
00762             int size = ds.getSize(); // データ系列サイズ取得
00763             int pos = (ds.getHeadPos() + offset) % size; // 初期書込位置決定
00764             dsList.add(ds); // データ系列リストに追加
00765             indList.add(ind); // 添字リストに追加
00766             posList.add(new Integer(pos)); // 配列書込位置リストに追加
00767             sizeList.add(new Integer(size)); // 配列長リストに追加
00768         }
00769         // データ読み出し
00770         int numObjs = indexListMap.size(); // オブジェクト数取得
00771         for (int i = 0; i < numObjs; i++) { // 全オブジェクトループ
00772             String obj = (String) objList.get(i); // オブジェクト名
00773             LogHeader header = (LogHeader) header_.get(obj); // ヘッダ
00774             int itemsPerRec = header.recordSize_ / LogHeader.FLOAT_DATA_SIZE; // レコードあたりのアイテム数
00775             double[] record = new double[itemsPerRec]; // レコードバッファ
00776             double[] data; // データバッファ
00777             long recNo = origin + offset; // レコード番号
00778             // リスト
00779             ArrayList dsList = (ArrayList) dsListMap.get(obj); // データ系列リスト
00780             ArrayList indList = (ArrayList) indexListMap.get(obj); // 添字リスト
00781             ArrayList posList = (ArrayList) posListMap.get(obj);// 配列書込位置リスト
00782             ArrayList sizeList = (ArrayList) sizeListMap.get(obj); // 配列長リスト
00783             int itemCount = dsList.size(); // アイテム数
00784             int[] posArray = new int[itemCount]; // 配列書込位置配列
00785             // 配列書込位置リストを配列にコピー
00786             for (int j = 0; j < itemCount; j++) {
00787                 posArray[j] = ((Integer) posList.get(j)).intValue();
00788             }
00789             // ファイル
00790             RandomAccessFile file = (RandomAccessFile) readFile_.get(obj);
00791             // System.out.println("obj=" + obj);
00792             synchronized (file) {
00793                 try {
00794                     // 開始レコードが先頭レコードより前か後ろか
00795                     if (recNo < 0) {
00796                         // 先頭レコードまでシーク
00797                         file.seek((long) header.headerSize_);
00798                     } else if (recNo < header.numRecords_) {
00799                         // 当該レコードまでシーク
00800                         file.seek((long) header.headerSize_ + header.recordSize_ * recNo);
00801                     }
00802 
00803                     // レコード数分ループ
00804                     for (int rec = 0; rec < count; rec++) {
00805                         // レコード読み出し
00806 
00807                         // レコード範囲外?
00808                         if (recNo < 0 || recNo >= header.numRecords_) {
00809                             // System.out.println("record = NaN, numRecords=" +
00810                             // header.numRecords_);
00811                             for (int k = 0; k < itemsPerRec; k++) {
00812                                 record[k] = Double.NaN;
00813                             }
00814                         } else {
00815                             for (int k = 0; k < itemsPerRec; k++) {
00816                                 record[k] = file.readFloat();
00817                             }
00818                         }
00819 
00820                         // アイテム数分ループ
00821                         for (int item = 0; item < itemCount; item++) {
00822                             // data = ((DataSeries)dsList.get(item)).getData();
00823                             DataSeries ds = (DataSeries) dsList.get(item);
00824                             data = ds.getData();
00825                             data[posArray[item]] = record[((Integer) indList.get(item)).intValue()];
00826                             if (posArray[item] < (((Integer) sizeList.get(item)).intValue() - 1)) {
00827                                 posArray[item]++;
00828                             } else {
00829                                 posArray[item] = 0;
00830                             }
00831                         }
00832                         recNo++;
00833                     }
00834                 } catch (IOException ex) {
00835                     ex.printStackTrace();
00836                 }
00837             }
00838         }
00839     }
00840     
00841     private HashMap<String, ArrayList<DataSeries>> dsListMap_ = new HashMap<String, ArrayList<DataSeries>>(); // データ系列リストのマップ
00842     private HashMap<String, ArrayList<Integer>> indexListMap_ = new HashMap<String, ArrayList<Integer>>();
00843     private int[] dataPos_ = null;
00844         private double[][] data_ = null;
00845         private int[] dsSize_ = null;
00846     public  void initGetData(DataModel[] dataModelArray){
00847         if(indexMapMap_ == null || indexMapMap_.isEmpty())
00848                 return;
00849         dsListMap_.clear();
00850         indexListMap_.clear();
00851         for (int i = 0; i < dataModelArray.length; i++) { // アイテム数分ループ
00852                 DataItem di = dataModelArray[i].dataItem; // データアイテム
00853                 DataSeries ds = dataModelArray[i].dataSeries; // データ系列
00854                 String obj = di.object; // オブジェクト名
00855                 if (obj == null || obj.equals("")) { // オブジェクト名なし?
00856                     obj = NONAME_OBJECT; // 無名オブジェクト
00857                 }
00858                 String attribute = di.attribute;
00859                 if(attribute.equals("attitude"))
00860                         attribute = "rotation";
00861                 Integer ind = ((Map<String, Integer>) indexMapMap_.get(obj)).get(di.node + "." + attribute + (di.index >= 0 ? "." + di.index : ""));
00862 
00863                 ArrayList<DataSeries> dsList = dsListMap_.get(obj);
00864                 ArrayList<Integer> indexList = indexListMap_.get(obj);
00865                 if(dsList==null){
00866                         dsList = new ArrayList<DataSeries>(); // データ系列リスト生成
00867                         dsListMap_.put(obj, dsList); // データ系列リストマップに追加
00868                         indexList = new ArrayList<Integer>();
00869                         indexListMap_.put(obj, indexList);
00870                 }
00871                 dsList.add(ds);
00872                 indexList.add(ind);
00873         }
00874         
00875         Iterator<String> it = dsListMap_.keySet().iterator();
00876         while (it.hasNext()) {
00877                 String obj = it.next();
00878                 ArrayList<DataSeries> dsList = dsListMap_.get(obj);
00879                 int dsNum = dsList.size();
00880                 dataPos_ = new int[dsNum];
00881                 data_ = new double[dsNum][];
00882                 dsSize_ = new int[dsNum];
00883                 for(int i=0; i<dsNum; i++){
00884                         DataSeries ds = dsList.get(i);
00885                         int size = ds.getSize(); // データ系列サイズ取得
00886                         data_[i] = ds.getData();
00887                         dsSize_[i] = size;
00888                 }
00889         }
00890     }
00891     
00892     public void getData(long origin, int offset, int count){
00893         Iterator<String> it = dsListMap_.keySet().iterator();
00894         while (it.hasNext()) {
00895                 String obj = it.next();
00896                 ArrayList<DataSeries> dsList = dsListMap_.get(obj);
00897                 int dsNum = dsList.size();
00898                 for(int i=0; i<dsNum; i++){
00899                         DataSeries ds = dsList.get(i);
00900                         int pos = (ds.getHeadPos() + offset) % dsSize_[i]; // 初期書込位置決定
00901                         dataPos_[i] = pos;
00902                 }
00903                 _getData(obj, origin+offset, count, indexListMap_.get(obj).toArray(new Integer[0]), data_, dataPos_, dsSize_);
00904         }
00905     }
00906     
00907     private void _getData(String obj, long recNo, int count, Integer[] itemIndex, double[][] data, int[] dataPos, int[] dsSize){
00908         LogHeader header = (LogHeader) header_.get(obj); // ヘッダ
00909         int itemsPerRec = header.recordSize_ / LogHeader.FLOAT_DATA_SIZE; // レコードあたりのアイテム数
00910         double[] record = new double[itemsPerRec]; // レコードバッファ
00911         RandomAccessFile file = (RandomAccessFile) readFile_.get(obj);
00912             synchronized (file) {
00913                 try {
00914                     // レコード数分ループ
00915                     for (int rec = 0; rec < count; rec++) {
00916                         // アイテム数分ループ
00917                         for (int item = 0; item < itemIndex.length; item++) {
00918                                 if (recNo < 0 || recNo >= header.numRecords_)
00919                                         data[item][dataPos[item]] = Double.NaN;
00920                                 else{
00921                                         file.seek((long) header.headerSize_ + header.recordSize_ * recNo + LogHeader.FLOAT_DATA_SIZE * itemIndex[item]);
00922                                         data[item][dataPos[item]] = file.readFloat();
00923                                 }
00924                                 if (dataPos[item] < dsSize[item]-1) {
00925                                         dataPos[item]++;
00926                         } else {
00927                                 dataPos[item] = 0;
00928                         }
00929                         }
00930                         recNo++;
00931                 }
00932             }catch (IOException ex) {
00933                 ex.printStackTrace();
00934             }
00935             }
00936     }
00937     
00938     private void _makeIndexMapMap(LogHeader header) {
00939         String[] format = header.dataFormat_;
00940         Map<String, Integer> indexMap = new HashMap<String, Integer>();
00941         int index = 0;
00942         for (int i = 0; i < format.length / 2; i++) {
00943             if (header.getUnitSize(i) == 0) {
00944                 indexMap.put(format[i * 2], new Integer(index));
00945                 index++;
00946             } else {
00947                 for (int j = 0; j < header.getUnitSize(i); j++) {
00948                     StringBuffer attrName = new StringBuffer(format[i * 2]);
00949                     attrName.append('.');
00950                     attrName.append(j);
00951                     indexMap.put(attrName.toString(), new Integer(index));
00952                     index++;
00953                 }
00954             }
00955         }
00956         indexMapMap_.put(header.objectName_, indexMap);
00957     }
00958 
00959     // --------------------------------------------------------------------
00960     // Inner Class
00967     class LogHeader {
00968         // 固定長ヘッダ部
00969         public byte[]   version_;     // ソフトウェアバージョン
00970         public int      headerSize_;  // ヘッダサイズ
00971         public long     totalTime_;   // シミュレーション総時間
00972         public long     startTime_;   // シミュレーション開始時間
00973         public long     endTime_;     // シミュレーション終了時間
00974         public long     timeStep_;    // ステップタイム (usec)
00975         public int      method_;      // 積分法
00976         public int      recordSize_;  // 1レコード当りのデータ量(byte数)
00977         public int      numRecords_;   // 総レコード数
00978         public byte[]   reserved_;    // リザーブド
00979         public byte[]   reserved_v1_0_;    // リザーブド(version 1.0)
00980 
00981         // 可変長ヘッダ部
00982         public String   objectName_;  // オブジェクト名
00983         public String[] dataFormat_;  // データフォーマット
00984 
00985         public int[]    unitSize_;    //
00986 
00987         private static final long DEFULT_TOTAL_TIME_MSEC = 20000;
00988         private static final long DEFULT_STEP_TIME_MSEC = 1;
00989         private static final int VERSION_DATA_SIZE = 4;
00990         private static final int INT_DATA_SIZE = 4;       
00991         private static final int LONG_DATA_SIZE = 8;
00992         private static final int FLOAT_DATA_SIZE = 4;
00993         private static final int FIXED_PART_SIZE = 64;
00994         private static final int RESERVED_DATA_SIZE =
00995             FIXED_PART_SIZE - (
00996                 VERSION_DATA_SIZE +
00997                 INT_DATA_SIZE * 4 +
00998                 LONG_DATA_SIZE * 4
00999             );
01000 
01001         private static final int RESERVED_DATA_SIZE_V1_0 =
01002             FIXED_PART_SIZE - (
01003                 VERSION_DATA_SIZE +
01004                 INT_DATA_SIZE * 4 +
01005                 FLOAT_DATA_SIZE * 3
01006             );
01007 
01008         private static final int END_TIME_SEEK_POINT =
01009             (VERSION_DATA_SIZE + INT_DATA_SIZE + LONG_DATA_SIZE * 2);
01010 
01011         private static final int NUM_RECORDS_SEEK_POINT =
01012             (VERSION_DATA_SIZE + INT_DATA_SIZE * 3 + LONG_DATA_SIZE * 4);
01013 
01014         LogHeader() {
01015             reserved_ = new byte[RESERVED_DATA_SIZE];
01016         }
01017 
01018         LogHeader(String objectName, String[] format)
01019             throws LogFileFormatException
01020         {
01021             reserved_ = new byte[RESERVED_DATA_SIZE];
01022             objectName_ = objectName;
01023             dataFormat_ = format;
01024 
01025             // ヘッダサイズの計算
01026             headerSize_ = FIXED_PART_SIZE;
01027             headerSize_ += objectName_.length() + 1;
01028             for (int i = 0; i < dataFormat_.length; i ++) {
01029                 headerSize_ += dataFormat_[i].length() + 1;
01030             }
01031 
01032             unitSize_ = new int[dataFormat_.length / 2];
01033 
01034             // 1レコード当りのデータ量を計算
01035             recordSize_ = 0;
01036             for (int i = 0; i < dataFormat_.length / 2; i ++) {
01037                 if (!dataFormat_[i * 2 + 1].startsWith("float")) {
01038                     throw new LogFileFormatException();
01039                 }
01040                 if (dataFormat_[i * 2 + 1].equals("float")) {
01041                     unitSize_[i] = 0;
01042                     recordSize_ ++;
01043                 } else {
01044                     try {
01045                         unitSize_[i] = Integer.parseInt(
01046                             dataFormat_[i * 2 + 1].substring(
01047                                 dataFormat_[i * 2 + 1].indexOf('[') + 1,
01048                                 dataFormat_[i * 2 + 1].indexOf(']')
01049                             )
01050                         );
01051 
01052                         recordSize_ += unitSize_[i];
01053                     } catch (NumberFormatException ex) {
01054                         throw new LogFileFormatException();
01055                     } catch (StringIndexOutOfBoundsException ex) {
01056                         throw new LogFileFormatException();
01057                     }
01058                 }
01059             }
01060             recordSize_ *= FLOAT_DATA_SIZE;
01061         }
01062 
01063         public int getVersion() {
01064             return (
01065                 version_[0] * 1000 +
01066                 version_[1] * 100 +
01067                 version_[2] * 10 + 
01068                 version_[3]
01069             );
01070         }
01071 
01072         public void output(DataOutputStream out)
01073             throws IOException
01074         {
01075             // for Debug
01076             /*
01077             System.out.println("Log header for export");
01078             System.out.println("Header Size: " + headerSize_);
01079             System.out.println("Total Time[us]: " + totalTime_);
01080             System.out.println("Start Time: " + startTime_);
01081             System.out.println("End Time: " + endTime_);
01082             System.out.println("method: " + method_);
01083             System.out.println("recordSize[byte]: " + recordSize_);
01084             System.out.println("numRecords: " + numRecords_);
01085             */
01086 
01087             version_ = new byte[] {0, 3, 1, 0};  // version 3.1.0
01088             out.write(version_, 0, VERSION_DATA_SIZE);
01089             out.writeInt(headerSize_);
01090             out.writeLong(totalTime_);
01091             out.writeLong(startTime_);
01092             out.writeLong(endTime_);
01093             out.writeLong(timeStep_);
01094             out.writeInt(method_);
01095             out.writeInt(recordSize_);
01096             out.writeInt(numRecords_);
01097             out.write(reserved_, 0, RESERVED_DATA_SIZE);
01098             out.writeBytes(objectName_);
01099             out.writeByte(0);
01100             for (int i = 0; i < dataFormat_.length; i ++) {
01101                 //if (i % 2 == 0) System.out.print("   " + dataFormat_[i]);
01102                 out.writeBytes(dataFormat_[i]);
01103                 out.writeByte(0);
01104             }
01105             //System.out.println("");
01106         }
01107 
01108         public void input(DataInputStream in)
01109             throws LogFileFormatException, IOException
01110         {
01111             version_ = new byte[4];
01112             in.readFully(version_);
01113             if (getVersion() <= 100) {
01114                  reserved_v1_0_ = new byte[RESERVED_DATA_SIZE_V1_0];
01115             }
01116 
01117             headerSize_ = in.readInt();
01118 
01119             if (getVersion() <= 100) {
01120                 totalTime_ = new Time(in.readDouble()).getUtime();
01121                 startTime_ = new Time(in.readDouble()).getUtime();
01122                 endTime_ = new Time(in.readDouble()).getUtime();
01123                 timeStep_ = in.readInt();
01124             } else {
01125                 totalTime_ = in.readLong();
01126                 startTime_ = in.readLong();
01127                 endTime_ = in.readLong();
01128                 timeStep_ = in.readLong();
01129             }
01130             method_ = in.readInt();
01131             recordSize_ = in.readInt();
01132 
01133             if (getVersion() <= 100) {
01134                  in.readFully(reserved_v1_0_);
01135             } else {
01136                  numRecords_ = in.readInt();
01137                  in.readFully(reserved_);
01138             }
01139          
01140             // for Debug
01141             /*
01142             System.out.println("Log header");
01143             System.out.println("Header Size: " + headerSize_);
01144             System.out.println("Total Time[us]: " + totalTime_);
01145             System.out.println("Start Time: " + startTime_);
01146             System.out.println("End Time: " + endTime_);
01147             System.out.println("method: " + method_);
01148             System.out.println("recordSize[byte]: " + recordSize_);
01149             System.out.println("numRecords: " + numRecords_);
01150             */
01151          
01152             byte[] readBuffer = new byte[headerSize_ - FIXED_PART_SIZE];
01153             in.readFully(readBuffer);
01154          
01155             // オブジェクト名を取得
01156             int ptr;
01157             for (ptr = 0; ptr < readBuffer.length; ptr ++) {
01158                 if (readBuffer[ptr] == 0) {
01159                     objectName_ = new String(readBuffer, 0, ptr);
01160                     ptr ++;
01161                     break;
01162                 }
01163             }
01164             
01165             // フォーマットストリングの数をカウント
01166             int counter = 0;
01167             for (int j = ptr; j < readBuffer.length; j ++) {
01168                 if (readBuffer[j] == 0) counter ++;
01169             }
01170             
01171             // フォーマットストリングの取得
01172             dataFormat_ = new String[counter];
01173             counter = 0;
01174             for (int j = ptr; j < readBuffer.length; j ++) {
01175                 if (readBuffer[j] == 0) {
01176                     dataFormat_[counter] = new String(readBuffer, ptr, j - ptr);
01177                     counter ++;
01178                     ptr = j + 1;
01179                 }
01180             }
01181         }
01182 
01183         public void calcUnitSize() throws LogFileFormatException {
01184             unitSize_ = new int[dataFormat_.length / 2];
01185 
01186             // 1レコード当りのデータ量を計算
01187             for (int i = 0; i < dataFormat_.length / 2; i ++) {
01188                 if (!dataFormat_[i * 2 + 1].startsWith("float")) {
01189                     throw new LogFileFormatException();
01190                 }
01191                 if (dataFormat_[i * 2 + 1].equals("float")) {
01192                     unitSize_[i] = 0;
01193                 } else {
01194                     try {
01195                         unitSize_[i] = Integer.parseInt(
01196                             dataFormat_[i * 2 + 1].substring(
01197                                 dataFormat_[i * 2 + 1].indexOf('[') + 1,
01198                                 dataFormat_[i * 2 + 1].indexOf(']')
01199                             )
01200                         );
01201                     } catch (NumberFormatException ex) {
01202                         throw new LogFileFormatException();
01203                     } catch (StringIndexOutOfBoundsException ex) {
01204                         throw new LogFileFormatException();
01205                     }
01206                 }
01207             }
01208         }
01209 
01210         int getUnitSize(int index) { return unitSize_[index]; }
01211 
01212         public void outEndTime(RandomAccessFile file) throws IOException {
01213             file.seek(END_TIME_SEEK_POINT);    // 終了時間までシーク
01214             file.writeLong(endTime_);
01215             file.seek(NUM_RECORDS_SEEK_POINT);    // 終了時間までシーク
01216             file.writeInt(numRecords_);
01217             //System.out.println("outEndTime(): numRecords="+numRecords_);
01218         }
01219 
01223         void setFileSize(long length) {
01224             if (recordSize_ == 0) {
01225                 numRecords_ = 0;
01226             } else {
01227                 numRecords_ = (int)((length - headerSize_) / recordSize_);
01228             }
01229         }
01230     }
01231 
01235     class CollisionLogHeader {
01236         // 固定長ヘッダ部
01237         public byte[]   version_;     // ソフトウェアバージョン
01238         public int      headerSize_;  // ヘッダサイズ
01239         public long     totalTime_;   // シミュレーション総時間
01240         public long     startTime_;   // シミュレーション開始時間
01241         public long     endTime_;     // シミュレーション終了時間
01242         public long     timeStep_;    // ステップタイム (usec)
01243         public byte[]   reserved_;    // リザーブド
01244         public byte[]   reserved_v1_0_;    // リザーブド(version 1.0)
01245 
01246         // 可変長ヘッダ部
01247         public ArrayList<Integer> position_ = new ArrayList<Integer>();    // シークオフセット値テーブル
01248 
01249         public int currentPos_;
01250         public int numRecords_;   // 総レコード数
01251 
01252         private static final int VERSION_DATA_SIZE = 4;
01253         private static final int INT_DATA_SIZE = 4;       
01254         private static final int LONG_DATA_SIZE = 8;
01255         private static final int FLOAT_DATA_SIZE = 4;
01256         private static final int FIXED_PART_SIZE = 64;
01257         private static final int RESERVED_DATA_SIZE =
01258             FIXED_PART_SIZE -
01259             (
01260                 VERSION_DATA_SIZE +
01261                 INT_DATA_SIZE +
01262                 LONG_DATA_SIZE * 4
01263             );
01264 
01265         private static final int RESERVED_DATA_SIZE_V1_0 =
01266             FIXED_PART_SIZE -
01267             (
01268                 VERSION_DATA_SIZE +
01269                 INT_DATA_SIZE * 2 +
01270                 FLOAT_DATA_SIZE * 3
01271             );
01272 
01273         private static final int END_TIME_SEEK_POINT =
01274             (VERSION_DATA_SIZE + INT_DATA_SIZE + LONG_DATA_SIZE * 2);
01275 
01276         private static final int TOTAL_TIME_SEEK_POINT = 
01277             VERSION_DATA_SIZE + INT_DATA_SIZE;
01278         
01279         public CollisionLogHeader() {
01280             reserved_ = new byte[RESERVED_DATA_SIZE];
01281         }
01282 
01283         public CollisionLogHeader(SimulationTime time) {
01284             reserved_ = new byte[RESERVED_DATA_SIZE];
01285             totalTime_ = time.totalTime_.getUtime();
01286             startTime_ = time.startTime_.getUtime();
01287             endTime_ = 0;
01288             timeStep_ = time.timeStep_.getUtime();
01289             position_.clear();
01290             headerSize_ = FIXED_PART_SIZE + INT_DATA_SIZE;
01291         }
01292         public int getVersion() {
01293             return (
01294                 version_[0] * 1000 +
01295                 version_[1] * 100 +
01296                 version_[2] * 10 + 
01297                 version_[3]
01298             );
01299         }
01300 
01301         public void input(DataInputStream in)
01302             throws LogFileFormatException, IOException
01303         {
01304             version_ = new byte[4];
01305             in.readFully(version_);
01306             if (getVersion() <= 100) {
01307                  reserved_v1_0_ = new byte[RESERVED_DATA_SIZE_V1_0];
01308             }
01309 
01310             headerSize_ = in.readInt();
01311 
01312             if (getVersion() <= 100) {
01313                 totalTime_ = new Time(in.readDouble()).getUtime();
01314                 startTime_ = new Time(in.readDouble()).getUtime();
01315                 endTime_ = new Time(in.readDouble()).getUtime();
01316                 timeStep_ = in.readInt();
01317             } else {
01318                 totalTime_ = in.readLong();
01319                 startTime_ = in.readLong();
01320                 endTime_ = in.readLong();
01321                 timeStep_ = in.readLong();
01322             }
01323 
01324             if (getVersion() <= 100) {
01325                  in.readFully(reserved_v1_0_);
01326             } else {
01327                  in.readFully(reserved_);
01328             }
01329 
01330             int frameSize =
01331                 (int)((endTime_ - startTime_) / timeStep_) + 
01332                      (((endTime_ - startTime_) % timeStep_) > timeStep_>>1 ? 1 : 0) + 1;
01333             for (int i = 0; i < frameSize + 1; ++i) {
01334                 position_.add(in.readInt());
01335             }
01336             
01337              numRecords_ = frameSize;
01338         }
01339 
01340         public void output(DataOutputStream out) throws IOException {
01341             //System.out.println("StartTime=" + startTime_ + ", endTime=" + endTime_);
01342             version_ = new byte[] {0, 3, 1, 0};  // version 3.1.0
01343             out.write(version_, 0, VERSION_DATA_SIZE);
01344             out.writeInt(headerSize_);
01345             out.writeLong(totalTime_);
01346             out.writeLong(startTime_);
01347             out.writeLong(endTime_);
01348             out.writeLong(timeStep_);
01349             out.write(reserved_, 0, RESERVED_DATA_SIZE);
01350             for (int i = 0; i < position_.size(); i ++) {
01351                 out.writeInt(position_.get(i));
01352             }
01353         }
01354 
01355         public void createLogHeader(DataOutputStream out) throws IOException {
01356             //System.out.println("StartTime=" + startTime_ + ", endTime=" + endTime_);
01357             version_ = new byte[] {0, 3, 1, 0};  // version 3.1.0
01358             out.write(version_, 0, VERSION_DATA_SIZE);
01359             out.writeInt(headerSize_);
01360             out.writeLong(totalTime_);
01361             out.writeLong(startTime_);
01362             out.writeLong(endTime_);
01363             out.writeLong(timeStep_);
01364             out.write(reserved_, 0, RESERVED_DATA_SIZE);
01365             for (int i = 0; i < position_.size(); i ++) {
01366                 out.writeInt(position_.get(i));
01367             }
01368             out.flush();
01369         }
01370         
01371         public void outTimesAndRecalculation(RandomAccessFile file) throws IOException {
01372             file.seek(TOTAL_TIME_SEEK_POINT);  // 総時間までシーク
01373             file.writeLong(endTime_  - startTime_);
01374             file.writeLong(startTime_);
01375             file.writeLong(endTime_);
01376         }
01377 
01378         public void outPositions(RandomAccessFile file) throws IOException {
01379             file.seek(FIXED_PART_SIZE);
01380             for (int i = 0; i < position_.size(); i ++) {
01381                 file.writeInt(position_.get(i));
01382             }
01383         }
01384         
01385         public boolean joinCollisionLogHeader(CollisionLogHeader ref){
01386             if( ref.equals(this) ){
01387                 return false;
01388             } else if( ref.timeStep_ != timeStep_) {
01389                 return false;
01390             }
01391             endTime_ = ref.endTime_;
01392             final int size = ref.position_.size();
01393             for(int i = 1; i < size; ++i){
01394                 position_.add(ref.position_.get(i) + currentPos_);
01395             }
01396             numRecords_ += size - 1;
01397             return true;
01398         }
01399         
01400         public boolean separateCollisionLogHeader(CollisionLogHeader ref, final int changePos){
01401             if( ref.equals(this) ){
01402                 return false;
01403             } else if( ref.timeStep_ != timeStep_) {
01404                 return false;
01405             }
01406             endTime_ = ref.endTime_;
01407             time_.setUtime(endTime_);
01408             final int size = ref.position_.size();
01409             final int offsetNum = ref.position_.get(changePos);
01410             for(int i = changePos; i < size; ++i){
01411                 position_.add(ref.position_.get(i) - offsetNum);
01412             }
01413             numRecords_ = position_.size() - 1;
01414             return true;
01415         }
01416     }
01417     
01418     
01419 // added by GRX 20070207
01420     public float[] get(String objectName, long record) throws IOException {
01421         if (readFile_ == null) return null;
01422 
01423         LogHeader header = (LogHeader)header_.get(objectName);
01424         if (header == null) return null;
01425 
01426         RandomAccessFile file = (RandomAccessFile)readFile_.get(objectName);
01427 
01428         float[] data = new float[header.recordSize_ / LogHeader.FLOAT_DATA_SIZE];
01429 
01430         try {
01431             synchronized (file) {
01432                 file.seek((long)header.headerSize_ + header.recordSize_ * record);
01433                 for (int i = 0; i < data.length; i ++)
01434                     data[i] = file.readFloat();
01435             }
01436         } catch (EOFException ex) {
01437             ex.printStackTrace();
01438         } catch (IOException ex) {
01439             closeAsRead();
01440             throw ex;
01441         }
01442         return data;
01443     }
01444 
01445     public CollisionPoint[] getCollisionPointData(int frameNum) throws IOException {
01446             if (collisionLog_.position_.size() < frameNum + 2)  {
01447                                 return null;
01448                 }
01449         int size = collisionLog_.position_.get(frameNum + 1) - collisionLog_.position_.get(frameNum);
01450                 int data_size=0;
01451                 Enumeration elements = header_.elements();
01452                 LogHeader header = (LogHeader)elements.nextElement();
01453                 int version = header.getVersion();
01454                 if (version <= 110){
01455                         data_size = 6 * 4;
01456                 }else{
01457                         data_size = COLLISION_DATA_SIZE;
01458                 }
01459         if ((size % data_size) != 0 || size <= 0) 
01460                 return null;
01461         size /= data_size;
01462         
01463         collisionDatIn_.seek(collisionLog_.position_.get(frameNum));
01464         CollisionPoint[] data = new CollisionPoint[size];
01465         for (int i = 0; i < size; i ++) {
01466                 data[i] = new CollisionPoint();
01467                 data[i].normal = new double[3];
01468                 data[i].normal[0] = collisionDatIn_.readFloat();
01469                 data[i].normal[1] = collisionDatIn_.readFloat();
01470                 data[i].normal[2] = collisionDatIn_.readFloat();
01471                 data[i].position = new double[3];
01472                 data[i].position[0] = collisionDatIn_.readFloat();
01473                 data[i].position[1] = collisionDatIn_.readFloat();
01474                 data[i].position[2] = collisionDatIn_.readFloat();
01475                 if (version <= 110){
01476                         data[i].idepth = 0.01;
01477                 }else{
01478                         data[i].idepth = collisionDatIn_.readDouble();
01479                 }
01480         }
01481         return data;
01482     }
01483 
01484     public int getCollisionPointDataSize(int frameNum){
01485         try {
01486             return collisionLog_.position_.get(frameNum + 1) - collisionLog_.position_.get(frameNum);
01487         } catch (IndexOutOfBoundsException ex) {
01488             ex.printStackTrace();
01489         }
01490         return -1;
01491     }
01492     
01493     public int getRecordNum(String objectName) {
01494         LogHeader header = (LogHeader)header_.get(objectName);
01495         return header.numRecords_;
01496     }
01497 
01498 // added by GRX 20070416
01499         public void setTempDir(String tmp) {
01500                 tmpdir = tmp;
01501         
01502         File f = new File(tmpdir);
01503         File pf = f.getParentFile();
01504         if (!pf.isDirectory())
01505             pf.mkdir();
01506         if (!f.isDirectory())
01507             f.mkdir();
01508 
01509                 collisionLogPath_ = tmpdir+File.separator+COLLISION_LOG_NAME;
01510         collisionLogDatPath_ = tmpdir+File.separator+COLLISION_LOG_DAT_NAME;
01511         }
01512 
01513     public String getTempDir() {
01514         return tmpdir;
01515     }
01516 
01526     public int getIndex(String obj,String member){
01527         return ((Integer) (((Map) indexMapMap_.get(obj)).get(member))).intValue();
01528     }
01529     
01530     private void _initTempInstance(LogManager logger){
01531         if( this != logger ){
01532             header_ = logger.header_;
01533             indexMapMap_ = logger.indexMapMap_;
01534             collisionLog_ = logger.collisionLog_;
01535             time_ = new Time();
01536         }
01537     }
01538 
01539     private static final String[] INTEGRATION_METHOD_NAMES = { "RUNGE_KUTTA", "EULER" }; //$NON-NLS-1$ //$NON-NLS-2$
01540     private int str2IntIntegrationMethod(String methodStr){
01541         for(int i= 0; i < INTEGRATION_METHOD_NAMES.length; i++){
01542             if(methodStr.equals(INTEGRATION_METHOD_NAMES[i])){
01543                 return i;
01544             }
01545         }
01546         return -1;
01547     }   
01548     private String int2StrIntegrationMethod(int methodInt){
01549         if(methodInt < 0 || INTEGRATION_METHOD_NAMES.length <= methodInt)
01550             return "";
01551         return INTEGRATION_METHOD_NAMES[methodInt];
01552     }
01553 }


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:17