00001 /* 00002 * Copyright (C) 2012-2016 Open Source Robotics Foundation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 */ 00017 00018 #include <limits> 00019 #include <string> 00020 00021 #include "ObjectDisposalPlugin.hh" 00022 #include <gazebo/transport/Node.hh> 00023 00024 using namespace gazebo; 00025 GZ_REGISTER_MODEL_PLUGIN(ObjectDisposalPlugin) 00026 00027 00028 ObjectDisposalPlugin::ObjectDisposalPlugin() : SideContactPlugin() 00029 { 00030 } 00031 00033 ObjectDisposalPlugin::~ObjectDisposalPlugin() 00034 { 00035 event::Events::DisconnectWorldUpdateBegin(this->updateConnection); 00036 this->parentSensor.reset(); 00037 this->world.reset(); 00038 } 00039 00041 void ObjectDisposalPlugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf) 00042 { 00043 SideContactPlugin::Load(_model, _sdf); 00044 this->centerOfGravityCheck = false; 00045 if (_sdf->HasElement("center_of_gravity_check")) 00046 { 00047 this->centerOfGravityCheck = _sdf->Get<bool>("center_of_gravity_check"); 00048 } 00049 } 00050 00052 void ObjectDisposalPlugin::OnUpdate(const common::UpdateInfo &/*_info*/) 00053 { 00054 this->CalculateContactingModels(); 00055 this->ActOnContactingModels(); 00056 } 00057 00059 void ObjectDisposalPlugin::ActOnContactingModels() 00060 { 00061 // Only remove models if their center of gravity is "above" the link 00062 // TODO: make more general than just z axis 00063 auto linkBox = this->parentLink->GetBoundingBox(); 00064 auto linkBoxMax = linkBox.max; 00065 auto linkBoxMin = linkBox.min; 00066 linkBoxMin.z = std::numeric_limits<double>::lowest(); 00067 linkBoxMax.z = std::numeric_limits<double>::max(); 00068 auto disposalBox = math::Box(linkBoxMin, linkBoxMax); 00069 00070 for (auto model : this->contactingModels) { 00071 if (model) { 00072 bool removeModel = true; 00073 if (this->centerOfGravityCheck) 00074 { 00075 // Calculate the center of gravity of the model 00076 math::Vector3 modelCog = math::Vector3::Zero; 00077 double modelMass = 0.0; 00078 for (auto modelLink : model->GetLinks()) 00079 { 00080 double linkMass = modelLink->GetInertial()->GetMass(); 00081 modelCog += modelLink->GetWorldCoGPose().pos * linkMass; 00082 modelMass += linkMass; 00083 } 00084 if (modelMass > 0.0) 00085 { 00086 modelCog /= modelMass; 00087 } 00088 removeModel = disposalBox.Contains(modelCog); 00089 } 00090 if (removeModel) 00091 { 00092 gzdbg << "[" << this->model->GetName() << "] Removing model: " << model->GetName() << "\n"; 00093 this->world->RemoveModel(model); 00094 } 00095 } 00096 } 00097 }