00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022 #include <stdio.h>
00023 #include <strings.h>
00024 #include <unistd.h>
00025
00026 #include <fcntl.h>
00027 #include <sys/time.h>
00028 #include <time.h>
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif // HAVE_CONFIG_H
00033
00034
00035 #include <shvel-param.h>
00036
00037
00038 #include <serial.h>
00039 #include <param.h>
00040 #include <control.h>
00041 #include <command.h>
00042 #include <ipcommunication.h>
00043 #include <yprintf.h>
00044
00045
00046 #include <ypspur.h>
00047 #include <cartesian2d.h>
00048
00049 #include <pthread.h>
00050
00051 SpurUserParams g_spur;
00052
00053 SpurUserParamsPtr get_spur_user_param_ptr()
00054 {
00055 return &g_spur;
00056 }
00057
00058 void command_loop_cleanup(void *data)
00059 {
00060 struct ipcmd_t *ipcmd;
00061
00062 ipcmd = data;
00063 yprintf(OUTPUT_LV_INFO, "Command analyzer stopped.\n");
00064
00065 ipcmd_close(ipcmd);
00066 }
00067
00068 void init_spur_command(void)
00069 {
00070 g_spur.x = 0;
00071 g_spur.y = 0;
00072 g_spur.theta = 0;
00073 g_spur.v = 0;
00074 g_spur.w = 0;
00075 g_spur.radius = 0;
00076 g_spur.tilt = 0;
00077 g_spur.dir = 0;
00078 g_spur.run_mode = RUN_STOP;
00079 g_spur.before_run_mode = -10000;
00080 g_spur.freeze = 0;
00081 g_spur.before_freeze = 0;
00082 g_spur.run_mode_cnt = 0;
00083 pthread_mutex_init(&g_spur.mutex, NULL);
00084 }
00085
00086
00087 void command(void)
00088 {
00089 YPSpur_msg msg, res_msg;
00090 int len;
00091 struct ipcmd_t ipcmd;
00092 char param_name[YP_PARAM_NUM][30] = YP_PARAM_NAME;
00093 ParametersPtr param;
00094
00095 param = get_param_ptr();
00096
00097
00098 if (option(OPTION_SOCKET))
00099 {
00100 len = ipcmd_open_tcp(&ipcmd, NULL, get_param_ptr()->port);
00101 }
00102 else
00103 {
00104 len = ipcmd_open_msq(&ipcmd, get_param_ptr()->msq_key, 1);
00105 }
00106 if (len < 0)
00107 {
00108
00109 yprintf(OUTPUT_LV_ERROR, "Error: Can't initialize message queue.\n");
00110 return;
00111 }
00112
00113
00114 ipcmd.flush(&ipcmd);
00115
00116 yprintf(OUTPUT_LV_INFO, "Command analyzer started.\n");
00117 pthread_cleanup_push(command_loop_cleanup, &ipcmd);
00118
00119 while (1)
00120 {
00121
00122 len = ipcmd.recv(&ipcmd, &msg);
00123 if (len < YPSPUR_MSG_SIZE)
00124 {
00125 yprintf(OUTPUT_LV_ERROR, "Error: Invalid command received\n");
00126 continue;
00127 }
00128
00129 pthread_mutex_lock(&g_spur.mutex);
00130
00131 switch (msg.type)
00132 {
00133
00134 case YPSPUR_SET_POS:
00135 set_pos_com(msg.cs, msg.data, &g_spur);
00136 yprintf(OUTPUT_LV_DEBUG, "Command: set pos %f %f %f\n", msg.data[0], msg.data[1], msg.data[2]);
00137 break;
00138 case YPSPUR_SET_GL_GL:
00139 set_GL_on_GL_com(msg.data, &g_spur);
00140 yprintf(OUTPUT_LV_DEBUG, "Command: GL on GL %f %f %f\n", msg.data[0], msg.data[1], msg.data[2]);
00141 break;
00142 case YPSPUR_ADJUST:
00143 set_adjust_com(msg.cs, msg.data, &g_spur);
00144 yprintf(OUTPUT_LV_DEBUG, "Command: adjust %f %f %f\n", msg.data[0], msg.data[1], msg.data[2]);
00145 break;
00146 case YPSPUR_SET_VEL:
00147 set_vel_com(msg.data, &g_spur);
00148 yprintf(OUTPUT_LV_DEBUG, "Command: vel %f\n", g_spur.v);
00149 break;
00150 case YPSPUR_SET_ANGVEL:
00151 set_ang_vel_com(msg.data, &g_spur);
00152 yprintf(OUTPUT_LV_DEBUG, "Command: w %f\n", g_spur.w);
00153 break;
00154 case YPSPUR_SET_ACCEL:
00155 set_accel_com(msg.data, &g_spur);
00156 yprintf(OUTPUT_LV_DEBUG, "Command: dvel %f\n", g_spur.dv);
00157 break;
00158 case YPSPUR_SET_ANGACCEL:
00159 set_ang_accel_com(msg.data, &g_spur);
00160 yprintf(OUTPUT_LV_DEBUG, "Command: dw %f\n", g_spur.dw);
00161 break;
00162 case YPSPUR_SET_TILT:
00163 set_tilt_com(msg.cs, msg.data, &g_spur);
00164 yprintf(OUTPUT_LV_DEBUG, "Command: tilt %f %f\n", g_spur.dir, g_spur.tilt);
00165 break;
00166
00167
00168 case YPSPUR_LINE:
00169 line_com(msg.cs, msg.data, &g_spur);
00170 yprintf(OUTPUT_LV_DEBUG, "Command: line %f %f %f\n", g_spur.x, g_spur.y, g_spur.theta);
00171 break;
00172 case YPSPUR_STOP_LINE:
00173 stop_line_com(msg.cs, msg.data, &g_spur);
00174 yprintf(OUTPUT_LV_DEBUG, "Command: stop_line %f %f %f\n", g_spur.x, g_spur.y, g_spur.theta);
00175 break;
00176 case YPSPUR_CIRCLE:
00177 circle_com(msg.cs, msg.data, &g_spur);
00178 yprintf(OUTPUT_LV_DEBUG, "Command: circle %f %f %f\n", g_spur.x, g_spur.y, g_spur.radius);
00179 break;
00180 case YPSPUR_SPIN:
00181 spin_com(msg.cs, msg.data, &g_spur);
00182 yprintf(OUTPUT_LV_DEBUG, "Command: spin %f\n", g_spur.theta);
00183 break;
00184 case YPSPUR_ORIENT:
00185 orient_com(msg.cs, msg.data, &g_spur);
00186 yprintf(OUTPUT_LV_DEBUG, "Command: orient %f\n", g_spur.theta);
00187 break;
00188 case YPSPUR_STOP:
00189 stop_com(msg.data, &g_spur);
00190 yprintf(OUTPUT_LV_DEBUG, "Command: stop\n");
00191 break;
00192 case YPSPUR_OPENFREE:
00193 openfree_com(msg.data, &g_spur);
00194 yprintf(OUTPUT_LV_DEBUG, "Command: openfree\n");
00195 break;
00196 case YPSPUR_FREE:
00197 free_com(msg.data, &g_spur);
00198 yprintf(OUTPUT_LV_DEBUG, "Command: free\n");
00199 break;
00200 case YPSPUR_FREEZE:
00201 g_spur.freeze = 1;
00202 yprintf(OUTPUT_LV_DEBUG, "Command: freeze\n");
00203 break;
00204 case YPSPUR_UNFREEZE:
00205 g_spur.freeze = 0;
00206 yprintf(OUTPUT_LV_DEBUG, "Command: unfreeze\n");
00207 break;
00208 case YPSPUR_ISFREEZE:
00209 res_msg.data[0] = g_spur.freeze;
00210 message_return(&ipcmd, msg.pid, &res_msg);
00211 yprintf(OUTPUT_LV_DEBUG, "Command: isfreeze %d\n", g_spur.freeze);
00212 break;
00213 case YPSPUR_VEL:
00214 vel_com(msg.data, &g_spur);
00215 yprintf(OUTPUT_LV_DEBUG, "Command: vel %f %f\n", g_spur.vref, g_spur.wref);
00216 break;
00217 case YPSPUR_WHEEL_VEL:
00218 wheel_vel_com(msg.data, &g_spur);
00219 yprintf(OUTPUT_LV_DEBUG, "Command: wheel_vel %f %f\n", g_spur.wvelref[0], g_spur.wvelref[1]);
00220 break;
00221 case YPSPUR_WHEEL_TORQUE:
00222 set_torque_com(msg.data, &g_spur);
00223 yprintf(OUTPUT_LV_DEBUG, "Command: set_torque %f %f\n", msg.data[0], msg.data[1]);
00224 break;
00225 case YPSPUR_SET_WHEEL_VEL:
00226 set_wheel_vel_com(msg.data, &g_spur);
00227 yprintf(OUTPUT_LV_DEBUG, "Command: set_wheel_vel %f %f\n", g_spur.wheel_vel[0], g_spur.wheel_vel[1]);
00228 break;
00229 case YPSPUR_SET_WHEEL_ACCEL:
00230 set_wheel_accel_com(msg.data, &g_spur);
00231 yprintf(OUTPUT_LV_DEBUG, "Command: set_wheel_accel %f %f\n", g_spur.wheel_accel[0], g_spur.wheel_accel[1]);
00232 break;
00233 case YPSPUR_WHEEL_ANGLE:
00234 wheel_angle_com(msg.data, &g_spur);
00235 yprintf(OUTPUT_LV_DEBUG, "Command: wheel_angle %f %f\n", g_spur.wheel_angle[0], g_spur.wheel_angle[1]);
00236 break;
00237
00238
00239 case YPSPUR_GET_POS:
00240 get_pos_com(msg.cs, msg.data, res_msg.data, &g_spur);
00241 message_return(&ipcmd, msg.pid, &res_msg);
00242 yprintf(OUTPUT_LV_DEBUG, "Command: get %f %f %f\n", res_msg.data[0], res_msg.data[1], res_msg.data[2]);
00243 break;
00244 case YPSPUR_GET_VEL:
00245 get_vel_com(msg.cs, msg.data, res_msg.data, &g_spur);
00246 message_return(&ipcmd, msg.pid, &res_msg);
00247 yprintf(OUTPUT_LV_DEBUG, "Command: getvel %f %f\n", res_msg.data[0], res_msg.data[1]);
00248 break;
00249 case YPSPUR_GET_VREF:
00250 get_vref_com(msg.cs, msg.data, res_msg.data, &g_spur);
00251 message_return(&ipcmd, msg.pid, &res_msg);
00252 yprintf(OUTPUT_LV_DEBUG, "Command: getvref %f %f\n", res_msg.data[0], res_msg.data[1]);
00253 break;
00254 case YPSPUR_GET_WHEEL_VREF:
00255 get_wheel_vref_com(msg.cs, msg.data, res_msg.data, &g_spur);
00256 message_return(&ipcmd, msg.pid, &res_msg);
00257 yprintf(OUTPUT_LV_DEBUG, "Command: getwheelvref %f %f\n", res_msg.data[0], res_msg.data[1]);
00258 break;
00259 case YPSPUR_GET_FORCE:
00260 get_force_com(msg.cs, msg.data, res_msg.data, &g_spur);
00261 message_return(&ipcmd, msg.pid, &res_msg);
00262 yprintf(OUTPUT_LV_DEBUG, "Command: getforce %f %f\n", res_msg.data[0], res_msg.data[1]);
00263 break;
00264 case YPSPUR_GET_WHEEL_TORQUE:
00265 get_wheel_torque_com(msg.cs, msg.data, res_msg.data, &g_spur);
00266 message_return(&ipcmd, msg.pid, &res_msg);
00267 yprintf(OUTPUT_LV_DEBUG, "Command: getwheeltorque %f %f\n", res_msg.data[0], res_msg.data[1]);
00268 break;
00269 case YPSPUR_GET_WHEEL_VEL:
00270 get_wheel_vel_com(msg.data, res_msg.data, &g_spur);
00271 message_return(&ipcmd, msg.pid, &res_msg);
00272 yprintf(OUTPUT_LV_DEBUG, "Command: get wheelvel %f %f\n", res_msg.data[0], res_msg.data[1]);
00273 break;
00274 case YPSPUR_GET_WHEEL_ANG:
00275 get_wheel_ang_com(msg.data, res_msg.data, &g_spur);
00276 message_return(&ipcmd, msg.pid, &res_msg);
00277 yprintf(OUTPUT_LV_DEBUG, "Command: get wheelang %f %f\n", res_msg.data[0], res_msg.data[1]);
00278 break;
00279 case YPSPUR_NEAR_POS:
00280 res_msg.cs = near_pos_com(msg.cs, msg.data, res_msg.data, &g_spur);
00281 message_return(&ipcmd, msg.pid, &res_msg);
00282 yprintf(OUTPUT_LV_DEBUG, "Command: near pos ( dist = %f )\n", res_msg.data[0]);
00283 break;
00284 case YPSPUR_NEAR_ANG:
00285 res_msg.cs = near_ang_com(msg.cs, msg.data, res_msg.data, &g_spur);
00286 message_return(&ipcmd, msg.pid, &res_msg);
00287 yprintf(OUTPUT_LV_DEBUG, "Command: near ang ( dist = %f )\n", res_msg.data[0]);
00288 break;
00289 case YPSPUR_OVER_LINE:
00290 res_msg.cs = over_line_com(msg.cs, msg.data, res_msg.data, &g_spur);
00291 message_return(&ipcmd, msg.pid, &res_msg);
00292 yprintf(OUTPUT_LV_DEBUG, "Command: over line ( dist = %f )\n", res_msg.data[0]);
00293 break;
00294
00295
00296 case YPSPUR_PARAM_SET:
00297 param_set_com(msg.cs, msg.data, &g_spur);
00298 yprintf(OUTPUT_LV_DEBUG, "Command: param_set %s %f\n", param_name[msg.cs], msg.data[0]);
00299 break;
00300
00301 case YPSPUR_PARAM_GET:
00302 res_msg.cs = param_get_com(msg.cs, res_msg.data, &g_spur);
00303 message_return(&ipcmd, msg.pid, &res_msg);
00304 yprintf(OUTPUT_LV_DEBUG, "Command: param_get %s %f\n", param_name[msg.cs], msg.data[0]);
00305 break;
00306
00307 case YPSPUR_PARAM_STATE:
00308 param_state_com(msg.cs, msg.data, &g_spur);
00309 break;
00310
00311
00312 case YPSPUR_GETAD:
00313 get_ad_com(msg.data, res_msg.data);
00314 message_return(&ipcmd, msg.pid, &res_msg);
00315 yprintf(OUTPUT_LV_DEBUG, "Command: get A/D%d value %d\n", (int)msg.data[0], (int)res_msg.data[0]);
00316 break;
00317
00318 case YPSPUR_SETIODIR:
00319 set_io_dir_com(msg.data, res_msg.data);
00320 yprintf(OUTPUT_LV_DEBUG, "Command: set IO dir %d\n", (int)msg.data[0]);
00321 break;
00322
00323 case YPSPUR_SETIODATA:
00324 set_io_data_com(msg.data, res_msg.data);
00325 yprintf(OUTPUT_LV_DEBUG, "Command: set IO data %d\n", (int)msg.data[0]);
00326 break;
00327
00328 case YPSPUR_GET_ERROR_STATE:
00329 get_error_state_com(msg.data, res_msg.data);
00330 message_return(&ipcmd, msg.pid, &res_msg);
00331 yprintf(OUTPUT_LV_DEBUG, "Command: get error state %d (id: %d)\n", (int)msg.data[0], (int)res_msg.data[0]);
00332 break;
00333
00334
00335 case YPSPUR_JOINT_TORQUE:
00336 joint_torque_com(msg.cs, msg.data, &g_spur);
00337 yprintf(OUTPUT_LV_DEBUG, "Command: joint %d torque %f\n", msg.cs, msg.data[0]);
00338 break;
00339
00340 case YPSPUR_JOINT_VEL:
00341 joint_vel_com(msg.cs, msg.data, &g_spur);
00342 yprintf(OUTPUT_LV_DEBUG, "Command: joint %d vel %f\n", msg.cs, msg.data[0]);
00343 break;
00344
00345 case YPSPUR_JOINT_ANG:
00346 joint_ang_com(msg.cs, msg.data, &g_spur);
00347 yprintf(OUTPUT_LV_DEBUG, "Command: joint %d ang %f\n", msg.cs, msg.data[0]);
00348 break;
00349
00350 case YPSPUR_JOINT_ANG_VEL:
00351 joint_ang_vel_com(msg.cs, msg.data, &g_spur);
00352 yprintf(OUTPUT_LV_DEBUG, "Command: joint %d ang %f vel %f\n", msg.cs, msg.data[0], msg.data[1]);
00353 break;
00354
00355 case YPSPUR_SET_JOINT_ACCEL:
00356 set_joint_accel_com(msg.cs, msg.data, &g_spur);
00357 yprintf(OUTPUT_LV_DEBUG, "Command: set joint %d accel %f\n", msg.cs, msg.data[0]);
00358 break;
00359
00360 case YPSPUR_SET_JOINT_VEL:
00361 set_joint_vel_com(msg.cs, msg.data, &g_spur);
00362 yprintf(OUTPUT_LV_DEBUG, "Command: set joint %d vel %f\n", msg.cs, msg.data[0]);
00363 break;
00364
00365 case YPSPUR_GET_JOINT_VEL:
00366 get_joint_vel_com(msg.cs, res_msg.data, &g_spur);
00367 message_return(&ipcmd, msg.pid, &res_msg);
00368 yprintf(OUTPUT_LV_DEBUG, "Command: get joint %d vel %f\n", msg.cs, res_msg.data[0]);
00369 break;
00370
00371 case YPSPUR_GET_JOINT_VREF:
00372 get_joint_vref_com(msg.cs, res_msg.data, &g_spur);
00373 message_return(&ipcmd, msg.pid, &res_msg);
00374 yprintf(OUTPUT_LV_DEBUG, "Command: get joint %d vref %f\n", msg.cs, res_msg.data[0]);
00375 break;
00376
00377 case YPSPUR_GET_JOINT_ANG:
00378 get_joint_ang_com(msg.cs, res_msg.data, &g_spur);
00379 message_return(&ipcmd, msg.pid, &res_msg);
00380 yprintf(OUTPUT_LV_DEBUG, "Command: get joint %d ang %f\n", msg.cs, res_msg.data[0]);
00381 break;
00382
00383 case YPSPUR_GET_JOINT_TORQUE:
00384 get_joint_torque_com(msg.cs, res_msg.data, &g_spur);
00385 message_return(&ipcmd, msg.pid, &res_msg);
00386 yprintf(OUTPUT_LV_DEBUG, "Command: get joint %d torque %f\n", msg.cs, res_msg.data[0]);
00387 break;
00388
00389 default:
00390 yprintf(OUTPUT_LV_WARNING, "Command: unknown\n");
00391 break;
00392 }
00393
00394
00395 if (g_spur.run_mode != g_spur.before_run_mode || g_spur.before_freeze != g_spur.freeze)
00396 {
00397 if (!g_spur.freeze)
00398 {
00399 if (g_spur.run_mode == RUN_FREE || g_spur.run_mode == RUN_WHEEL_TORQUE)
00400 {
00401 int i;
00402 for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
00403 {
00404 if (!param->motor_enable[i])
00405 continue;
00406 if (p(YP_PARAM_VEHICLE_CONTROL, i) > 0)
00407 g_spur.wheel_mode[i] = MOTOR_CONTROL_FREE;
00408 }
00409 yprintf(OUTPUT_LV_DEBUG, "Mode: free\n");
00410 }
00411 else if (g_spur.run_mode == RUN_OPENFREE)
00412 {
00413 int i;
00414 for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
00415 {
00416 if (!param->motor_enable[i])
00417 continue;
00418 if (p(YP_PARAM_VEHICLE_CONTROL, i) > 0)
00419 g_spur.wheel_mode[i] = MOTOR_CONTROL_OPENFREE;
00420 }
00421 yprintf(OUTPUT_LV_DEBUG, "Mode: openfree\n");
00422 }
00423 else
00424 {
00425 int i;
00426 for (i = 0; i < YP_PARAM_MAX_MOTOR_NUM; i++)
00427 {
00428 if (!param->motor_enable[i])
00429 continue;
00430 if (p(YP_PARAM_VEHICLE_CONTROL, i) > 0)
00431 g_spur.wheel_mode[i] = MOTOR_CONTROL_VEHICLE;
00432 }
00433 yprintf(OUTPUT_LV_DEBUG, "Mode: servo %d\n", g_spur.run_mode);
00434 }
00435 }
00436 else
00437 {
00438 yprintf(OUTPUT_LV_DEBUG, "Mode: freeze\n");
00439 }
00440 }
00441 g_spur.before_run_mode = g_spur.run_mode;
00442 g_spur.before_freeze = g_spur.freeze;
00443
00444 pthread_mutex_unlock(&g_spur.mutex);
00445
00446 pthread_testcancel();
00447 }
00448
00449 pthread_cleanup_pop(1);
00450 }
00451
00452
00453 void message_return(struct ipcmd_t *ipcmd, long retpid, YPSpur_msg *res_msg)
00454 {
00455 res_msg->type = 0;
00456 res_msg->msg_type = retpid;
00457 res_msg->pid = 0;
00458 ipcmd->send(ipcmd, res_msg);
00459 }
00460
00461
00462 void init_command_thread(pthread_t *thread)
00463 {
00464 if (pthread_create(thread, NULL, (void *)command, NULL) != 0)
00465 {
00466 yprintf(OUTPUT_LV_ERROR, "Can't create command thread\n");
00467 }
00468 }