diff --git a/include/dynamixel_servo.h b/include/dynamixel_servo.h
index bd043068e4903ff0c0716a3a40c7e00baa0366b8..880d2c5b8d6b3031cbcab2f90c08f5aa8ad69ec5 100644
--- a/include/dynamixel_servo.h
+++ b/include/dynamixel_servo.h
@@ -33,9 +33,13 @@ namespace dynamixel_robot_gazebo
       void init_memory(void);
       void set_current_angle(double angle);
       void set_current_speed(double speed);
-      void set_current_effort(double effort);
+      void set_current_pwm(double pwm);
+      double saturate_command(double command);
       double get_target_angle(void);
       double get_target_speed(void);
+      double get_target_pwm(void);
+      double get_max_pwm(void);
+      bool is_position_control(void);
       void on_ping(void);
       unsigned char on_read(unsigned short int address, unsigned short int length, unsigned char *data);
       unsigned char on_write(unsigned short int address, unsigned short int length, unsigned char *data);
diff --git a/src/compliance_control.cpp b/src/compliance_control.cpp
index 03faba88cd5df5855000fde03042513090f5326c..50d5c23b2d29fec29ad6852951cc8e24de66adcd 100644
--- a/src/compliance_control.cpp
+++ b/src/compliance_control.cpp
@@ -27,17 +27,19 @@ bool CComplianceControl::init(ros::NodeHandle &nh,double max_torque,unsigned int
   this->enc_res=enc_res;
   this->max_angle=max_angle;
   this->max_torque=max_torque;
+
+  return true;
 }
 
 double CComplianceControl::control(double error)
 {
   double p,cmd;
 
-  if(fabs(error)<this->margin*this->max_angle*3.14159/(this->enc_res*180.0))
+  if(fabs(error)<this->margin*this->max_angle*3.14159/(2.0*this->enc_res*180.0))
     return 0.0;
   else
   {
-    p=this->max_torque*(this->enc_res-this->punch)*180.0/(this->slope*this->max_angle*3.14159);
+    p=this->max_torque*(this->enc_res-this->punch)*180.0/(this->enc_res*this->slope*(this->max_angle/2.0)*3.14159);
     if(error<0.0)
     {
       cmd=p*error-this->max_torque*this->punch/this->enc_res;
diff --git a/src/dynamixel_servo.cpp b/src/dynamixel_servo.cpp
index 6839362745d7a466cdc44a63549dbf9fe964ae94..5ca6b0802fed0456c8722e00d3ecce480bfa90c2 100644
--- a/src/dynamixel_servo.cpp
+++ b/src/dynamixel_servo.cpp
@@ -186,7 +186,7 @@ namespace dynamixel_robot_gazebo
     this->compliance=new CComplianceControl();
     if(!this->compliance->init(params_nh,this->max_torque,this->encoder_res,this->max_angle))
     {
-      ROS_WARN_STREAM("Dynamixel gazebo plugin: Failed to initialize Complaince params from ROS parameter server.");
+      ROS_WARN_STREAM("Dynamixel gazebo plugin: Failed to initialize Compliance params from ROS parameter server.");
       delete this->compliance;
       this->compliance=NULL;
       throw;
@@ -510,14 +510,14 @@ namespace dynamixel_robot_gazebo
     }
   }
 
-  void CDynServo::set_current_effort(double effort)
+  void CDynServo::set_current_pwm(double pwm)
   {
     unsigned int value;
 
-    if(effort<0.0)
-      value=((fabs(effort)*1023.0)/this->max_torque)+1024;
+    if(pwm<0.0)
+      value=((fabs(pwm)*1023.0)/this->max_torque)+1024;
     else
-      value=((fabs(effort)*1023.0)/this->max_torque);
+      value=((fabs(pwm)*1023.0)/this->max_torque);
     if(model=="AX12W" || model=="AX12A" || model=="AX18A" || model=="MX12W" || model=="MX28v1" || model=="MX64v1" || model=="MX106v1")
     {
       this->memory[40]=value&0x000000FF;
@@ -535,6 +535,16 @@ namespace dynamixel_robot_gazebo
     }
   }
 
+  double CDynServo::saturate_command(double command)
+  {
+    if(command>this->get_max_pwm())
+      command=this->get_max_pwm();
+    else if(command<-this->get_max_pwm())
+      command=-this->get_max_pwm();
+
+    return command;
+  }
+
   double CDynServo::get_target_angle(void)
   {
     unsigned int value=0;
@@ -579,6 +589,75 @@ namespace dynamixel_robot_gazebo
     return speed;
   }
 
+  double CDynServo::get_target_pwm(void)
+  {
+    short int value=0;
+    double pwm;
+
+    if(model=="AX12W" || model=="AX12A" || model=="AX18A" || model=="MX12W" || model=="MX28v1" || model=="MX64v1" || model=="MX106v1" || model=="XL320")
+    {
+      value=this->memory[32];
+      value+=this->memory[33]<<8;
+      if(value>1024)
+        pwm=-(value-1024)*this->max_torque/1024.0;
+      else
+        pwm=value*this->max_torque/1024.0;
+    }
+    else
+    {
+      value=this->memory[100];
+      value+=this->memory[101]<<8;
+      pwm=value*this->max_torque/885.0;
+    }
+ 
+    return pwm;
+  }
+
+  double CDynServo::get_max_pwm(void)
+  {
+    unsigned int value=0;
+    double pwm;
+
+    if(model=="AX12W" || model=="AX12A" || model=="AX18A" || model=="MX12W" || model=="MX28v1" || model=="MX64v1" || model=="MX106v1")
+    {
+      value=this->memory[14];
+      value+=this->memory[15]<<8;
+      pwm=this->max_torque*value/1024;
+    }
+    else if(model=="XL320")
+    {
+      value=this->memory[15];
+      value+=this->memory[16]<<8;
+      pwm=this->max_torque*value/1024;
+    }
+    else
+    {
+      value=this->memory[36];
+      value+=this->memory[37]<<8;
+      pwm=this->max_torque*value/885;
+    }
+ 
+    return pwm;
+  }
+
+  bool CDynServo::is_position_control(void)
+  {
+    if(model=="AX12W" || model=="AX12A" || model=="AX18A" || model=="MX12W" || model=="MX28v1" || model=="MX64v1" || model=="MX106v1" || model=="XL320")
+    {
+      if(this->memory[6]==0x00 && this->memory[7]==0x00 && this->memory[8]==0x00 && this->memory[9]==0x00)
+        return false;
+      else
+        return true;
+    }
+    else
+    {
+      if(this->memory[11]==0x03)
+        return true;
+      else
+        return false;
+    }
+  }
+
   void CDynServo::on_ping(void)
   {
   }
@@ -600,18 +679,28 @@ namespace dynamixel_robot_gazebo
 
   void CDynServo::update(const ros::Duration& period)
   {
-    double real_angle,target_angle,command=0.0;
+    double real_angle,target_angle,target_pwm,command=0.0;
 
     real_angle=this->joint.getPosition();
     this->set_current_angle(real_angle);
     this->set_current_speed(this->joint.getVelocity());
-    this->set_current_effort(this->joint.getEffort());
-    target_angle=this->get_target_angle();
-    if(this->pid!=NULL)
-      command=this->pid->computeCommand(target_angle-real_angle,period);
-    else if(this->compliance!=NULL)
-      command=this->compliance->control(target_angle-real_angle);
-    this->joint.setCommand(command);
+    this->set_current_pwm(this->joint.getEffort());
+    if(this->is_position_control())
+    {
+      target_angle=this->get_target_angle();
+      if(this->pid!=NULL)
+        command=this->pid->computeCommand(target_angle-real_angle,period);
+      else if(this->compliance!=NULL)
+        command=this->compliance->control(target_angle-real_angle);
+      command=this->saturate_command(command);
+      this->joint.setCommand(command);
+    }
+    else
+    {
+      target_pwm=this->get_target_pwm();
+      command=this->saturate_command(target_pwm);
+      this->joint.setCommand(command);
+    }
   }
 
   unsigned char CDynServo::get_id(void)