00001 #include "r2_gazebo_interface/JointController.h"
00002
00003 using namespace gazebo;
00004
00005 JointController::JointController(physics::JointPtr _jointPtr, bool _advancedMode)
00006 : jointPtr(_jointPtr)
00007 , passive(false)
00008 , position(0.)
00009 , velocity(0.)
00010 , effort(0.)
00011 , advancedMode(_advancedMode)
00012 , controlMode(POS_COM)
00013 , fault(OK)
00014 {
00015 currStatusPtr.reset(new r2_msgs::JointStatus);
00016 currStatusPtr->publisher = "GazeboSim";
00017 currStatusPtr->joint = _jointPtr->GetName();
00018
00019
00020
00021 currStatusPtr->bridgeEnabled = true;
00022 currStatusPtr->motorPowerDetected = true;
00023 currStatusPtr->embeddedMotCom = true;
00024
00025 ROS_DEBUG("GetLimits for %s", _jointPtr->GetName().c_str());
00026 jointLowLimit = _jointPtr->GetLowStop(0).Radian();
00027 jointHighLimit = _jointPtr->GetHighStop(0).Radian();
00028
00029
00030 releaseBrake(!_advancedMode);
00031 }
00032
00033 JointController::~JointController()
00034 {
00035 }
00036
00037 void JointController::setPosPid(double _p, double _i, double _d,
00038 double _imax, double _imin, double _cmdMax, double _cmdMin)
00039 {
00040 boost::mutex::scoped_lock lock(controllerMutex);
00041 posPid.Init(_p, _i, _d, _imax, _imin, _cmdMax, _cmdMin);
00042 }
00043
00044 void JointController::setVelPid(double _p, double _i, double _d,
00045 double _imax, double _imin, double _cmdMax, double _cmdMin)
00046 {
00047 boost::mutex::scoped_lock lock(controllerMutex);
00048 velPid.Init(_p, _i, _d, _imax, _imin, _cmdMax, _cmdMin);
00049 }
00050
00051 void JointController::setPosTarget(double target)
00052 {
00053 boost::mutex::scoped_lock lock(controllerMutex);
00054 position = target;
00055
00056
00057 if (!advancedMode)
00058 {
00059 controlMode = POS_COM;
00060 }
00061 }
00062
00063 void JointController::setVelTarget(double target)
00064 {
00065 boost::mutex::scoped_lock lock(controllerMutex);
00066 velocity = target;
00067
00068
00069 if (!advancedMode)
00070 {
00071 controlMode = VEL_COM;
00072 }
00073 }
00074
00075 void JointController::setEffortTarget(double target)
00076 {
00077 boost::mutex::scoped_lock lock(controllerMutex);
00078 effort = target;
00079
00080
00081 if (!advancedMode)
00082 {
00083 controlMode = TORQ_COM;
00084 }
00085 }
00086
00087 void JointController::update(common::Time& stepTime)
00088 {
00089 boost::mutex::scoped_lock lock(controllerMutex);
00090
00091 if (advancedMode && (!currStatusPtr->embeddedMotCom || !currStatusPtr->motorEnabled))
00092 {
00093
00094 return;
00095 }
00096
00097 double cmd = 0;
00098
00099 switch (controlMode)
00100 {
00101 case TORQ_COM:
00102 cmd = effort;
00103 break;
00104
00105 case POS_COM:
00106 cmd = posPid.Update(jointPtr->GetAngle(0).Radian() - position, stepTime);
00107 break;
00108
00109 case VEL_COM:
00110 cmd = velPid.Update(jointPtr->GetVelocity(0) - velocity, stepTime);
00111 break;
00112
00113 case IMP_COM:
00114 {
00115 static bool warnReported = false;
00116
00117 if (!warnReported)
00118 {
00119 ROS_WARN("GazeboInterface JointController received impedence command which is unsupported. This message will only be shown once.");
00120 warnReported = true;
00121 }
00122
00123 break;
00124 }
00125
00126 default:
00127 {
00128 static bool warnReported = false;
00129
00130 if (!warnReported)
00131 {
00132 ROS_WARN("GazeboInterface JointController received unsupported joint command. This message will only be shown once.");
00133 warnReported = true;
00134 }
00135 }
00136 }
00137
00138 jointPtr->SetForce(0, cmd);
00139 }
00140
00141 void JointController::setJointControl(const r2_msgs::JointControl::ConstPtr& msg)
00142 {
00143 if (msg->joint != currStatusPtr->joint)
00144 {
00145 ROS_WARN("GazeboInterface setJointControl %s recieved control command for the wrong joint (%s), ignored",
00146 currStatusPtr->joint.c_str(), msg->joint.c_str());
00147 return;
00148 }
00149 else
00150 {
00151 boost::mutex::scoped_lock lock(controllerMutex);
00152
00153
00154 currStatusPtr->bridgeEnabled = msg->enableBridge;
00155 currStatusPtr->motorEnabled = msg->enableMotor;
00156 currStatusPtr->embeddedMotCom = msg->embeddedMotCom;
00157 controlMode = (JointControlMode)msg->controlMode;
00158 lock.unlock();
00159
00160 if (msg->clearFaults)
00161 {
00162 clearFaults();
00163 }
00164
00165 releaseBrake(msg->releaseBrake);
00166 }
00167 }
00168
00169 const r2_msgs::JointStatus& JointController::getJointStatus() const
00170 {
00171 return *currStatusPtr;
00172 }
00173
00174 void JointController::clearFaults()
00175 {
00176 boost::mutex::scoped_lock lock(controllerMutex);
00177 fault = OK;
00178 currStatusPtr->jointFaulted = false;
00179 }
00180
00181 void JointController::releaseBrake(bool release)
00182 {
00183 boost::mutex::scoped_lock lock(controllerMutex);
00184 ROS_DEBUG("%s brake for %s", release ? "release" : "set", jointPtr->GetName().c_str());
00185
00186 if (release)
00187 {
00188 jointPtr->SetHighStop(0, jointHighLimit);
00189 jointPtr->SetLowStop(0, jointLowLimit);
00190 }
00191 else
00192 {
00193 math::Angle currAngle = jointPtr->GetAngle(0);
00194 jointPtr->SetHighStop(0, currAngle);
00195 jointPtr->SetLowStop(0, currAngle);
00196 }
00197
00198 currStatusPtr->brakeReleased = release;
00199 }