From 292b5cc8a10a640a8b364a529e3eadffffc9b56b Mon Sep 17 00:00:00 2001 From: Jeremy Zoss Date: Tue, 18 Jun 2013 14:23:04 -0500 Subject: [PATCH] bugFix #1: FS100 reply to JointTrajPtFull message contains invalid sequence/robot_id fields bugFix: always publish state for all active robot groups, even if no motion pending --- fs100/MotoPlus/MotionServer.c | 20 ++++++++++++++++---- fs100/MotoPlus/SimpleMessage.c | 12 ++++++++---- fs100/MotoPlus/output/MPRosFS100.out | Bin 120773 -> 120961 bytes 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/fs100/MotoPlus/MotionServer.c b/fs100/MotoPlus/MotionServer.c index d29ea484..b3530139 100644 --- a/fs100/MotoPlus/MotionServer.c +++ b/fs100/MotoPlus/MotionServer.c @@ -1,5 +1,10 @@ // MotionServer.c // +// History: +// 05/22/2013: Original release v.1.0.0 +// 06/05/2013: Fix for multi-arm control to prevent return -3 (Invalid group) +// when calling function mpExRcsIncrementMove. +// 06/12/2013: Release v.1.0.1 /* * Software License Agreement (BSD License) * @@ -1072,6 +1077,7 @@ BOOL Ros_MotionServer_HasDataInQueue(Controller* controller) //------------------------------------------------------------------- // Task to move the robot at each interpolation increment +// 06/05/13: Modified to always send information for all defined groups even if the inc_q is empty //------------------------------------------------------------------- void Ros_MotionServer_IncMoveLoopStart(Controller* controller) //<-- IP_CLK priority task { @@ -1089,6 +1095,7 @@ void Ros_MotionServer_IncMoveLoopStart(Controller* controller) //<-- IP_CLK prio for(i=0; inumGroup; i++) { + moveData.ctrl_grp |= (0x01 << i); moveData.grp_pos_info[i].pos_tag.data[0] = Ros_CtrlGroup_GetAxisConfig(controller->ctrlGroups[i]); } @@ -1099,7 +1106,6 @@ void Ros_MotionServer_IncMoveLoopStart(Controller* controller) //<-- IP_CLK prio if (controller->bRobotJobReady && Ros_MotionServer_HasDataInQueue(controller) && !controller->bStopMotion) { //bNoData = FALSE; // for testing - moveData.ctrl_grp = 0; for(i=0; inumGroup; i++) { @@ -1112,8 +1118,6 @@ void Ros_MotionServer_IncMoveLoopStart(Controller* controller) //<-- IP_CLK prio { time = q->data[q->idx].time; q_time = controller->ctrlGroups[i]->q_time; - moveData.ctrl_grp |= (0x01 << i); - moveData.grp_pos_info[i].pos_tag.data[0] = Ros_CtrlGroup_GetAxisConfig(controller->ctrlGroups[i]); moveData.grp_pos_info[i].pos_tag.data[2] = q->data[q->idx].tool; moveData.grp_pos_info[i].pos_tag.data[3] = q->data[q->idx].frame; moveData.grp_pos_info[i].pos_tag.data[4] = q->data[q->idx].user; @@ -1162,6 +1166,9 @@ void Ros_MotionServer_IncMoveLoopStart(Controller* controller) //<-- IP_CLK prio } else { + moveData.grp_pos_info[i].pos_tag.data[2] = 0; + moveData.grp_pos_info[i].pos_tag.data[3] = MP_INC_PULSE_DTYPE; + moveData.grp_pos_info[i].pos_tag.data[4] = 0; memset(&moveData.grp_pos_info[i].pos, 0x00, sizeof(LONG) * MP_GRP_AXES_NUM); } @@ -1179,7 +1186,12 @@ void Ros_MotionServer_IncMoveLoopStart(Controller* controller) //<-- IP_CLK prio ret = mpExRcsIncrementMove(&moveData); if(ret != 0) - printf("mpExRcsIncrementMove returned: %d\r\n", ret); + { + if(ret == -3) + printf("mpExRcsIncrementMove returned: %d (ctrl_grp = %d)\r\n", ret, moveData.ctrl_grp); + else + printf("mpExRcsIncrementMove returned: %d\r\n", ret); + } } //else // for testing //{ diff --git a/fs100/MotoPlus/SimpleMessage.c b/fs100/MotoPlus/SimpleMessage.c index c1226402..ba4213f8 100644 --- a/fs100/MotoPlus/SimpleMessage.c +++ b/fs100/MotoPlus/SimpleMessage.c @@ -1,5 +1,8 @@ // SimpleMessage.c // +// History: +// 06/12/2013: Fix reply to ROS_MSG_JOINT_TRAJ_PT_FULL message +// 06/12/2013: Release v.1.0.1 /* * Software License Agreement (BSD License) * @@ -89,6 +92,7 @@ int Ros_SimpleMsg_JointFeedback(CtrlGroup* ctrlGroup, SimpleMsg* sendMsg) // Creates a simple message of type MOTO_MOTION_REPLY to reply to a received message // result code and subcode indication result of the processing of the received message +// 06/12/2013: Modified to fix reply to ROS_MSG_JOINT_TRAJ_PT_FULL message int Ros_SimpleMsg_MotionReply(SimpleMsg* receiveMsg, int result, int subcode, SimpleMsg* replyMsg) { //initialize memory @@ -109,11 +113,11 @@ int Ros_SimpleMsg_MotionReply(SimpleMsg* receiveMsg, int result, int subcode, Si replyMsg->body.motionReply.sequence = receiveMsg->body.motionCtrl.sequence; replyMsg->body.motionReply.command = receiveMsg->body.motionCtrl.command; } - else if(receiveMsg->header.msgType == ROS_MSG_MOTO_MOTION_CTRL) + else if(receiveMsg->header.msgType == ROS_MSG_JOINT_TRAJ_PT_FULL) { - replyMsg->body.motionReply.groupNo = receiveMsg->body.motionCtrl.groupNo; - replyMsg->body.motionReply.sequence = receiveMsg->body.motionCtrl.sequence; - replyMsg->body.motionReply.command = ROS_MSG_MOTO_MOTION_CTRL; + replyMsg->body.motionReply.groupNo = receiveMsg->body.jointTrajData.groupNo; + replyMsg->body.motionReply.sequence = receiveMsg->body.jointTrajData.sequence; + replyMsg->body.motionReply.command = ROS_MSG_JOINT_TRAJ_PT_FULL; } else { diff --git a/fs100/MotoPlus/output/MPRosFS100.out b/fs100/MotoPlus/output/MPRosFS100.out index 59e0a37934467995b6a3a39ef0f6ef8a8afd34e2..61a0f8a09651ca18f246ebddf93659f3c795af9a 100644 GIT binary patch delta 11265 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 delta 10812 zcmY+K4^&jwoyYH;8FfH3s6@wsj3Xj2fJ(x|pfN2;NP`LDsE8wuI>2DT@MnT(h!tj% z*n}jU7WzDSY(ug%ab25b6B0dvwnT{`hFI$%t((%VZEb6NXqU~Qt=mI)X|vzoyT9j< zIcK<^-|znZ-QT_M&CJuM-k$g2Tk|?oEoI$rr~UllIlgDk3y0RbB}vOIdRU&+T8bWC z;LaC9bgmGNA~EMG<{a9!qKrkQPkmXWMB{{QT~vsISLP&W!ObaJ?&dX`Eb?pru{rfj zWOJcSW@^Eb4DHJ$p*imS6~e9c-|0xX|JA?s-{%%0zt%bt{b!L>eDThwi-eGme*U*^ zZR*}TG|$%cGT}^c>l4dmkrp`cfJF|U={@i@sp$t-I)XyX>y8u7_BfFoMr9%K`R76L z`6p*a5BAMH)AIOz_P7P{qVOoD#F@{Ye9tP~T3_paIdUeU?T2e16ny9YGt2w@i@vl) zl8q3S5dC%Fy}?;5#G=1gx@wjm3JDU#vzD$pC&of&iIM^&6+5?TZ@qW-ea|2Sx!VFz zu2CVL<`5(mJ0Te{l52(YxZ+@Pb1kBOU0ZoBSw5@Xcka&0_Yj9-%KTu*vYjR~_?V+m1hKA}Ys7JJg=kp@-QIdQ{m1J*$<=5}PpAAkK$90id zY=}l-B(8PJcp;MRuyh4UJY|S98zOP_t=SrvkzXc2i&>wmx+RR%)u9KTY_2{eoN|HC zhR-|XLhWbgHTEEn_aBEbD_ZL<*KRT#2!?A zkE+^|rzL!_KH|ePodTL#d=t}^JdHi1Zu&_qc3RBKl*F}8%hoTP0#gjRnwu&P^4hlH z;!m-3mD19ZotEv0mqmxtXp&_IrL}Zv?|*Q+^lLx;V58^TTnSZidoe2cCgp;MGV0lAp8S%ZT(Vbx5)ri_Wuloo#hhR8>9LSbgA5C~=By6V|T5Hdn=brM(N<4DCA?m*Qh- z@S@A`tZ-vpX>C1jmewq7>Y`(Lw%VrYHdjOS6TZWBhpLV3v*u_kKUyN!Xm@|K zDewmRMb|j>%Wa3l{oJ$fs-79Ave0RTXf!)5gbS^-@u7xoNCRccBHSynlu&gG6#u5I zid~OGcvJh)N8a^6XrrrOsBN1C_93z$1wpy$G_^zdQBTXvKxd-zz~y<;u@l}ZF|RDdVNL9 z{VnvtWqapL-=)qZIbwXvX#3Ug5=v=-0(WzIS&q@)B~{H$bq_Z+9u5nq7fEmg{7Vku z_#5|1(&)G>lhkgY3F0}rb0&pvoxppvfytb*y&RZ=#*e^k&61|-s_NP!)kd6visOg! z(BV4t2nz8W0xvmqxU#A-gmccCAWXt_Pb#l78~*#LY*{q$1BZOwB7+0_ljY=mnXDIQ z$n;2Hv6y2KVpTL*jqOX-IJ8WSBP@^cIHmMyiAqj$^H_AdVV_pRW0c2X9%t0JI-kd8 z(~ z&+@T8z+(sNhj?5xnP>#cwyR}kyI;CbrVecM$jXJXNPp!X*(ja*f_&MqAxV{O_bXR> zj~e6rs)V?4CC7(Us`%3^j~Ed@&6nE}WQv~okW9CDCI@^E$$zyVLqP#fLgPa+d0=gk zd^vtCt`_SzJJA*MMVF6fN=SU9Vh~w4@{i{lBd#j_sjbpAaQhB<)FMZe@a9f@S&<34 zf0s<1TOJi+`KTVCMUjWG_AtID(W?koajnV4 zLToh|x05~0n|(3+NAP9R!}=}LLR2u9;I4nj7J;8Lwot&KQFfMsPIU9V!a8|w}vwZ)^_J~*V8QX(>h!Me?UOvQ*pa_FYk^k$Q z%(o9cHH|94rcp?U8q=mnh-Q;t6C%U3KLs}JZ^mM7Lnl(%ep{jtPndj#3yl;Bu?^pm zs4aHlU-AUnzwI}yC!P?Zk)5|A=uze!_(*9nxdyjN=29%c=$v1O(gPfaxQX>a@DX&v zNDN_TbF7U!Utl8y-1!Z5ChivEF;1`(A0tMBF!b-T4e?N{(49A8=VRwgjLVRZ&q_p; zp$a2Vix6c;IS}#jShBKjvrQEGSJ{U6WGvY(Br^}-uK#6w6us*oY!CL^V=?`yWP|;; zqiTOT8xiNkg8Dmle%Igt z_n7S^J~=DspE+?S^nc|*-~fs;+a7q0ZIB>vDwZtJA8UKy65Akt;0p2^6_Ic?mMlOC zs6{w%0oqHd8oYNg>(Tzb)JD>S_gPrq3#PV{o;U#?`&cEt_GPgR7PW6J+nmJu_j!e= zHjPSStJzn{4kNHRzz)P%-BQz@T1thEL4TBOh>zj%l4*ku-Qr#$>P-D5*wbCfj+O7b z!p_8a-zw;4tf2jNd?vB;{!Ag#O!f-#h{=8-9yR&65YL!AE=0S@ld(9FAcC5Kf=RJJ z!D!4Ocp~Ny?4M;nG|T=s+zAvM{5>y*cmkIxC$2EJX&Q^d!m&*eVJ9IGmz`Pz|p^awI6@9THDzM61`WrEQB`1!v2~nvM3xgA||7NQzv1jH<4xzorxS&u7 zzhRiGaga=#`t_>NIM~*2RD~K`5c_bdKZP#`NJy{xH^3;sU@Y4B+@b5QAq^kBoSG8ziHXA4iO?;N#VJHQW&5N#@1`A#zRj;rhSF6k29Y zw8uWF8WG4WuJIjCHiAp_T~0oV<5=5>!xA)NRQ2VDGKzvFBv!!mVSto<37L zU-YGRxoklc4{T7A^3c=T<+|ngC13nkrK&6i{zIDyC?LH=jGb6-4oFLTItF=!M{^Q#G&re-7$UXUd4NIps!Fi@hidCX6dgh4utf? z7f=P|ULNKi^ z;@m$04=YncKVpW^TV6!eejyHcl7sh-CZ2CjBU%c@8b!mW5rDT{K!hnVxhUt_KVKf~M%evuhTR%pz< z;Fp<)!LKu8l`HV6x`1|2F9FWe;s#5_plQ1ELON-NE2HVz%Vp;6L_4t4h$zl zPst{jDcKY={8qg+i@&GXXM_HIW-M&g#|B4)uLi;=JP`%|jQIrk*UY`(KPbk}SF!3( z%qVmfpYm-<_`E>zR2<#o(mQ7HOU#+j{rAkn;Ln(Ef^k2hyxZxMG5sGbplbT5WlW@j7cv)smof*y zE@rebBc1sqcrEh{@Os5ND9)Fd3&CGu_JK>V|CDS81uf%=X7E1dDEI&~R+-Vj+zmd$ zJPvMSo(4awxRe(24d#6COUy;!SD8=X`p-DU!XPHzWTq9o%RB)-rx;g~$QWg&1UPK8 zfSt6;ab{ZOb>SWlIC4k+` z&}G7ze9OGxTxK6QpBY7D7BIJiiEofle#IkBT$I=njxrwyk1-=)<~Va7 z_&W1tFcMNhevFw@igyd}G~fSsd+|dP3NqS_1Rgu{X>cO*FxbJ2pdL5#1UOT1IbwKn znRCEc5XCIV=qX^v!aPOHKJ358#{#YbkDs{)9As_=LpB0+g2T+G!7a>auP4fU9o)`5 z4TcZ-?y-TpnG?aiV7mX)mk*+<3;Aq4SI@4kUq5 z2*nIg{0ZiK@DwvTanLi(LP$LdG#rkB?X2$vCo-P}JD3qX%gsCq&Q!b?tIWz}hF=yE zQp~++dhVcH7O8>C$Eq;c&)fnIGDpF%Gu-;YurqiN3_F8Iz_2rT4BXB<1MXD3&jIdc zP6PJ}p*otfibAkHj3`(=V7@W!a5IC1P49;i9u4Kc=wmA8#v0G0B&b?gOQNzgS3EdW-qvxxd8kIa{!DV zQHFgpF7fQ|vv3>}7ntFgeTlgb{9|US`ahXR!M|a?3jQNAEr5SB1aE@*mq-wc$+0M# ziX?D6F)r~6Y(dUqosUQFe6TG5;J1t zrYJs;i~Y|{V}T}e6o2(J*sHh(1?3_z1+D1=7b>nLeX-($h>=^$O!@#b*@u|1eYtgt zA0vG;m~QcPIS^1SC8!$&A7`EccPOrR2$AQT#e9hBQDj~v>rq(VL1x(I@gCPBQQlG3 zcY>d0K8fo;?*%0^*fH@f<`nR^nKQw!F{98tR8EC9P_nbklx&C@=OAx{8J)lc{t7cH^_DQ71mnA&VUI$+{6)AC#d!~~eiYomd>wp5aae%) zi*VQuewOw6p7SyxLgl{18kl3L1utmttZ9nWr}%=y()!ou*4MeOXP%Q=~C99U9XUFJcX@Ia zrt!3-;G$e=!6TBDyJX5h^F{eJDWm$-M{?g>dJtnT8Ymr=@sccpAItMHq`NQ4#+8UA z^B3a}{v(SYKf}>j>17$$UU{e9e@VLN3EvovSmPAjWUn6lq5LiW^|J7?Ji3@VVwqN6 z^D=~}cj#l6ala_geLs@xFhqYO_pd}-#gsC#x6_j(I2~j8B>mQX>5ANnntfN`>Kz!n IBHxbtf3nH+z5oCK