StateServer.c
Go to the documentation of this file.
00001 // StateServer.c
00002 //
00003 /*
00004 * Software License Agreement (BSD License) 
00005 *
00006 * Copyright (c) 2013, Yaskawa America, Inc.
00007 * All rights reserved.
00008 *
00009 * Redistribution and use in binary form, with or without modification,
00010 * is permitted provided that the following conditions are met:
00011 *
00012 *       * Redistributions in binary form must reproduce the above copyright
00013 *       notice, this list of conditions and the following disclaimer in the
00014 *       documentation and/or other materials provided with the distribution.
00015 *       * Neither the name of the Yaskawa America, Inc., nor the names 
00016 *       of its contributors may be used to endorse or promote products derived
00017 *       from this software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 * POSSIBILITY OF SUCH DAMAGE.
00030 */ 
00031 
00032 #include "MotoROS.h"
00033 
00034 //-----------------------
00035 // Function Declarations
00036 //-----------------------
00037 void Ros_StateServer_StartNewConnection(Controller* controller, int sd);
00038 void Ros_StateServer_SendState(Controller* controller);
00039 BOOL Ros_StateServer_SendMsgToAllClient(Controller* controller, SimpleMsg* sendMsg, int msgSize);
00040 
00041 //-----------------------
00042 // Function implementation
00043 //-----------------------
00044 
00045 //-----------------------------------------------------------------------
00046 // Start the task for a new state server connection:
00047 // - Ros_StateServer_SendState: Task that broadcasts controller & robot state to the connected client
00048 //-----------------------------------------------------------------------
00049 void Ros_StateServer_StartNewConnection(Controller* controller, int sd)
00050 {
00051         int connectionIndex;
00052 
00053         printf("Starting new connection to the State Server\r\n");
00054         
00055         //look for next available connection slot
00056         for (connectionIndex = 0; connectionIndex < MAX_STATE_CONNECTIONS; connectionIndex++)
00057         {
00058                 if (controller->sdStateConnections[connectionIndex] == INVALID_SOCKET)
00059                 {
00060                         //Start the new connection in a different task.
00061                         //Each task's memory will be unique IFF the data is on the stack.
00062                         //Any global or heap stuff will not be unique.
00063                         controller->sdStateConnections[connectionIndex] = sd;
00064                         
00065                         // If not started
00066                         if(controller->tidStateSendState == INVALID_TASK)
00067                         {
00068                                 //start task that will send the controller state
00069                                 controller->tidStateSendState = mpCreateTask(MP_PRI_TIME_NORMAL, MP_STACK_SIZE, 
00070                                                                                         (FUNCPTR)Ros_StateServer_SendState,
00071                                                                                         (int)controller, 0, 0, 0, 0, 0, 0, 0, 0, 0);
00072                                 
00073                                 //set feedback signal
00074                                 if(controller->tidStateSendState != INVALID_TASK)
00075                                         Ros_Controller_SetIOState(IO_FEEDBACK_STATESERVERCONNECTED, TRUE);
00076                         }
00077                         
00078                         break;
00079                 }
00080         }
00081         
00082         if (connectionIndex == MAX_STATE_CONNECTIONS)
00083         {
00084                 printf("Too many State server connections... not accepting last attempt.\r\n");
00085                 mpClose(sd);
00086         }
00087 }
00088 
00089 
00090 //-----------------------------------------------------------------------
00091 // Send state (robot position and controller status) as long as there is
00092 // an active connection
00093 //-----------------------------------------------------------------------
00094 void Ros_StateServer_SendState(Controller* controller)
00095 {
00096         int groupNo;
00097         SimpleMsg sendMsg;
00098         SimpleMsg sendMsgFEx;
00099         int msgSize, fexMsgSize = 0;
00100         BOOL bOkToSendExFeedback;
00101         BOOL bHasConnections;
00102         BOOL bSuccesfulSend;
00103         
00104         printf("Starting State Server Send State task\r\n");
00105         printf("Controller number of group = %d\r\n", controller->numGroup);
00106         
00107         bHasConnections = FALSE;
00108 
00109         //Thread for state server should never terminate
00110         while(TRUE)
00111         {
00112                 Ros_SimpleMsg_JointFeedbackEx_Init(controller->numGroup, &sendMsgFEx);
00113                 bOkToSendExFeedback = TRUE;
00114 
00115                 // Send feedback position for each control group
00116                 for(groupNo=0; groupNo < controller->numGroup; groupNo++)
00117                 {
00118                         msgSize = Ros_SimpleMsg_JointFeedback(controller->ctrlGroups[groupNo], &sendMsg);
00119                         fexMsgSize = Ros_SimpleMsg_JointFeedbackEx_Build(groupNo, &sendMsg, &sendMsgFEx);
00120                         if(msgSize > 0)
00121                         {
00122                                 bSuccesfulSend = Ros_StateServer_SendMsgToAllClient(controller, &sendMsg, msgSize);
00123                                 if (bSuccesfulSend != bHasConnections)
00124                                 {
00125                                         bHasConnections = bSuccesfulSend;
00126                                         Ros_Controller_SetIOState(IO_FEEDBACK_STATESERVERCONNECTED, bHasConnections);
00127                                 }
00128                         }
00129                         else
00130                         {
00131                                 printf("Ros_SimpleMsg_JointFeedback returned a message size of 0\r\n");
00132                                 bOkToSendExFeedback = FALSE;
00133                         }
00134                 }
00135 
00136                 if (controller->numGroup < 2) //only send the ROS_MSG_MOTO_JOINT_FEEDBACK_EX message if we have multiple control groups
00137                         bOkToSendExFeedback = FALSE;
00138 
00139                 if (bOkToSendExFeedback) //send extended-feedback message
00140                         Ros_StateServer_SendMsgToAllClient(controller, &sendMsgFEx, fexMsgSize);
00141 
00142                 // Send controller/robot status
00143                 msgSize = Ros_Controller_StatusToMsg(controller, &sendMsg);
00144                 if(msgSize > 0)
00145                 {
00146                         Ros_StateServer_SendMsgToAllClient(controller, &sendMsg, msgSize);
00147                 }
00148                 Ros_Sleep(STATE_UPDATE_MIN_PERIOD);
00149         }
00150         
00151         // Terminate this task
00152         controller->tidStateSendState = INVALID_TASK;
00153         Ros_Controller_SetIOState(IO_FEEDBACK_STATESERVERCONNECTED, FALSE);
00154         printf("State Server Send State task was terminated\r\n");
00155         mpDeleteSelf;
00156 }
00157 
00158 
00159 //-----------------------------------------------------------------------
00160 // Send state message to all active connections
00161 // return TRUE if message was send to at least one client
00162 //-----------------------------------------------------------------------
00163 BOOL Ros_StateServer_SendMsgToAllClient(Controller* controller, SimpleMsg* sendMsg, int msgSize)
00164 {
00165         int index;
00166         int ret;
00167         BOOL bSuccessfulSend = FALSE;
00168         
00169         // Check all active connections
00170         for(index = 0; index < MAX_STATE_CONNECTIONS; index++)
00171         {
00172                 if(controller->sdStateConnections[index] != INVALID_SOCKET)
00173                 {
00174                         ret = mpSend(controller->sdStateConnections[index], (char*)(sendMsg), msgSize, 0);
00175                         if(ret <= 0)
00176                         {
00177                                 printf("StateServer Send failure.  Closing state server connection.\r\n");
00178                                 mpClose(controller->sdStateConnections[index]);
00179                                 controller->sdStateConnections[index] = INVALID_SOCKET;
00180                         }
00181                         else
00182                         {
00183                                 bSuccessfulSend = TRUE;
00184                         }
00185                 }
00186         }
00187         return bSuccessfulSend;
00188 }


motoman_driver
Author(s): Jeremy Zoss (Southwest Research Institute)
autogenerated on Sat Jun 8 2019 19:06:58