00001
00133 #ifndef _GNU_SOURCE
00134 #define _GNU_SOURCE
00135 #endif
00136
00137 #include <map>
00138 #include <sstream>
00139 #include <ltdl.h>
00140
00141 #include "config.h"
00142 #include "stage.hh"
00143 #include "worldfile.hh"
00144 #include "file_manager.hh"
00145 using namespace Stg;
00146
00147
00148 uint32_t Model::count(0);
00149 uint32_t Model::trail_length(50);
00150 uint64_t Model::trail_interval(5);
00151 std::map<Stg::id_t,Model*> Model::modelsbyid;
00152 std::map<std::string, creator_t> Model::name_map;
00153
00154
00155 static const double DEFAULT_FRICTION = 0.0;
00156
00157
00158 Bounds& Bounds::Load( Worldfile* wf, const int section, const char* keyword )
00159 {
00160 wf->ReadTuple( section, keyword, 0, 2, "ll", &min, &max );
00161 return *this;
00162 }
00163
00164 double Bounds::Constrain( double value )
00165 {
00166 return Stg::constrain( value, min, max );
00167 }
00168
00169 Stg::Size& Stg::Size::Load( Worldfile* wf, const int section, const char* keyword )
00170 {
00171 wf->ReadTuple( section, keyword, 0, 3, "lll", &x, &y, &z );
00172 return *this;
00173 }
00174
00175 void Stg::Size::Save( Worldfile* wf, int section, const char* keyword ) const
00176 {
00177 wf->WriteTuple( section, keyword, 0, 3, "lll", x, y, z );
00178 }
00179
00180 Pose& Pose::Load( Worldfile* wf, const int section, const char* keyword )
00181 {
00182 wf->ReadTuple( section, keyword, 0, 4, "llla", &x, &y, &z, &a );
00183 normalize( a );
00184 return *this;
00185 }
00186
00187 void Pose::Save( Worldfile* wf, const int section, const char* keyword )
00188 {
00189 wf->WriteTuple( section, keyword, 0, 4, "llla", x, y, z, a );
00190 }
00191
00192 Model::Visibility::Visibility() :
00193 blob_return( true ),
00194 fiducial_key( 0 ),
00195 fiducial_return( 0 ),
00196 gripper_return( false ),
00197 obstacle_return( true ),
00198 ranger_return( 1.0 )
00199 { }
00200
00201
00202 Model::Visibility& Model::Visibility::Load( Worldfile* wf, int wf_entity )
00203 {
00204 blob_return = wf->ReadInt( wf_entity, "blob_return", blob_return);
00205 fiducial_key = wf->ReadInt( wf_entity, "fiducial_key", fiducial_key);
00206 fiducial_return = wf->ReadInt( wf_entity, "fiducial_return", fiducial_return);
00207 gripper_return = wf->ReadInt( wf_entity, "gripper_return", gripper_return);
00208 obstacle_return = wf->ReadInt( wf_entity, "obstacle_return", obstacle_return);
00209 ranger_return = wf->ReadFloat( wf_entity, "ranger_return", ranger_return);
00210
00211 return *this;
00212 }
00213
00214 void Model::Visibility::Save( Worldfile* wf, int wf_entity )
00215 {
00216 wf->WriteInt( wf_entity, "blob_return", blob_return);
00217 wf->WriteInt( wf_entity, "fiducial_key", fiducial_key);
00218 wf->WriteInt( wf_entity, "fiducial_return", fiducial_return);
00219 wf->WriteInt( wf_entity, "gripper_return", gripper_return);
00220 wf->WriteInt( wf_entity, "obstacle_return", obstacle_return);
00221 wf->WriteFloat( wf_entity, "ranger_return", ranger_return);
00222 }
00223
00224
00225 Model::GuiState::GuiState() :
00226 grid( false ),
00227 move( false ),
00228 nose( false ),
00229 outline( false )
00230 { }
00231
00232 Model::GuiState& Model::GuiState::Load( Worldfile* wf, int wf_entity )
00233 {
00234 nose = wf->ReadInt( wf_entity, "gui_nose", nose);
00235 grid = wf->ReadInt( wf_entity, "gui_grid", grid);
00236 outline = wf->ReadInt( wf_entity, "gui_outline", outline);
00237 move = wf->ReadInt( wf_entity, "gui_move", move );
00238
00239 return *this;
00240 }
00241
00242
00243 Model::Model( World* world,
00244 Model* parent,
00245 const std::string& type,
00246 const std::string& name ) :
00247 Ancestor(),
00248 mapped(false),
00249 drawOptions(),
00250 alwayson(false),
00251 blockgroup(),
00252 blocks_dl(0),
00253 boundary(false),
00254 callbacks(__CB_TYPE_COUNT),
00255 color( 1,0,0 ),
00256 data_fresh(false),
00257 disabled(false),
00258 cv_list(),
00259 flag_list(),
00260 friction(DEFAULT_FRICTION),
00261 geom(),
00262 has_default_block(true),
00263 id(Model::count++),
00264 interval((usec_t)1e5),
00265 interval_energy((usec_t)1e5),
00266 last_update(0),
00267 log_state(false),
00268 map_resolution(0.1),
00269 mass(0),
00270 parent(parent),
00271 pose(),
00272 power_pack(NULL),
00273 pps_charging(),
00274 rastervis(),
00275 rebuild_displaylist(true),
00276 say_string(),
00277 stack_children(true),
00278 stall(false),
00279 subs(0),
00280 thread_safe(false),
00281 trail(trail_length),
00282 trail_index(0),
00283 type(type),
00284 event_queue_num(0),
00285 used(false),
00286 watts(0.0),
00287 watts_give(0.0),
00288 watts_take(0.0),
00289 wf(NULL),
00290 wf_entity(0),
00291 world(world),
00292 world_gui( dynamic_cast<WorldGui*>( world ) )
00293 {
00294 assert( world );
00295
00296 PRINT_DEBUG3( "Constructing model world: %s parent: %s type: %s \n",
00297 world->Token(),
00298 parent ? parent->Token() : "(null)",
00299 type.c_str() );
00300
00301 modelsbyid[id] = this;
00302
00303 if( name.size() )
00304 {
00305
00306 SetToken( name );
00307 }
00308 else
00309
00310 {
00311 char buf[2048];
00312
00313
00314
00315
00316
00317 if( parent )
00318 {
00319 snprintf( buf, 2048, "%s.%s:%u",
00320 parent->Token(),
00321 type.c_str(),
00322 parent->child_type_counts[type] );
00323 }
00324 else
00325 {
00326 snprintf( buf, 2048, "%s:%u",
00327 type.c_str() ,
00328 world->child_type_counts[type] );
00329 }
00330
00331
00332 SetToken( buf );
00333 }
00334
00335
00336
00337 world->AddModel( this );
00338
00339 if ( parent )
00340 parent->AddChild( this );
00341 else
00342 {
00343 world->AddChild( this );
00344
00345 gui.move = true;
00346 }
00347
00348
00349 AddBlockRect( -0.5, -0.5, 1.0, 1.0, 1.0 );
00350
00351 AddVisualizer( &rastervis, false );
00352
00353 PRINT_DEBUG2( "finished model %s @ %p", this->Token(), this );
00354 }
00355
00356 Model::~Model( void )
00357 {
00358
00359
00360 if( world )
00361 {
00362 UnMap();
00363
00364
00365
00366 EraseAll( this, parent ? parent->children : world->children );
00367
00368 modelsbyid.erase(id);
00369
00370 world->RemoveModel( this );
00371 }
00372 }
00373
00374
00375 void Model::InitControllers()
00376 {
00377 CallCallbacks( CB_INIT );
00378 }
00379
00380
00381 void Model::AddFlag( Flag* flag )
00382 {
00383 if( flag )
00384 {
00385 flag_list.push_back( flag );
00386 CallCallbacks( CB_FLAGINCR );
00387 }
00388 }
00389
00390 void Model::RemoveFlag( Flag* flag )
00391 {
00392 if( flag )
00393 {
00394 EraseAll( flag, flag_list );
00395 CallCallbacks( CB_FLAGDECR );
00396 }
00397 }
00398
00399 void Model::PushFlag( Flag* flag )
00400 {
00401 if( flag )
00402 {
00403 flag_list.push_front( flag);
00404 CallCallbacks( CB_FLAGINCR );
00405 }
00406 }
00407
00408 Model::Flag* Model::PopFlag()
00409 {
00410 if( flag_list.size() == 0 )
00411 return NULL;
00412
00413 Flag* flag = flag_list.front();
00414 flag_list.pop_front();
00415
00416 CallCallbacks( CB_FLAGDECR );
00417
00418 return flag;
00419 }
00420
00421 void Model::ClearBlocks()
00422 {
00423 blockgroup.UnMap(0);
00424 blockgroup.UnMap(1);
00425 blockgroup.Clear();
00426
00427 NeedRedraw();
00428 }
00429
00430 void Model::LoadBlock( Worldfile* wf, int entity )
00431 {
00432 if( has_default_block )
00433 {
00434 blockgroup.Clear();
00435 has_default_block = false;
00436 }
00437
00438 blockgroup.LoadBlock( this, wf, entity );
00439 }
00440
00441
00442 Block* Model::AddBlockRect( meters_t x,
00443 meters_t y,
00444 meters_t dx,
00445 meters_t dy,
00446 meters_t dz )
00447 {
00448 UnMap();
00449
00450 std::vector<point_t> pts(4);
00451 pts[0].x = x;
00452 pts[0].y = y;
00453 pts[1].x = x + dx;
00454 pts[1].y = y;
00455 pts[2].x = x + dx;
00456 pts[2].y = y + dy;
00457 pts[3].x = x;
00458 pts[3].y = y + dy;
00459
00460 Block* newblock = new Block( this,
00461 pts,
00462 0, dz,
00463 color,
00464 true,
00465 false );
00466
00467 blockgroup.AppendBlock( newblock );
00468
00469 Map();
00470
00471 return newblock;
00472 }
00473
00474
00475 RaytraceResult Model::Raytrace( const Pose &pose,
00476 const meters_t range,
00477 const ray_test_func_t func,
00478 const void* arg,
00479 const bool ztest )
00480 {
00481 return world->Raytrace( LocalToGlobal(pose),
00482 range,
00483 func,
00484 this,
00485 arg,
00486 ztest );
00487 }
00488
00489 RaytraceResult Model::Raytrace( const radians_t bearing,
00490 const meters_t range,
00491 const ray_test_func_t func,
00492 const void* arg,
00493 const bool ztest )
00494 {
00495 return world->Raytrace( LocalToGlobal(Pose(0,0,0,bearing)),
00496 range,
00497 func,
00498 this,
00499 arg,
00500 ztest );
00501 }
00502
00503
00504 void Model::Raytrace( const radians_t bearing,
00505 const meters_t range,
00506 const radians_t fov,
00507 const ray_test_func_t func,
00508 const void* arg,
00509 RaytraceResult* samples,
00510 const uint32_t sample_count,
00511 const bool ztest )
00512 {
00513 world->Raytrace( LocalToGlobal(Pose( 0,0,0,bearing)),
00514 range,
00515 fov,
00516 func,
00517 this,
00518 arg,
00519 samples,
00520 sample_count,
00521 ztest );
00522 }
00523
00524
00525 Pose Model::GlobalToLocal( const Pose& pose ) const
00526 {
00527
00528 const Pose org( GetGlobalPose() );
00529 const double cosa(cos(org.a));
00530 const double sina(sin(org.a));
00531
00532
00533 return Pose( (pose.x - org.x) * cosa + (pose.y - org.y) * sina,
00534 -(pose.x - org.x) * sina + (pose.y - org.y) * cosa,
00535 pose.z - org.z,
00536 pose.a - org.a );
00537 }
00538
00539 void Model::Say( const std::string& str )
00540 {
00541 say_string = str;
00542 }
00543
00544
00545 bool Model::IsAntecedent( const Model* testmod ) const
00546 {
00547 if( parent == NULL )
00548 return false;
00549
00550 if( parent == testmod )
00551 return true;
00552
00553 return parent->IsAntecedent( testmod );
00554 }
00555
00556
00557 bool Model::IsDescendent( const Model* testmod ) const
00558 {
00559 if( this == testmod )
00560 return true;
00561
00562 FOR_EACH( it, children )
00563 if( (*it)->IsDescendent( testmod ) )
00564 return true;
00565
00566
00567 return false;
00568 }
00569
00570 bool Model::IsRelated( const Model* that ) const
00571 {
00572
00573 if( this == that )
00574 return true;
00575
00576
00577 Model* candidate = (Model*)this;
00578 while( candidate->parent )
00579 {
00580
00581 if( candidate->parent == that )
00582 return true;
00583
00584 candidate = candidate->parent;
00585 }
00586
00587
00588 return candidate->IsDescendent( that );
00589
00590
00591 }
00592
00593 point_t Model::LocalToGlobal( const point_t& pt) const
00594 {
00595 const Pose gpose = LocalToGlobal( Pose( pt.x, pt.y, 0, 0 ) );
00596 return point_t( gpose.x, gpose.y );
00597 }
00598
00599
00600 std::vector<point_int_t> Model::LocalToPixels( const std::vector<point_t>& local ) const
00601 {
00602 std::vector<point_int_t> global;
00603
00604 const Pose gpose( GetGlobalPose() + geom.pose );
00605 Pose ptpose;
00606
00607 FOR_EACH( it, local )
00608 {
00609 ptpose = gpose + Pose( it->x, it->y, 0, 0 );
00610 global.push_back( point_int_t( (int32_t)floor( ptpose.x * world->ppm) ,
00611 (int32_t)floor( ptpose.y * world->ppm) ));
00612 }
00613
00614 return global;
00615 }
00616
00617 void Model::MapWithChildren( unsigned int layer )
00618 {
00619 UnMap(layer);
00620 Map(layer);
00621
00622
00623 FOR_EACH( it, children )
00624 (*it)->MapWithChildren(layer);
00625 }
00626
00627 void Model::MapFromRoot( unsigned int layer )
00628 {
00629 Root()->MapWithChildren(layer);
00630 }
00631
00632 void Model::UnMapWithChildren(unsigned int layer)
00633 {
00634 UnMap(layer);
00635
00636
00637 FOR_EACH( it, children )
00638 (*it)->UnMapWithChildren(layer);
00639 }
00640
00641 void Model::UnMapFromRoot(unsigned int layer)
00642 {
00643 Root()->UnMapWithChildren(layer);
00644 }
00645
00646 void Model::Subscribe( void )
00647 {
00648 subs++;
00649 world->total_subs++;
00650 world->dirty = true;
00651
00652
00653
00654
00655 if( subs == 1 )
00656 Startup();
00657 }
00658
00659 void Model::Unsubscribe( void )
00660 {
00661 subs--;
00662 world->total_subs--;
00663 world->dirty = true;
00664
00665
00666
00667
00668 if( subs == 0 )
00669 this->Shutdown();
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 void Model::Print( char* prefix ) const
00681 {
00682 if( prefix )
00683 printf( "%s model ", prefix );
00684 else
00685 printf( "Model ");
00686
00687 printf( "%s:%s\n",
00688 world->Token(),
00689 Token() );
00690
00691 FOR_EACH( it, children )
00692 (*it)->Print( prefix );
00693 }
00694
00695 const char* Model::PrintWithPose() const
00696 {
00697 const Pose gpose = GetGlobalPose();
00698
00699 static char txt[256];
00700 snprintf(txt, sizeof(txt), "%s @ [%.2f,%.2f,%.2f,%.2f]",
00701 Token(),
00702 gpose.x, gpose.y, gpose.z, gpose.a );
00703
00704 return txt;
00705 }
00706
00707 void Model::Startup( void )
00708 {
00709
00710
00711
00712
00713 event_queue_num = thread_safe ? world->GetEventQueue( this ) : 0;
00714
00715 world->Enqueue( event_queue_num, interval, this, UpdateWrapper, NULL );
00716
00717 if( FindPowerPack() )
00718 world->EnableEnergy( this );
00719
00720 CallCallbacks( CB_STARTUP );
00721 }
00722
00723 void Model::Shutdown( void )
00724 {
00725
00726 CallCallbacks( CB_SHUTDOWN );
00727
00728 world->DisableEnergy( this );
00729
00730
00731 NeedRedraw();
00732 }
00733
00734
00735 void Model::Update( void )
00736 {
00737
00738
00739
00740
00741 last_update = world->sim_time;
00742
00743 if( subs > 0 )
00744 world->Enqueue( event_queue_num, interval, this, UpdateWrapper, NULL );
00745
00746
00747
00748
00749
00750
00751
00752 if( ! callbacks[Model::CB_UPDATE].empty() )
00753 world->pending_update_callbacks[event_queue_num].push(this);
00754 }
00755
00756 void Model::CallUpdateCallbacks( void )
00757 {
00758 CallCallbacks( CB_UPDATE );
00759 }
00760
00761 meters_t Model::ModelHeight() const
00762 {
00763 meters_t m_child = 0;
00764 FOR_EACH( it, children )
00765 m_child = std::max( m_child, (*it)->ModelHeight() );
00766
00767
00768 return geom.size.z + m_child;
00769 }
00770
00771 void Model::AddToPose( double dx, double dy, double dz, double da )
00772 {
00773 Pose p( this->pose );
00774 p.x += dx;
00775 p.y += dy;
00776 p.z += dz;
00777 p.a += da;
00778
00779 this->SetPose( p );
00780 }
00781
00782 void Model::AddToPose( const Pose& pose )
00783 {
00784 this->AddToPose( pose.x, pose.y, pose.z, pose.a );
00785 }
00786
00787 void Model::PlaceInFreeSpace( meters_t xmin, meters_t xmax,
00788 meters_t ymin, meters_t ymax )
00789 {
00790 while( TestCollision() )
00791 SetPose( Pose::Random( xmin,xmax, ymin, ymax ));
00792 }
00793
00794 void Model::AppendTouchingModels( std::set<Model*>& touchers )
00795 {
00796 blockgroup.AppendTouchingModels( touchers );
00797 }
00798
00799
00800 Model* Model::TestCollision()
00801 {
00802 Model* hitmod( blockgroup.TestCollision() );
00803
00804 if( hitmod == NULL )
00805 FOR_EACH( it, children )
00806 {
00807 hitmod = (*it)->TestCollision();
00808 if( hitmod )
00809 break;
00810 }
00811
00812
00813 return hitmod;
00814 }
00815
00816 void Model::UpdateCharge()
00817 {
00818 PowerPack* mypp = FindPowerPack();
00819 assert( mypp );
00820
00821 if( watts > 0 )
00822 {
00823
00824 mypp->Dissipate( watts * (interval_energy * 1e-6), GetGlobalPose() );
00825 }
00826
00827 if( watts_give > 0 )
00828 {
00829
00830 FOR_EACH( it, pps_charging )
00831 (*it)->ChargeStop();
00832 pps_charging.clear();
00833
00834
00835 std::set<Model*> touchers;
00836 AppendTouchingModels( touchers );
00837
00838 FOR_EACH( it, touchers )
00839 {
00840 Model* toucher = (*it);
00841 PowerPack* hispp =toucher->FindPowerPack();
00842
00843 if( hispp && toucher->watts_take > 0.0)
00844 {
00845
00846
00847
00848 const watts_t rate = std::min( watts_give, toucher->watts_take );
00849 const joules_t amount = rate * interval_energy * 1e-6;
00850
00851
00852
00853
00854
00855 hispp->ChargeStart();
00856
00857
00858 mypp->TransferTo( hispp, amount );
00859
00860
00861 pps_charging.push_front( hispp );
00862 }
00863 }
00864 }
00865 }
00866
00867
00868 void Model::UpdateTrail()
00869 {
00870
00871 TrailItem* item = &trail[trail_index++];
00872
00873
00874 item->time = world->sim_time;
00875 item->pose = GetGlobalPose();
00876 item->color = color;
00877
00878
00879 trail_index %= trail_length;
00880 }
00881
00882 Model* Model::GetUnsubscribedModelOfType( const std::string& type ) const
00883 {
00884 if( (this->type == type) && (this->subs == 0) )
00885 return const_cast<Model*> (this);
00886
00887
00888 FOR_EACH( it, children )
00889 {
00890 Model* found = (*it)->GetUnsubscribedModelOfType( type );
00891 if( found )
00892 return found;
00893 }
00894
00895
00896 return NULL;
00897 }
00898
00899 void Model::NeedRedraw( void )
00900 {
00901 this->rebuild_displaylist = true;
00902
00903 if( parent )
00904 parent->NeedRedraw();
00905 else
00906 world->NeedRedraw();
00907 }
00908
00909 void Model::Redraw( void )
00910 {
00911 world->Redraw();
00912 }
00913
00914 Model* Model::GetUnusedModelOfType( const std::string& type )
00915 {
00916
00917
00918 if( (this->type == type) && (!this->used ) )
00919 {
00920 this->used = true;
00921 return this;
00922 }
00923
00924
00925 FOR_EACH( it, children )
00926 {
00927 Model* found = (*it)->GetUnusedModelOfType( type );
00928 if( found )
00929 return found;
00930 }
00931
00932
00933 if( ! parent ) PRINT_WARN1( "Request for unused model of type %s failed", type.c_str() );
00934 return NULL;
00935 }
00936
00937 kg_t Model::GetTotalMass() const
00938 {
00939 kg_t sum = mass;
00940
00941 FOR_EACH( it, children )
00942 sum += (*it)->GetTotalMass();
00943
00944 return sum;
00945 }
00946
00947 kg_t Model::GetMassOfChildren() const
00948 {
00949 return( GetTotalMass() - mass);
00950 }
00951
00952 void Model::Map( unsigned int layer )
00953 {
00954 if( ! mapped )
00955 {
00956
00957 blockgroup.Map( layer );
00958 mapped = true;
00959 }
00960 }
00961
00962 void Model::UnMap( unsigned int layer )
00963 {
00964 if( mapped )
00965 {
00966 blockgroup.UnMap(layer);
00967 mapped = false;
00968 }
00969 }
00970
00971 void Model::BecomeParentOf( Model* child )
00972 {
00973 if( child->parent )
00974 child->parent->RemoveChild( child );
00975 else
00976 world->RemoveChild( child );
00977
00978 child->parent = this;
00979
00980 this->AddChild( child );
00981
00982 world->dirty = true;
00983 }
00984
00985 PowerPack* Model::FindPowerPack() const
00986 {
00987 if( power_pack )
00988 return power_pack;
00989
00990 if( parent )
00991 return parent->FindPowerPack();
00992
00993 return NULL;
00994 }
00995
00996 void Model::RegisterOption( Option* opt )
00997 {
00998 world->RegisterOption( opt );
00999 }
01000
01001
01002 void Model::Rasterize( uint8_t* data,
01003 unsigned int width,
01004 unsigned int height,
01005 meters_t cellwidth,
01006 meters_t cellheight )
01007 {
01008 rastervis.ClearPts();
01009 blockgroup.Rasterize( data, width, height, cellwidth, cellheight );
01010 rastervis.SetData( data, width, height, cellwidth, cellheight );
01011 }
01012
01013 void Model::SetFriction( double friction )
01014 {
01015 this->friction = friction;
01016 }
01017
01018 Model* Model::GetChild( const std::string& modelname ) const
01019 {
01020
01021
01022 const std::string fullname = token + "." + modelname;
01023
01024 Model* mod = world->GetModel( fullname );
01025
01026 if( mod == NULL )
01027 PRINT_WARN1( "Model %s not found", fullname.c_str() );
01028
01029 return mod;
01030 }
01031
01032
01033
01034
01035
01036 Model::RasterVis::RasterVis()
01037 : Visualizer( "Rasterization", "raster_vis" ),
01038 data(NULL),
01039 width(0),
01040 height(0),
01041 cellwidth(0),
01042 cellheight(0),
01043 pts()
01044 {
01045
01046 }
01047
01048 void Model::RasterVis::Visualize( Model* mod, Camera* cam )
01049 {
01050 (void)cam;
01051
01052 if( data == NULL )
01053 return;
01054
01055
01056 glPushMatrix();
01057 mod->PushColor( 1,0,0,0.5 );
01058
01059 Gl::pose_inverse_shift( mod->GetGlobalPose() );
01060
01061 if( pts.size() > 0 )
01062 {
01063 glPushMatrix();
01064
01065
01066
01067
01068
01069 glPointSize( 4 );
01070 glBegin( GL_POINTS );
01071
01072 FOR_EACH( it, pts )
01073 {
01074 point_t& pt = *it;
01075 glVertex2f( pt.x, pt.y );
01076
01077 char buf[128];
01078 snprintf( buf, 127, "[%.2f x %.2f]", pt.x, pt.y );
01079 Gl::draw_string( pt.x, pt.y, 0, buf );
01080 }
01081 glEnd();
01082
01083 mod->PopColor();
01084
01085 glPopMatrix();
01086 }
01087
01088
01089 glTranslatef( -mod->geom.size.x / 2.0, -mod->geom.size.y/2.0, 0 );
01090
01091
01092 glScalef( cellwidth, cellheight, 1 );
01093
01094 mod->PushColor( 0,0,0,0.5 );
01095 glPolygonMode( GL_FRONT, GL_FILL );
01096 for( unsigned int y=0; y<height; ++y )
01097 for( unsigned int x=0; x<width; ++x )
01098 {
01099
01100 if( data[ x + y*width ] )
01101 glRectf( x, y, x+1, y+1 );
01102 }
01103
01104 glTranslatef( 0,0,0.01 );
01105
01106 mod->PushColor( 0,0,0,1 );
01107 glPolygonMode( GL_FRONT, GL_LINE );
01108 for( unsigned int y=0; y<height; ++y )
01109 for( unsigned int x=0; x<width; ++x )
01110 {
01111 if( data[ x + y*width ] )
01112 glRectf( x, y, x+1, y+1 );
01113
01114
01115
01116
01117 }
01118
01119
01120 glPolygonMode( GL_FRONT, GL_FILL );
01121
01122 mod->PopColor();
01123 mod->PopColor();
01124
01125 mod->PushColor( 0,0,0,1 );
01126 char buf[128];
01127 snprintf( buf, 127, "[%u x %u]", width, height );
01128 glTranslatef( 0,0,0.01 );
01129 Gl::draw_string( 1, height-1, 0, buf );
01130
01131 mod->PopColor();
01132
01133 glPopMatrix();
01134 }
01135
01136 void Model::RasterVis::SetData( uint8_t* data,
01137 const unsigned int width,
01138 const unsigned int height,
01139 const meters_t cellwidth,
01140 const meters_t cellheight )
01141 {
01142
01143 if( this->data )
01144 delete[] this->data;
01145 size_t len = sizeof(uint8_t) * width * height;
01146
01147 this->data = new uint8_t[len];
01148 memcpy( this->data, data, len );
01149 this->width = width;
01150 this->height = height;
01151 this->cellwidth = cellwidth;
01152 this->cellheight = cellheight;
01153 }
01154
01155
01156 void Model::RasterVis::AddPoint( const meters_t x, const meters_t y )
01157 {
01158 pts.push_back( point_t( x, y ) );
01159 }
01160
01161 void Model::RasterVis::ClearPts()
01162 {
01163 pts.clear();
01164 }
01165
01166
01167 Model::Flag::Flag( const Color& color, const double size )
01168 : color(color), size(size), displaylist(0)
01169 {
01170 }
01171
01172 Model::Flag* Model::Flag::Nibble( double chunk )
01173 {
01174 Flag* piece = NULL;
01175
01176 if( size > 0 )
01177 {
01178 chunk = std::min( chunk, this->size );
01179 piece = new Flag( this->color, chunk );
01180 this->size -= chunk;
01181 }
01182
01183 return piece;
01184 }
01185
01186
01187 void Model::Flag::SetColor( const Color& c )
01188 {
01189 color = c;
01190
01191 if( displaylist )
01192 {
01193
01194 glDeleteLists( displaylist, 1 );
01195 displaylist = 0;
01196 }
01197 }
01198
01199 void Model::Flag::SetSize( double sz )
01200 {
01201 size = sz;
01202
01203 if( displaylist )
01204 {
01205
01206 glDeleteLists( displaylist, 1 );
01207 displaylist = 0;
01208 }
01209 }
01210
01211
01212 void Model::Flag::Draw( GLUquadric* quadric )
01213 {
01214 if( displaylist == 0 )
01215 {
01216 displaylist = glGenLists(1);
01217 assert( displaylist > 0 );
01218
01219 glNewList( displaylist, GL_COMPILE );
01220
01221 glColor4f( color.r, color.g, color.b, color.a );
01222
01223 glEnable(GL_POLYGON_OFFSET_FILL);
01224 glPolygonOffset(1.0, 1.0);
01225 gluQuadricDrawStyle( quadric, GLU_FILL );
01226 gluSphere( quadric, size/2.0, 4,2 );
01227 glDisable(GL_POLYGON_OFFSET_FILL);
01228
01229
01230 glColor4f( color.r/2.0, color.g/2.0, color.b/2.0, color.a/2.0 );
01231
01232 gluQuadricDrawStyle( quadric, GLU_LINE );
01233 gluSphere( quadric, size/2.0, 4,2 );
01234
01235 glEndList();
01236 }
01237
01238 glCallList( displaylist );
01239 }
01240
01241
01242
01243 void Model::SetGeom( const Geom& val )
01244 {
01245 UnMapWithChildren(0);
01246 UnMapWithChildren(1);
01247
01248 geom = val;
01249
01250 blockgroup.CalcSize();
01251
01252 NeedRedraw();
01253
01254 MapWithChildren(0);
01255 MapWithChildren(1);
01256
01257 CallCallbacks( CB_GEOM );
01258 }
01259
01260 void Model::SetColor( Color val )
01261 {
01262 color = val;
01263 NeedRedraw();
01264 }
01265
01266 void Model::SetMass( kg_t val )
01267 {
01268 mass = val;
01269 }
01270
01271 void Model::SetStall( bool val )
01272 {
01273 stall = val;
01274 }
01275
01276 void Model::SetGripperReturn( bool val )
01277 {
01278 vis.gripper_return = val;
01279 }
01280
01281 void Model::SetFiducialReturn( int val )
01282 {
01283 vis.fiducial_return = val;
01284
01285
01286
01287 if( val == 0 )
01288 world->FiducialErase( this );
01289 else
01290 world->FiducialInsert( this );
01291 }
01292
01293 void Model::SetFiducialKey( int val )
01294 {
01295 vis.fiducial_key = val;
01296 }
01297
01298 void Model::SetObstacleReturn( bool val )
01299 {
01300 vis.obstacle_return = val;
01301 }
01302
01303 void Model::SetBlobReturn( bool val )
01304 {
01305 vis.blob_return = val;
01306 }
01307
01308 void Model::SetRangerReturn( double val )
01309 {
01310 vis.ranger_return = val;
01311 }
01312
01313 void Model::SetBoundary( bool val )
01314 {
01315 boundary = val;
01316 }
01317
01318 void Model::SetGuiNose( bool val )
01319 {
01320 gui.nose = val;
01321 }
01322
01323 void Model::SetGuiMove( bool val )
01324 {
01325 gui.move = val;
01326 }
01327
01328 void Model::SetGuiGrid( bool val )
01329 {
01330 gui.grid = val;
01331 }
01332
01333 void Model::SetGuiOutline( bool val )
01334 {
01335 gui.outline = val;
01336 }
01337
01338 void Model::SetWatts( watts_t val )
01339 {
01340 watts = val;
01341 }
01342
01343 void Model::SetMapResolution( meters_t val )
01344 {
01345 map_resolution = val;
01346 }
01347
01348
01349 void Model::SetGlobalPose( const Pose& gpose )
01350 {
01351 SetPose( parent ? parent->GlobalToLocal( gpose ) : gpose );
01352 }
01353
01354 int Model::SetParent( Model* newparent)
01355 {
01356 Pose oldPose = GetGlobalPose();
01357
01358
01359 if( parent )
01360 parent->RemoveChild( this );
01361 else
01362 world->RemoveChild( this );
01363
01364 this->parent = newparent;
01365
01366 if( newparent )
01367 newparent->AddChild( this );
01368 else
01369 world->AddModel( this );
01370
01371 CallCallbacks( CB_PARENT );
01372
01373 SetGlobalPose( oldPose );
01374
01375 return 0;
01376 }
01377
01378
01379 Pose Model::GetGlobalPose() const
01380 {
01381
01382 if( parent == NULL )
01383 return pose;
01384
01385
01386 Pose global_pose = parent->GetGlobalPose() + pose;
01387
01388 if ( parent->stack_children )
01389 global_pose.z += parent->geom.size.z;
01390
01391 return global_pose;
01392 }
01393
01394
01395
01396 void Model::SetPose( const Pose& newpose )
01397 {
01398
01399 if( memcmp( &pose, &newpose, sizeof(Pose) ) != 0 )
01400 {
01401 pose = newpose;
01402 pose.a = normalize(pose.a);
01403
01404
01405
01406
01407
01408 NeedRedraw();
01409
01410 UnMapWithChildren(0);
01411 UnMapWithChildren(1);
01412
01413 MapWithChildren(0);
01414 MapWithChildren(1);
01415
01416 world->dirty = true;
01417 }
01418
01419 CallCallbacks( CB_POSE );
01420 }
01421
01422 void Model::Load()
01423 {
01424 assert( wf );
01425 assert( wf_entity );
01426
01427 PRINT_DEBUG1( "Model \"%s\" loading...", token.c_str() );
01428
01429
01430 event_queue_num = wf->ReadInt( wf_entity, "event_queue", event_queue_num );
01431
01432 if( wf->PropertyExists( wf_entity, "joules" ) )
01433 {
01434 if( !power_pack )
01435 power_pack = new PowerPack( this );
01436
01437 joules_t j = wf->ReadFloat( wf_entity, "joules",
01438 power_pack->GetStored() ) ;
01439
01440
01441
01442 power_pack->SetStored( j );
01443 power_pack->SetCapacity( j );
01444 }
01445
01446 if( wf->PropertyExists( wf_entity, "joules_capacity" ) )
01447 {
01448 if( !power_pack )
01449 power_pack = new PowerPack( this );
01450
01451 power_pack->SetCapacity( wf->ReadFloat( wf_entity, "joules_capacity",
01452 power_pack->GetCapacity() ) );
01453 }
01454
01455 if( wf->PropertyExists( wf_entity, "kjoules" ) )
01456 {
01457 if( !power_pack )
01458 power_pack = new PowerPack( this );
01459
01460 joules_t j = 1000.0 * wf->ReadFloat( wf_entity, "kjoules",
01461 power_pack->GetStored() ) ;
01462
01463
01464
01465 power_pack->SetStored( j );
01466 power_pack->SetCapacity( j );
01467 }
01468
01469 if( wf->PropertyExists( wf_entity, "kjoules_capacity" ) )
01470 {
01471 if( !power_pack )
01472 power_pack = new PowerPack( this );
01473
01474 power_pack->SetCapacity( 1000.0 * wf->ReadFloat( wf_entity, "kjoules_capacity",
01475 power_pack->GetCapacity() ) );
01476 }
01477
01478
01479 watts = wf->ReadFloat( wf_entity, "watts", watts );
01480 watts_give = wf->ReadFloat( wf_entity, "give_watts", watts_give );
01481 watts_take = wf->ReadFloat( wf_entity, "take_watts", watts_take );
01482
01483 debug = wf->ReadInt( wf_entity, "debug", debug );
01484
01485 const std::string& name = wf->ReadString(wf_entity, "name", token );
01486 if( name != token )
01487 SetToken( name );
01488
01489
01490
01491 Geom g( GetGeom() );
01492
01493 if( wf->PropertyExists( wf_entity, "origin" ) )
01494 g.pose.Load( wf, wf_entity, "origin" );
01495
01496 if( wf->PropertyExists( wf_entity, "size" ) )
01497 g.size.Load( wf, wf_entity, "size" );
01498
01499 SetGeom( g );
01500
01501 if( wf->PropertyExists( wf_entity, "pose" ))
01502 SetPose( GetPose().Load( wf, wf_entity, "pose" ) );
01503
01504
01505 if( wf->PropertyExists( wf_entity, "color" ))
01506 {
01507 Color col( 1,0,0 );
01508 const std::string& colorstr = wf->ReadString( wf_entity, "color", "" );
01509 if( colorstr != "" )
01510 {
01511 if( colorstr == "random" )
01512 col = Color( drand48(), drand48(), drand48() );
01513 else
01514 col = Color( colorstr );
01515 }
01516 this->SetColor( col );
01517 }
01518
01519 this->SetColor( GetColor().Load( wf, wf_entity ) );
01520
01521 if( wf->ReadInt( wf_entity, "noblocks", 0 ) )
01522 {
01523 if( has_default_block )
01524 {
01525 blockgroup.Clear();
01526 has_default_block = false;
01527 blockgroup.CalcSize();
01528 }
01529 }
01530
01531 if( wf->PropertyExists( wf_entity, "bitmap" ) )
01532 {
01533 const std::string bitmapfile = wf->ReadString( wf_entity, "bitmap", "" );
01534 if( bitmapfile == "" )
01535 PRINT_WARN1( "model %s specified empty bitmap filename\n", Token() );
01536
01537 if( has_default_block )
01538 {
01539 blockgroup.Clear();
01540 has_default_block = false;
01541 }
01542
01543 blockgroup.LoadBitmap( this, bitmapfile, wf );
01544 }
01545
01546 if( wf->PropertyExists( wf_entity, "boundary" ))
01547 {
01548 this->SetBoundary( wf->ReadInt(wf_entity, "boundary", this->boundary ));
01549
01550 if( boundary )
01551 {
01552
01553
01554 blockgroup.CalcSize();
01555
01556 double epsilon = 0.01;
01557 Size bgsize = blockgroup.GetSize();
01558
01559 AddBlockRect(blockgroup.minx,blockgroup.miny, epsilon, bgsize.y, bgsize.z );
01560 AddBlockRect(blockgroup.minx,blockgroup.miny, bgsize.x, epsilon, bgsize.z );
01561 AddBlockRect(blockgroup.minx,blockgroup.maxy-epsilon, bgsize.x, epsilon, bgsize.z );
01562 AddBlockRect(blockgroup.maxx-epsilon,blockgroup.miny, epsilon, bgsize.y, bgsize.z );
01563 }
01564 }
01565
01566 this->stack_children =
01567 wf->ReadInt( wf_entity, "stack_children", this->stack_children );
01568
01569 kg_t m = wf->ReadFloat(wf_entity, "mass", this->mass );
01570 if( m != this->mass )
01571 SetMass( m );
01572
01573 vis.Load( wf, wf_entity );
01574 SetFiducialReturn( vis.fiducial_return );
01575
01576 gui.Load( wf, wf_entity );
01577
01578 double res = wf->ReadFloat(wf_entity, "map_resolution", this->map_resolution );
01579 if( res != this->map_resolution )
01580 SetMapResolution( res );
01581
01582 if( wf->PropertyExists( wf_entity, "friction" ))
01583 {
01584 this->SetFriction( wf->ReadFloat(wf_entity, "friction", this->friction ));
01585 }
01586
01587 if( CProperty* ctrlp = wf->GetProperty( wf_entity, "ctrl" ) )
01588 {
01589 for( unsigned int index=0; index < ctrlp->values.size(); index++ )
01590 {
01591
01592 const char* lib = wf->GetPropertyValue( ctrlp, index );
01593
01594 if( !lib )
01595 printf( "Error - NULL library name specified for model %s\n", Token() );
01596 else
01597 LoadControllerModule( lib );
01598 }
01599 }
01600
01601
01602 interval = 1000 * wf->ReadInt( wf_entity, "update_interval", interval/1000 );
01603
01604 Say( wf->ReadString(wf_entity, "say", "" ));
01605
01606 trail_length = wf->ReadInt( wf_entity, "trail_length", trail_length );
01607 trail.resize( trail_length );
01608
01609 trail_interval = wf->ReadInt( wf_entity, "trail_interval", trail_interval );
01610
01611 this->alwayson = wf->ReadInt( wf_entity, "alwayson", alwayson );
01612 if( alwayson )
01613 Subscribe();
01614
01615
01616 this->CallCallbacks( CB_LOAD );
01617
01618
01619 blockgroup.CalcSize();
01620
01621 UnMapWithChildren(0);
01622 UnMapWithChildren(1);
01623 MapWithChildren(0);
01624 MapWithChildren(1);
01625
01626 if( this->debug )
01627 printf( "Model \"%s\" is in debug mode\n", Token() );
01628
01629 PRINT_DEBUG1( "Model \"%s\" loading complete", Token() );
01630 }
01631
01632
01633 void Model::Save( void )
01634 {
01635
01636
01637
01638 if( wf == NULL )
01639 return;
01640
01641 assert( wf_entity );
01642
01643 PRINT_DEBUG5( "saving model %s pose [ %.2f, %.2f, %.2f, %.2f]",
01644 token.c_str(),
01645 pose.x,
01646 pose.y,
01647 pose.z,
01648 pose.a );
01649
01650
01651 pose.a = normalize( pose.a );
01652 geom.pose.a = normalize( geom.pose.a );
01653
01654 if( wf->PropertyExists( wf_entity, "pose" ) )
01655 pose.Save( wf, wf_entity, "pose" );
01656
01657 if( wf->PropertyExists( wf_entity, "size" ) )
01658 geom.size.Save( wf, wf_entity, "size" );
01659
01660 if( wf->PropertyExists( wf_entity, "origin" ) )
01661 geom.pose.Save( wf, wf_entity, "origin" );
01662
01663 vis.Save( wf, wf_entity );
01664
01665
01666 CallCallbacks( CB_SAVE );
01667
01668 PRINT_DEBUG1( "Model \"%s\" saving complete.", token.c_str() );
01669 }
01670
01671
01672 void Model::LoadControllerModule( const char* lib )
01673 {
01674
01675
01676
01677
01678 int errors = lt_dlinit();
01679 if (errors)
01680 {
01681 printf( "Libtool error: %s. Failed to init libtool. Quitting\n",
01682 lt_dlerror() );
01683 puts( "libtool error #1" );
01684 fflush( stdout );
01685 exit(-1);
01686 }
01687
01688 lt_dlsetsearchpath( FileManager::stagePath().c_str() );
01689
01690
01691 lt_dladdsearchdir( PLUGIN_PATH );
01692
01693 lt_dlhandle handle = NULL;
01694
01695
01696 char libname[256];
01697 sscanf( lib, "%s %*s", libname );
01698
01699 if(( handle = lt_dlopenext( libname ) ))
01700 {
01701
01702
01703 model_callback_t initfunc = (model_callback_t)lt_dlsym( handle, "Init" );
01704 if( initfunc == NULL )
01705 {
01706 printf( "Libtool error: %s. Something is wrong with your plugin. Quitting\n",
01707 lt_dlerror() );
01708 puts( "libtool error #1" );
01709 fflush( stdout );
01710 exit(-1);
01711 }
01712
01713 AddCallback( CB_INIT, initfunc, new CtrlArgs(lib,World::ctrlargs) );
01714 }
01715 else
01716 {
01717 printf( "Libtool error: %s. Can't open your plugin controller. Quitting\n",
01718 lt_dlerror() );
01719
01720 PRINT_ERR1( "Failed to open \"%s\". Check that it can be found by searching the directories in your STAGEPATH environment variable, or the current directory if STAGEPATH is not set.]\n", lib );
01721 puts( "libtool error #2" );
01722 fflush( stdout );
01723 exit(-1);
01724 }
01725
01726 fflush(stdout);
01727 }
01728