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]