Giter VIP home page Giter VIP logo

robodk / robodk-api Goto Github PK

View Code? Open in Web Editor NEW
223.0 29.0 115.0 64.51 MB

Implementation of the RoboDK API in different programming languages. The RoboDK API allows simulating and programming any industrial robot (offline and online)

Home Page: https://robodk.com/doc/en/RoboDK-API.html

License: Other

Python 33.87% C# 27.11% QMake 0.04% C++ 14.44% MATLAB 7.22% Batchfile 0.18% HTML 1.07% Visual Basic .NET 12.33% GLSL 0.14% C 3.54% CMake 0.06%
robotics robot-programming robot-simulator offline-programming robodk industrial-robots universal-robots post-processor robodk-api

robodk-api's People

Contributors

alexsilza898 avatar bychvip avatar dummygithubaccount avatar halmusaibeli avatar huberchristian avatar jasonl-robodk avatar katharinakoslowski avatar m79lol avatar markusleder avatar markusthomi avatar noelpenne avatar phillip-may avatar robodk avatar sambertrdk avatar sancelot avatar scotty1701 avatar vdm-dev avatar vin-eet-singh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

robodk-api's Issues

NameError: name 'Robolink' is not defined

When trying to execute the following script:

from robolink import *    # RoboDK's API
from robodk import *      # Math toolbox for robots

RDK = Robolink()

I'm getting NameError: name 'Robolink' is not defined. This happens on Ubuntu 20.04 when trying to execute script in terminal, however everything is fine when executing the script with RoboDK 5.0 gui. I installed robodk with pip3 install robodk but also tried setting PYTHONPATH: export PYTHONPATH=/home/$USER/RoboDK/Python/ and then executing script with both python and python3.

PoseFrame() raises Exception

When I try to use the PoseFrame() method on a target, I receive the following error:

Exception: Invalid item provided: The item identifier provided is not valid or it does not exist.

This is the code I used:

    target = link.Item('my_target', robolink.ITEM_TYPE_TARGET)
    assert target.Valid()
    pose_relative_to_robot_base = target.PoseFrame()

I tried this using rdk v4.2.3.15578 and v5.0.0-17259 in conjunction with pypi package robodk version 4.2.3 and 5.0.0.
But it doesn't look like an error in the pypi package, as the command G_Frame is not understood.

Any Ideas?

As a workaround I moved the robot into the origin of the world coordinate system so I can use PoseAbs().

Error in C++ API

Hi,
I started to use your API a few days ago for a C++ program and I have several issue:

  1. The function AddStation doesn't work
  • The argument name is not even used in robodk_api.cpp
  • The function doesn't create anything, it just print in console: RoboDK API ERROR: ""

Once I get this error, all function of the API will give the same error until I disconnect / reconnect

  1. I often get the error Communication problems with the RoboDK API and after RoboDK API ERROR: "" without any more information or error. Even if first I got The RoboDK API is connected, I don't know why and restart the software reset the problem, I cannot debug it without more informations.

  2. SolveIK just crash (core dump) without any information, I started to modify robodk_api.cpp to debug but it could take a while.

  3. In all your example, you add the robot, the tool etc.. and only use the pointer afterward. But if you read from an existing .RDK file, you will not get any pointer but the real item. I don't really understand why it use this pattern, if the pointer is not required to manipulate an object, why not use a reference, which is simpler and safer. And if the pointer is required, the API will simply not work when opening an existing scene and editing the object since we do not get a pointer but an Item (ex: AddFile)

  4. Why is there "Finish" and "Disconnect", according to your API, it's exactly the same. Is one depreciated ?


The last part is not really a problem but more a personal note about the API, it does not seems to follow the usual standard, it looks more like a port from C than a code written for C++, since it doesn't seems to be done I give you my feedback:

  • I understand that there is some Qt overhead for the Matrix etc. But it bother me that I have to convert each "std::string" to the QString format. It's not necessary since you don't even use the QString, you parse it toUtf8 before sending it, so I don't really see the point.
  • The use of raw pointer is more common in C, the new standard is to use the Smart pointer, which avoid any memory handling / pointer movement.
  • In your API, you sometime ask for pointer, sometime for the object. It would be better to just call the reference for most functions, it did not feel really consistent when using the API.
  • There is no apparent Linting standard, it's sometimes Pascal case, sometimes Camel case, sometimes even Snake case. This caused a lot of correct / recompile during the use of the API, which was annoying.

Some of my remark could be wrong or even a choice you made on purpose. I just wanted to notified what could be improve in my point of view


Lastly, is there a way to try mulptiple "MoveL_Test" in separate thread simultaneously ?

[Python] Optional argument "size" in robodk.eye not used

Function definition: def eye(size=4) would allow for multiple sizes of Identity Matrix to be created, however the argument is not used. Specifying size=3 instantiates a matrix of size 4 which is confusing for the user.
Behavior should be:
if size == 4:
return Mat(4x4)
else:
should either return a matrix of the proper size or raise NotImplementedError("Size other than 4 not supported")

Select NC file/object in robot machining/3D Print project with RoboDK API?

I not sure how to select NC file or object/pass NC file or object at all to the RoboDK API for robot machining/3D print project.
I checked API and examples.
Am I missing something? If this isn't part of the API, are there plans to implement it?
Could do it as a PR but would need to know how the object (or the G-code generated by Slic3r) is passed to RoboDK from your proprietary code.
image

