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
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
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
00068
00069
00070
00071 void Hydraulic::publishCanMessage(tinycan::CanMsg *msg)
00072 {
00073 if (cpub != NULL)
00074 cpub->publish(*msg);
00075 }
00076
00077
00078
00079
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);
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:
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:
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:
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
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
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
00162
00163
00164
00165 void Hydraulic::callbackRobotTrajectory(const sensor_msgs::JointState::ConstPtr& msg)
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
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;
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
00191 else if (msg->name[i].compare(std::string("rot_dreharm_hauptarm")) == 0)
00192 {
00193
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
00213 else if (msg->name[i].compare(std::string("rot_hauptarm_nebenarm")) == 0)
00214 {
00215
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
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
00239 else if (msg->name[i].compare(std::string("rot_nebenarm_schnellwechselsystem")) == 0)
00240 {
00241
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
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
00268 else if (msg->name[i].compare(std::string("rot_schnellwechselsystem_maehkopf")) == 0)
00269 {
00270
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)
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
00296
00297
00298
00299 void Hydraulic::callbackCanMessageRaw(const tinycan::CanMsg::ConstPtr& msg)
00300 {
00301 uint16_t cid = 0;
00302 uint8_t node_id = 0;
00303
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
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;
00350
00351 ausleger[IDX_Schwenkfix].position = 0.039 * pivoting - 97.101;
00352
00353
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
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
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
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)
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)
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
00468
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)
00479 {
00480
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
00488 cmsg.id = 0x314;
00489 cmsg.len = 2;
00490
00491
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
00501 cmsg.id = 0x314;
00502 cmsg.len = 2;
00503
00504
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
00520 cmsg.id = 0x314;
00521 cmsg.len = 2;
00522
00523
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)
00539 {
00540
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
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
00560 cmsg.id = 0x214;
00561 cmsg.len = 3;
00562 hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] | 0x02;
00563 memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00564 publishCanMessage(&cmsg);
00565 memset(&cmsg.data,0x00,3);
00566
00567
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
00578 cmsg.id = 0x214;
00579 cmsg.len = 3;
00580 hydraulic_states[HYDRAULIC_HA_SWK][2] = hydraulic_states[HYDRAULIC_HA_SWK][2] | 0x01;
00581 memcpy(&cmsg.data,hydraulic_states[HYDRAULIC_HA_SWK], 3);
00582 publishCanMessage(&cmsg);
00583 memset(&cmsg.data,0x00,3);
00584
00585
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
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
00604 publishCanMessage(&cmsg);
00605 memset(&cmsg.data,0x00,8);
00606
00607
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
00619 cmsg.id = 0x314;
00620 cmsg.len = 2;
00621 hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] | 0x08;
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
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
00640 cmsg.id = 0x314;
00641 cmsg.len = 2;
00642 hydraulic_states[HYDRAULIC_NA_VS][0] = hydraulic_states[HYDRAULIC_NA_VS][0] | 0x04;
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
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
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
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
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
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
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
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
00728
00729
00730
00731 int Hydraulic::checkTask()
00732 {
00733 if (is_man_ctr)
00734 return 0;
00735
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
00743 for (uint8_t i = 0 ; i < 5 ; i++)
00744 {
00745 if (ausleger[i].is_moveing == false && ausleger[i].state != MOVE_HALT)
00746 {
00747
00748 if (Ausleger::pre_control_signal == PRE_CONTROL_SIG_OFF_ACK)
00749 {
00750
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
00759 setPWM(ausleger[i].node_id, 1250);
00760
00761 ausleger[i].is_moveing = true;
00762 }
00763 }
00764 }
00765
00766
00767 for (uint8_t i = 0 ; i < 5 ; i++)
00768 {
00769 if (ausleger[i].is_moveing == true && ausleger[i].state >= MOVE_MOVING)
00770 {
00771
00772
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);
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);
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
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
00807 cmdToCanMessage("pcs_off");
00808 Ausleger::pre_control_signal = PRE_CONTROL_SIG_OFF;
00809
00810 for (uint8_t i = 0 ; i < 3 ; i++)
00811 {
00812 memset(hydraulic_states[i], 0x00, 8);
00813 }
00814 }
00815
00816 }