diff --git a/include/dynamixel_servo.h b/include/dynamixel_servo.h
index 294edcc5bd3d8a8cecbc308f52dbf7237793791e..bd15fb6dbdecd4311416add58f60a391087bb4cc 100644
--- a/include/dynamixel_servo.h
+++ b/include/dynamixel_servo.h
@@ -6,19 +6,26 @@
 #include <boost/shared_ptr.hpp>
 
 #include "dynamixel_slave_serial.h"
+#include "compliance_control.h"
 
 namespace dynamixel_robot_gazebo
 {
+  #define SERVO_MEM_SIZE   147
+
   class CDynServo
   { 
     private:
       typedef typename hardware_interface::EffortJointInterface::ResourceHandleType JointHandle;
       JointHandle joint;
-      typedef boost::shared_ptr<control_toolbox::Pid> PidPtr;
-      PidPtr pid;
+      control_toolbox::Pid *pid;
+      CComplianceControl *compliance;
       unsigned char id;
+      std::string model;
+      unsigned char memory[SERVO_MEM_SIZE];
     protected:
       void init_pid(const std::string &joint_name,ros::NodeHandle &controller_nh);
+      void init_compliance(const std::string &joint_name,ros::NodeHandle &controller_nh,double max_torque,unsigned int enc_res,double max_angle);
+      void init_memory(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/dynamixel_servo.cpp b/src/dynamixel_servo.cpp
index 7141fdd7b8597929a11bb08b547dc902eb78b297..21a71ff682ec42229d713fb4c561b27e5cf43b8c 100644
--- a/src/dynamixel_servo.cpp
+++ b/src/dynamixel_servo.cpp
@@ -1,11 +1,9 @@
-#include "dynamixel_slave_serial.h"
 #include "dynamixel_servo.h"
 
 namespace dynamixel_robot_gazebo
 {
   CDynServo::CDynServo(const std::string &joint_name,CDynamixelSlaveSerial *dyn_slave,hardware_interface::EffortJointInterface* hw,ros::NodeHandle &controller_nh)
   {
-    std::string model;
     int id;
 
     // Joint handle
@@ -16,19 +14,29 @@ namespace dynamixel_robot_gazebo
       throw;
     }
     // Node handle to PID gains
+    this->pid=NULL;
+    this->compliance=NULL;
     ros::NodeHandle servo_nh(controller_nh,joint_name);
-    servo_nh.getParam("model",model);
+    if(!servo_nh.getParam("model",this->model))
+    {
+      ROS_ERROR_STREAM("Dynamixel servo: No servo model specified");
+      throw;
+    }
     if(model=="AX12W")
     {
+      this->init_compliance(joint_name,controller_nh,1.5,1024,300.0);
     }
     else if(model=="AX12A")
     {
+      this->init_compliance(joint_name,controller_nh,1.5,1024,300.0);
     }
     else if(model=="AX18A")
     {
+      this->init_compliance(joint_name,controller_nh,1.8,1024,300.0);
     }
     else if(model=="MX12W")
     {
+      this->init_pid(joint_name,controller_nh);
     }
     else if(model=="MX28v1")
     {
@@ -69,35 +77,283 @@ namespace dynamixel_robot_gazebo
     }
 
     // Init PID gains from ROS parameter server
-    servo_nh.getParam("id",id);
+    if(!servo_nh.getParam("id",id))
+    {
+      ROS_ERROR_STREAM("Dynamixel servo: No ID for the servo");
+      throw;
+    }
+    else 
+      this->id=id;
+    this->init_memory();
     dyn_slave->add_slave(id,boost::bind(&CDynServo::on_ping,this),boost::bind(&CDynServo::on_read,this,_1,_2,_3),boost::bind(&CDynServo::on_write,this,_1,_2,_3));
-    this->id=id;
   }
 
   void CDynServo::init_pid(const std::string &joint_name,ros::NodeHandle &controller_nh)
   {
     ros::NodeHandle gain_nh(controller_nh,joint_name+std::string("/gains"));
-    this->pid.reset(new control_toolbox::Pid());
+    control_toolbox::Pid::Gains gains;
+
+    this->pid=new control_toolbox::Pid();
     if(!this->pid->init(gain_nh))
     {
       ROS_WARN_STREAM("Dynamixel gazebo plugin: Failed to initialize PID gains from ROS parameter server.");
+      delete this->pid;
+      this->pid=NULL;
       throw;
     } 
+    else
+    {
+      gains=this->pid->getGains();
+      if(this->model=="MX28v1" || model=="MX64v1" || model=="MX106v1")
+      {
+        this->memory[26]=gains.d_gain_;
+        this->memory[27]=gains.i_gain_;
+        this->memory[28]=gains.p_gain_;
+      }
+      else if(this->model=="MX28v2" || model=="MX64v2" || model=="MX106v2")
+      {
+        *((unsigned short int *)&this->memory[80])=gains.d_gain_;
+        *((unsigned short int *)&this->memory[82])=gains.d_gain_;
+        *((unsigned short int *)&this->memory[84])=gains.d_gain_;
+      }
+    }
   }
 
-  void CDynServo::on_ping(void)
+  void CDynServo::init_compliance(const std::string &joint_name,ros::NodeHandle &controller_nh,double max_torque,unsigned int enc_res,double max_angle)
+  {
+    ros::NodeHandle params_nh(controller_nh,joint_name+std::string("/params"));
+    this->compliance=new CComplianceControl();
+    if(!this->compliance->init(params_nh,max_torque,enc_res,max_angle))
+    {
+      ROS_WARN_STREAM("Dynamixel gazebo plugin: Failed to initialize Complaince params from ROS parameter server.");
+      delete this->compliance;
+      this->compliance=NULL;
+      throw;
+    } 
+    else
+    {
+      this->memory[48]=this->compliance->get_punch();
+      this->memory[26]=this->compliance->get_margin();
+      this->memory[27]=this->compliance->get_margin();
+      this->memory[28]=this->compliance->get_slope();
+      this->memory[29]=this->compliance->get_slope();
+    }
+  }
+
+  void CDynServo::init_memory(void)
   {
+    for(unsigned int i=0;i<SERVO_MEM_SIZE;i++)
+      this->memory[i]=0;
+    if(model=="AX12W" || model=="AX12A" || model=="AX18A" || model=="MX12W" || model=="MX28v1" || model=="MX64v1" || model=="MX106v1")
+    {
+      this->memory[3]=this->id;
+      this->memory[4]=1;
+      this->memory[5]=250;
+      this->memory[11]=70;
+      this->memory[12]=60;
+      this->memory[13]=140;
+      this->memory[16]=2;
+      this->memory[17]=36;
+      this->memory[18]=36;
+      if(model=="AX12W")
+      {
+        this->memory[0]=12;
+        this->memory[8]=255;
+        this->memory[9]=3;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        // initialize RAM
+        this->memory[26]=4;
+        this->memory[27]=4;
+        this->memory[28]=64;
+        this->memory[28]=64;
+        this->memory[34]=255;
+        this->memory[35]=3;
+        this->memory[48]=32;
+      }
+      else if(model=="AX12A")
+      {
+        this->memory[0]=44;
+        this->memory[1]=1;
+        this->memory[8]=255;
+        this->memory[9]=3;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        // initialize RAM
+        this->memory[26]=1;
+        this->memory[27]=1;
+        this->memory[28]=32;
+        this->memory[28]=32;
+        this->memory[34]=255;
+        this->memory[35]=3;
+        this->memory[48]=32;
+      }
+      else if(model=="AX18A")
+      {
+        this->memory[0]=18;
+        this->memory[8]=255;
+        this->memory[9]=3;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        // initialize RAM
+        this->memory[26]=1;
+        this->memory[27]=1;
+        this->memory[28]=32;
+        this->memory[28]=32;
+        this->memory[34]=255;
+        this->memory[35]=3;
+        this->memory[48]=32;
+      }
+      else if(model=="MX12W")
+      {
+        this->memory[0]=105;
+        this->memory[1]=1;
+        this->memory[8]=255;
+        this->memory[9]=15;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        this->memory[22]=1;
+        // initialize RAM
+        this->memory[26]=8;
+        this->memory[28]=8;
+        this->memory[34]=255;
+        this->memory[35]=3;
+        this->memory[48]=32;
+      }
+      else if(model=="MX28v1")
+      {
+        this->memory[0]=29;
+        this->memory[8]=255;
+        this->memory[9]=15;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        this->memory[22]=1;
+        // initialize RAM
+        this->memory[28]=32;
+        this->memory[34]=255;
+        this->memory[35]=3;
+      }
+      else if(model=="MX64v1")
+      {
+        this->memory[0]=54;
+        this->memory[1]=1;
+        this->memory[8]=255;
+        this->memory[9]=15;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        this->memory[22]=1;
+        // initialize RAM
+        this->memory[28]=32;
+        this->memory[34]=255;
+        this->memory[35]=3;
+      }
+      else if(model=="MX106v1")
+      {
+        this->memory[0]=64;
+        this->memory[1]=1;
+        this->memory[8]=255;
+        this->memory[9]=15;
+        this->memory[14]=255;
+        this->memory[15]=3;
+        this->memory[22]=1;
+        // initialize RAM
+        this->memory[28]=32;
+        this->memory[34]=255;
+        this->memory[35]=3;
+      }
+    }
+    else
+    {
+      this->memory[7]=this->id;
+      this->memory[8]=1;
+      this->memory[9]=250;
+      this->memory[11]=3;
+      this->memory[12]=255;
+      this->memory[13]=2;
+      this->memory[24]=10;
+      this->memory[31]=80;
+      this->memory[32]=160;
+      this->memory[34]=95;
+      this->memory[63]=52;
+      if(model=="MX28v2")
+      {
+        this->memory[0]=30;
+        this->memory[36]=117;
+        this->memory[37]=3;
+        this->memory[40]=127;
+        this->memory[41]=255;
+        this->memory[44]=230;
+        this->memory[48]=255;
+        this->memory[49]=15;
+        // initialize RAM
+        this->memory[68]=2;
+        this->memory[76]=80;
+        this->memory[77]=7;
+        this->memory[78]=100;
+        this->memory[84]=52;
+        this->memory[85]=3;
+      }
+      else if(model=="MX64v2")
+      {
+        this->memory[0]=55;
+        this->memory[1]=1;
+        this->memory[36]=117;
+        this->memory[37]=3;
+        this->memory[38]=95;
+        this->memory[39]=7;
+        this->memory[40]=127;
+        this->memory[41]=255;
+        this->memory[44]=29;
+        this->memory[45]=1;
+        this->memory[48]=255;
+        this->memory[49]=15;
+        // initialize RAM
+        this->memory[68]=2;
+        this->memory[76]=80;
+        this->memory[77]=7;
+        this->memory[78]=100;
+        this->memory[84]=52;
+        this->memory[85]=3;
+      }
+      else if(model=="MX106v2")
+      {
+        this->memory[0]=65;
+        this->memory[1]=1;
+        this->memory[36]=117;
+        this->memory[37]=3;
+        this->memory[38]=255;
+        this->memory[39]=7;
+        this->memory[40]=127;
+        this->memory[41]=255;
+        this->memory[44]=210;
+        this->memory[48]=255;
+        this->memory[49]=15;
+        // initialize RAM
+        this->memory[68]=2;
+        this->memory[76]=80;
+        this->memory[77]=7;
+        this->memory[78]=100;
+        this->memory[84]=52;
+        this->memory[85]=3;
+      }
+    }
+  }
 
+  void CDynServo::on_ping(void)
+  {
+    std::cout << "Servo " << this->id << " pinged" << std::endl;
   }
 
   unsigned char CDynServo::on_read(unsigned short int address, unsigned short int length, unsigned char *data)
   {
-
+    for(unsigned int i=0;i<length;i++)
+      data[i]=this->memory[address+i];
   }
 
   unsigned char CDynServo::on_write(unsigned short int address, unsigned short int length, unsigned char *data)
   {
-
+    for(unsigned int i=0;i<length;i++)
+      this->memory[address+i]=data[i];
   }
 
   void CDynServo::update(const ros::Duration& period)
@@ -106,7 +362,8 @@ namespace dynamixel_robot_gazebo
 
     real_angle=this->joint.getPosition();
     target_angle=0.0;//((manager_servos[i+1].current_angle*3.14159)/180.0)/128.0;
-    command=this->pid->computeCommand(target_angle-real_angle,period);
+    if(this->pid!=NULL)
+      command=this->pid->computeCommand(target_angle-real_angle,period);
     this->joint.setCommand(command);
   }
 
@@ -117,6 +374,15 @@ namespace dynamixel_robot_gazebo
 
   CDynServo::~CDynServo()
   {
-
+    if(this->pid!=NULL)
+    {
+      delete this->pid;
+      this->pid=NULL;
+    }
+    if(this->compliance!=NULL)
+    {
+      delete this->compliance;
+      this->compliance=NULL;
+    }
   }
 }