[BUG] AddShape specifiying the addTo parameter does not work

Using AddShape in either python or c++ language does not permit to specify the addTo parameter.

when setted in, the function replies with following message:
WARNING: Invalid shape, a 3xN (or 6xN) list of points must be provided (N must be multiple of 3)
Invalid item provided: The item identifier provided is not valid or it does not exist.

The following code reproduces the problem :

from robodk import *
from robolink import *



# Octahedron vertices 
A = [ 0.17770898,  0.72315927,  0.66742804]
B = [-0.65327074, -0.4196453 ,  0.63018661]
C = [ 0.65382635,  0.42081934, -0.62882604]
D = [-0.17907021, -0.72084723, -0.66956189]
E = [-0.73452809,  0.5495376 , -0.39809158]
F = [ 0.73451554, -0.55094017,  0.39617148]

# Octadron faces by groups of vertices
SHAPE = [E, B, A,
        E, D, B,
        E, C, D,
        E, A, C,
        F, A, B,
        F, B, D,
        F, D, C,
        F, C, A,
]

##### Add the shape as an object in RoboDK

RDK = Robolink() # Initialize the RoboDK API
part = RDK.Item("Part")
if part.Valid():
    new_object = RDK.AddShape(SHAPE,part)

[Python] Use Qt instead of tkinter if available

Hello,

Right now, using this library forces tkinter to be included (which increases the size of program's executable!) for the file management functions.

Would there be a way to use Qt instead if PySide2 is already being imported into the project?

Regards,
David

Mistaken function call

The example code uses calls to Item::RunCodeCustom, which is not part of the class Item.
What function is meant ? Item::RunCode ? Item::RunInstruction ?

RoboDK License in docker container

According the documentation, when running RoboDK in a Docker container I can use a network license by setting the environment variable RDK_LIC.

I imagine this will activate the license.

How can I deactivate it afterwards?

Deactivation would be needed from my understanding as once the container is removed if the license is not deactivated, no one else can anymore use it (for example a new container from same image or another container running on another machine).

And how can I deactivate the license if (could happen during development) my container crash without I deactivated the license?

Update to .Net Core 3.0

I've updated the project for C# to .Net Core 3.0.

Are you interested in me opening a pull request? The changes are honestly very minimal to the code.

I'd need to update the Sample Project as well, but I first wanted to see if you would accept the PR or not.

Copied Rotational Matrices in Degree and not Rad

The highlighted section contains an error. According to the Documentation robodk.robomath.roty(ry) must recive ry in radians and not degrees. This can be confusing when copying this snippet into a Python Project.

image

I don't know if this is the correct place to post these errors. Please redirect me if I´m wrong here.
Thank you.

MoveJ can not simulate

When I use MoveL, robot can move to the target point slowly.
But when I use MoveJ, robot will move to the target point in an instant.

A few bugs in C API

Hi,
the new C API cannot compile with a clang compiler:
In robodk_api_c.h, line 292, 295, 296, 324, the char& variables in the function declarations should be char*
Same file, lines 324, the const Mat_t& tool_pose should be const struct Mat_t* tool_pose
Same file, line 349, the Joint_t& joints should be Joint_t* joint

These reflect in the function definitions in robodk_api_c.cpp
Moreover, in the .cpp file I find errors at
line 556, should be const struct Mat_t *tool_pose, const char *tool_name) {
line 560, should be *tool_pose
line 561, should be tool_name
line 674, correct typecasting should be (int)zonedata
line 689, no * operator, should be nofilename
line 721, should be *parameters
line 728, no * operator, should be parameters
line 1010, it is joints->_Values, joints->_nDOFs);

Keep up with the good job!

Using RoboDK Docker image

The How to use this image documentation of the RoboDK docker image says that connection to RoboDK within the image should be done as

RDK = robolink.Robolink(port=20501)

That doesnt seem correct to me. I had to use

RDK = robolink.Robolink(robodk_ip='127.0.0.1',
                        port=20501,
                        robodk_path='/home/user/RoboDK/bin/RoboDK')

Is this a bug in the documentation or on my side?

Filters in RoboDK lib

Hi,

this is again a website issue and not about the the API, just like #97.
Since I can't find your website source on GitHub and haven't received a reply via email, I don't know where else to make you aware of it but here.

The library filters are static. This leads to you having to add a new static filter term every time you add an object to the lib with a new attribute that does not exist yet. For example, you have tools from various Brands in your lib (ATI, Aim Robotics, ...), but these brands cannot be searched via the filters on the left as the filter terms are hardcoded. Your website doesn't even allow a manual query: https://robodk.com/library#filter?brand=ATI&type=tool is forwarded to https://robodk.com/library#filter?type=tool.

Now you could go ahead and keep hardcoding the terms manually, but I think it would be wise to make them dynamic: Show all brands, types, axes etc. of objects you add to the lib as search terms in the filter. This could be a PR if your website code was on GH.

setSpeed method enhancement

RoboDK software will crash without showing any error if setSpeed() method is called in for or while loop with an unexpected value, a negative speed value for example. Would be better to check the value and confirm it before sending it to the platform and throw an error if an incorrect value is given?

Thank you

Mat.ToQuaternion() function have some problem.

when input Mat is a particular value ,for example
Mat1:
{X= 0.000 mm , Y= 0.000 mm , Z= 0.000 mm , Rx=-180.000 deg , Ry=-45.000 deg , Rz= 0.000 deg}
Vector3d x2 = new Vector3d(0.7071, 0, -0.7071);
Vector3d y2 = new Vector3d(0, -1, 0);
Vector3d z2 = new Vector3d(-0.7071, 0, -0.7071);

