multicar_hydraulic_core.cpp
Go to the documentation of this file.
00001 #include <iostream>
00002 #include <iomanip>
00003 #include <cstring>
00004 #include <cstdio>
00005 #include <stdint.h>
00006 #include <string>
00007 #include <vector>
00008 #include "ros/ros.h"
00009 #include "multicar_hydraulic_core.h"
00010 #include "multicar_hydraulic/CanCmd.h"
00011 #include "tinycan/CanMsg.h"
00012 #include "sensor_msgs/JointState.h"
00013 
00014 #define DEBUG_CAN_OUTPUT true
00015 #define ALLOW_SWK true
00016 #define ALLOW_SF false
00017 
00018 namespace hydraulic {
00019 
00020 uint8_t Ausleger::pre_control_signal = PRE_CONTROL_SIG_OFF_ACK;
00021 
00022 bool isBetween(uint32_t num, uint32_t lower, uint32_t upper)
00023 {
00024   if (num >= lower && num <= upper)
00025     return true;
00026   else
00027     return false;
00028 }
00029 
00030 Hydraulic::Hydraulic()
00031 {
00032   return;
00033 }
00034 
00035 Hydraulic::~Hydraulic()
00036 {
00037 
00038 }
00039 
00040 int Hydraulic::init()
00041 {
00042   std::string names[5] = {"Schnellwechselkopf", "Nebenarm", "Hauptarm", "Verschub", "Schwenkfix"};
00043   // init Ausleger
00044   for (int i = 0 ; i < 5 ; i++)
00045   {
00046     ausleger[i].node_id = i + 125;
00047     ausleger[i].node_name = names[i];
00048     ausleger[i].state = MOVE_HALT;
00049     ausleger[i].is_moveing = false;
00050     ausleger[i].setValues(0,0);
00051     ausleger[i].target_position = 0;
00052     ausleger[i].target_velocity = 0;
00053   }
00054   // init hydraulic states
00055   for (uint8_t i = 0 ; i < 3 ; i++)
00056   {
00057     memset(hydraulic_states[i], 0x00, 8);
00058   }
00059 
00060   is_man_ctr = false;
00061   is_man_ctr_act = false;
00062 
00063   cpub = NULL;
00064 }
00065 
00066 /*----------------------------------------------------------------------
00067  * publishCanMessage()
00068  * Publish can message.
00069  *--------------------------------------------------------------------*/
00070 
00071 void Hydraulic::publishCanMessage(tinycan::CanMsg *msg)
00072 {
00073   if (cpub != NULL)
00074     cpub->publish(*msg);
00075 }
00076 
00077 /*----------------------------------------------------------------------
00078  * publishJointState()
00079  * Publisher JointState Message
00080  *--------------------------------------------------------------------*/
00081 
00082 void Hydraulic::publishJointStateMessage(int nid, uint32_t pos, uint16_t velo)
00083 {
00084   if (jspub == NULL)
00085     return;
00086 
00087   static uint32_t seq = 0;
00088   ros::Time current_time = ros::Time::now();
00089   sensor_msgs::JointState js_msg;
00090   std::vector<std::string> s;
00091   std::vector<double> p;
00092   std::vector<double> v;
00093   std::vector<double> e;
00094   double tmp = 0.0;
00095 
00096   v.push_back(velo/1000.0); // from mm/s to m/s
00097 
00098   js_msg.header.seq = seq;
00099   js_msg.header.stamp = current_time;
00100   js_msg.header.frame_id = "odom";
00101 
00102   switch(nid)
00103   {
00104     case NID_THRUST:
00105       if (pos > 612)
00106         p.push_back((pos-612)/1000.0*-1);
00107       else
00108         p.push_back((612-pos)/1000.0);
00109       s.push_back("trans_schlitten");
00110       e.push_back(0);
00111     break;
00112     case NID_Hauptarm: // hauptarm.ods
00113       tmp = -0.003853211*pos + 5.4794495413;
00114       if (tmp < 3.68) tmp = 3.68;
00115       if (tmp > 4.94) tmp = 4.94;
00116       p.push_back(tmp);
00117       s.push_back("rot_dreharm_hauptarm");
00118       e.push_back(1000);
00119     break;
00120     case NID_Nebenarm: // nebenarm.ods
00121       tmp = -0.0086239216 * pos + 6.1126003922;
00122       if (tmp < 3.51) tmp = 3.51;
00123       if (tmp > 5.72) tmp = 5.72;
00124       p.push_back(tmp);
00125       s.push_back("rot_hauptarm_nebenarm");
00126       e.push_back(1000);
00127     break;
00128     case NID_Schnellwechselkopf: // swk.ods
00129       tmp = 0.0113780769 * pos + 1.2488742308;
00130       if (tmp < 1.80) tmp = 1.80;
00131       if (tmp > 4.76) tmp = 4.76;
00132       p.push_back(tmp);
00133       s.push_back("rot_nebenarm_schnellwechselsystem");
00134       e.push_back(1000);
00135     break;
00136     case NID_Schwenkfix:
00137       tmp = 0.0079487179*pos + 4.2133;
00138       // check if state is outside bounds by a significant margin
00139       if (tmp > 6.28318)
00140         tmp = 6.28318;
00141       else if ( tmp < 4.7298)
00142         tmp = 4.7298;
00143       p.push_back(tmp);
00144       //std::cout << "::" << (0.0079487179*pos + 4.2133) << std::endl;
00145       s.push_back("rot_schnellwechselsystem_maehkopf");
00146       e.push_back(1000);   
00147     break;
00148   }
00149   js_msg.position = p;
00150   js_msg.velocity = v;
00151 
00152   js_msg.name = s;
00153   js_msg.effort = e;
00154 
00155   jspub->publish(js_msg);
00156   seq++;
00157   return;
00158 }
00159 
00160 /*----------------------------------------------------------------------
00161  * callbackRobotTrajectory()
00162  * Callback for robot trajectory.
00163  *--------------------------------------------------------------------*/
00164 
00165 void Hydraulic::callbackRobotTrajectory(const sensor_msgs::JointState::ConstPtr& msg) //trajectory_msgs::JointTrajectory
00166 {
00167   uint16_t p = 0;
00168   for (unsigned int i=0; i< msg->name.size(); i++)
00169   {
00170     std::cout << msg->name[i] << std::endl;
00171     // Verschub
00172     if (msg->name[i].compare(std::string("trans_schlitten")) == 0)
00173     {
00174       std::cout << "    " << "Velocity soll (real):" << msg->velocity[i] << "m/s" << std::endl;
00175       std::cout << "    " << "Position (ROS):" << msg->position[i] << std::endl;
00176       p = msg->position[i] * 1000; // convert from m to mm
00177       if (p > 0)
00178         p = 612-p;
00179       else
00180         p = 612 + (-1*p);
00181       std::cout << "    " << "Position soll (real):" << p << "mm" << std::endl;
00182       std::cout << "    " << "Position ist  (real):" << ausleger[IDX_VERSCHUB].position << "mm" << std::endl;
00183       ausleger[IDX_VERSCHUB].target_position = p;
00184       ausleger[IDX_VERSCHUB].is_moveing = false;
00185       if ( ausleger[IDX_VERSCHUB].position < ausleger[IDX_VERSCHUB].target_position)
00186         ausleger[IDX_VERSCHUB].state = MOVE_THRUST_RIGHT;
00187       else
00188         ausleger[IDX_VERSCHUB].state = MOVE_THRUST_LEFT;
00189     }
00190     // Hauptarm
00191     else if (msg->name[i].compare(std::string("rot_dreharm_hauptarm")) == 0)
00192     {
00193       // convert from rad to mm hauptarm.ods
00194       p = -259.5238095238 * msg->position[i] + 1422.0476190476;
00195       if (p > 467.0) p = 467.0;
00196       if (p < 140.0) p = 140.0;
00197       std::cout << "    " << "Velocity soll (real):" << msg->velocity[i] << "m/s" << std::endl;
00198       std::cout << "    " << "Position (ROS):" << msg->position[i] << std::endl;
00199       std::cout << "    " << "Position (real):" << p << "mm" << std::endl;
00200       std::cout << "    " << "Position ist (real):" << ausleger[IDX_Hauptarm].position << "mm" << std::endl;
00201       ausleger[IDX_Hauptarm].target_position = p;
00202       ausleger[IDX_Hauptarm].is_moveing = false;
00203       if (p < ausleger[IDX_Hauptarm].position)
00204       {
00205         ausleger[IDX_Hauptarm].state = MOVE_DOWN;
00206       }
00207       else
00208       {
00209         ausleger[IDX_Hauptarm].state = MOVE_UP;
00210       }
00211     }
00212     // Nebenarm
00213     else if (msg->name[i].compare(std::string("rot_hauptarm_nebenarm")) == 0)
00214     {
00215       // convert from rad to mm nebenarm.ods
00216       p = (-115.9565276704 * msg->position[i] + 708.7959165113);
00217       if (p > 301.0) p = 301.0;
00218       if (p <  46.0) p =  46.0;
00219       std::cout << "    " << "Velocity soll (real):" << msg->velocity[i] << "m/s" << std::endl;
00220       std::cout << "    " << "Position (ROS):" << msg->position[i] << std::endl;
00221       std::cout << "    " << "Position (real):" << p << "mm" << std::endl;
00222       std::cout << "    " << "Position ist (real):" << ausleger[IDX_Nebenarm].position << "mm" << std::endl;
00223       // Workaround
00224       if (!is_man_ctr)
00225                 setPWM(NID_Nebenarm, 0);
00226       // -----
00227       ausleger[IDX_Nebenarm].target_position = p;
00228       ausleger[IDX_Nebenarm].is_moveing = false;
00229       if (p < ausleger[IDX_Nebenarm].position)
00230       {
00231         ausleger[IDX_Nebenarm].state = MOVE_DOWN;
00232       }
00233       else
00234       {
00235         ausleger[IDX_Nebenarm].state = MOVE_UP;
00236       }
00237     }
00238     // Schnellwechselkopf
00239     else if (msg->name[i].compare(std::string("rot_nebenarm_schnellwechselsystem")) == 0)
00240     {
00241       // convert from rad to mm swk.ods
00242       p = (87.8883142345 * msg->position[i] - 109.7614508332);
00243       if (p > 309.0) p = 309.0;
00244       if (p <  49.0) p =  49.0;
00245       std::cout << "    " << "Velocity soll (real):" << msg->velocity[i] << "m/s" << std::endl;
00246       std::cout << "    " << "Position (ROS):" << msg->position[i] << std::endl;
00247       std::cout << "    " << "Position (real):" << p << "mm" << std::endl;
00248       std::cout << "    " << "Position ist (real):" << ausleger[IDX_Schnellwechselkopf].position << "mm" << std::endl;
00249       if (ALLOW_SWK)
00250       {
00251         // Workaround
00252         if (!is_man_ctr)
00253           setPWM(NID_Schnellwechselkopf, 0);
00254         // -----
00255         ausleger[IDX_Schnellwechselkopf].target_position = p;
00256         ausleger[IDX_Schnellwechselkopf].is_moveing = false;
00257         if (p < ausleger[IDX_Schnellwechselkopf].position)
00258         {
00259           ausleger[IDX_Schnellwechselkopf].state = MOVE_DOWN;
00260         }
00261         else
00262         {
00263           ausleger[IDX_Schnellwechselkopf].state = MOVE_UP;
00264         }
00265       }
00266     }
00267     // Schwenkfix
00268     else if (msg->name[i].compare(std::string("rot_schnellwechselsystem_maehkopf")) == 0)
00269     {
00270       // convert from rad to mm
00271       p = (125.8064516129 * msg->position[i] - 530.064516129);
00272       std::cout << "    " << "Velocity soll (real):" << msg->velocity[i] << "m/s" << std::endl;
00273       std::cout << "    " << "Position (ROS):" << msg->position[i] << std::endl;
00274       std::cout << "    " << "Position (real):" << p << "mm" << std::endl;
00275       std::cout << "    " << "Position ist (real):" << ausleger[IDX_Schwenkfix].position << "mm" << std::endl;
00276       if (ALLOW_SF)
00277       {
00278         ausleger[IDX_Schwenkfix].target_position = p;
00279         ausleger[IDX_Schwenkfix].is_moveing = false;
00280         if (p < ausleger[IDX_Schwenkfix].position) // TODO: check direction
00281         {
00282           ausleger[IDX_Schwenkfix].state = MOVE_DOWN;
00283         }
00284         else
00285         {
00286           ausleger[IDX_Schwenkfix].state = MOVE_UP;
00287         }
00288       }
00289     }
00290   }
00291   return;
00292 }
00293 
00294 /*----------------------------------------------------------------------
00295  * canMsgRawCallback()
00296  * Callback for can messages.
00297  *--------------------------------------------------------------------*/
00298 
00299 void Hydraulic::callbackCanMessageRaw(const tinycan::CanMsg::ConstPtr& msg)
00300 {
00301   uint16_t cid = 0;
00302   uint8_t node_id = 0;
00303   //cid = msg->id >> 7;
00304   cid = msg->id & 0x0000FF80;
00305   node_id = msg->id & 0x0000007F;
00306 
00307   if (node_id == NID_Hydraulik)
00308   {
00309     switch(cid)
00310     {
00311       case CO_HYDRAULIC_ACK:
00312         if (msg->data[1] == 0x40)
00313         {
00314           hydraulic_states[HYDRAULIC_HA_SWK][1] = 0x40;
00315           Ausleger::pre_control_signal = PRE_CONTROL_SIG_ON_ACK;
00316           printf("pre sig on ack\n");
00317           if (is_man_ctr)
00318           {
00319                         if (!is_man_ctr_act)
00320                         {  
00321                           is_man_ctr_act = true;
00322                       setPWM(NID_Hauptarm, 0);
00323                       setPWM(NID_Nebenarm, 0);
00324                       setPWM(NID_THRUST, 0);
00325                     }
00326                   }        
00327         }
00328         if (msg->data[1] == 0x00)
00329         {
00330           hydraulic_states[HYDRAULIC_HA_SWK][1] = 0x00;
00331           Ausleger::pre_control_signal = PRE_CONTROL_SIG_OFF_ACK;
00332           printf("pre sig off ack\n"); 
00333         }
00334       break;
00335       case CO_PRE_CONTROL:
00336                 printf("manuelle Kontrolle!\n");
00337                 is_man_ctr = true;
00338       break;
00339       case CO_BOOM_MSG:
00340       {
00341         uint16_t Schnellwechselkopf = 0, thrust = 0, main_pressure = 0, pivoting = 0;
00342         pivoting = msg->data[0] + (msg->data[1] << 8);
00343         thrust = msg->data[2] + (msg->data[3] << 8);
00344         main_pressure = msg->data[4] + (msg->data[5] << 8);        
00345         // calc position (pos = 0.120 * thrust - 27.200)
00346         if (0.120 * thrust - 27.200 <= 0)
00347           ausleger[IDX_VERSCHUB].position = 0;
00348         else
00349           ausleger[IDX_VERSCHUB].position = 0.120 * thrust - 27.200; // in mm
00350         
00351         ausleger[IDX_Schwenkfix].position = 0.039 * pivoting - 97.101; // in mm
00352         //if (ausleger[NID_Schwenkfix].position < 0)
00353                 //  ausleger[NID_Schwenkfix].position = 
00354         if (DEBUG_CAN_OUTPUT) printf("Verschub:%lf :: Druck Hauptarm:%d :: Schwenken:%lf\n", ausleger[IDX_VERSCHUB].position, main_pressure, ausleger[IDX_Schwenkfix].position);
00355         publishJointStateMessage(NID_THRUST, ausleger[IDX_VERSCHUB].position, 0);
00356         publishJointStateMessage(NID_Schwenkfix, ausleger[IDX_Schwenkfix].position, 0);
00357       }
00358       break;
00359       default:
00360 
00361       break;
00362     }
00363   }
00364   else if (node_id >= 125 && node_id <= 127)
00365   {
00366     switch(cid)
00367     {
00368       case CO_VALUES_MSG:
00369       {
00370         int32_t pos = msg->data[0] + (msg->data[1] << 8) + (msg->data[2] << 16) + (msg->data[3] << 24);
00371         int16_t v = msg->data[4] + (msg->data[5] << 8);
00372         ausleger[node_id-125].setValues(pos,v);
00373         if (DEBUG_CAN_OUTPUT)  ausleger[node_id-125].printValues();
00374         publishJointStateMessage(node_id, ausleger[node_id-125].position, ausleger[node_id-125].velocity);
00375       }
00376       break;
00377       case CO_HEARTBEAT_MSG:
00378         if (DEBUG_CAN_OUTPUT) printf("Heartbeat from Node:%d :: State:%X\n", node_id, msg->data[0]);
00379       break;
00380       default:
00381         if (DEBUG_CAN_OUTPUT) printf("other message from device:%d :: %d\n", msg->id, node_id);
00382       break;
00383     }
00384   }
00385   else
00386   {
00387     switch(cid)
00388     {
00389       case CO_NMT_MSG:
00390         if (msg->data[0] == 0x01)
00391           if (DEBUG_CAN_OUTPUT) printf("NMT start indicate to node:%X\n", msg->data[1]);
00392       break;
00393       case CO_HEARTBEAT_MSG:
00394         if (DEBUG_CAN_OUTPUT) printf("Heartbeat from Node %X, State: %d\n", node_id, msg->data[0]);
00395       break;
00396       case 0x80:
00397         if (node_id == 0x00)
00398           if (DEBUG_CAN_OUTPUT) printf("Sync Message\n");
00399       break;
00400       case 0x180:
00401         if (DEBUG_CAN_OUTPUT) printf("TxPDO1 Message from Node %X\n", node_id);
00402       break;
00403       case 0x280:
00404         if (DEBUG_CAN_OUTPUT) printf("TxPDO2 Message from Node %X\n", node_id);
00405       break;
00406       case 0x580:
00407         if (DEBUG_CAN_OUTPUT) printf("SDO Response from Node %X\n",node_id);
00408       break;
00409       case 0x600:
00410         if (DEBUG_CAN_OUTPUT) printf("SDO Request from Node %X\n",node_id);
00411       break;
00412       default:
00413         ;
00414         if (DEBUG_CAN_OUTPUT) printf("message from unknown node:%X :: %X\n", node_id, msg->id);
00415       break;
00416     }
00417   }
00418 }
00419 
00420 /*----------------------------------------------------------------------
00421  * cmdToCanMessage()
00422  *
00423  *--------------------------------------------------------------------*/
00424 
00425 void Hydraulic::cmdToCanMessage(std::string cmd, int val = 0)
00426 {
00427   tinycan::CanMsg cmsg;
00428   cmsg.id = 0x000;
00429   cmsg.len = 8;
00430   for (uint8_t i = 0; i < 8 ; i++)
00431     cmsg.data[i] = 0;
00432   //std::cout << cmd << std::endl;
00433   if (cmd.compare("boot") == 0)
00434   {
00435     cmsg.id = 0x000;
00436     cmsg.len = 2;
00437     cmsg.data[0] = 0x01;
00438     cmsg.data[1] = val;
00439     //std::cout << cmsg.len << std::endl;
00440   } else if (cmd.compare("preop") == 0)
00441   {
00442     cmsg.id = 0x000;
00443     cmsg.len = 2;
00444     cmsg.data[0] = 0x80;
00445     cmsg.data[1] = 0x00;
00446   } else if (cmd.compare("sync") == 0)
00447   {
00448     cmsg.id = 0x080;
00449     cmsg.len = 0;
00450   } else if (cmd.compare("pcs_on") == 0) // activate pre control signal
00451   {
00452     std::cout << "pcs_on" << std::endl;
00453     cmsg.id = 0x214;
00454     cmsg.len = 3;
00455     cmsg.data[1] = 0x40;
00456   } else if (cmd.compare("pcs_off") == 0) // deactivate pre control signal
00457   {
00458         std::cout << "pcs_off" << std::endl;  
00459     cmsg.id = 0x214;
00460     cmsg.len = 3;
00461     cmsg.data[1] = 0x00;
00462   }
00463   cpub->publish(cmsg);
00464 }
00465 
00466 /*----------------------------------------------------------------------
00467  * setPWM()
00468  * Set PWM signal for selected node.
00469  *--------------------------------------------------------------------*/
00470 void Hydraulic::setPWM(uint8_t nid, uint16_t pwm)
00471 {
00472   tinycan::CanMsg cmsg;
00473   for (uint8_t i = 0 ; i < 8 ; i++)
00474     cmsg.data[i] = 0x00;
00475   switch(nid)
00476   {
00477     case NID_THRUST:
00478       if (pwm == 0) // stop moveing
00479       {
00480         // set pwm value 0
00481         cmsg.id = 0x514;
00482         cmsg.len = 8;
00483         cmsg.data[0] = cmsg.data[1] = cmsg.data[2] = cmsg.data[3] = 0x00;
00484         publishCanMessage(&cmsg);
00485         memset(&cmsg.data,0x00,8);
00486         
00487         // deactivate pwm
00488         cmsg.id = 0x314;
00489         cmsg.len = 2;
00490         //cmsg.data[0] = 0x00; // pwm thrust left on
00491         //cmsg.data[1] = 0x02;
00492         hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] & 0x0C;
00493         hydraulic_states[HYDRAULIC_NA_VS][1] = 0x02;       
00494         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_NA_VS], 8); 
00495         publishCanMessage(&cmsg);
00496         break;
00497       }
00498       if (ausleger[IDX_VERSCHUB].state == MOVE_THRUST_LEFT)
00499       {
00500         // activate pwm left
00501         cmsg.id = 0x314;
00502         cmsg.len = 2;
00503         //cmsg.data[0] = 0x10; // pwm thrust left on
00504         //cmsg.data[1] = 0x02;
00505         hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] | 0x10;
00506         hydraulic_states[HYDRAULIC_NA_VS][1] = 0x02;        
00507         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_NA_VS], 8);
00508         publishCanMessage(&cmsg);
00509         memset(&cmsg.data,0x00,8);
00510 
00511         cmsg.id = 0x514;
00512         cmsg.len = 8;
00513         cmsg.data[0] = pwm & 0x00FF;
00514         cmsg.data[1] = pwm >> 8;
00515         publishCanMessage(&cmsg);
00516       }
00517       else
00518       {
00519         // activate pwm right
00520         cmsg.id = 0x314;
00521         cmsg.len = 2;
00522         //cmsg.data[0] = 0x20; // pwm thrust right on
00523         //cmsg.data[1] = 0x02;
00524         hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] | 0x20;
00525         hydraulic_states[HYDRAULIC_NA_VS][1] = 0x02;
00526         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_NA_VS], 8);    
00527         publishCanMessage(&cmsg);
00528         memset(&cmsg.data,0x00,8);
00529 
00530         cmsg.id = 0x514;
00531         cmsg.len = 8;
00532         cmsg.data[2] = pwm & 0x00FF;
00533         cmsg.data[3] = pwm >> 8;
00534         publishCanMessage(&cmsg);
00535       }
00536     break;
00537     case NID_Hauptarm:
00538       if (pwm == 0) // stop moveing
00539       {
00540         // deactivate hauptarm
00541         cmsg.id = 0x214;
00542         cmsg.len = 3;
00543         hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] & 0xC0;
00544         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00545         publishCanMessage(&cmsg);
00546         memset(&cmsg.data,0x00,3);
00547         
00548         // set pwm value 0
00549         cmsg.id = 0x394;
00550         cmsg.len = 8;
00551         for (uint8_t i = 0 ; i < 4 ; i++)
00552           hydraulic_states[HYDRAULIC_HA_NA][i] = 0;
00553         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_NA], 8);
00554         publishCanMessage(&cmsg);
00555         break;
00556       }
00557       if (ausleger[IDX_Hauptarm].state == MOVE_UP)
00558       {
00559         // activate hauptarm up
00560         cmsg.id = 0x214;
00561         cmsg.len = 3;
00562         hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] | 0x02; //0xC2
00563         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00564         publishCanMessage(&cmsg);
00565         memset(&cmsg.data,0x00,3);
00566 
00567         // activate pwm up
00568         cmsg.id = 0x394;
00569         cmsg.len = 8;
00570         hydraulic_states[HYDRAULIC_HA_NA][2] = pwm & 0x00FF;
00571         hydraulic_states[HYDRAULIC_HA_NA][3] = pwm >> 8;
00572         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_NA], 8);
00573         publishCanMessage(&cmsg);
00574       }
00575       else
00576       {
00577         // activate hauptarm up
00578         cmsg.id = 0x214;
00579         cmsg.len = 3;
00580         hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] | 0x01; //0xC1
00581         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00582         publishCanMessage(&cmsg);
00583         memset(&cmsg.data,0x00,3);
00584 
00585         // activate pwm down
00586         cmsg.id = 0x394;
00587         cmsg.len = 8;
00588         hydraulic_states[HYDRAULIC_HA_NA][0] = pwm & 0x00FF;
00589         hydraulic_states[HYDRAULIC_HA_NA][1] = pwm >> 8;
00590         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_NA], 8);
00591         publishCanMessage(&cmsg);
00592       }
00593     break;
00594     case NID_Nebenarm:
00595       if (pwm == 0)
00596       {
00597         // set pwm value 0
00598         cmsg.id = 0x414;
00599         cmsg.len = 8;
00600         cmsg.data[4] = cmsg.data[5] = cmsg.data[6] = cmsg.data[7] = 0x00;
00601         for (uint8_t i = 4 ; i < 8 ; i++)
00602           hydraulic_states[HYDRAULIC_HA_NA][i] = 0;
00603         //memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_NA], 8);
00604         publishCanMessage(&cmsg);
00605         memset(&cmsg.data,0x00,8);
00606         
00607         // deactivate pwm
00608         cmsg.id = 0x314;
00609         cmsg.len = 2;
00610         hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] & 0x30;
00611         hydraulic_states[HYDRAULIC_NA_VS][1] = 0x02;
00612         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_NA_VS], 8);    
00613         publishCanMessage(&cmsg);
00614         break;
00615       }
00616       if (ausleger[IDX_Nebenarm].state == MOVE_UP)
00617       {
00618         // activate Nebenarm up
00619         cmsg.id = 0x314;
00620         cmsg.len = 2;
00621         hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] | 0x08; // pwm nebenarm ausfahren
00622         hydraulic_states[HYDRAULIC_NA_VS][1] = 0x02;
00623         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_NA_VS], 8);    
00624         publishCanMessage(&cmsg);
00625         memset(&cmsg.data,0x00,8);
00626 
00627         // set pwm value
00628         cmsg.id = 0x414;
00629         cmsg.len = 8;
00630         hydraulic_states[HYDRAULIC_HA_NA][4] = 0x00;
00631         hydraulic_states[HYDRAULIC_HA_NA][5] = 0x00;
00632         hydraulic_states[HYDRAULIC_HA_NA][6] = pwm & 0x00FF;
00633         hydraulic_states[HYDRAULIC_HA_NA][7] = pwm >> 8;
00634         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_NA], 8);
00635         publishCanMessage(&cmsg);
00636       }
00637       else
00638       {
00639         // activate Nebenarm down
00640         cmsg.id = 0x314;
00641         cmsg.len = 2;
00642         hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] | 0x04; // pwm nebenarm einfahren
00643         hydraulic_states[HYDRAULIC_NA_VS][1] = 0x02;
00644         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_NA_VS], 8);  
00645         publishCanMessage(&cmsg);
00646         memset(&cmsg.data,0x00,8);
00647 
00648         // set pwm value
00649         cmsg.id = 0x414;
00650         cmsg.len = 8;
00651         hydraulic_states[HYDRAULIC_HA_NA][4] = pwm & 0x00FF;
00652         hydraulic_states[HYDRAULIC_HA_NA][5] = pwm >> 8;
00653         hydraulic_states[HYDRAULIC_HA_NA][6] = 0x00;
00654         hydraulic_states[HYDRAULIC_HA_NA][7] = 0x00;
00655         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_NA], 8);
00656         publishCanMessage(&cmsg);
00657       }
00658     break;
00659     case NID_Schnellwechselkopf:
00660       if (pwm == 0)
00661       {
00662         // set pwm value 0        
00663         cmsg.id = 0x494;
00664         cmsg.len = 8;
00665         memset(&cmsg.data,0x00,8);
00666         publishCanMessage(&cmsg);
00667         memset(&cmsg.data,0x00,8);
00668         
00669         // deactivate schnellwechselkopf
00670         cmsg.id = 0x214;
00671         cmsg.len = 3;
00672         hydraulic_states[HYDRAULIC_HA_SWK][0] = 0x00;
00673         hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] &  0x03;
00674         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00675         publishCanMessage(&cmsg);
00676         memset(&cmsg.data,0x00,8);
00677         break;
00678       }
00679       if (ausleger[IDX_Schnellwechselkopf].state == MOVE_UP)
00680       {
00681         // activate schnellwechselkopf
00682         cmsg.id = 0x214;
00683         cmsg.len = 3;
00684 
00685         hydraulic_states[HYDRAULIC_HA_SWK][0] = 0x00;
00686         hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] |  0x80;
00687         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00688         publishCanMessage(&cmsg);
00689         memset(&cmsg.data,0x00,8);
00690 
00691         // set pwm value
00692         cmsg.id = 0x494;
00693         cmsg.len = 8;
00694         cmsg.data[4] = 0x00;
00695         cmsg.data[5] = 0x00;
00696         cmsg.data[6] = pwm & 0x00FF;
00697         cmsg.data[7] = pwm >> 8;
00698         publishCanMessage(&cmsg);
00699         memset(&cmsg.data,0x00,8);
00700       }
00701       else
00702       {
00703         // activate schnellwechselkopf
00704         cmsg.id = 0x214;
00705         cmsg.len = 3;
00706         hydraulic_states[HYDRAULIC_HA_SWK][0] = 0x00;
00707         hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] |  0x40;
00708         memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00709         publishCanMessage(&cmsg);
00710         memset(&cmsg.data,0x00,8);
00711 
00712         // set pwm value
00713         cmsg.id = 0x494;
00714         cmsg.len = 8;
00715         cmsg.data[4] = pwm & 0x00FF;
00716         cmsg.data[5] = pwm >> 8;
00717         cmsg.data[6] = 0x00;
00718         cmsg.data[7] = 0x00;
00719         publishCanMessage(&cmsg);
00720         memset(&cmsg.data,0x00,8);
00721       }      
00722     break;
00723   }
00724 }
00725 
00726 /*----------------------------------------------------------------------
00727  * checkTask()
00728  * Handle hydraulic movement tasks.
00729  *--------------------------------------------------------------------*/
00730 
00731 int Hydraulic::checkTask()
00732 {
00733   if (is_man_ctr)
00734     return 0;
00735   // check if waiting for pre-control singal ack
00736   if (Ausleger::pre_control_signal == PRE_CONTROL_SIG_ON ||
00737       Ausleger::pre_control_signal == PRE_CONTROL_SIG_OFF)
00738   {
00739      return 0;
00740   }
00741 
00742   // check for new movement
00743   for (uint8_t i = 0 ; i < 5 ; i++)
00744   {
00745     if (ausleger[i].is_moveing == false && ausleger[i].state != MOVE_HALT)
00746     {
00747       // check if pre control signal is active
00748       if (Ausleger::pre_control_signal == PRE_CONTROL_SIG_OFF_ACK)
00749       { // not active
00750         //set pcs on and waiting for ack
00751         cmdToCanMessage("pcs_on");
00752         Ausleger::pre_control_signal = PRE_CONTROL_SIG_ON;
00753         return 0;
00754       }
00755       else
00756       {
00757         ROS_INFO_STREAM("New movement for node " << ausleger[i].node_name << " id:" << ausleger[i].node_id);
00758         // set pwm
00759         setPWM(ausleger[i].node_id, 1250);
00760 
00761         ausleger[i].is_moveing = true;
00762       }
00763     }
00764   }
00765 
00766   // check for stopping movement or changing
00767   for (uint8_t i = 0 ; i < 5 ; i++)
00768   {
00769     if (ausleger[i].is_moveing == true && ausleger[i].state >= MOVE_MOVING)
00770     {
00771       //ROS_INFO_STREAM("Check movement for node " << ausleger[i].node_name << "::" << ausleger[i].position << "::" << ausleger[i].target_position);
00772       // check target
00773       if (ausleger[i].state == MOVE_THRUST_LEFT)
00774       {
00775         if (ausleger[i].position <= ausleger[i].target_position)
00776         {
00777           setPWM(ausleger[i].node_id,0); // stop moveing
00778           ROS_INFO_STREAM("Check movement l for node " << ausleger[i].node_name << "::" << ausleger[i].position << "::" << ausleger[i].target_position);
00779           ausleger[i].is_moveing = false;
00780           ausleger[i].state = MOVE_HALT;
00781         }
00782       }
00783       if (ausleger[i].state == MOVE_THRUST_RIGHT)
00784       {
00785         if (ausleger[i].position >= ausleger[i].target_position)
00786         {
00787           setPWM(ausleger[i].node_id,0); // stop moveing
00788           ROS_INFO_STREAM("Check movement r for node " << ausleger[i].node_name << "::" << ausleger[i].position << "::" << ausleger[i].target_position);
00789           ausleger[i].is_moveing = false;
00790           ausleger[i].state = MOVE_HALT;
00791         }
00792       }
00793     }
00794   }
00795 
00796   // check for any active movement
00797   for (uint8_t i = 0; i < 5 ; i++)
00798   {
00799     if (ausleger[i].is_moveing == true)
00800       return 0;
00801   }
00802   
00803   if (Ausleger::pre_control_signal == PRE_CONTROL_SIG_OFF_ACK)
00804     return 0;
00805   
00806   // set pcs off and wait for ack
00807   cmdToCanMessage("pcs_off");
00808   Ausleger::pre_control_signal = PRE_CONTROL_SIG_OFF;
00809   // reset hydraulic states
00810   for (uint8_t i = 0 ; i < 3 ; i++)
00811   {
00812     memset(hydraulic_states[i], 0x00, 8);
00813   }
00814 }
00815 
00816 }


multicar_hydraulic
Author(s): M.Fischer
autogenerated on Thu Jun 6 2019 20:39:31