1 //#************************************************************** 2 //# 3 //# filename: sensors.h 4 //# 5 //# author: Gerstmayr Johannes 6 //# Vetyukov Yury 7 //# 8 //# generated: February-June 2012 9 //# description: 10 //# 11 //# remarks: HotInt sensors - 2nd generation 12 //# 13 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian 14 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the 15 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved. 16 //# 17 //# This file is part of HotInt. 18 //# HotInt is free software: you can redistribute it and/or modify it under the terms of 19 //# the HOTINT license. See folder 'licenses' for more details. 20 //# 21 //# bug reports are welcome!!! 22 //# WWW: www.hotint.org 23 //# email: bug_reports@hotint.org or support@hotint.org 24 //#************************************************************** 25 26 #pragma once 27 28 #include "sensorProcessors.h" 29 30 // bit-wise flags for possible data storage options in a sensor - can be combined 31 enum SensorSignalStorageMode 32 { 33 SSM_None = 0, // no data storage 34 SSM_CommonFile = 1, // general solution file of the simulation - prescribed output frequency is governed by MBS 35 SSM_OwnFile = 2, // separate file with the results of this particular sensor - prescribed output frequency is governed by MBS 36 SSM_InternalArray = 4 // internal array in memory - all time signal points; will be set automatically if a signal processor with post computation is applied 37 }; 38 39 // - this is a base class for actually used sensor classes 40 // - these sensors can have only one scalar value at a time (for multiple-value sensors other mechanisms will be involved) 41 // - the base class includes data storing functions 42 // - the base class is responsible for the interaction with possible signal processors 43 // - the base class provides interaction with mbs 44 // - there are no copy features for the sensors: the instances are created with "new" and added to mbs per pointer 45 // - tha base class is abstract and cannot be instantiated 46 class Sensor //$EDC$[beginclass,classname=Sensor] 47 { 48 private: 49 // data of the sensor 50 SensorSignalStorageMode signalStorageMode; 51 // these are the processors for the signals attached to the present sensor; 52 // the processors are applied one after another for the actual value, and are invoked at the post computation stage 53 TArray<SensorProcessor*> sensorProcessors; 54 55 // computation results 56 // this value and time point correspond to the last call to Evaluate() - instant value of the sensor between time steps; 57 // will be used by MBS::WriteSol() 58 double lastSensorSignalTime; 59 double lastSensorSignalValue; 60 // the arrays below contain measured signal time history if signalStorageMode & SSM_InternalArray != 0 61 // the two arrays are made protected to be available in MBSSensor - as soon as it is removed from the system, they can be made private again 62 protected: 63 TArray<double> signalHistoryValues; // stored measured values 64 TArray<double> signalHistoryTimes; // times of the measurements 65 int sensnum; //$EDC$[varaccess,EDCvarname="sensor_number",EDCfolder="",readonly,tooltiptext="number of the sensor in the mbs"] //number in MBS-system 66 67 private: 68 // at the post-computation stage the sensor processors may generate a set of values, 69 // which characterize the measured time signal and which might then be used for optimization, sensitivity analysis, etc. 70 TArray<double> sensorProcessingEvaluationData; 71 72 // draw settings 73 bool visibleFlag; 74 Vector3D drawColor; 75 Vector3D drawDimension; 76 77 // system variables 78 MBS * mbs; 79 mystr name; //$EDC$[varaccess,EDCvarname="name",EDCfolder="",tooltiptext="name of the sensor for the output files and for the plot tool"] 80 bool openSensorWatchPlotToolAtStartUpFlag; // if this flag is set, then a window with the time history of the sensor signal is opened by mbs at the initialization stage after assembling the model 81 int precision; // precision of output of the sensor signal 82 ofstream * ownOutputFile; // stream to which the sensor signal history is written if SSM_OwnFile flag is set - is created, opened, written to, closed and deleted by mbs 83 84 // adds a measured value for the present time instant AddLastSignalToHistory()85 void AddLastSignalToHistory() 86 { 87 signalHistoryValues.Add(lastSensorSignalValue); 88 signalHistoryTimes.Add(lastSensorSignalTime); 89 } 90 91 public: 92 // access to the above variables GetMBS()93 MBS * GetMBS() { return mbs; } GetMBS()94 const MBS * GetMBS() const { return mbs; } GetSignalStorageMode()95 SensorSignalStorageMode GetSignalStorageMode() const { return signalStorageMode; } SetSignalStorageMode(SensorSignalStorageMode mode)96 void SetSignalStorageMode(SensorSignalStorageMode mode) { signalStorageMode = mode; } 97 void ModifySignalStorageMode(SensorSignalStorageMode flagsSet, SensorSignalStorageMode flagsRemove = SSM_None) 98 { 99 signalStorageMode = SensorSignalStorageMode( (signalStorageMode | flagsSet) & (~flagsRemove) ); 100 } GetSignalHistoryValuesPtr()101 TArray<double>* GetSignalHistoryValuesPtr() { return &signalHistoryValues; } GetSignalHistoryTimesPtr()102 TArray<double>* GetSignalHistoryTimesPtr() { return &signalHistoryTimes; } 103 GetOwnNum()104 virtual int GetOwnNum() const {return sensnum;} SetOwnNum(int i)105 virtual void SetOwnNum(int i) {sensnum = i;} 106 107 // draw settings GetVisible()108 bool GetVisible() const { return visibleFlag; } SetVisible(bool visibleFlag)109 void SetVisible(bool visibleFlag) { this->visibleFlag = visibleFlag; } GetDrawColor()110 Vector3D GetDrawColor() const { return drawColor; } SetDrawColor(Vector3D drawColor)111 void SetDrawColor(Vector3D drawColor) { this->drawColor = drawColor; } GetDrawDimension()112 Vector3D GetDrawDimension() const { return drawDimension; } SetDrawDimension(Vector3D drawDimension)113 void SetDrawDimension(Vector3D drawDimension) { this->drawDimension = drawDimension; } 114 // name of the sensor used in the user interface (sensors list, plot tool, etc.) 115 // and in the text files with the values; should be set in the constructor of a derived class GetSensorName()116 mystr GetSensorName() const { return name; } 117 //$ PG 2013-1-16:[ 118 // name of the sensor MAY be automatically set in SensorName::AfterSetFunction, 119 // which is overwritten in the derived classes, and called at the end of the specific set functions of the derived classes 120 // (such as FieldVariableElementSensor::SetFVESPos3D, SingleElementDataSensor::SetSingleElementDataSensor, LoadSensor::SetLoadSensor), 121 // i.e., SetSensorName has to be called AFTER those set-functions in the models-cpp-files to take effect SetSensorName(mystr name)122 void SetSensorName(mystr name) { this->name = name; } 123 //$ PG 2013-1-16:] IsSensorOnEigensystem()124 virtual bool IsSensorOnEigensystem() { return 0; } //$ PG 2013-11-27: potentially overridden in derived class GetOpenSensorWatchPlotToolAtStartUpFlag()125 bool GetOpenSensorWatchPlotToolAtStartUpFlag() const { return openSensorWatchPlotToolAtStartUpFlag; } SetOpenSensorWatchPlotToolAtStartUpFlag(bool openSensorWatchPlotToolAtStartUpFlag)126 void SetOpenSensorWatchPlotToolAtStartUpFlag(bool openSensorWatchPlotToolAtStartUpFlag) { this->openSensorWatchPlotToolAtStartUpFlag = openSensorWatchPlotToolAtStartUpFlag; } 127 // precision of output to the text file GetPrecision()128 int GetPrecision() const { return precision; } SetPrecision(int precision)129 void SetPrecision(int precision) { this->precision = precision; } 130 // output file GetOwnOutputFile()131 ofstream * GetOwnOutputFile() const { return ownOutputFile; } SetOwnOutputFile(ofstream * ownOutputFilei)132 void SetOwnOutputFile(ofstream * ownOutputFilei) { ownOutputFile = ownOutputFilei; } 133 134 // adds a copy of a sensor processor to the processing chain; 135 void AddSensorProcessor(SensorProcessor & sp); 136 // if some of the signal processors require a file stream to write the results of the postcomputation evaluation, 137 // the sensor needs to report it; 138 // the function is virtual for compatibility with the obsolete MBSSensor NeedsFileForPostComputationProcessing()139 virtual bool NeedsFileForPostComputationProcessing() 140 { 141 for(int i = 1; i <= sensorProcessors.Length(); i++) 142 if(sensorProcessors(i)->NeedsFileForPostComputationProcessing()) 143 return true; 144 return false; 145 } 146 // clears the list of attached sensor processors 147 void RemoveSensorProcessors(); 148 149 // access to computation results; some functions below are virtual for compatibility with the obsolete MBSSensor HasSensorProcessingEvaluationData()150 virtual bool HasSensorProcessingEvaluationData() { return sensorProcessingEvaluationData.Length() != 0; } GetSignalProcessingEvaluationData()151 virtual TArray<double> & GetSignalProcessingEvaluationData() { return sensorProcessingEvaluationData; } GetLastValue()152 double GetLastValue() { return lastSensorSignalValue; } 153 154 // building dependencies requires that the elements, which affect the signal of this sensor, are known 155 // these numbers may be modified by mbs when elements are inserted/deleted GetNumberOfRelatedElements()156 virtual int GetNumberOfRelatedElements() { return 0; } GetRelatedElementNumber(int nElement)157 virtual int& GetRelatedElementNumber(int nElement) { assert(0); static int dummy = 0; return dummy; } GetNumberOfRelatedNodes()158 virtual int GetNumberOfRelatedNodes() { return 0; } //$ DR 2013-05-21 GetRelatedNodeNumber(int nNode)159 virtual int& GetRelatedNodeNumber(int nNode) { assert(0); static int dummy = 0; return dummy; } //$ DR 2013-05-21 GetNumberOfRelatedLoads()160 virtual int GetNumberOfRelatedLoads() { return 0; } //$ DR 2013-05-21 GetRelatedLoadNumber(int nLoad)161 virtual int& GetRelatedLoadNumber(int nLoad) { assert(0); static int dummy = 0; return dummy; } //$ DR 2013-05-21 GetNumberOfRelatedSensors()162 virtual int GetNumberOfRelatedSensors() { return 0; } //$ DR 2013-05-21 GetRelatedSensorNumber(int nSensor)163 virtual int& GetRelatedSensorNumber(int nSensor) { assert(0); static int dummy = 0; return dummy; } //$ DR 2013-05-21 164 165 166 protected: 167 // the functions below are assumed to be overridden 168 // the following function computes the present value of the sensor 169 // and it must be implemented in the derived sensor class; 170 // this function is unavailable outside of the class as this value is not yet processed by sensor processors 171 virtual double GetCurrentValue(double time) = 0; 172 public: 173 // literal identifier of the type of the sensor GetTypeName()174 virtual mystr GetTypeName() {return "Sensor";}; //$EDC$[funcaccess,EDCvarname="sensor_type",tooltiptext="specification of sensor type. Once the sensor is added to the mbs, you MUST NOT change this type anymore!"] 175 // the derived sensor classes may provide particular positions for drawing (if it makes sense); 176 // then this function tells how many points should be plotted for this sensor in the 3D scene GetNumberOfDrawingPositions()177 virtual int GetNumberOfDrawingPositions() { return 0; } 178 // the drawing positions are indexed as there might be several ones for a given sensor GetDrawPosition(int i)179 virtual Vector3D GetDrawPosition(int i) { assert(0); return Vector3D(); } 180 // for the auto generated documentation //$ DR 2012-10 added GetSensorTypeTexDescription()181 virtual mystr GetSensorTypeTexDescription() {return mystr("");}; 182 183 protected: 184 // default constructor is just for copy making Sensor()185 Sensor() {} 186 // this function should be called after setting the data of a sensor by 187 // - set functions 188 // - setting the data from an EDC 189 // - modifying or setting up a sensor via user interface 190 // in this function additional initialization is performed, e.g. a name is generated AfterSetFunction()191 virtual void AfterSetFunction() {} 192 193 public: 194 // creating / copying - must be overridden in the derived class 195 virtual Sensor * GetCopy() = 0; 196 // these functions need to be normally overridden in the derived class (the base implementation must be called) 197 virtual void CopyFrom(const Sensor& s); 198 199 // constructor / destructor 200 // default constructor with member initialization 201 Sensor(MBS * mbs); 202 Sensor(const Sensor & s); 203 // default destructor - deletes signal processors ~Sensor()204 virtual ~Sensor() { RemoveSensorProcessors(); } 205 // performs an evaluation of the present value, then sensor processing, 206 // and saves to time history if the corresponding flag is set; 207 // should be used between time steps 208 // the function is virtual for compatibility with the obsolete MBSSensor 209 virtual void Evaluate(double time); 210 // the following function evaluates the present value with sensor processing but does not store the results anywhere; 211 // should be used during iterations within a time step 212 // the function is virtual for compatibility with the obsolete MBSSensor 213 double GetCurrentValueWithSensorProcessing(double time); 214 // derived sensor classes may redefine the default drawing behavior 215 // label (text caption) for the sensor will be provided by mbs 216 virtual void Draw(const char * textLabel); 217 // testing the data integrity IsConsistent(mystr & errorStr)218 virtual bool IsConsistent(mystr & errorStr) { return true; } 219 // this function is called by mbs after the computation is finished 220 // the post-processing procedures the attached signal processors are invoked one after another; 221 // these may write the results into the provided file stream (managed by mbs) and provide some sensor evaluation vectors, 222 // which are then combined into a common vector signalProcessingEvaluationData 223 // the function is virtual for compatibility with the obsolete MBSSensor 224 virtual void ApplyPostComputationSensorProcessing(ofstream * outputFile); 225 226 // sensor data setting/retrieving; these functions need to be normally inherited (the base class implementation is to be called in the derived class) 227 virtual void GetElementData(ElementDataContainer& edc); 228 virtual int SetElementData(ElementDataContainer& edc); 229 virtual void GetElementDataAuto(ElementDataContainer& edc); //fill in all element data 230 virtual int SetElementDataAuto(ElementDataContainer& edc); //set element data acc. to ElementDataContainer, return 0 if failed or values invalid! 231 virtual int ReadSingleElementDataAuto(ReadWriteElementDataVariableType& RWdata); //automatically generated function from EDC_converter 232 virtual int WriteSingleElementDataAuto(const ReadWriteElementDataVariableType& RWdata); //automatically generated function from EDC_converter 233 virtual int GetAvailableSpecialValuesAuto(TArrayDynamic<ReadWriteElementDataVariableType>& available_variables); //automatically generated function from EDC_converter 234 235 };//$EDC$[endclass,Sensor]