diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 969571b2a1ea8a07471304992d780861da89a94c..1c99f00d7dcc5423fb969bdb96da0d03db38be9e 100755
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,20 +1,7 @@
-# locate the necessary dependencies
-FIND_PACKAGE(iriutils REQUIRED)
-FIND_PACKAGE(comm REQUIRED)
+ADD_SUBDIRECTORY(fw_downloader)
 
-# add the necessary include directories
-INCLUDE_DIRECTORIES(.)
-INCLUDE_DIRECTORIES(${iriutils_INCLUDE_DIR})
-INCLUDE_DIRECTORIES(${comm_INCLUDE_DIR})
+ADD_SUBDIRECTORY(robotis_mtn)
 
-# application source files
-SET(sources fw_downloader.cpp hex2bin.cpp)
-# application header files
-SET(headers fw_downloader.h hex2bin.h)
+ADD_SUBDIRECTORY(robotis_mtn_file)
 
-# create the executable file
-ADD_EXECUTABLE(fw_downloader ${sources})
-
-# link necessary libraries
-TARGET_LINK_LIBRARIES(fw_downloader ${iriutils_LIBRARY})
-TARGET_LINK_LIBRARIES(fw_downloader ${comm_LIBRARY})
+ADD_SUBDIRECTORY(robotis_bin_file)
diff --git a/src/fw_downloader/CMakeLists.txt b/src/fw_downloader/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..969571b2a1ea8a07471304992d780861da89a94c
--- /dev/null
+++ b/src/fw_downloader/CMakeLists.txt
@@ -0,0 +1,20 @@
+# locate the necessary dependencies
+FIND_PACKAGE(iriutils REQUIRED)
+FIND_PACKAGE(comm REQUIRED)
+
+# add the necessary include directories
+INCLUDE_DIRECTORIES(.)
+INCLUDE_DIRECTORIES(${iriutils_INCLUDE_DIR})
+INCLUDE_DIRECTORIES(${comm_INCLUDE_DIR})
+
+# application source files
+SET(sources fw_downloader.cpp hex2bin.cpp)
+# application header files
+SET(headers fw_downloader.h hex2bin.h)
+
+# create the executable file
+ADD_EXECUTABLE(fw_downloader ${sources})
+
+# link necessary libraries
+TARGET_LINK_LIBRARIES(fw_downloader ${iriutils_LIBRARY})
+TARGET_LINK_LIBRARIES(fw_downloader ${comm_LIBRARY})
diff --git a/src/fw_downloader.cpp b/src/fw_downloader/fw_downloader.cpp
similarity index 100%
rename from src/fw_downloader.cpp
rename to src/fw_downloader/fw_downloader.cpp
diff --git a/src/hex2bin.cpp b/src/fw_downloader/hex2bin.cpp
similarity index 100%
rename from src/hex2bin.cpp
rename to src/fw_downloader/hex2bin.cpp
diff --git a/src/hex2bin.h b/src/fw_downloader/hex2bin.h
similarity index 100%
rename from src/hex2bin.h
rename to src/fw_downloader/hex2bin.h
diff --git a/src/robotis_bin_file/CMakeLists.txt b/src/robotis_bin_file/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..772e4c9d97c4a6b1480859d30ed7ec768b329789
--- /dev/null
+++ b/src/robotis_bin_file/CMakeLists.txt
@@ -0,0 +1,21 @@
+# driver source files
+SET(sources robotis_bin_parser.cpp)
+# application header files
+SET(headers robotis_bin_parser.h)
+# locate the necessary dependencies
+FIND_PACKAGE(robotis_mtn REQUIRED)
+
+# add the necessary include directories
+INCLUDE_DIRECTORIES(.)
+INCLUDE_DIRECTORIES(${robotis_mtn_INCLUDE_DIR})
+# create the shared library
+ADD_LIBRARY(robotis_bin_parser SHARED ${sources})
+
+TARGET_LINK_LIBRARIES(robotis_bin_parser ${robotis_mtn_LIBRARY})
+# link necessary libraries
+INSTALL(TARGETS robotis_bin_parser
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib
+        ARCHIVE DESTINATION lib)
+INSTALL(FILES ${headers} DESTINATION include)
+ADD_SUBDIRECTORY(examples)
diff --git a/src/robotis_bin_file/examples/CMakeLists.txt b/src/robotis_bin_file/examples/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..592f2554e4d9e281199bdcadff81b733ae017e48
--- /dev/null
+++ b/src/robotis_bin_file/examples/CMakeLists.txt
@@ -0,0 +1,4 @@
+# create an example application
+ADD_EXECUTABLE(robotis_bin_file_test robotis_bin_file_test.cpp)
+# link necessary libraries
+TARGET_LINK_LIBRARIES(robotis_bin_file_test robotis_bin_parser)
diff --git a/src/robotis_bin_file/examples/robotis_bin_file_test.cpp b/src/robotis_bin_file/examples/robotis_bin_file_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4e2eeab37d04bf7e7572e63698f07d8f670be6e
--- /dev/null
+++ b/src/robotis_bin_file/examples/robotis_bin_file_test.cpp
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <cstdlib>
+#include <string.h>
+
+#include "robotis_bin_parser.h"
+#include "mtn_exceptions.h"
+
+int main(int argc, char *argv[])
+{
+  std::vector<unsigned short int> angles;
+  CBinFileParser mtn_parser;
+  unsigned int i=0,j=0,k=0;
+  CRobotisMtn motions;
+  CRobotisPage page;
+  CRobotisStep step;
+
+  if(argc!=2)
+  {
+    std::cout << "A motion file must be provided (.bin)" << std::endl;
+    return (EXIT_FAILURE);
+  }
+  else
+  {
+    if(strstr(argv[1],".bin")!=NULL)
+    {
+      try{
+        mtn_parser.parse(argv[1]);
+        mtn_parser.get_motions(motions);
+      }catch(CMtnException &e){
+        std::cout << e.what() << std::endl;
+      }
+    }
+    else
+    {
+      std::cout << "Invalid file format. Supported format is .bin" << std::endl;
+      return (EXIT_FAILURE);
+    }
+  }
+  /* show motion pages */
+  std::cout << "Num. pages: " << motions.get_num_pages() << std::endl;
+  for(i=0;i<motions.get_num_pages();i++)
+  {
+    page=motions.get_page(i);
+    std::cout << "name: " << page.get_name() << std::endl;
+    std::cout << "next page: " << page.get_next_page() << std::endl;
+    std::cout << "exit page: " << page.get_exit_page() << std::endl;
+    std::cout << "repetitions: " << page.get_repetitions() << std::endl;
+    std::cout << "speed rate: " << page.get_speed_rate() << std::endl;
+    std::cout << "inertial force: " << page.get_inertial() << std::endl;
+    std::cout << "Num. steps: " << page.get_num_steps() << std::endl;
+    for(j=0;j<page.get_num_steps();j++)
+    {
+      step=page.get_step(j);
+      std::cout << "angles: ";
+      angles=step.get_angles();
+      for(k=0;k<angles.size();k++)
+        std::cout << angles[k] << ",";
+      std::cout << std::endl;
+      std::cout << "pausetime: " << step.get_pause_time() << std::endl;
+      std::cout << "step time: " << step.get_step_time() << std::endl;
+    }
+  }
+}
diff --git a/src/robotis_bin_file/robotis_bin_parser.cpp b/src/robotis_bin_file/robotis_bin_parser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e86a0a836616d1dc8c836fe9146fe1c2ea7b7667
--- /dev/null
+++ b/src/robotis_bin_file/robotis_bin_parser.cpp
@@ -0,0 +1,124 @@
+#include "robotis_bin_parser.h"
+#include "mtn_exceptions.h"
+#include <fstream>
+#include <string.h>
+#include <iostream>
+#include <stdlib.h>
+
+CBinFileParser::CBinFileParser()
+{
+  memset(this->pages,0x00,sizeof(this->pages));
+}
+
+unsigned char CBinFileParser::generate_checksum(TPage *page)
+{
+  unsigned char checksum=0x00;
+  unsigned int i=0;
+
+  page->header.checksum=0x00;
+  for(i=0;i<sizeof(TPage);i++)
+    checksum+=((char *)page)[i];
+
+  return checksum;
+}
+
+bool CBinFileParser::check_checksum(TPage *page)
+{
+  unsigned char checksum=0x00;
+  unsigned int i=0;
+
+  for(i=0;i<sizeof(TPage);i++)
+    checksum+=((char *)page)[i];
+  if(checksum==0xFF)
+    return true;
+  else
+    return false;
+}
+
+void CBinFileParser::parse(const char *filename)
+{
+  std::vector<unsigned short int> angles;
+  std::vector<unsigned char> cw_compliance;
+  std::vector<unsigned char> ccw_compliance;
+  std::ifstream in_file(filename);
+  int length=0,i=0,j=0,k=0;
+  CRobotisPage page;
+  CRobotisStep step;
+
+  if(!in_file.good())
+  {
+    std::cout << " File << " << filename << " not found" << std::endl;
+    exit(EXIT_FAILURE);
+  }
+  in_file.seekg (0, in_file.end);
+  length = in_file.tellg();
+  in_file.seekg (0, in_file.beg);
+  if(length!=sizeof(this->pages))
+  {
+    std::cout << "Invalid binary motion file" << std::endl;
+    exit(EXIT_FAILURE);
+  }
+  in_file.read((char *)this->pages,length);
+  in_file.close();
+  // initialize the CMtnFile class
+  this->motions.set_type(std::string("motion"));
+  this->motions.set_version(1.0);
+  this->motions.set_num_servos(PAGE_MAX_NUM_SERVOS);
+  for(i=0;i<MAX_NUM_PAGES;i++)
+  {
+    page.clear();
+    page.set_num_servos(PAGE_MAX_NUM_SERVOS);
+    page.set_name(std::string(this->pages[i].header.name));
+    cw_compliance.resize(PAGE_MAX_NUM_SERVOS);
+    ccw_compliance.resize(PAGE_MAX_NUM_SERVOS);
+    for(j=0;j<PAGE_MAX_NUM_SERVOS;j++)
+    {
+      cw_compliance[j]=(this->pages[i].header.slope[j]>>4);
+      ccw_compliance[j]=(this->pages[i].header.slope[j]&0x0F);
+    }
+    page.set_cw_compliances(cw_compliance);
+    page.set_ccw_compliances(ccw_compliance);
+    page.set_next_page(this->pages[i].header.next);
+    page.set_exit_page(this->pages[i].header.exit);
+    page.set_repetitions(this->pages[i].header.repeat);
+    page.set_speed_rate(this->pages[i].header.speed/32.0);
+    page.set_inertial(this->pages[i].header.accel);
+    for(j=0;j<this->pages[i].header.stepnum;j++)
+    {
+      step.clear();
+      step.set_num_servos(PAGE_MAX_NUM_SERVOS);
+      step.set_pause_time(this->pages[i].steps[j].pause*0.0078);
+      step.set_step_time(this->pages[i].steps[j].time*0.0078);
+      angles.resize(PAGE_MAX_NUM_SERVOS);
+      for(k=0;k<PAGE_MAX_NUM_SERVOS;k++)
+        angles[k]=this->pages[i].steps[j].position[k];
+      step.set_angles(angles);
+      page.add_step(step);
+    }
+      this->motions.add_page(page);
+    if(!this->check_checksum(&this->pages[i]))
+      std::cout << "Page with invalid checksum" << std::endl;
+  }
+}
+
+void CBinFileParser::serialize(const char *filename)
+{
+
+}
+
+void CBinFileParser::get_motions(CRobotisMtn &motions)
+{
+  motions.clear();
+  motions=this->motions;
+}
+
+void CBinFileParser::set_motions(CRobotisMtn &motions)
+{
+  this->motions.clear();
+  this->motions=motions;
+}
+
+CBinFileParser::~CBinFileParser()
+{
+  memset(this->pages,0x00,sizeof(this->pages));
+}
diff --git a/src/robotis_bin_file/robotis_bin_parser.h b/src/robotis_bin_file/robotis_bin_parser.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e8c86f1b7138c80ee36a69849b29998b09d4888
--- /dev/null
+++ b/src/robotis_bin_file/robotis_bin_parser.h
@@ -0,0 +1,59 @@
+#ifndef _BIN_FILE_PARSER_H
+#define _BIN_FILE_PARSER_H
+
+#include "robotis_mtn.h"
+
+#define       MAX_NUM_PAGES                 256
+#define       PAGE_MAX_NUM_SERVOS           31
+#define       POSE_NUMBER_OF_POSES_PER_PAGE 7
+
+typedef struct // Header Structure (total 64unsigned char)
+{
+  char name[14];         // Name             0~13
+  unsigned char reserved1;        // Reserved1        14
+  unsigned char repeat;           // Repeat count     15
+  unsigned char schedule;         // schedule         16
+  unsigned char reserved2[3];     // reserved2        17~19
+  unsigned char stepnum;          // Number of step   20
+  unsigned char reserved3;        // reserved3        21
+  unsigned char speed;            // Speed            22
+  unsigned char reserved4;        // reserved4        23
+  unsigned char accel;            // Acceleration time 24
+  unsigned char next;             // Link to next     25
+  unsigned char exit;             // Link to exit     26
+  unsigned char reserved5[4];     // reserved5        27~30
+  unsigned char checksum;         // checksum         31
+  unsigned char slope[PAGE_MAX_NUM_SERVOS];        // CW/CCW compliance slope  32~62
+  unsigned char reserved6;        // reserved6        63
+} TPageHeader;
+
+typedef struct // Step Structure (total 64unsigned char)
+{
+  unsigned short int position[PAGE_MAX_NUM_SERVOS];    // Joint position   0~61
+  unsigned char pause;            // Pause time       62
+  unsigned char time;             // Time             63
+} TStep;
+
+typedef struct // Page Structure (total 512unsigned char)
+{
+  TPageHeader header;       // Page header  0~64
+  TStep steps[POSE_NUMBER_OF_POSES_PER_PAGE];           // Page step    65~511
+} TPage;
+
+class CBinFileParser
+{
+  private:
+    CRobotisMtn motions;
+    TPage pages[MAX_NUM_PAGES];
+    unsigned char generate_checksum(TPage *page);
+    bool check_checksum(TPage *page);
+  public:
+    CBinFileParser();
+    void parse(const char *filename);
+    void serialize(const char *filename);
+    void get_motions(CRobotisMtn &motions);
+    void set_motions(CRobotisMtn &motions);
+    ~CBinFileParser();
+};
+
+#endif
diff --git a/src/robotis_mtn/CMakeLists.txt b/src/robotis_mtn/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7e5a6aae822a80d63f9472bcc66ada7ab83b356a
--- /dev/null
+++ b/src/robotis_mtn/CMakeLists.txt
@@ -0,0 +1,16 @@
+# driver source files
+SET(sources robotis_mtn.cpp robotis_page.cpp robotis_step.cpp mtn_exceptions.cpp)
+# application header files
+SET(headers robotis_mtn.h robotis_page.h robotis_step.h mtn_exceptions.h)
+# locate the necessary dependencies
+# add the necessary include directories
+INCLUDE_DIRECTORIES(.)
+# create the shared library
+ADD_LIBRARY(robotis_mtn SHARED ${sources})
+# link necessary libraries
+INSTALL(TARGETS robotis_mtn
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib
+        ARCHIVE DESTINATION lib)
+INSTALL(FILES ${headers} DESTINATION include)
+ADD_SUBDIRECTORY(examples)
diff --git a/src/robotis_mtn/examples/CMakeLists.txt b/src/robotis_mtn/examples/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e0c2cfec0f403f880b1f2b99d08ca0a575741056
--- /dev/null
+++ b/src/robotis_mtn/examples/CMakeLists.txt
@@ -0,0 +1,4 @@
+# create an example application
+ADD_EXECUTABLE(robotis_mtn_test robotis_mtn_test.cpp)
+# link necessary libraries
+TARGET_LINK_LIBRARIES(robotis_mtn_test robotis_mtn)
diff --git a/src/robotis_mtn/examples/robotis_mtn_test.cpp b/src/robotis_mtn/examples/robotis_mtn_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f5e42eb34a3ab45292d2de25c61ce3857202f6c7
--- /dev/null
+++ b/src/robotis_mtn/examples/robotis_mtn_test.cpp
@@ -0,0 +1,5 @@
+#include "robotis_mtn.h"
+
+int main(int argc, char *argv[])
+{
+}
diff --git a/src/robotis_mtn/mtn_exceptions.cpp b/src/robotis_mtn/mtn_exceptions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..34720cd019d5ed036a7f07407896b03fa706f41d
--- /dev/null
+++ b/src/robotis_mtn/mtn_exceptions.cpp
@@ -0,0 +1,23 @@
+#include "mtn_exceptions.h"
+#include <string.h>
+#include <stdio.h>
+
+const std::string mtn_exception_msg="[Motion Exception caught] - ";
+
+CMtnException::CMtnException(const std::string& where, const std::string& error_msg)
+{
+  this->error_msg=mtn_exception_msg;
+  this->error_msg+=where;
+  this->error_msg+="\nError: ";
+  this->error_msg+=error_msg;
+}
+
+const std::string& CMtnException::what(void)
+{
+  return this->error_msg;
+}
+
+CMtnException::~CMtnException() throw()
+{
+  /* the error message is destroyed by its own destructor */
+}
diff --git a/src/robotis_mtn/mtn_exceptions.h b/src/robotis_mtn/mtn_exceptions.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ecc0a3788b562a71d5535a2cf451e48d1758b85
--- /dev/null
+++ b/src/robotis_mtn/mtn_exceptions.h
@@ -0,0 +1,30 @@
+#ifndef _MTN_EXCEPTIONS_H
+#define _MTN_EXCEPTIONS_H
+
+#include <exception>
+#include <sstream>
+#include <string>
+
+template <typename T_> 
+inline std::string tostring (const T_ & src)
+{
+  std::ostringstream out;
+
+  out << src;
+  return out.str();
+}
+
+#define _HERE_ (std::string(__PRETTY_FUNCTION__) + " at " + \
+        std::string(__FILE__) + ":" +tostring(__LINE__))
+
+class CMtnException : public std::exception
+{
+  protected:
+    std::string error_msg;
+  public:
+    CMtnException(const std::string& where, const std::string& error_msg);
+    virtual const std::string& what(void);
+    virtual ~CMtnException() throw();
+};
+
+#endif
diff --git a/src/robotis_mtn/robotis_mtn.cpp b/src/robotis_mtn/robotis_mtn.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4e5271ba313c6b925f24e5148149cdb82526fae
--- /dev/null
+++ b/src/robotis_mtn/robotis_mtn.cpp
@@ -0,0 +1,388 @@
+#include "robotis_mtn.h"
+#include "mtn_exceptions.h"
+
+CRobotisMtn::CRobotisMtn()
+{
+  this->type="";
+  this->version=0.0;
+  this->enable.clear();  
+  this->pages.clear();
+  this->info.clear();
+  this->num_servos=0;
+}
+
+CRobotisMtn::CRobotisMtn(CRobotisMtn &mtn)
+{
+  unsigned int i=0;
+
+  this->type=mtn.type;
+  this->version=mtn.version;  
+  this->enable.clear();
+  for(i=0;i<mtn.get_num_servos();i++)
+    this->enable.push_back(mtn.enable.at(i));
+  this->info.clear();
+  for(i=0;i<mtn.get_num_servos();i++)
+    this->info.push_back(mtn.info[i]);
+  this->pages.clear();
+  for(i=0;i<mtn.pages.size();i++)
+    this->pages.push_back(mtn.pages[i]);
+  this->num_servos=mtn.get_num_servos();
+}
+
+void CRobotisMtn::set_type(const std::string &type)
+{
+  this->type=type;
+}
+
+void CRobotisMtn::set_version(double version)
+{
+  this->version=version;
+}
+
+void CRobotisMtn::set_num_servos(unsigned int num_servos)
+{
+  this->enable.resize(num_servos);
+  this->info.resize(num_servos);
+  this->num_servos=num_servos;
+}
+
+void CRobotisMtn::set_enable(unsigned int servo,bool enable)
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    this->enable[servo]=enable;
+}
+
+void CRobotisMtn::set_enables(std::vector<bool> &enables)
+{
+  unsigned int i=0;
+
+  if(this->get_num_servos()!=enables.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid enable vector size");
+  }
+  else
+    for(i=0;i<this->get_num_servos();i++)
+      this->enable[i]=enables[i];
+}
+
+void CRobotisMtn::set_motor_type(unsigned int servo, int motor_type)
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+  {
+    switch(motor_type)
+    {
+      case SERVO_AX12A: this->info[servo].encoder_resolution=1024;
+                        this->info[servo].max_angle=300;
+                        this->info[servo].center_angle=150;
+                        this->info[servo].max_speed=354;
+                        this->info[servo].model=SERVO_AX12A;
+                        this->info[servo].model_string="AX-12A";
+                        break;
+      case SERVO_AX12W: this->info[servo].encoder_resolution=1023;
+                        this->info[servo].max_angle=3000;
+                        this->info[servo].center_angle=1500;
+                        this->info[servo].max_speed=2830;
+                        this->info[servo].model=SERVO_AX12W;
+                        this->info[servo].model_string="AX-12W";
+                        break;
+      case SERVO_AX18A: this->info[servo].encoder_resolution=1023;
+                        this->info[servo].max_angle=3000;
+                        this->info[servo].center_angle=1500;
+                        this->info[servo].max_speed=582;
+                        this->info[servo].model=SERVO_AX18A;
+                        this->info[servo].model_string="AX-18A";
+                        break;
+      case SERVO_MX28: this->info[servo].encoder_resolution=4095;
+                       this->info[servo].max_angle=3600;
+                       this->info[servo].center_angle=1800;
+                       this->info[servo].max_speed=330;
+                       this->info[servo].model=SERVO_MX28;
+                       this->info[servo].model_string="MX-28";
+                       break;
+      case SERVO_RX24F: this->info[servo].encoder_resolution=1023;
+                        this->info[servo].max_angle=3000;
+                        this->info[servo].center_angle=1500;
+                        this->info[servo].max_speed=756;
+                        this->info[servo].model=SERVO_RX24F;
+                        this->info[servo].model_string="RX-24F";
+                        break;
+      case SERVO_RX28: this->info[servo].encoder_resolution=1023;
+                       this->info[servo].max_angle=3000;
+                       this->info[servo].center_angle=1500;
+                       this->info[servo].max_speed=402;
+                       this->info[servo].model=SERVO_RX28;
+                       this->info[servo].model_string="RX-28";
+                       break;
+      case SERVO_RX64: this->info[servo].encoder_resolution=1023;
+                       this->info[servo].max_angle=3000;
+                       this->info[servo].center_angle=1500;
+                       this->info[servo].max_speed=294;
+                       this->info[servo].model=SERVO_RX64;
+                       this->info[servo].model_string="RX-64";
+                       break;
+      case SERVO_MX64: this->info[servo].encoder_resolution=4095;
+                       this->info[servo].max_angle=3600;
+                       this->info[servo].center_angle=1800;
+                       this->info[servo].max_speed=378;
+                       this->info[servo].model=SERVO_MX64;
+                       this->info[servo].model_string="MX-64";
+                       break;
+      case SERVO_EX106: this->info[servo].encoder_resolution=1023;
+                        this->info[servo].max_angle=2500;
+                        this->info[servo].center_angle=1250;
+                        this->info[servo].max_speed=414;
+                        this->info[servo].model=SERVO_EX106;
+                        this->info[servo].model_string="EX-106";
+                        break;
+      case SERVO_MX106: this->info[servo].encoder_resolution=4095;
+                        this->info[servo].max_angle=3600;
+                        this->info[servo].center_angle=1800;
+                        this->info[servo].max_speed=270;
+                        this->info[servo].model=SERVO_MX106;
+                        this->info[servo].model_string="MX-106";
+                        break;
+      default: throw CMtnException(_HERE_,"Invalid servo type");
+               break;
+    }
+  }
+}
+
+void CRobotisMtn::set_motor_type(unsigned int servo, std::string model)
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+  {
+    if(model=="AX-12A")
+      this->set_motor_type(servo,SERVO_AX12A);
+    else if(model=="AX-12W")
+      this->set_motor_type(servo,SERVO_AX12W);
+    else if(model=="AX-18A")
+      this->set_motor_type(servo,SERVO_AX18A);
+    else if(model=="MX-28")
+      this->set_motor_type(servo,SERVO_MX28);
+    else if(model=="RX24F")
+      this->set_motor_type(servo,SERVO_RX24F);
+    else if(model=="RX-28")
+      this->set_motor_type(servo,SERVO_RX28);
+    else if(model=="RX-64")
+      this->set_motor_type(servo,SERVO_RX64);
+    else if(model=="MX64")
+      this->set_motor_type(servo,SERVO_MX64);
+    else if(model=="EX-106")
+      this->set_motor_type(servo,SERVO_EX106);
+    else if(model=="MX-106")
+      this->set_motor_type(servo,SERVO_MX106);
+    else
+      throw CMtnException(_HERE_,"Invalid servo type");
+  }
+}
+
+void CRobotisMtn::set_motor_types(std::vector<std::string> &models)
+{
+  unsigned int i=0;
+
+  if(this->get_num_servos()!=models.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid motor type vector size");
+  }
+  else
+    for(i=0;i<this->get_num_servos();i++)
+      this->set_motor_type(i,models[i]);
+}
+
+void CRobotisMtn::set_motor_types(std::vector<int> &motor_types)
+{
+  unsigned int i=0;
+
+  if(this->get_num_servos()!=motor_types.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid motor type vector size");
+  }
+  else
+    for(i=0;i<this->get_num_servos();i++)
+      this->set_motor_type(i,motor_types[i]);
+}
+
+void CRobotisMtn::add_page(CRobotisPage &page)
+{
+  this->pages.push_back(page);
+}
+
+std::string CRobotisMtn::get_type(void) const
+{
+  return this->type;
+}
+
+double CRobotisMtn::get_version(void) const
+{
+  return this->version;
+}  
+
+unsigned int CRobotisMtn::get_num_servos(void) const
+{
+  return this->num_servos;
+}
+
+bool CRobotisMtn::get_enable(unsigned int servo) const
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->enable[servo];
+}
+
+std::vector<bool> CRobotisMtn::get_enables(void) const
+{
+  return this->enable;
+}
+
+int CRobotisMtn::get_motor_type(unsigned int servo) const
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->info[servo].model;
+}
+
+std::string CRobotisMtn::get_motor_model(unsigned int servo) const
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->info[servo].model_string;
+}
+
+std::vector<int> CRobotisMtn::get_motor_types(void) const
+{
+  std::vector<int> types;
+  unsigned int i=0;
+
+  for(i=0;i<this->get_num_servos();i++)
+    types.push_back(this->info[i].model);
+
+  return types;
+}
+
+std::vector<std::string> CRobotisMtn::get_motor_models(void) const
+{
+  std::vector<std::string> models;
+  unsigned int i=0;
+
+  for(i=0;i<this->get_num_servos();i++)
+    models.push_back(this->info[i].model_string);
+
+  return models;
+}
+
+TServoInfo CRobotisMtn::get_motor_info(unsigned int servo) const
+{
+  if(servo>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->info[servo];
+}
+
+std::vector<TServoInfo> CRobotisMtn::get_motor_infos(void) const
+{
+  return this->info;
+}
+
+unsigned int CRobotisMtn::get_num_pages(void) const
+{
+  return this->pages.size();
+}
+
+CRobotisPage CRobotisMtn::get_page(unsigned int page) const
+{
+  if(page>this->pages.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid page index");
+  }
+  else
+    return this->pages[page];
+}
+
+void CRobotisMtn::clear(void)
+{
+  this->type="";
+  this->version=0.0;
+  this->enable.clear();
+  this->info.clear();
+  this->pages.clear();
+}
+
+CRobotisMtn CRobotisMtn::operator =(CRobotisMtn mtn)
+{
+  unsigned int i=0;
+
+  this->type=mtn.type;
+  this->version=mtn.version;  
+  this->enable.clear();
+  for(i=0;i<mtn.get_num_servos();i++)
+    this->enable.push_back(mtn.enable[i]);
+  this->info.clear();
+  for(i=0;i<mtn.get_num_servos();i++)
+    this->info.push_back(mtn.info[i]);
+  pages.clear();
+  for(i=0;i<mtn.pages.size();i++)
+    this->pages.push_back(mtn.pages[i]);
+  this->num_servos=mtn.get_num_servos();
+
+  return *this;
+}
+
+double CRobotisMtn::get_angle(unsigned int servo_id, unsigned char page_id, unsigned char step_id)
+{
+  CRobotisPage page;
+  CRobotisStep step;
+  unsigned short int value;
+
+  page=this->get_page(page_id);
+  step=page.get_step(step_id);
+  if(servo_id>this->get_num_servos())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+  {
+    value=step.get_angle(servo_id);
+    return (value*this->info[servo_id].max_angle)/this->info[servo_id].encoder_resolution-this->info[servo_id].center_angle;
+  }
+}
+
+CRobotisMtn::~CRobotisMtn()
+{
+  this->clear();
+}
+
diff --git a/src/robotis_mtn/robotis_mtn.h b/src/robotis_mtn/robotis_mtn.h
new file mode 100644
index 0000000000000000000000000000000000000000..e50f377c4d86bc323ac577cd117715487f07f6c2
--- /dev/null
+++ b/src/robotis_mtn/robotis_mtn.h
@@ -0,0 +1,69 @@
+#ifndef _ROBOTIS_MTN_H
+#define _ROBOTIS_MTN_H
+
+#include "robotis_page.h"
+
+#define       SERVO_AX12A     0x000C
+#define       SERVO_AX12W     0x012C
+#define       SERVO_AX18A     0x0012
+#define       SERVO_MX28      0x001D
+#define       SERVO_RX24F     0x0018
+#define       SERVO_RX28      0x001C
+#define       SERVO_RX64      0x0040
+#define       SERVO_MX64      0x0136
+#define       SERVO_EX106     0x006B
+#define       SERVO_MX106     0x0140
+
+typedef struct
+{
+  unsigned short int model;
+  std::string model_string; 
+  unsigned short int encoder_resolution;
+  double max_angle;
+  double center_angle;
+  double max_speed;
+}TServoInfo;
+
+class CRobotisMtn
+{
+  private:
+    std::string type;
+    double version;
+    int num_servos;
+    std::vector<bool> enable;
+    std::vector<CRobotisPage> pages;
+    std::vector<TServoInfo> info; 
+  public:
+    CRobotisMtn();
+    CRobotisMtn(CRobotisMtn &mtn);
+    void set_type(const std::string &type);
+    void set_version(double version);
+    void set_num_servos(unsigned int num_servos);
+    void set_enable(unsigned int servo,bool enable);
+    void set_enables(std::vector<bool> &enables);
+    void set_motor_type(unsigned int servo, int motor_type);
+    void set_motor_type(unsigned int servo, std::string model);
+    void set_motor_types(std::vector<int> &motor_types);
+    void set_motor_types(std::vector<std::string> &models);
+    void add_page(CRobotisPage &page);
+    std::string get_type(void) const;
+    double get_version(void) const;
+    unsigned int get_num_servos(void) const;
+    bool get_enable(unsigned int servo) const;
+    std::vector<bool> get_enables(void) const;
+    int get_motor_type(unsigned int servo) const;
+    std::string get_motor_model(unsigned int servo) const;
+    std::vector<int> get_motor_types(void) const;
+    std::vector<std::string> get_motor_models(void) const;
+    TServoInfo get_motor_info(unsigned int servo) const;
+    std::vector<TServoInfo> get_motor_infos(void) const;
+    unsigned int get_num_pages(void) const;
+    CRobotisPage get_page(unsigned int page) const;
+    void clear(void);
+    CRobotisMtn operator=(CRobotisMtn mtn);
+    // angle conversion functions
+    double get_angle(unsigned int servo_id, unsigned char page_id, unsigned char step_id);
+    ~CRobotisMtn();
+};
+
+#endif
diff --git a/src/robotis_mtn/robotis_page.cpp b/src/robotis_mtn/robotis_page.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f35cd31ca434e44ef3ba4da9c819ba552fbf2ce9
--- /dev/null
+++ b/src/robotis_mtn/robotis_page.cpp
@@ -0,0 +1,283 @@
+#include "robotis_page.h"
+#include "mtn_exceptions.h"
+
+CRobotisPage::CRobotisPage()
+{
+  this->name="";
+  this->cw_compliance.clear();
+  this->ccw_compliance.clear();
+  this->next_page=0;
+  this->exit_page=0;
+  this->repetitions=0;
+  this->speed_rate=0;
+  this->inertial=0;
+  this->steps.clear();
+}
+
+CRobotisPage::CRobotisPage(const CRobotisPage &page)
+{
+  unsigned int i=0;
+
+  this->name=page.name;
+  this->cw_compliance.resize(page.cw_compliance.size());
+  this->ccw_compliance.resize(page.ccw_compliance.size());
+  for(i=0;i<page.cw_compliance.size();i++)
+  {
+    this->cw_compliance[i]=page.cw_compliance[i];
+    this->ccw_compliance[i]=page.ccw_compliance[i];
+  }
+  this->next_page=page.next_page;
+  this->exit_page=page.exit_page;
+  this->repetitions=page.repetitions;
+  this->speed_rate=page.speed_rate;
+  this->inertial=page.inertial;
+  this->steps.clear();
+  for(i=0;i<page.steps.size();i++)
+    this->steps.push_back(page.get_step(i));
+}
+
+void CRobotisPage::set_num_servos(unsigned int num_servos)
+{
+  this->cw_compliance.resize(num_servos);
+  this->ccw_compliance.resize(num_servos);
+}
+
+void CRobotisPage::set_name(const std::string &name)
+{
+  this->name=name;
+}
+
+void CRobotisPage::set_cw_compliance(unsigned int servo,unsigned char cw_compliance)
+{
+  if(servo>this->cw_compliance.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    this->cw_compliance[servo]=cw_compliance;
+}
+
+void CRobotisPage::set_cw_compliances(std::vector<unsigned char> cw_compliances)
+{
+  unsigned int i=0;
+
+  if(this->cw_compliance.size()!=cw_compliances.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid compliance vector size");
+  }
+  else
+  {
+    for(i=0;i<this->cw_compliance.size();i++)
+      this->cw_compliance[i]=cw_compliances[i];
+  }
+}
+
+void CRobotisPage::set_ccw_compliance(unsigned int servo,unsigned char ccw_compliance)
+{
+  if(servo>this->ccw_compliance.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    this->ccw_compliance[servo]=ccw_compliance;
+}
+
+void CRobotisPage::set_ccw_compliances(std::vector<unsigned char> ccw_compliances)
+{
+  unsigned int i=0;
+
+  if(this->ccw_compliance.size()!=ccw_compliances.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid compliance vector size");
+  }
+  else
+  {
+    for(i=0;i<this->ccw_compliance.size();i++)
+      this->ccw_compliance[i]=ccw_compliances[i];
+  }
+}
+
+void CRobotisPage::set_next_page(unsigned int page)
+{
+  if(page>=256)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid next page index");
+  }
+  else
+    this->next_page=page;
+}
+
+void CRobotisPage::set_exit_page(unsigned int page)
+{
+  if(page>=256)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid exit page index");
+  }
+  else
+    this->exit_page=page;
+}
+
+void CRobotisPage::set_repetitions(unsigned int num)
+{
+  if(num>=256)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid number of repetitions");
+  }
+  else
+    this->repetitions=num;
+}
+
+void CRobotisPage::set_speed_rate(double rate)
+{
+  this->speed_rate=rate;
+}
+
+void CRobotisPage::set_inertial(unsigned int inertia)
+{
+  if(inertia>=256)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid inertial force value");
+  }
+  else
+    this->inertial=inertia;
+}
+
+void CRobotisPage::add_step(CRobotisStep &step)
+{
+  if(this->steps.size()>=7)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Impossible to add more steps");
+  }
+  else
+    this->steps.push_back(step);
+}
+
+std::string CRobotisPage::get_name(void) const
+{
+  return this->name;
+}
+
+unsigned char CRobotisPage::get_cw_compliance(unsigned int servo) const
+{
+  if(servo>this->cw_compliance.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->cw_compliance[servo];
+}
+
+std::vector<unsigned char> CRobotisPage::get_cw_compliances(void) const
+{
+  return this->cw_compliance;
+}
+
+unsigned char CRobotisPage::get_ccw_compliance(unsigned int servo) const
+{
+  if(servo>this->ccw_compliance.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->ccw_compliance[servo];
+}
+
+std::vector<unsigned char> CRobotisPage::get_ccw_compliances(void) const
+{
+  return this->ccw_compliance;
+}
+
+unsigned int CRobotisPage::get_next_page(void) const
+{
+  return this->next_page;
+}
+
+unsigned int CRobotisPage::get_exit_page(void) const
+{
+  return this->exit_page;
+}
+
+unsigned int CRobotisPage::get_repetitions(void) const
+{
+  return this->repetitions;
+}
+
+double CRobotisPage::get_speed_rate(void) const
+{
+  return this->speed_rate;
+}
+
+unsigned int CRobotisPage::get_inertial(void) const
+{
+  return this->inertial;
+}
+
+unsigned int CRobotisPage::get_num_steps(void) const
+{
+  return this->steps.size();
+}
+
+CRobotisStep CRobotisPage::get_step(unsigned int step) const
+{
+  if(step>this->steps.size())
+  {
+    /* handle error */
+    throw CMtnException(_HERE_,"Invalid step index");
+  }
+  else
+    return this->steps[step];
+}
+
+void CRobotisPage::clear(void)
+{
+  this->name.clear();
+  this->cw_compliance.clear();
+  this->ccw_compliance.clear();
+  this->next_page=0;
+  this->exit_page=0;
+  this->repetitions=0;
+  this->speed_rate=0;
+  this->inertial=0;
+  this->steps.clear();
+}
+
+CRobotisPage CRobotisPage::operator =(CRobotisPage page)
+{
+  unsigned int i=0;
+
+  this->name=page.name;
+  this->cw_compliance.resize(page.cw_compliance.size());
+  this->ccw_compliance.resize(page.ccw_compliance.size());
+  for(i=0;i<page.cw_compliance.size();i++)
+  {
+    this->cw_compliance[i]=page.cw_compliance[i];
+    this->ccw_compliance[i]=page.ccw_compliance[i];
+  }
+  this->next_page=page.next_page;
+  this->exit_page=page.exit_page;
+  this->repetitions=page.repetitions;
+  this->speed_rate=page.speed_rate;
+  this->inertial=page.inertial;
+  this->steps.clear();
+  for(i=0;i<page.steps.size();i++)
+    this->steps.push_back(page.get_step(i));
+
+  return *this;
+}
+
+CRobotisPage::~CRobotisPage()
+{
+  this->clear();
+}
+
diff --git a/src/robotis_mtn/robotis_page.h b/src/robotis_mtn/robotis_page.h
new file mode 100644
index 0000000000000000000000000000000000000000..890b3f35a871fa9d05bc6ea066e45a7b1957a6ad
--- /dev/null
+++ b/src/robotis_mtn/robotis_page.h
@@ -0,0 +1,51 @@
+#ifndef _ROBOTIS_PAGE_H
+#define _ROBOTIS_PAGE_H
+
+#include "robotis_step.h"
+#include <string>
+
+class CRobotisPage
+{
+  private:
+    std::string name;
+    std::vector<unsigned char> cw_compliance;
+    std::vector<unsigned char> ccw_compliance;
+    unsigned int next_page;
+    unsigned int exit_page;
+    unsigned int repetitions;
+    double speed_rate;
+    unsigned int inertial;
+    std::vector<CRobotisStep> steps;
+  public:
+    CRobotisPage();
+    CRobotisPage(const CRobotisPage &page);
+    void set_num_servos(unsigned int num_servos);
+    void set_name(const std::string &name);
+    void set_cw_compliance(unsigned int servo,unsigned char cw_compliance);
+    void set_cw_compliances(std::vector<unsigned char> cw_compliances);
+    void set_ccw_compliance(unsigned int servo,unsigned char ccw_compliance);
+    void set_ccw_compliances(std::vector<unsigned char> ccw_compliances);
+    void set_next_page(unsigned int page);
+    void set_exit_page(unsigned int page);
+    void set_repetitions(unsigned int num);
+    void set_speed_rate(double rate);
+    void set_inertial(unsigned int inertia);
+    void add_step(CRobotisStep &step);
+    std::string get_name(void) const;
+    unsigned char get_cw_compliance(unsigned int servo) const;
+    std::vector<unsigned char> get_cw_compliances(void) const;
+    unsigned char get_ccw_compliance(unsigned int servo) const;
+    std::vector<unsigned char> get_ccw_compliances(void) const;
+    unsigned int get_next_page(void) const;
+    unsigned int get_exit_page(void) const;
+    unsigned int get_repetitions(void) const;
+    double get_speed_rate(void) const;
+    unsigned int get_inertial(void) const;
+    unsigned int get_num_steps(void) const;
+    CRobotisStep get_step(unsigned int step) const;
+    void clear(void);
+    CRobotisPage operator =(CRobotisPage page);
+    ~CRobotisPage();
+};
+
+#endif
diff --git a/src/robotis_mtn/robotis_step.cpp b/src/robotis_mtn/robotis_step.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8519811dc711c03f44284133d730d2c335068317
--- /dev/null
+++ b/src/robotis_mtn/robotis_step.cpp
@@ -0,0 +1,126 @@
+#include "robotis_step.h"
+#include "mtn_exceptions.h"
+
+CRobotisStep::CRobotisStep()
+{
+  this->angles.clear();
+  this->pause_time=0.0;
+  this->step_time=0.0;
+}
+
+CRobotisStep::CRobotisStep(const CRobotisStep &step)
+{
+  unsigned int i=0;
+
+  this->pause_time=step.pause_time;
+  this->step_time=step.step_time;
+  this->angles.resize(step.angles.size());
+  for(i=0;i<step.angles.size();i++)
+    this->angles[i]=step.angles[i];
+}
+
+void CRobotisStep::set_num_servos(unsigned int num_servos)
+{
+  this->angles.resize(num_servos);
+}
+
+void CRobotisStep::set_angle(unsigned int servo,unsigned short int angle)
+{
+  if(servo>this->angles.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    this->angles[servo]=angle;
+}
+
+void CRobotisStep::set_angles(std::vector<unsigned short int> &angles)
+{
+  unsigned int i=0;
+
+  if(angles.size()!=this->angles.size())
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid vector size");
+  }
+  else
+  {
+    for(i=0;i<angles.size();i++)
+      this->angles[i]=angles[i];
+  }
+}
+
+void CRobotisStep::set_pause_time(double time)
+{
+  if(time<0.0)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid pause time");
+  }
+  else
+    this->pause_time=time;
+}
+
+void CRobotisStep::set_step_time(double time)
+{
+  if(time<0.0)
+  {
+    /* handle errors */
+    throw CMtnException(_HERE_,"Invalid step time");
+  }
+  else
+    this->step_time=time;
+}
+
+unsigned short int CRobotisStep::get_angle(unsigned int servo) const
+{
+  if(servo>this->angles.size())
+  {
+    /* handler errors */
+    throw CMtnException(_HERE_,"Invalid servo index");
+  }
+  else
+    return this->angles[servo];
+}
+
+std::vector<unsigned short int> CRobotisStep::get_angles(void) const
+{
+  return this->angles;
+}
+
+double CRobotisStep::get_pause_time(void) const
+{
+  return this->pause_time;
+}
+
+double CRobotisStep::get_step_time(void) const
+{
+  return this->step_time;
+}
+
+void CRobotisStep::clear(void)
+{
+  this->angles.clear();
+  this->pause_time=0.0;
+  this->step_time=0.0;
+}
+
+CRobotisStep CRobotisStep::operator =(CRobotisStep step)
+{
+  unsigned int i=0;
+
+  this->pause_time=step.pause_time;
+  this->step_time=step.step_time;
+  this->angles.resize(step.angles.size());
+  for(i=0;i<step.angles.size();i++)
+    this->angles[i]=step.angles[i];
+
+  return *this;
+}
+
+CRobotisStep::~CRobotisStep()
+{
+  this->clear();
+}
+
diff --git a/src/robotis_mtn/robotis_step.h b/src/robotis_mtn/robotis_step.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d5dd573831918629b62e9f0aabd33ad2298d593
--- /dev/null
+++ b/src/robotis_mtn/robotis_step.h
@@ -0,0 +1,29 @@
+#ifndef _ROBOTIS__STEP_H
+#define _ROBOTIS_STEP_H
+
+#include <vector>
+
+class CRobotisStep
+{
+  private:
+    std::vector<unsigned short int> angles;
+    double pause_time;
+    double step_time;
+  public:
+    CRobotisStep();
+    CRobotisStep(const CRobotisStep &object);
+    void set_num_servos(unsigned int num_servos);
+    void set_angle(unsigned int servo,unsigned short int angle);
+    void set_angles(std::vector<unsigned short int> &angles);
+    void set_pause_time(double time);
+    void set_step_time(double time);
+    unsigned short int get_angle(unsigned int servo) const;
+    std::vector<unsigned short int> get_angles(void) const;
+    double get_pause_time(void) const;
+    double get_step_time(void) const;
+    void clear();
+    CRobotisStep operator =(CRobotisStep step);
+    ~CRobotisStep();
+};
+
+#endif
diff --git a/src/robotis_mtn_file/CMakeLists.txt b/src/robotis_mtn_file/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2be43f12d2f251fd780ec02326289ae5cf8fef73
--- /dev/null
+++ b/src/robotis_mtn_file/CMakeLists.txt
@@ -0,0 +1,50 @@
+# Create target for the parser
+FIND_PACKAGE(BISON REQUIRED)
+FIND_PACKAGE(FLEX REQUIRED)
+FIND_PACKAGE(robotis_mtn REQUIRED)
+
+SET(BisonOutput mtn_parser.cpp)
+IF(BISON_FOUND)
+    ADD_CUSTOM_COMMAND(
+      OUTPUT ${BisonOutput}
+      COMMAND ${BISON_EXECUTABLE}
+              --output=${BisonOutput}
+              ${CMAKE_CURRENT_SOURCE_DIR}/mtn_file.y
+      COMMENT "Generating mtn_parser.cpp"
+    )
+ENDIF(BISON_FOUND)
+
+FIND_PACKAGE(FLEX REQUIRED)
+SET(FlexOutput mtn_scanner.cpp)
+IF(FLEX_FOUND)
+    ADD_CUSTOM_COMMAND(
+      OUTPUT ${FlexOutput}
+      COMMAND ${FLEX_EXECUTABLE}
+              --outfile=${FlexOutput}
+              ${CMAKE_CURRENT_SOURCE_DIR}/mtn_file.l
+      COMMENT "Generating mtn_scanner.cpp"
+    )
+ENDIF(FLEX_FOUND)
+
+SET(sources mtn_file_parser.cpp)
+SET(headers mtn_file_parser.hpp mtn_file_scanner.hpp)
+
+include_directories(.)
+include_directories(${robotis_mtn_INCLUDE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_library(robotis_mtn_parser SHARED ${BisonOutput} ${FlexOutput} ${sources})
+
+target_link_libraries(robotis_mtn_parser ${robotis_mtn_LIBRARY})
+
+INSTALL(TARGETS robotis_mtn_parser
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib
+        ARCHIVE DESTINATION lib)
+INSTALL(FILES ${headers} DESTINATION include)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mtn_parser.hpp DESTINATION include)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/location.hh DESTINATION include)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/position.hh DESTINATION include)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/stack.hh DESTINATION include)
+ADD_SUBDIRECTORY(examples)
+
diff --git a/src/robotis_mtn_file/examples/CMakeLists.txt b/src/robotis_mtn_file/examples/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..595cbf73befdc8646c74eea0756e1dfde8506ec6
--- /dev/null
+++ b/src/robotis_mtn_file/examples/CMakeLists.txt
@@ -0,0 +1,4 @@
+# create an example application
+ADD_EXECUTABLE(robotis_mtn_file_test robotis_mtn_file_test.cpp)
+# link necessary libraries
+TARGET_LINK_LIBRARIES(robotis_mtn_file_test robotis_mtn_parser)
diff --git a/src/robotis_mtn_file/examples/robotis_mtn_file_test.cpp b/src/robotis_mtn_file/examples/robotis_mtn_file_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..56b985366711c2fe2d1ce33539dd30f1208b613c
--- /dev/null
+++ b/src/robotis_mtn_file/examples/robotis_mtn_file_test.cpp
@@ -0,0 +1,69 @@
+#include <iostream>
+#include <cstdlib>
+#include <string.h>
+
+#include "mtn_file_parser.hpp"
+#include "mtn_exceptions.h"
+
+int main(int argc, char *argv[])
+{
+  std::vector<unsigned short int> angles;
+  MTN::CMtnFileParser mtn_parser;
+  unsigned int i=0,j=0,k=0;
+  CRobotisMtn motions;
+  CRobotisPage page;
+  CRobotisStep step;
+
+  if(argc!=2)
+  {
+    std::cout << "A motion file must be provided (.mtn)" << std::endl;
+    return (EXIT_FAILURE);
+  }
+  else
+  {
+    if(strstr(argv[1],".mtn")!=NULL)
+    {
+      try{
+        mtn_parser.parse(argv[1]);
+        mtn_parser.get_motions(motions);
+      }catch(CMtnException &e){
+        std::cout << e.what() << std::endl;
+      }
+    }
+    else
+    {
+      std::cout << "Invalid file format. Supported format is .mtn" << std::endl;
+      return (EXIT_FAILURE);
+    }
+  }
+  /* show motion pages */
+  std::cout << "Num. pages: " << motions.get_num_pages() << std::endl;
+  for(i=0;i<motions.get_num_pages();i++)
+  {
+    page.clear();
+    page.set_num_servos(motions.get_num_servos());
+    page=motions.get_page(i);
+    std::cout << "name: " << page.get_name() << std::endl;
+    std::cout << "next page: " << page.get_next_page() << std::endl;
+    std::cout << "exit page: " << page.get_exit_page() << std::endl;
+    std::cout << "repetitions: " << page.get_repetitions() << std::endl;
+    std::cout << "speed rate: " << page.get_speed_rate() << std::endl;
+    std::cout << "inertial force: " << page.get_inertial() << std::endl;
+    std::cout << "Num. steps: " << page.get_num_steps() << std::endl;
+    for(j=0;j<page.get_num_steps();j++)
+    {
+      step.clear();
+      step.set_num_servos(motions.get_num_servos());
+      step=page.get_step(j);
+      std::cout << "angles: ";
+      angles=step.get_angles();
+      for(k=0;k<angles.size();k++)
+        std::cout << angles[k] << ",";
+      std::cout << std::endl;
+      std::cout << "pausetime: " << step.get_pause_time() << std::endl;
+      std::cout << "step time: " << step.get_step_time() << std::endl;
+    }
+  }
+
+  return(EXIT_SUCCESS);
+}
diff --git a/src/robotis_mtn_file/mtn_file.l b/src/robotis_mtn_file/mtn_file.l
new file mode 100644
index 0000000000000000000000000000000000000000..04d5f5860a6219cac95925f4a35b656a8e8d8f9c
--- /dev/null
+++ b/src/robotis_mtn_file/mtn_file.l
@@ -0,0 +1,37 @@
+%{
+/* Implementation of yyFlexScanner */
+#include "mtn_file_scanner.hpp"
+#include "mtn_parser.hpp"
+
+/* typedef to make the returns for the tokens shorter */
+typedef MTN::MTN_Parser::token token;
+
+%}
+
+%option debug
+%option nodefault
+%option yyclass="MTN_File_Scanner"
+%option noyywrap
+%option c++
+%option yylineno
+
+%%
+[ \t\n] ;
+"type" { return token::TYPE; }
+"version" { return token::VERSION; }
+"enable" { return token::ENABLE; }
+"motor_type" { return token::MOTOR_TYPE; }
+"page_begin" { return token::BEGIN_PAGE; }
+"name" { return token::NAME; }
+"compliance" { return token::COMPLIANCE; }
+"play_param" { return token::PLAY_PARAMS; }
+"step" { return token::STEP; }
+"page_end" { return token::END_PAGE; }
+"=" { return token::EQUAL; }
+[0-9]+"."[0-9]+ { yylval->fval=atof(yytext); return token::FLOAT; }
+[0-9]+ { yylval->ival=atoi(yytext); return token::INT; }
+[a-zA-Z0-9_]+ { yylval->sval=new std::string(yytext);
+               return token::STRING; }
+. { std::cout << "bad input character " << yytext << " at line " << yylineno << std::endl; }
+%%
+
diff --git a/src/robotis_mtn_file/mtn_file.y b/src/robotis_mtn_file/mtn_file.y
new file mode 100644
index 0000000000000000000000000000000000000000..b94beb8843730da723c33050c0bdcd782a596f6c
--- /dev/null
+++ b/src/robotis_mtn_file/mtn_file.y
@@ -0,0 +1,163 @@
+%skeleton "lalr1.cc"
+%require "2.5"
+%defines
+%define namespace "MTN"
+%define parser_class_name "MTN_Parser"
+%name-prefix "mtn_"
+ 
+%code requires
+{
+  namespace MTN
+  {
+    class CMtnFileParser;
+    class CMtnFileScanner;
+  }
+}
+ 
+%lex-param { CMtnFileScanner &scanner }
+%parse-param { CMtnFileScanner &scanner }
+ 
+%lex-param { CMtnFileParser &parser }
+%parse-param { CMtnFileParser &parser }
+
+%code
+{
+  #include <iostream>
+  #include <cstdlib>
+  #include <fstream>
+  /* include for all driver functions */
+  #include "mtn_file_parser.hpp"
+
+  namespace MTN
+  {
+    /* motion files variables */
+    int num_servos;
+    std::vector<bool> enables;
+    std::vector<int> motor_types;
+    CRobotisPage page;
+    std::string motion_name;
+    std::vector<unsigned char> compliances;
+    CRobotisStep step;
+    std::vector<unsigned short int> angles;
+
+    /* this is silly, but I can't figure out a way around */
+    static int yylex(MTN::MTN_Parser::semantic_type *yylval,MTN::CMtnFileScanner &scanner,MTN::CMtnFileParser &parser);
+  }
+}
+ 
+/* token types */
+%union {
+  int ival;
+  float fval;
+  std::string *sval;
+}
+
+%token TYPE VERSION ENABLE MOTOR_TYPE BEGIN_PAGE END_PAGE
+%token NAME COMPLIANCE PLAY_PARAMS STEP
+%token EQUAL
+%token <ival> INT
+%token <fval> FLOAT
+%token <sval> STRING
+
+/* destructor rule for <sval> objects */
+%destructor { if ($$) { delete ($$); ($$) = NULL; } } <sval>
+ 
+%%
+motion_file: type version enables motor_types pages 
+             ;
+
+type: TYPE EQUAL STRING { parser.set_type(*($3)); 
+                          num_servos=0; }
+      ;
+
+version: VERSION EQUAL FLOAT { parser.set_version($3); }
+         ;
+
+enables: ENABLE EQUAL enable { parser.set_num_servos(num_servos);
+                               parser.set_enables(enables); }
+         ;
+
+enable: enable INT { num_servos++;
+                     enables.push_back($2); }
+        | INT { num_servos++; 
+                enables.push_back($1); }
+        ;
+
+motor_types: 
+             | MOTOR_TYPE EQUAL motor_type { parser.set_motor_types(motor_types); }
+             ;
+
+motor_type: motor_type INT { motor_types.push_back($2); }
+            | INT { motor_types.push_back($1); }
+            ;
+
+pages: pages page 
+       | page 
+       ;
+
+page: BEGIN_PAGE name compliances params steps END_PAGE { parser.add_page(page); 
+                                                          motion_name="";
+                                                          compliances.clear(); }
+      | BEGIN_PAGE name compliances params END_PAGE { parser.add_page(page); 
+                                                      motion_name="";
+                                                      compliances.clear(); }
+      ;
+
+name: NAME EQUAL { page.clear();
+                   page.set_num_servos(num_servos);
+                   page.set_name(std::string("")); }
+      | NAME EQUAL strings { page.clear();
+                             page.set_num_servos(num_servos);
+                             page.set_name(motion_name); }
+      ;
+
+strings: strings STRING { motion_name+=" "+*($2); }
+         | STRING { motion_name+=*($1); }
+         ;
+
+compliances: COMPLIANCE EQUAL compliance { page.set_cw_compliances(compliances);
+                                           page.set_ccw_compliances(compliances); }
+             ;
+
+compliance: compliance INT { compliances.push_back($2); }
+            | INT { compliances.push_back($1); }
+            ;
+
+params: PLAY_PARAMS EQUAL INT INT INT FLOAT INT { page.set_next_page($3);
+                                                  page.set_exit_page($4);
+                                                  page.set_repetitions($5);
+                                                  page.set_speed_rate($6);
+                                                  page.set_inertial($7); }
+        
+
+steps: steps step 
+       | step 
+       ;
+
+
+step: STEP EQUAL angles FLOAT FLOAT { step.clear();
+                                      step.set_num_servos(num_servos);
+                                      step.set_angles(angles);
+                                      angles.clear();
+                                      step.set_pause_time($4);
+                                      step.set_step_time($5);
+                                      page.add_step(step); }
+      ;
+
+angles: angles INT { angles.push_back($2); }
+        | INT { angles.push_back($1); }
+        ;
+%%
+void
+MTN::MTN_Parser::error(const MTN::MTN_Parser::location_type &l,const std::string &err_message )
+{
+  std::cerr << "Error: " << err_message << "\n";
+}
+ 
+/* include for access to scanner.yylex */
+#include "mtn_file_scanner.hpp"
+
+static int MTN::yylex(MTN::MTN_Parser::semantic_type *yylval,MTN::CMtnFileScanner &scanner,MTN::CMtnFileParser &parser)
+{
+  return(scanner.yylex(yylval));
+}
diff --git a/src/robotis_mtn_file/mtn_file_parser.cpp b/src/robotis_mtn_file/mtn_file_parser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1dd6a80fa0f5b6efb7e20412be8f20ac2efb4ce9
--- /dev/null
+++ b/src/robotis_mtn_file/mtn_file_parser.cpp
@@ -0,0 +1,93 @@
+#include <cctype>
+#include <fstream>
+#include <cassert>
+ 
+#include "mtn_file_parser.hpp"
+#include "mtn_parser.hpp"
+
+MTN::CMtnFileParser::CMtnFileParser()
+{
+  this->scanner=NULL;
+  this->parser=NULL;
+}
+ 
+MTN::CMtnFileParser::~CMtnFileParser()
+{
+  if(this->scanner!=NULL)
+  {
+    delete this->scanner;
+    this->scanner=NULL;
+  }
+  if(this->parser!=NULL)
+  {
+    delete this->parser;
+    this->parser=NULL;
+  }
+}
+ 
+void MTN::CMtnFileParser::parse(const char *filename)
+{
+  std::ifstream in_file(filename);
+  if(!in_file.good()) 
+    exit( EXIT_FAILURE );
+  if(this->scanner!=NULL)
+    delete this->scanner;
+  try
+  {
+    scanner=new MTN::CMtnFileScanner(&in_file);
+  }catch(std::bad_alloc &ba){
+    std::cerr << "Failed to allocate scanner: (" << ba.what() << "), exiting!!\n";
+    exit( EXIT_FAILURE );
+  }
+  if(this->parser!=NULL)
+    delete this->parser;
+  try
+  {
+    parser = new MTN::MTN_Parser((*scanner),(*this));
+  }catch(std::bad_alloc &ba){
+    std::cerr << "Failed to allocate parser: (" << ba.what() << "), exiting!!\n";
+    exit( EXIT_FAILURE );
+  }
+
+  const int accept(0);
+  if(parser->parse()!=accept)
+  {
+    std::cerr << "Parse failed!!\n";
+  }
+}
+
+void MTN::CMtnFileParser::set_type(std::string &type)
+{
+  this->motions.set_type(type);
+}
+
+void MTN::CMtnFileParser::set_version(double version)
+{
+  this->motions.set_version(version);
+}
+
+void MTN::CMtnFileParser::set_num_servos(unsigned int num_servos)
+{
+  this->motions.set_num_servos(num_servos);
+}
+
+void MTN::CMtnFileParser::set_enables(std::vector<bool> &enables)
+{
+  this->motions.set_enables(enables);
+}
+
+void MTN::CMtnFileParser::set_motor_types(std::vector<int> &motor_types)
+{
+  this->motions.set_motor_types(motor_types);
+}
+
+void MTN::CMtnFileParser::add_page(CRobotisPage &page)
+{
+  this->motions.add_page(page);
+}
+
+void MTN::CMtnFileParser::get_motions(CRobotisMtn &motions)
+{
+  motions.clear();
+  motions=this->motions;
+}
diff --git a/src/robotis_mtn_file/mtn_file_parser.hpp b/src/robotis_mtn_file/mtn_file_parser.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9ca45cf84f6d5e5cc9e22b632b1b4db5af8d093
--- /dev/null
+++ b/src/robotis_mtn_file/mtn_file_parser.hpp
@@ -0,0 +1,33 @@
+#ifndef _MTN_FILE_PARSER_HPP
+#define _MTN_FILE_PARSER_HPP
+ 
+#include <string>
+#include "mtn_file_scanner.hpp"
+#include "robotis_mtn.h"
+ 
+namespace MTN
+{
+  class CMtnFileParser
+  {
+    friend class MTN_Parser;
+    private:
+      MTN::MTN_Parser *parser;
+      MTN::CMtnFileScanner *scanner;
+      CRobotisMtn motions;
+    protected:
+      // motion files functions
+      void set_type(std::string &type);
+      void set_version(double version); 
+      void set_num_servos(unsigned int num_servos);
+      void set_enables(std::vector<bool> &enables);
+      void set_motor_types(std::vector<int> &motor_types);
+      void add_page(CRobotisPage &page);
+    public:
+      CMtnFileParser(); 
+      void parse(const char *filename);
+      virtual ~CMtnFileParser();
+      void get_motions(CRobotisMtn &motions);
+  };
+} 
+
+#endif 
diff --git a/src/robotis_mtn_file/mtn_file_scanner.hpp b/src/robotis_mtn_file/mtn_file_scanner.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..02f31a54d243c345966f245b86c4029d6559cf72
--- /dev/null
+++ b/src/robotis_mtn_file/mtn_file_scanner.hpp
@@ -0,0 +1,35 @@
+#ifndef _MTN_FILE_SCANNER_HPP
+#define _MTN_FILE_SCANNER_HPP 
+ 
+#if !defined(yyFlexLexerOnce)
+#include <FlexLexer.h>
+#endif
+ 
+#undef YY_DECL
+#define YY_DECL int MTN::CMtnFileScanner::yylex()
+
+#include "mtn_parser.hpp"
+ 
+namespace MTN
+{
+  class CMtnFileScanner : public yyFlexLexer
+  {
+    public:
+      CMtnFileScanner(std::istream *in) : yyFlexLexer(in), yylval( NULL )
+      {
+      };
+      int yylex(MTN::MTN_Parser::semantic_type *lval)
+      {
+        yylval = lval;
+        return( yylex() );
+      }
+ 
+    private:
+      /* hide this one from public view */
+      int yylex();
+      /* yyval ptr */
+      MTN::MTN_Parser::semantic_type *yylval;
+  };
+} /* end namespace MC */
+ 
+#endif