command.cpp
Go to the documentation of this file.
00001 
00010 /*****************************************************************************
00011 ** Includes
00012 *****************************************************************************/
00013 
00014 #include "../../include/kobuki_driver/command.hpp"
00015 
00016 /*****************************************************************************
00017 ** Namespaces
00018 *****************************************************************************/
00019 
00020 namespace kobuki {
00021 
00022 /*****************************************************************************
00023 ** Static variables initialization
00024 *****************************************************************************/
00025 
00026 const unsigned char Command::header0 = 0xaa;
00027 const unsigned char Command::header1 = 0x55;
00028 
00029 /*****************************************************************************
00030 ** Implementation [Command Generators]
00031 *****************************************************************************/
00032 
00053 Command Command::SetLedArray(const enum LedNumber &number, const enum LedColour &colour, Command::Data &current_data)
00054 {
00055   // gp_out is 16 bits
00056   uint16_t value;
00057   if (number == Led1)
00058   {
00059     value = colour; // defined with the correct bit specification.
00060     current_data.gp_out = (current_data.gp_out & 0xfcff) | value; // update first
00061   }
00062   else
00063   {
00064     value = colour << 2;
00065     current_data.gp_out = (current_data.gp_out & 0xf3ff) | value; // update first
00066   }
00067   Command outgoing;
00068   outgoing.data = current_data;
00069   outgoing.data.command = Command::SetDigitalOut;
00070   return outgoing;
00071 }
00072 
00084 Command Command::SetDigitalOutput(const DigitalOutput &digital_output, Command::Data &current_data)
00085 {
00086   uint16_t values = 0x0000;
00087   uint16_t clear_mask = 0xfff0;
00088   for ( unsigned int i = 0; i < 4; ++i ) {
00089     if ( digital_output.mask[i] ) {
00090       if ( digital_output.values[i] ) {
00091         values |= ( 1 << i );
00092       }
00093     } else {
00094       clear_mask |= ( 1 << i ); // don't clear this bit, so set a 1 here
00095     }
00096   }
00097   current_data.gp_out = (current_data.gp_out & clear_mask) | values;
00098   Command outgoing;
00099   outgoing.data = current_data;
00100   outgoing.data.command = Command::SetDigitalOut;
00101   return outgoing;
00102 }
00103 
00115 Command Command::SetExternalPower(const DigitalOutput &digital_output, Command::Data &current_data)
00116 {
00117   uint16_t values = 0x0000;
00118   uint16_t clear_mask = 0xff0f;
00119   for ( unsigned int i = 0; i < 4; ++i ) {
00120     if ( digital_output.mask[i] ) {
00121       if ( digital_output.values[i] ) {
00122         values |= ( 1 << (i+4) );
00123       }
00124     } else {
00125       clear_mask |= ( 1 << (i+4) ); // don't clear this bit, so set a 1 here
00126     }
00127   }
00128   current_data.gp_out = (current_data.gp_out & clear_mask) | values;
00129   Command outgoing;
00130   outgoing.data = current_data;
00131   outgoing.data.command = Command::SetDigitalOut;
00132   return outgoing;
00133 }
00134 
00135 Command Command::PlaySoundSequence(const enum SoundSequences &number, Command::Data &current_data)
00136 {
00137   uint16_t value; // gp_out is 16 bits
00138   value = number; // defined with the correct bit specification.
00139 
00140   Command outgoing;
00141   outgoing.data.segment_name = value;
00142   outgoing.data.command = Command::SoundSequence;
00143   return outgoing;
00144 }
00145 
00146 Command Command::GetVersionInfo()
00147 {
00148   Command outgoing;
00149   outgoing.data.request_flags = 0;
00150   outgoing.data.request_flags |= static_cast<uint16_t>(HardwareVersion);
00151   outgoing.data.request_flags |= static_cast<uint16_t>(FirmwareVersion);
00152   outgoing.data.request_flags |= static_cast<uint16_t>(UniqueDeviceID);
00153   outgoing.data.command = Command::RequestExtra;
00154   return outgoing;
00155 }
00156 
00157 Command Command::SetVelocityControl(DiffDrive& diff_drive)
00158 {
00159   Command outgoing;
00160   std::vector<short> velocity_commands = diff_drive.velocityCommands();
00161   outgoing.data.speed = velocity_commands[0];
00162   outgoing.data.radius = velocity_commands[1];
00163   outgoing.data.command = Command::BaseControl;
00164   return outgoing;
00165 }
00166 Command Command::SetVelocityControl(const int16_t &speed, const int16_t &radius)
00167 {
00168   Command outgoing;
00169   outgoing.data.speed = speed;
00170   outgoing.data.radius = radius;
00171   outgoing.data.command = Command::BaseControl;
00172   return outgoing;
00173 }
00174 
00175 /*****************************************************************************
00176 ** Implementation [Serialisation]
00177 *****************************************************************************/
00181 void Command::resetBuffer(Buffer& buffer) {
00182   buffer.clear();
00183   buffer.resize(64);
00184   buffer.push_back(Command::header0);
00185   buffer.push_back(Command::header1);
00186   buffer.push_back(0); // just initialise, we usually write in the payload here later (size of payload only, not stx, not etx, not length)
00187 }
00188 
00189 bool Command::serialise(ecl::PushAndPop<unsigned char> & byteStream)
00190 {
00191   if (!(byteStream.size() > 0))
00192   {
00193     //ROS_WARN_STREAM("kobuki_node: kobuki_command: serialise failed. empty byte stream.");
00194     return false;
00195   }
00196   // need to be sure we don't pass through an emum to the Trans'd buildBytes functions.
00197   unsigned char cmd = static_cast<unsigned char>(data.command);
00198   unsigned char length = 0;
00199   switch (data.command)
00200   {
00201     case BaseControl:
00202       buildBytes(cmd, byteStream);
00203       buildBytes(length=4, byteStream);
00204       buildBytes(data.speed, byteStream);
00205       buildBytes(data.radius, byteStream);
00206       break;
00207     case Sound:
00208       buildBytes(cmd, byteStream);
00209       buildBytes(length=3, byteStream);
00210       buildBytes(data.note, byteStream);
00211       buildBytes(data.duration, byteStream);
00212       break;
00213     case SoundSequence:
00214       buildBytes(cmd, byteStream);
00215       buildBytes(length=1, byteStream);
00216       buildBytes(data.segment_name, byteStream);
00217       break;
00218     case RequestExtra:
00219       buildBytes(cmd, byteStream);
00220       buildBytes(length=2, byteStream);
00221       buildBytes(data.request_flags, byteStream);
00222       break;
00223     case ChangeFrame:
00224       buildBytes(cmd, byteStream);
00225       buildBytes(length=1, byteStream);
00226       buildBytes(data.frame_id, byteStream);
00227       break;
00228     case RequestEeprom:
00229       buildBytes(cmd, byteStream);
00230       buildBytes(length=1, byteStream);
00231       buildBytes(data.frame_id, byteStream);
00232       break;
00233     case SetDigitalOut:
00234     { // this one controls led, external power sources, gp digitial output
00235       buildBytes(cmd, byteStream);
00236       buildBytes(length=2, byteStream);
00237       buildBytes(data.gp_out, byteStream);
00238       break;
00239     }
00240     default:
00241       return false;
00242       break;
00243   }
00244   return true;
00245 }
00246 
00247 
00248 
00249 } // namespace kobuki


kobuki_driver
Author(s): Daniel Stonier , Younghun Ju , Jorge Santos Simon
autogenerated on Mon Oct 6 2014 01:31:09