Mat2:
{X= 0.000 mm , Y= 0.000 mm , Z= 0.000 mm , Rx=-180.000 deg , Ry=45.000 deg , Rz= 0.000 deg}
Vector3d x2 = new Vector3d(0.7071, 0, 0.7071);
Vector3d y2 = new Vector3d(0, -1, 0);
Vector3d z2 = new Vector3d(0.7071, 0, -0.7071);

the function gives the same result (0,0.92387952923661276,0,0.38268344027085205)
but Mat1 correct result should be (0,0.92387952923661276,0,-0.38268344027085205)
so I write a program to caculate it ,and I get the correct result. am I right?

    public static double[] ToQuaternion(Mat Ti)
    {
        var q1 = new double[4];
        var a1 = Ti[0, 0];
        var b1 = Ti[1, 1];
        var c1 = Ti[2, 2];
        q1[0] = 0.5 * Math.Sqrt(Math.Max(a1 + b1 + c1 + 1, 0));
        q1[1] = 0.5 * Math.Sqrt(Math.Max(a1 - b1 - c1 + 1, 0));
        q1[2] = 0.5 * Math.Sqrt(Math.Max(-a1 + b1 - c1 + 1, 0));
        q1[3] = 0.5 * Math.Sqrt(Math.Max(-a1 - b1 + c1 + 1, 0));
        double qMax = 0d;
        for (int i = 0; i < 4; i++)
        {
            if (q1[i] > qMax) qMax = q1[i];
        }
        if (q1[0] == qMax)//w
        {
            q1[1] = 0.25 * (Ti[2, 1] - Ti[1, 2]) / qMax;
            q1[2] = 0.25 * (Ti[0, 2] - Ti[2, 0]) / qMax;
            q1[3] = 0.25 * (Ti[1, 0] - Ti[0, 1]) / qMax;
        }
        if (q1[1] == qMax)//x
        {
            q1[0] = 0.25 * (Ti[2, 1] - Ti[1, 2]) / qMax;
            q1[2] = 0.25 * (Ti[0, 1] + Ti[1, 0]) / qMax;
            q1[3] = 0.25 * (Ti[2, 0] + Ti[0, 2]) / qMax;
        }
        if (q1[2] == qMax)//y
        {
            q1[0] = 0.25 * (Ti[0, 2] - Ti[2, 0]) / qMax;
            q1[1] = 0.25 * (Ti[0, 1] + Ti[1, 0]) / qMax;
            q1[3] = 0.25 * (Ti[2, 1] + Ti[1, 2]) / qMax;
        }
        if (q1[3] == qMax)//z
        {
            q1[0] = 0.25 * (Ti[1, 0] - Ti[0, 1]) / qMax;
            q1[1] = 0.25 * (Ti[0, 2] + Ti[2, 0]) / qMax;
            q1[2] = 0.25 * (Ti[2, 1] + Ti[1, 2]) / qMax;
        }
        return q1;

}

robot not responsive to keyboard

Hi,
I recently got the license for RoboDK and I wanted to control a KUKA arm using keyboard. I am using the provided sample.

# This macro allows moving a robot using the keyboard
# Note: This works on console mode only, you must run the PY file separately
#
# More information about the RoboDK API here:
# https://robodk.com/doc/en/RoboDK-API.html
# Type help("robolink") or help("robodk") for more information

from robolink import *    # API to communicate with RoboDK
from robodk import *      # basic matrix operations
RDK = Robolink()

# Arrow keys program example

# get a robot
robot = RDK.Item('', ITEM_TYPE_ROBOT)
if not robot.Valid():
    print("No robot in the station. Load a robot first, then run this program.")
    pause(5)
    raise Exception("No robot in the station!")

print('Using robot: %s' % robot.Name())
print('Use the arrows (left, right, up, down), Q and A keys to move the robot')
print('Note: This works on console mode only, you must run the PY file separately')

# define the move increment
move_speed = 10

import msvcrt
while True:  
    key = ord(msvcrt.getch())
    move_direction = [0,0,0]
    print(key)
    if key == 75:
        print('arrow left (Y-)')
        move_direction = [0,-1,0]
    elif key == 77:
        print('arrow right (Y+)')
        move_direction = [0,1,0]
    elif key == 72:
        print('arrow up (X-)')
        move_direction = [-1,0,0]
    elif key == 80:
        print('arrow down (X+)')
        move_direction = [1,0,0]
    elif key == chr(113):
        print('Q (Z+)')
        move_direction = [0,0,10]
    elif key == 97:
        print('A (Z-)')
        move_direction = [0,0,-1]

    # make sure that a movement direction is specified
    if norm(move_direction) <= 0:
        continue

    # calculate the movement in mm according to the movement speed
    xyz_move = mult3(move_direction, move_speed)

    # get the robot joints
    robot_joints = robot.Joints()

    # get the robot position from the joints (calculate forward kinematics)
    robot_position = robot.SolveFK(robot_joints)

    # get the robot configuration (robot joint state)
    robot_config = robot.JointsConfig(robot_joints)

    # calculate the new robot position
    new_robot_position = transl(xyz_move)*robot_position

    # calculate the new robot joints
    new_robot_joints = robot.SolveIK(new_robot_position)
    if len(new_robot_joints.tolist()) < 6:
        print("No robot solution!! The new position is too far, out of reach or close to a singularity")
        continue

    # calculate the robot configuration for the new joints
    new_robot_config = robot.JointsConfig(new_robot_joints)

    if robot_config[0] != new_robot_config[0] or robot_config[1] != new_robot_config[1] or robot_config[2] != new_robot_config[2]:
        print("Warning!! Robot configuration changed!! This will lead to unextected movements!")
        print(robot_config)
        print(new_robot_config)

    # move the robot joints to the new position
    robot.MoveJ(new_robot_joints)
    #robot.MoveL(new_robot_joints)

