Extending the Remote API

The remote API can easily be extended by the user, with the creation of custom remote API functions. Following section will briefly explain how to proceed in order to do so.

First, let's have a look at how commands (or command replies) are sent or received from/to the client/server. Without entering too much into details, consider following figure:

[Remote API message content]


From above figure, focus on following 3 elements:

  • The command ID: the command ID, which is a simple integer value, identifies a type of command. As an example, following command ID is linked to the remote API function simxSetJointPosition: simx_cmd_set_joint_position. A command ID is most of the time not enough to fully describe (or identify) a command (see next item).
  • The command data: the command data is often required, but not always. It might be needed to fully describe a command. As an example, the remote API function simxSetJointPosition requires the handle of the joint as command data.
  • The pure data: the pure data is data that accompanies a command or a command reply. As an example, the remote API function simxSetJointPosition would have the joint position value specified in the pure data section. Internally, the pure data might be split into smaller chunks when sent, if a split operation mode was chosen (e.g. simx_opmode_oneshot_split or simx_opmode_streaming_split)
  • Two commands are considered same if they have the same command ID and the same command data. It is important to be able to compare commands, since a remote API function will often send a request, and fetch the reply from a previously made request in the inbox buffer to reduce the communication lag (i.e. non-blocking operation, for instance with the simx_opmode_streaming or the simx_opmode_buffer operation mode). A command waiting to be sent in the outbox buffer will also be overwritten by a same command (e.g. if you call simxSetJointPosition(jointHandle1,42.0f,simx_opmode_oneshot), directly followed by simxSetJointPosition(jointHandle1,0.0f,simx_opmode_oneshot), then the second function call will overwrite what the first function call generated in the outbox buffer. If however the second function call had been simxSetJointPosition(jointHandle2,0.0f,simx_opmode_oneshot), then we would have two distinct commands in the outbox buffer (since the command data differs)).

    To add an additional command to the remote API, proceed as follows:

  • Select a command ID, and add it to the file "programming/include/extApiCustomConst.h". Make sure to add it at the right position, according to what other values are needed to fully identify the command (see above explanation)
  • Add a function declaration in the file "programming/remoteApi/extApiCustom.h". Follow the examples provided in that file.
  • Add the function body in the file "programming/remoteApi/extApiCustom.c". Follow the examples provided in that file (or get inspired by the actual implementation in the file "programming/remoteApi/extApi.c"). Basically there should be 4 sections inside the function:
    1. The section where the operation mode simx_opmode_remove is taken care of. Call the function _removeCommandReply_xxx, where xxx represents the command data (i.e. "null", "int", "intint" or "string")
    2. The section where the command is put into the outbox buffer and a command reply fetched from the inbox buffer. Call the function _exec_xxx_yyy, where xxx represents the command data (i.e. "null", "int", "intint" or "string"), and yyy represents the pure data to send
    3. The section where pure data is extracted from the command reply. The pointer returned by the above _exec_xxx_yyy function points at the beginning of the command reply. Use the function _readPureDataXXX, where XXX can be "Char", "Int" or "Float" according to the pure data you wish to read. If the pure data is a mixture of various types, you will have to extract it yourself. The pointer to the pure data is given by: cmdReplyPointer+SIMX_SUBHEADER_SIZE+_getCmdDataSize(cmdReplyPointer). The buffer where the cmdReplyPointer points is a copy of the actual command reply, and remains valid until next remote API function is called.
    4. The section where the error code is returned.
  • Include the files "programming/remoteApi/extApiCustom.h" and "programming/remoteApi/extApiCustom.c" to your client project files.
  • Add following code line in every file where you call the new remote API functions: #include "extApiCustom.h"
  • Add the command handling part in the file "programming/v_repExtRemoteApi/simxCustomCmd.cpp". Follow the examples provided in that file (or get inspired by the actual implementation in the file "programming/v_repExtRemoteApi/simxCmd.cpp"). Basically there should be 3 sections inside each code block related to a specific command:
    1. The section where the command data and pure data is retrieved. Command data is stored in _cmdData and/or _cmdString. Pure data is stored in _pureData. Endianness of the client is detected on the server side, and should be handled by the server (using the function littleEndianXXXXConversion).
    2. The section where the command is handled. This usually involves one or several calls to regular API functions, and/or execution of various algorithms. The success state of the command execution should be returned in section 3
    3. The section where the command success state and the return values (i.e. pure data) are prepared. Use the code retCmd->setDataReply_xxxx. If the pure data you send back is a complex type (e.g. a buffer), then you will be in charge to convert that buffer to the correct endianness (using the function littleEndianXXXXConversion).
  • Make sure to recompile the client application and the remote API plugin


  • Recommended topics

  • Remote API modus operandi