00001
00008 #include "stage.hh"
00009 #include "texture_manager.hh"
00010 using namespace Stg;
00011
00012
00013 joules_t PowerPack::global_stored = 0.0;
00014 joules_t PowerPack::global_input = 0.0;
00015 joules_t PowerPack::global_capacity = 0.0;
00016 joules_t PowerPack::global_dissipated = 0.0;
00017
00018 PowerPack::PowerPack( Model* mod ) :
00019 event_vis( 2.0 * std::max( fabs(ceil(mod->GetWorld()->GetExtent().x.max)),
00020 fabs(floor(mod->GetWorld()->GetExtent().x.min))),
00021 2.0 * std::max( fabs(ceil(mod->GetWorld()->GetExtent().y.max)),
00022 fabs(floor(mod->GetWorld()->GetExtent().y.min))),
00023 1.0 ),
00024 output_vis( 0,100,200,40, 1200, Color(1,0,0), Color(0,0,0,0.5), "energy output", "energy_input" ),
00025 stored_vis( 0,142,200,40, 1200, Color(0,1,0), Color(0,0,0,0.5), "energy stored", "energy_stored" ),
00026 mod( mod),
00027 stored( 0.0 ),
00028 capacity( 0.0 ),
00029 charging( false ),
00030 dissipated( 0.0 ),
00031 last_time(0),
00032 last_joules(0.0),
00033 last_watts(0.0)
00034 {
00035
00036 mod->world->AddPowerPack( this );
00037
00038 mod->AddVisualizer( &event_vis, false );
00039 mod->AddVisualizer( &output_vis, false );
00040 mod->AddVisualizer( &stored_vis, false );
00041 }
00042
00043 PowerPack::~PowerPack()
00044 {
00045 mod->world->RemovePowerPack( this );
00046 mod->RemoveVisualizer( &event_vis );
00047 mod->RemoveVisualizer( &output_vis );
00048 mod->RemoveVisualizer( &stored_vis );
00049 }
00050
00052 void PowerPack::Visualize( Camera* cam )
00053 {
00054 (void)cam;
00055
00056 const double height = 0.5;
00057 const double width = 0.2;
00058
00059 double percent = stored/capacity * 100.0;
00060
00061 const double alpha = 0.5;
00062
00063 if( percent > 50 )
00064 glColor4f( 0,1,0, alpha );
00065 else if( percent > 25 )
00066 glColor4f( 1,0,1, alpha );
00067 else
00068 glColor4f( 1,0,0, alpha );
00069
00070
00071
00072 glTranslatef( -width, 0.0, 0.0 );
00073
00074 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
00075
00076 GLfloat fullness = height * (percent * 0.01);
00077 glRectf( 0,0,width, fullness);
00078
00079
00080 glTranslatef( 0,0,0.1 );
00081 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
00082
00083 glColor4f( 0,0,0,0.7 );
00084
00085 glRectf( 0,0,width, height );
00086
00087 glBegin( GL_LINES );
00088 glVertex2f( 0, fullness );
00089 glVertex2f( width, fullness );
00090 glEnd();
00091
00092 if( stored < 0.0 )
00093 {
00094
00095 glBegin( GL_LINES );
00096 glVertex2f( width/3.0, height/3.0 );
00097 glVertex2f( 2.0 * width/3, height/3.0 );
00098
00099 glVertex2f( width/3.0, height/3.0 );
00100 glVertex2f( width/3.0, height - height/5.0 );
00101
00102 glVertex2f( width/3.0, height - height/5.0 );
00103 glVertex2f( 0, height - height/5.0 );
00104
00105 glVertex2f( 0, height - height/5.0 );
00106 glVertex2f( width/2.0, height );
00107
00108 glVertex2f( width/2.0, height );
00109 glVertex2f( width, height - height/5.0 );
00110
00111 glVertex2f( width, height - height/5.0 );
00112 glVertex2f( 2.0 * width/3.0, height - height/5.0 );
00113
00114 glVertex2f( 2.0 * width/3.0, height - height/5.0 );
00115 glVertex2f( 2.0 * width/3, height/3.0 );
00116
00117 glEnd();
00118 }
00119
00120
00121 if( charging )
00122 {
00123 glLineWidth( 6.0 );
00124 glColor4f( 1,0,0,0.7 );
00125
00126 glRectf( 0,0,width, height );
00127
00128 glLineWidth( 1.0 );
00129 }
00130
00131
00132
00133 usec_t time_now = mod->world->SimTimeNow();
00134 usec_t delta_t = time_now - last_time;
00135 watts_t watts = last_watts;
00136
00137 if( delta_t > 0 )
00138 {
00139 joules_t delta_j = stored - last_joules;
00140 watts_t watts = (-1e6 * delta_j) / (double)delta_t;
00141
00142 last_joules = stored;
00143 last_time = time_now;
00144 last_watts = watts;
00145 }
00146
00147 if( fabs(watts) > 1e-5 )
00148 {
00149 glColor4f( 1,0,0,0.8 );
00150 char buf[32];
00151 snprintf( buf, 32, "%.1fW", watts );
00152 Gl::draw_string( -0.05,height+0.05,0, buf );
00153 }
00154 }
00155
00156
00157 joules_t PowerPack::RemainingCapacity() const
00158 {
00159 return( capacity - stored );
00160 }
00161
00162 void PowerPack::Add( joules_t j )
00163 {
00164 joules_t amount = std::min( RemainingCapacity(), j );
00165 stored += amount;
00166 global_stored += amount;
00167
00168 if( amount > 0 ) charging = true;
00169 }
00170
00171 void PowerPack::Subtract( joules_t j )
00172 {
00173 if( stored < 0 )
00174 {
00175 global_input += j;
00176 return;
00177 }
00178
00179 joules_t amount = std::min( stored, j );
00180
00181 stored -= amount;
00182 global_stored -= amount;
00183 }
00184
00185 void PowerPack::TransferTo( PowerPack* dest, joules_t amount )
00186 {
00187
00188
00189
00190
00191
00192 if( stored >= 0.0 )
00193 amount = std::min( stored, amount );
00194
00195
00196 amount = std::min( amount, dest->RemainingCapacity() );
00197
00198
00199
00200
00201 Subtract( amount );
00202 dest->Add( amount );
00203
00204 mod->NeedRedraw();
00205 }
00206
00207
00208 void PowerPack::SetCapacity( joules_t cap )
00209 {
00210 global_capacity -= capacity;
00211 capacity = cap;
00212 global_capacity += capacity;
00213
00214 if( stored > cap )
00215 {
00216 global_stored -= stored;
00217 stored = cap;
00218 global_stored += stored;
00219 }
00220 }
00221
00222 joules_t PowerPack::GetCapacity() const
00223 {
00224 return capacity;
00225 }
00226
00227 joules_t PowerPack::GetStored() const
00228 {
00229 return stored;
00230 }
00231
00232 joules_t PowerPack::GetDissipated() const
00233 {
00234 return dissipated;
00235 }
00236
00237 void PowerPack::SetStored( joules_t j )
00238 {
00239 global_stored -= stored;
00240 stored = j;
00241 global_stored += stored;
00242 }
00243
00244 void PowerPack::Dissipate( joules_t j )
00245 {
00246 joules_t amount = (stored < 0) ? j : std::min( stored, j );
00247
00248 Subtract( amount );
00249 dissipated += amount;
00250 global_dissipated += amount;
00251
00252 output_vis.AppendValue( amount );
00253 stored_vis.AppendValue( stored );
00254 }
00255
00256 void PowerPack::Dissipate( joules_t j, const Pose& p )
00257 {
00258 Dissipate( j );
00259 event_vis.Accumulate( p.x, p.y, j );
00260 }
00261
00262
00263
00264
00265 joules_t PowerPack::DissipationVis::global_peak_value = 0.0;
00266
00267 PowerPack::DissipationVis::DissipationVis( meters_t width,
00268 meters_t height,
00269 meters_t cellsize )
00270 : Visualizer( "energy dissipation", "energy_dissipation" ),
00271 columns(width/cellsize),
00272 rows(height/cellsize),
00273 width(width),
00274 height(height),
00275 cells( columns*rows ),
00276 peak_value(0),
00277 cellsize(cellsize)
00278 { }
00279
00280 PowerPack::DissipationVis::~DissipationVis()
00281 {
00282 }
00283
00284 void PowerPack::DissipationVis::Visualize( Model* mod, Camera* cam )
00285 {
00286 (void)cam;
00287
00288
00289
00290 glPushMatrix();
00291
00292 Gl::pose_inverse_shift( mod->GetGlobalPose() );
00293
00294 glTranslatef( -width/2.0, -height/2.0, 0.01 );
00295 glScalef( cellsize, cellsize, 1 );
00296
00297 for( unsigned int y=0; y<rows; y++ )
00298 for( unsigned int x=0; x<columns; x++ )
00299 {
00300 joules_t j = cells[ y*columns + x ];
00301
00302
00303
00304 if( j > 0 )
00305 {
00306 glColor4f( 1.0, 0, 0, j/global_peak_value );
00307 glRectf( x,y,x+1,y+1 );
00308 }
00309 }
00310
00311 glPopMatrix();
00312 }
00313
00314
00315
00316 void PowerPack::DissipationVis::Accumulate( meters_t x,
00317 meters_t y,
00318 joules_t amount )
00319 {
00320
00321
00322 int ix = (x+width/2.0)/cellsize;
00323 int iy = (y+height/2.0)/cellsize;
00324
00325
00326 if( ix < 0 || ix >= int(columns) || iy < 0 || iy >= int(rows) )
00327 return;
00328
00329 joules_t& j = cells[ ix + (iy*columns) ];
00330
00331 j += amount;
00332 if( j > peak_value )
00333 {
00334 peak_value = j;
00335
00336 if( peak_value > global_peak_value )
00337 global_peak_value = peak_value;
00338 }
00339 }