00001 00002 // Copyright (C) 2012, hiDOF INC. 00003 // Copyright (C) 2013, PAL Robotics S.L. 00004 // 00005 // Redistribution and use in source and binary forms, with or without 00006 // modification, are permitted provided that the following conditions are met: 00007 // * Redistributions of source code must retain the above copyright notice, 00008 // this list of conditions and the following disclaimer. 00009 // * Redistributions in binary form must reproduce the above copyright 00010 // notice, this list of conditions and the following disclaimer in the 00011 // documentation and/or other materials provided with the distribution. 00012 // * Neither the name of PAL Robotics S.L. nor the names of its 00013 // contributors may be used to endorse or promote products derived from 00014 // this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00019 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00020 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00021 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00022 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00023 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00024 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00025 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00026 // POSSIBILITY OF SUCH DAMAGE. 00028 00030 00031 00032 #include "imu_sensor_controller/imu_sensor_controller.h" 00033 00034 00035 00036 namespace imu_sensor_controller 00037 { 00038 00039 bool ImuSensorController::init(hardware_interface::ImuSensorInterface* hw, ros::NodeHandle &root_nh, ros::NodeHandle& controller_nh) 00040 { 00041 // get all joint states from the hardware interface 00042 const std::vector<std::string>& sensor_names = hw->getNames(); 00043 for (unsigned i=0; i<sensor_names.size(); i++) 00044 ROS_DEBUG("Got sensor %s", sensor_names[i].c_str()); 00045 00046 // get publishing period 00047 if (!controller_nh.getParam("publish_rate", publish_rate_)){ 00048 ROS_ERROR("Parameter 'publish_rate' not set"); 00049 return false; 00050 } 00051 00052 for (unsigned i=0; i<sensor_names.size(); i++){ 00053 // sensor handle 00054 sensors_.push_back(hw->getHandle(sensor_names[i])); 00055 00056 // realtime publisher 00057 RtPublisherPtr rt_pub(new realtime_tools::RealtimePublisher<sensor_msgs::Imu>(root_nh, sensor_names[i], 4)); 00058 realtime_pubs_.push_back(rt_pub); 00059 } 00060 00061 // Last published times 00062 last_publish_times_.resize(sensor_names.size()); 00063 return true; 00064 } 00065 00066 void ImuSensorController::starting(const ros::Time& time) 00067 { 00068 // initialize time 00069 for (unsigned i=0; i<last_publish_times_.size(); i++){ 00070 last_publish_times_[i] = time; 00071 } 00072 } 00073 00074 void ImuSensorController::update(const ros::Time& time, const ros::Duration& /*period*/) 00075 { 00076 using namespace hardware_interface; 00077 00078 // limit rate of publishing 00079 for (unsigned i=0; i<realtime_pubs_.size(); i++){ 00080 if (publish_rate_ > 0.0 && last_publish_times_[i] + ros::Duration(1.0/publish_rate_) < time){ 00081 // try to publish 00082 if (realtime_pubs_[i]->trylock()){ 00083 // we're actually publishing, so increment time 00084 last_publish_times_[i] = last_publish_times_[i] + ros::Duration(1.0/publish_rate_); 00085 00086 // populate message 00087 realtime_pubs_[i]->msg_.header.stamp = time; 00088 realtime_pubs_[i]->msg_.header.frame_id = sensors_[i].getFrameId(); 00089 00090 // Orientation 00091 if (sensors_[i].getOrientation()) 00092 { 00093 realtime_pubs_[i]->msg_.orientation.x = sensors_[i].getOrientation()[0]; 00094 realtime_pubs_[i]->msg_.orientation.y = sensors_[i].getOrientation()[1]; 00095 realtime_pubs_[i]->msg_.orientation.z = sensors_[i].getOrientation()[2]; 00096 realtime_pubs_[i]->msg_.orientation.w = sensors_[i].getOrientation()[3]; 00097 } 00098 00099 // Orientation covariance 00100 if (sensors_[i].getOrientationCovariance()) 00101 { 00102 for (unsigned j=0; j<realtime_pubs_[i]->msg_.orientation_covariance.size(); ++j){ 00103 realtime_pubs_[i]->msg_.orientation_covariance[j] = sensors_[i].getOrientationCovariance()[j]; 00104 } 00105 } 00106 else 00107 { 00108 if (sensors_[i].getOrientation()) 00109 { 00110 // Orientation available 00111 for (unsigned j=0; j<realtime_pubs_[i]->msg_.orientation_covariance.size(); ++j){ 00112 realtime_pubs_[i]->msg_.orientation_covariance[j] = 0.0; 00113 } 00114 } 00115 else 00116 { 00117 // No orientation available 00118 realtime_pubs_[i]->msg_.orientation_covariance[0] = -1.0; 00119 } 00120 } 00121 00122 // Angular velocity 00123 if (sensors_[i].getAngularVelocity()) 00124 { 00125 realtime_pubs_[i]->msg_.angular_velocity.x = sensors_[i].getAngularVelocity()[0]; 00126 realtime_pubs_[i]->msg_.angular_velocity.y = sensors_[i].getAngularVelocity()[1]; 00127 realtime_pubs_[i]->msg_.angular_velocity.z = sensors_[i].getAngularVelocity()[2]; 00128 } 00129 00130 // Angular velocity covariance 00131 if (sensors_[i].getAngularVelocityCovariance()) 00132 { 00133 for (unsigned j=0; j<realtime_pubs_[i]->msg_.angular_velocity_covariance.size(); ++j){ 00134 realtime_pubs_[i]->msg_.angular_velocity_covariance[j] = sensors_[i].getAngularVelocityCovariance()[j]; 00135 } 00136 } 00137 else 00138 { 00139 if (sensors_[i].getAngularVelocity()) 00140 { 00141 // Angular velocity available 00142 for (unsigned j=0; j<realtime_pubs_[i]->msg_.angular_velocity_covariance.size(); ++j){ 00143 realtime_pubs_[i]->msg_.angular_velocity_covariance[j] = 0.0; 00144 } 00145 } 00146 else 00147 { 00148 // No angular velocity available 00149 realtime_pubs_[i]->msg_.angular_velocity_covariance[0] = -1.0; 00150 } 00151 } 00152 00153 // Linear acceleration 00154 if (sensors_[i].getLinearAcceleration()) 00155 { 00156 realtime_pubs_[i]->msg_.linear_acceleration.x = sensors_[i].getLinearAcceleration()[0]; 00157 realtime_pubs_[i]->msg_.linear_acceleration.y = sensors_[i].getLinearAcceleration()[1]; 00158 realtime_pubs_[i]->msg_.linear_acceleration.z = sensors_[i].getLinearAcceleration()[2]; 00159 } 00160 00161 // Linear acceleration covariance 00162 if (sensors_[i].getLinearAccelerationCovariance()) 00163 { 00164 for (unsigned j=0; j<realtime_pubs_[i]->msg_.linear_acceleration_covariance.size(); ++j){ 00165 realtime_pubs_[i]->msg_.linear_acceleration_covariance[j] = sensors_[i].getLinearAccelerationCovariance()[j]; 00166 } 00167 } 00168 else 00169 { 00170 if (sensors_[i].getLinearAcceleration()) 00171 { 00172 // Linear acceleration available 00173 for (unsigned j=0; j<realtime_pubs_[i]->msg_.linear_acceleration_covariance.size(); ++j){ 00174 realtime_pubs_[i]->msg_.linear_acceleration_covariance[j] = 0.0; 00175 } 00176 } 00177 else 00178 { 00179 // No linear acceleration available 00180 realtime_pubs_[i]->msg_.linear_acceleration_covariance[0] = -1.0; 00181 } 00182 } 00183 00184 realtime_pubs_[i]->unlockAndPublish(); 00185 } 00186 } 00187 } 00188 } 00189 00190 void ImuSensorController::stopping(const ros::Time& /*time*/) 00191 {} 00192 00193 } 00194 00195 PLUGINLIB_EXPORT_CLASS(imu_sensor_controller::ImuSensorController, controller_interface::ControllerBase)