But the robot is not responsive to the keyboard press. When I print the key it is always on 255.If I give a specific value to 'key' and then run the program, the robot moves. But it always goes back to its starting position. Any help or suggestions will be greatly appreciated.

Possible to overwrite motion planning module as a plugin?

Hi, I am Yikai.

May I ask if I can overwrite motion planning module(moveJ moveL...) with my own implementations?

Motivation is i want to precisely simulate the circle time using my motion planners.

I am looking forward to your reply. Thanks

[BUG][c++] AddShape unreferenced pointer access.

Only when color parameter is NULL , a read access to undefined memory is done.

This code prevents this issue :

Item RoboDK::AddShape(tMatrix2D *trianglePoints, Item *addTo, bool shapeOverride, Color *color)
{
    double colorArray[4];
    if (color)
    {
     colorArray[0] = color->r;
     colorArray[1] = color->g;
     colorArray[2] = color->b;
     colorArray[3] = color->a;
    }
    _check_connection();
    _send_Line("AddShape3");
    _send_Matrix2D(trianglePoints);
    _send_Item(addTo);
    _send_Int(shapeOverride? 1 : 0);
    if (color)
        _send_Array(colorArray,4);
    Item newitem = _recv_Item();
    _check_status();
    return newitem;
}

Incorrect CMake build instructions in ReadMe

In C++ > readme.md > Alternative CMake Instructions, the last of the command line commands fails with the error at the end of this issue.

I believe the fix is below.
IS:
cmake --build
SHOULD BE:
cmake --build .


The error:

Usage: cmake --build <dir>             [options] [-- [native-options]]
       cmake --build --preset <preset> [options] [-- [native-options]]
Options:
  <dir>          = Project binary directory to be built.
  --preset <preset>, --preset=<preset>
                 = Specify a build preset.
  --list-presets[=<type>]
                 = List available build presets.
  --parallel [<jobs>], -j [<jobs>]
                 = Build in parallel using the given number of jobs.
                   If <jobs> is omitted the native build tool's
                   default number is used.
                   The CMAKE_BUILD_PARALLEL_LEVEL environment variable
                   specifies a default parallel level when this option
                   is not given.
  -t <tgt>..., --target <tgt>...
                 = Build <tgt> instead of default targets.
  --config <cfg> = For multi-configuration tools, choose <cfg>.
  --clean-first  = Build target 'clean' first, then build.
                   (To clean only, use --target 'clean'.)
  --resolve-package-references={on|only|off}
                 = Restore/resolve package references during build.
  -v, --verbose  = Enable verbose output - if supported - including
                   the build commands to be executed.
  --             = Pass remaining options to the native tool.

Problem in controlling the robotic arm from the software

Helllo everybody,

I am currently using RoboDK software, as well as the libraries for python, in order to control a Staubli TX2-90, linked to a SP2 controller.

I am able to make the python script control the simulated robotic arm (on the software). However, when I try to move the actual robotic arm, it does not work. I also tried from the software. I am able to connect to the robotic arm (I am able to retrieve the robotic arm current position), but I am unable to make it move from the software as I wish (in real time)

I found this forum detailing the same issue that I have, but with a different controller. Does anybody knows how to access the /usr/configs on the machine?

Gratefully,

Leo

SpayOn macro

Hi guys, now I am trying to use C# API.
I know you already have python script for this.
However, when I play, I couldn't see any spray behavior.

Could I use it as in the guide?

Error while loading shared libraries: libQt5WebSockets.so.5: cannot open shared object file: No such file or directory

hello,i have an error when i run

RDK = Robolink()

in python3.6,ubuntu18.04,the error is

error while loading shared libraries: libQt5WebSockets.so.5: cannot open shared object file: No such file or directory,

but i can find libQt5WebSockets.so.5 in my system and roboDK dirctory:

./usr/local/lib/python3.6/dist-packages/PyQt5/Qt5/lib/libQt5WebSockets.so.5
./home/sunzengpeng/RoboDK/bin/lib/libQt5WebSockets.so.5.12.0
./home/sunzengpeng/RoboDK/bin/lib/libQt5WebSockets.so
./home/sunzengpeng/RoboDK/bin/lib/libQt5WebSockets.so.5
./home/sunzengpeng/RoboDK/bin/lib/libQt5WebSockets.so.5.12

i would apprectiate so much if you can give me some suggestions.
thanks

MakeProgram freeze

