RobotExMachina / Machina.NET

A library for real-time robot control.
MIT License
86 stars 33 forks source link

How to use "Custom Code" #13

Closed robin-gdwl closed 5 years ago

robin-gdwl commented 5 years ago

Hello again, I have been trying to iimplement a custom code into my Program, but machina Bridge always says cannot stream action Add Custom instruction Is the custom code implemented ? I am using a Universal Robot (UR5) No command that I have tried seems to work, so I'm guessing its not the custom code itself that is the problem, but instead machina has problems executing the command. This is where the error is executed in the UR Communications protocol. It seems as though the cutom action command is Commented out.

Thank you very much for any help.

robin-gdwl commented 5 years ago

This is commented out in the [UR drivers ] (https://github.com/RobotExMachina/Machina.NET/blob/76b8d7b22642b8dae38498a4f8409b3fdfedc374/src/Machina/Drivers/Communication/Protocols/URCommunicationProtocol.cs#L316)

Screenshot 2019-05-21 at 11 02 53

but its not commented out in the Abb drivers

Screenshot 2019-05-21 at 11 04 30
garciadelcastillo commented 5 years ago

Hi @boundlessmaking!

Sorry for the confusion around CustomCode, it is an action that I used primarily for debugging, and its use is not very consistent.

The main use of CustomCode() is to insert custom lines on code on programs which cannot be directly generated through the use of regular actions. For example, Machina doesn't incorporate circular motion (yet), so calling

bot.CustomCode("movec(p[0.3,0.3,0.3,0,0,0], p[0.4,0.4,0.3,0,0,0], a=1.2, v=0.25, r=0.05, mode=1)");

would insert the following line of code in your program:

movec(p[0.3,0.3,0.3,0,0,0], p[0.4,0.4,0.3,0,0,0], a=1.2, v=0.25, r=0.05, mode=1)

This can also be used to call custom functions in external modules, remote procedures, etc.

CustomCode() was primarily designed for offline mode. Machina relies on custom drivers to receive instructions in online mode, and if the driver doesn't have instruction codes for that particular instruction, it cannot execute it. Additionally, most low-level robot programming languages (URScript, RAPID) do not support reflection, so sending the full custom code as a string does not work either. Hence the reasons why this action only works well in offline mode.

Now, over time, I found myself needing to debug a lot of low-level communication stuff in online mode, so started using this action to send custom instruction codes via TCP. On ABB robots, this works by sending a string with a custom buffer code, the way represented here. This means that if an user requests

bot.AxesTo(0, 0, 0, 0, 90, 0);

the driver receives a TCP string message with the CONST num INST_MOVEABSJ := 3; ! MoveAbsJ J1 J2 J3 J4 J5 J6 format, or in for the concrete action above

"@23 3 0 0 0 0 90 0;"

where 23 is the id number of that action. If you turn "Debug" mode on the Bridge, you can see all the back and forth of this kind of low-level communication protocol.

Due to certain limitations with the capacity for URScript to parse strings, for UR robots it works a little different, and communication is handled via a buffer of int32 values. Additionally (and this requires its own dedicated explanation as well), in order to be able to pass float values, these must be pre-inflated by a coefficient, rounded to integers, sent via the communication protocol, and deflated back into floats by dividing by the same coefficient. So, for the above action, and following the protocol, the values are converted to radians and inflated by a FACTOR_RAD of 10000.0, resulting in the following buffer:

[23,3,0,0,0,0,15707,0]

Confusing? I know! It is just a workaround to maximize compatibility with older UR operating systems.

So, I have been using this CustomCode() action to debug online communication by sending my own protocol-formatted instructions, as simple strings for ABB and as int32 buffers for UR. I forget why I deactivated this option at some point for URs, I assume that there was something not quite working there, or that it was giving me unstable results, I forget.

So... TL;DR! What is the summary:

You are probably wondering then, how can you send your own code to the robot in real time then? It would require forking the project and extending it to satisfy your needs. This could be done by:

However, at this point, you have gone through so much effort that you are probably ready to just add your own custom actions to the framework! If they are general enough (nothing too specific to a particular project) and good implemented, I will be happy to merge them to the main project :)

WARNING: ALL OF THIS CAN BE DANGEROUS FOR YOU AND THE ROBOT. Sending your own low-level instructions in real-time is confusing and easily leads to error. Make sure you use all the caution in the world, and know what you are doing at every time. :pray:

robin-gdwl commented 5 years ago

Thank you for the comprehensive answer! This helps a lot. I will see how I can achieve what I need with this knowledge.