When running MakeProgram in conditions where an error happens (e.g. the path is not writable or doesn't exist), the method call freeze.

  • When running with a GUI a popup window with error message appears (very good)
  • But when running in headless mode (e.g. RoboDK/bin/RoboDK --platform minimal -NOUI) it would be desired that the method call does not freeze and returns error in order actions can be taken from the user code side.

Same behaviour is observed in a try-except statement like so:

try:
   prog.MakeProgram(filesave)
except:
   print("[ERROR] could not save robot code file '" + filesave + "'")

command line option '-HIDDEN' is not working in the API

I am using the '-HIDDEN' command line option with the C++ API and it is not working, RoboDK is not starting in background and the application show up. I use the following constructor:

RoboDK_API::RoboDK *rdk_=new RoboDK_API::RoboDK("",kRoboDKPragmaPort,"/NOSPLASH /HIDDEN");

The '-NOSPLAHS' option is working.
When I run the command directly with robodk.exe -HIDDEN it is not working either.

Am I doing something wrong or is it suppose to work?

I use the latest C++ API and RoboDK v5.2.1

Thanks,
Francois.

robolink.Robolink modifies list passed to args

When launching a new RoboDK instance using rdk = robolink.Robolink(args=my_args), the list passed to the args kwarg is interpreted by-reference and will have the port appended to it.

The workaround is easy: pass my_args.copy() instead of my_args when calling robolink.Robolink. However, the symptoms are more complicated. I was only able to encounter adverse results when multithreading across several instances of RoboDK as part of a larger project. Consequently, this was not super easy to debug.

In my situation, I encountered a timeout when attempting to access the .Item method of one of the robolink.Robolink instances that was launched. This was substantially more difficult to trace back to the args issue, so I think implementing the (very easy) fix would be worthwhile so others do not also have to debug this.

Here's a minimal reproducible example:

from robodk import robolink as rl
import time
import threading
import os

class MyClass():

    def __init__(self):
        self.workstation_items_lock = threading.RLock()

    def start_rdk(self, launch_rdk_gui:bool=False, num_threads:int=1):

        __args = ['-NEWINSTANCE', '-SKIPMAINT', '-NOUI', os.path.join(os.getcwd(), 'resources', 'workstation.rdk')]

        self.num_threads = num_threads
        self.threads = []

        self.rdk = [None]*self.num_threads
        self.tool = [None]*self.num_threads
        __t:list[threading.Thread] = []
        print(f'__args prior to launching RoboDK instances: {__args}')
        for __i in range(self.num_threads):
            __t.append(threading.Thread(target=self.__start_rdk, kwargs={'thread': __i, 'args': __args}))
            __t[-1].start()
        for __i in range(self.num_threads):
            __t[__i].join()
        print(f'__args after launching RoboDK instances: {__args}')
        pass
    
    def __start_rdk(self, thread:int, args:list[str]):
        __rdk = rl.Robolink(args=args)
        __tool = __rdk.Item('end_effector', rl.ITEM_TYPE_TOOL)

my_class = MyClass()
my_class.start_rdk(launch_rdk_gui=False, num_threads=4)

When running this (must have a .rdk workstation at the right path that at least includes an item called "end_effector"), a TimeoutError occurs on the line __tool = __rdk.Item('end_effector').

I am not sure how the timeout is related to the args issue, but I can definitely confirm that:

  1. The variable __args is as-expected prior to launching RoboDK.
  2. The variable __args includes a bunch of appended port number arguments ("-PORT=...") at the time the exception occurs.
  3. Passing __args.copy() fixes the problem outright.
    Based on this, I think a change to robolink.py is the cleanest solution.

Asking about online programming for Denso robot arm, not included in RoboDK library

Hi,

Thank you so much for your contributions!

Previously, I already used RoboDK Python API to do online programming for a Fanuc robot arm included in RoboDK library.
It means, I am able to send control commands and both simulated and real Fanuc robot arms simultaneously move correctly.

However, in my current task, I need to control Denso VM-6083 and it is not included in RoboDK library. Meanwhile, RoboDK includes another model, Denso-VM-60B1 with the same payload as VM-6083 but different from forward kinematics (max arm reach is different).

In particular, my Denso arm uses Robot Controller RC8A and it is supported for online programming
(https://robodk.com/doc/en/Robots-Denso.html)

Therefore, I'd like to ask questions as follows.

  1. How can I do online programming if the exact model is not included in RoboDK library?

  2. In the case of not feasible, what if I just use Denso-VM-60B1 for simulated robot, am I still able to connect to real Denso VM-6083 and send control commands to that real arm. Because, for my main purpose, I only need to control the real arm, not simulated arm.
    Or, any case, I can connect and control the real Denso VM-6083 via Python API from RoboDK?

  3. I am still confusing that, RoboDK API (Python) will work directly with robot controller of the real arm, or it also needs the matching between the simulated arm from RoboDK library and the real arm?

`robolink.Robolink.ShowMessage()` prints message in command line

Pretty much the title.

The ShowMessage method of the Robolink class has a line: print(message) after being called. If a CLI uses the RoboDK API, this can be disruptive.

I think either this line should be removed completely or print_msg:str=True should be an optional argument that controls whether the message is also printed to the command line.

C API: Extraneous console prints present in robodk_api_c.c

The functions below each print once to the console. This is likely leftover from when the functions were being debugged. Printing statuses like this is at least not consistent with the behavior of other functions in the C API. Ideally, the prints would be removed, but at least they should have an option to disable console prints when calling the function.
struct Mat_t Item_PoseFrame()
struct Mat_t Item_PoseTool()

Consideratins on the new definition of MAX_STR_LENGTH in robodk_api_c.h

MAX_STR_LENGTH is now defined as 2048 chars long. Where do these numbers (1024, 2048) come from? This should be equal to the longest diagnostic message that the API is expected to receive.
The question comes from the fact that the new definition doesn't solve my communication issue: after having commanded a motion via the API, the API goes into a status -1 (as returned by _RoboDK_recv_Int, line 2156) and thus goes into the condition handled by the lines 2185 to 2188 of robodk_api_c.c (I have waited more than 8000 characters and still havent received the expected '\n' string terminator).
There (between lines 2185 and 2188), the API repeatedly invokes _RoboDK_recv_Line, where you have introduced a potential source of bugs:

  1. making MAX_STR_LENGTH longer does not address the main issue that _RoboDK_recv_Line never receives '\n' by the SocketRead call on line 2059. As such, isDone never becomes true and the API will always freeze there;
  2. lines 2067 to 2069 have been replaced by those between 2064 and 2069 by filling up the output buffer only if i < MAX_STR_LENGTH. This avoids that the if condition writes beyond the end of the buffer (that would be a fault), but does not solve the system freeze: the loop still waits for the '\n' character to be received by SocketRead on line 2059!

My doubt is: what does status variable in _RoboDK_check_status represent? Where are these values (and their meanings) defined? By looking at the code in _RoboDK_check_status I infer that there is a first set of status values between 1 and 9 (both included) representing expected successful execution of the commands received, and then a second set of status values < 100 (where currently also -1 falls) apparently representing error conditions (the buffer strProblems is to be filled with a diagnostic string to be attached to "RoboDK API ERROR: %s").
I wonder if that -1 hanging the API is correctly handled here, it perhaps representing a not better specified communication problem (lines from 2190 to 2192) that needs NOT filling up a buffer (obviously, as the error condition is not better specified and thus probably not even recognised).
A way to put it without changing the type definition of status (int32_t on line 2156), is to replace line 2185 with
else if ((status < 100) && (status > 0)) {
But at this point, the neater way to put it is to have:

  • 2161 - else if (status > 0) {
  • 2162 - if (status < 10) { ...
  • 2163 to 2184 a switch clause instead of repeated ifs (with default instead of the else at 2179)
  • another } after 2189 to close the 2161 if condition

The status -1 would thus immediately be sent to 2190: no buffer filling required, no crashing, and error message.

Bug in RoboDK::WindowID()

I think there is a bug in the C++ API method RoboDK::WindowID().
The current method from the repositery is like this:

quint64 RoboDK::WindowID(){
    qint64 window_id;
    if (window_id == 0) {
        QString response = Command("MainWindow_ID");
        window_id = response.toInt();
    }
    return window_id;
}

But window_id is not initialized.
I changed the code to:

quint64 RoboDK::WindowID(){
    QString response = Command("MainWindow_ID");
    quint64 window_id = response.toInt();
    
    return window_id;
}

And now it is working.

Mat_PoseAbs

Hi,
I tried to apply Mat_PoseAbs to a tool item, wishing that it returned the TCP in base coordinates, but it only returned coordinates to a reference frame I selected. This is more like the behaviour of Mat_PoseFrame. Please, verify.

ERROR: Package 'robodk' requires a different Python: 3.8.10 not in '<3.5'

In 5.6.9, installing robodk via pip3 install robodk fails on Ubuntu 20.04.

  • Installing 5.6.8 works fine on Ubuntu 20.04.
  • Issue doesn't happen on Ubuntu 22.04.
Collecting robodk
  Downloading robodk-5.6.9-py2.py3-none-any.whl (117 kB)
     |████████████████████████████████| 117 kB 7.1 MB/s 
ERROR: Package 'robodk' requires a different Python: 3.8.10 not in '<3.5'

Feature Request: Allow merge of splitted objects

I would like to be able to merge a previously splitted object in RoboDK back together to one object. This is currently not possible, there is only the option to split an object. Once it is splitted, one cannot merge it back together again. I have to keep a backup of every file that I split in RoboDK.

Another question: I have an unsplitted object that I would like to generate a 3D print path for. I cannot select the whole object even though it is one whole object in RoboDK station tree. I can only select parts of the object and thus only generate 3D print path for a part of the object. Same behaviour when selecting the object with your API, except with the API I have even less control of what part of the object is selected:

m = RDK.ItemUserPick(message='Select a robot machining project', itemtype_or_list=ITEM_TYPE_MACHINING)
m.setMachiningParameters(ncfile=file)

How do I do this? 3D file that this is happening with is attached.
tesla roadster 2020.zip

Wrong string format for double type

Hello,

at line 1512 the character array bufferTemp is filled with the double values of a Mat structure x, y, z, w, p, r.
First, the lf instead of the bare f field specifier should be used, but I had problems from another point of view: my robot arm tried to reach a pose where x was in the 1e+80s, and y and z were in the 1e-300s. In this case, bufferTemp is filled with 80 characters from x alone, and when sprintf adds the values from the other members of the Mat, you get an out-of-bounds (bufferTemp is only 128 chars long).
In this case, the g field specifier should be used.
In order to respect your own style of code, I wrote:

if ((x < 1e9) && (x > 1e-9))
    sprintf(bufferTemp, "%12.3lf,", x);
else
    sprintf(bufferTemp, "%12.3g,", x);
strcat(output, bufferTemp);
if ((y < 1e9) && (y > 1e-9))
    sprintf(bufferTemp, "%12.3lf,", y);
else
    sprintf(bufferTemp, "%12.3g,", y);
strcat(output, bufferTemp);
if ((z < 1e9) && (z > 1e-9))
    sprintf(bufferTemp, "%12.3lf,", z);
else
    sprintf(bufferTemp, "%12.3g,", z);
strcat(output, bufferTemp);
if ((w < 1e9) && (w > 1e-9))
    sprintf(bufferTemp, "%12.3lf,", w);
else
    sprintf(bufferTemp, "%12.3g,", w);
strcat(output, bufferTemp);
if ((p < 1e9) && (p > 1e-9))
    sprintf(bufferTemp, "%12.3lf,", p);
else
    sprintf(bufferTemp, "%12.3g,", p);
strcat(output, bufferTemp);
if ((r < 1e9) && (r > 1e-9))
    sprintf(bufferTemp, "%12.3lf))\n", r);
else
    sprintf(bufferTemp, "%12.3g))\n", r);
strcat(output, bufferTemp);

I also corrected the f specifier at line 1522, 1611 and 1780.

C API: RoboDK_Collisions does not appear in robodk_api_c.h

Pretty much the title.

There is no function prototype for the RoboDK_Collisions() function that is defined in robodk_api_c.c, which causes compiler errors when attempting to build code that uses that function.

(Note that RoboDK_Collision() IS defined, but the plural is not.)

[Python] Update() replies with incorrect simulation time

Using the next snippet, that generates a program with different targets and speed, the update func is used to know the estimated simulation time.

Unfortunately, it replies correctly only for the first program call.
To obtain the right simulation time, I have to uncomment this code (and this not wanted in my case....):

   prog.RunProgram()
   while prog.Busy():
         time.sleep(0.1)

python program I used:

# # -*- coding: utf-8 -*-
from robolink import *    # API to communicate with RoboDK for simulation and offline/online programming
from robodk import *      # Robotics toolbox for industrial robots

#
# https://robodk.com/doc/en/PythonAPI/robodk.html#robodk.Mat
#
import time


def AddTarget(name,pos):
    item = RDK.Item(name)
    itemparent = RDK.Item("World")
    if not item.Valid():
        item = RDK.AddTarget(name, itemparent, itemrobot=0)
    #print(item)
    m = item.Pose()
    #print(m)
    #print(type(m))
    m=Mat().eye()
    #m=transl(pos[0], pos[1], pos[2])
    # xyz wpr deg
    m = m.Offset(pos[0],pos[1],pos[2],pos[3],pos[4],pos[5])
    item.setPose(m)
    




# Any interaction with RoboDK must be done through RDK:
RDK = Robolink()

# Select a robot (popup is displayed if more than one robot is available)
robot = RDK.ItemUserPick('Select a robot', ITEM_TYPE_ROBOT)
if not robot.Valid():
    raise Exception('No robot selected or available')

tool = RDK.Item('flange')
tool.AttachClosest()
tool.DetachAll()
HomeJoints=[-66.18,-17.813,-3.961,0,-86.039,66.18]
robot.setJoints(HomeJoints)

# Turn off rendering (faster)
RDK.Render(True)


HomeTarget=[445,-1008,1000,180,0,0]
ErwinHome = AddTarget("ErwinHome",HomeTarget)
home=RDK.Item("ErwinHome")
# definit la vitesse lineaire
robot.setSpeed(40,-1,-1,-1), # linear mm/sec
init = True
result =""
no=0
mode = 'L' # 'L' Lineaire / Sinon Joint MoveJ
#RDK.setSimulationSpeed(100)

for speed in [40,400,1000,2000,4000]:
 for rounding in [-1,0,10,25,50,100]:
  for dx in [10,100,500,1000,1500]:
    oldprog = RDK.Item("AutoProgram")
    if oldprog.Valid():
        oldprog.Delete()
    #robot.setPose(RDK.Item("T1").Pose())
    nomprog = 'Program_dx'+str(dx)+'_cnt_'+str(rounding)+'_speed_'+str(speed)
    prog = RDK.AddProgram("AutoProgram")
    if init:
        if mode == 'L':
            prog.MoveL(home)
        else:
            prog.MoveJ(home)
        init = False
    # Hide program instructions (optional, but faster)
    prog.ShowInstructions(True)
    prog.setSpeed(speed,speed)
    prog.setRounding(rounding)
    Home = Pose(445,-1008,1000,180,0,0)

    T1=Pose(0,-dx,0,0,0,0)
    M=Home*T1
    AddTarget("T1",Pose_2_Fanuc(M))
    t1 = RDK.Item("T1")
    if mode == 'L':
        prog.MoveL(t1)
    else:
        prog.MoveJ(t1)
    T2=Pose(dx,-dx,0,0,0,0)
    M=Home*T2
    AddTarget("T2",Pose_2_Fanuc(M))
    t2 = RDK.Item("T2")
    if mode == 'L':
        prog.MoveL(t2)
    else:
        prog.MoveJ(t2)
    T=Pose(dx,-dx,dx,0,0,0)
    M=Home*T

    AddTarget("T3",Pose_2_Fanuc(M))
    t3 = RDK.Item("T3")
    if mode == 'L':
        prog.MoveL(t3)
    else:
        prog.MoveJ(t3)

    T=Pose(dx,0,dx,0,0,0)
    M=Home*T
    AddTarget("T4",Pose_2_Fanuc(M))
    t4 = RDK.Item("T4")
    if mode == 'L':
        prog.MoveL(t4)
    else:
        prog.MoveJ(t4)

    T=Pose(0,0,dx,0,0,0)
    M=Home*T
    AddTarget("T5",Pose_2_Fanuc(M))
    t5 = RDK.Item("T5")
    if mode == 'L':
        prog.MoveL(t5)
    else:
        prog.MoveJ(t5)
    if mode == 'L':
        prog.MoveL(home)
    else:
        prog.MoveJ(home)
    check_collisions =  False
#    prog.RunProgram()
#    while prog.Busy():
#         time.sleep(0.1)
    update_result = prog.Update(check_collisions)

#    print("Valid instructions ",update_result[0])
#    print("valid_ratio ",update_result[3])
#    print("message ",update_result[4])
    s = "%6.3f" % update_result[1]
    s=s.replace('.',',') # pauvre conversion pour excel en mode french
    print(s)
    r = "dx %d speed: %d mm/s CNT:%d temps cycle %f sec.\n" % (dx,speed,rounding,update_result[1])
    #print(r)
    result +=r
#    time.sleep(30)


print("END")
print(result)

wrong results without RunProgram():

wrong_results.txt

good results with RunProgram():

good_results.txt

Edits proposal in connect functions

Please, consider these edits for file robodk_api_c.c (C API):

line 105: RoboDK_Connect(inst, "", ROBODK_DEFAULT_PORT, "", "");

delete lines 119 to 121

Regards

C# - RoboDK top level window was not found...

Hello.
I cloned the repo, tried to run the project from Visual Studio (tried versions 2017 and 2019) and got System.FormatException at RoboDK.cs line 584, as the previous line
var mainWindowId = Command("MainWindow_ID");
returns "RoboDK top level window was not found..." instead of int descriptor of the window. This happens both if the RDK is opened previously before the project is run, or if the RDK is not running.

I couldn't find much help on the toppic, the thread
https://robodk.com/forum/Thread-Problem-in-installing-running-the-RoboDk-software-Windows-8-64bit
didnt help.

Python API: In robomath.py, multiple issues with transl function

  1. Documentation states that tx, ty, and tz are all floats. However, if ty is None, tx gets interpreted as a list: xx = tx[0].
  2. Both ty and tz are listed as optional arguments, but if ty is not passed, tz is ignored. This is probably fine, but it's unclear enough that it should be documented.
  3. Both ty and tz are listed as optional arguments, but if ty is passed but not tz, then zz will be set to None. This doesn't immediately cause an exception when the Mat() is constructed on return. Worse, it causes an exception later, when the code calling the API attempts to use the Mat.

For reference, the transl function is below.

def transl(tx, ty=None, tz=None):
    r"""Returns a translation matrix (mm)

    .. math::

        T(t_x, t_y, t_z) = \begin{bmatrix} 1 & 0 & 0 & t_x \\
        0 & 1 & 0 & t_y \\
        0 & 0 & 1 & t_z \\
        0 & 0 & 0 & 1
        \end{bmatrix}

    :param float tx: translation along the X axis
    :param float ty: translation along the Y axis
    :param float tz: translation along the Z axis

    .. seealso:: :func:`~robodk.robomath.rotx`, :func:`~robodk.robomath.roty`, :func:`~robodk.robomath.rotz`
    """
    if ty is None:
        xx = tx[0]
        yy = tx[1]
        zz = tx[2]
    else:
        xx = tx
        yy = ty
        zz = tz
    return Mat([[1, 0, 0, xx], [0, 1, 0, yy], [0, 0, 1, zz], [0, 0, 0, 1]])

Recommended change: adjust code to handle and update documentation accordingly. Backwards-compatibility is preserved in most cases, though some edge cases like passing tz but not ty will now behave differently (though this was likely not intended to be supported in the first place).

def transl(tx:float|list[float]=0, ty:float=0, tz:float=0):
    r"""Returns a translation matrix (mm) given translations in each dimension. Supports passing inputs as a list through the tx argument, but
    this ignores ty and tz.

    .. math::

        T(t_x, t_y, t_z) = \begin{bmatrix} 1 & 0 & 0 & t_x \\
        0 & 1 & 0 & t_y \\
        0 & 0 & 1 & t_z \\
        0 & 0 & 0 & 1
        \end{bmatrix}

    :param float tx: translation along the X axis
    :param float ty: translation along the Y axis
    :param float tz: translation along the Z axis

    .. seealso:: :func:`~robodk.robomath.rotx`, :func:`~robodk.robomath.roty`, :func:`~robodk.robomath.rotz`
    """
    if type(tx) == list:
        # optionally: assert ty=0 and tz=0, 'TyAndTzUnsupportedWhenPassingTranslationAsListThroughTx'
        xx = tx[0]
        yy = tx[1]
        zz = tx[2]
    else:
        xx = tx
        yy = ty
        zz = tz
    return Mat([[1, 0, 0, xx], [0, 1, 0, yy], [0, 0, 1, zz], [0, 0, 0, 1]])

RoboDK Python interface does not support v3.11

Some of RoboDKs features requires PySide2 which is not supported after Python version 3.10.

With my limited knowledge of QT, It sounds like changing to PySide6 for Python versions >3 would be an easy fix.

There is a current work around:

  1. Install the latest version of Python that that package supports (sounds like that's Python 3.10).
  2. Copy that module's code from the site-packages folder of the Python 3.10 installation to the site-packages folder of the Python 3.11 installation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.