Getting joint angles of programmed points in Python

I have a robot and programmed some PTPMotion statements that the robot drives to:


Now, when I select any point, I can check the corresponding values of the joints, see below:

I selected point #17 and can now see the joint values of the robot when it drives to this point (as highlighted).
Ultimately, I would like to export the joint values of every single point to a csv file.
However, I’m unsure on what would be best practice to programmatically get those values for each point using a python script.

If anyone has any ideas I would be really thankful,
cheers

Hi @TStotz

This should be fairly straightforward to do with a python script once you know the basics.
I would recommend to start with going through thecourses Basics of Python Scripting (https://academy.visualcomponents.com/courses/basics-of-python-scripting/) and Python Robotics (https://academy.visualcomponents.com/courses/python-robotics-programming-a-robot-with-python/) to get more familiar with scripting.

After going through these courses, you should have a solid understanding of python scripting and you can implement custom scripts with help form the API documentation.

1 Like

The recommended courses can help because the following might read like gibberish.

About the API in relation to linear and PTP motion statements, each point is a vcPositionFrame object that has a JointValues property, which gives you a list of the joint values for that target. The assumption would be the motion statement was made with the robot in your setup.

In relation to points in a Path statement, each point is a vcSchemaPositionFrame. You need to do a little more work to get the joint values for each point since a point gives you a position matrix and any external joint values. So the example in vcSchemaPositionFrame has a section on how to create a vcMotionTarget, and that target can be used in conjunction with robot controller to find the joint values. For custom statements using schema, the workflow would be similar, but there are probably easier ways to get the values, such as using the vcMotionInterpolator object.

This is a helpful question @TStotz since I noticed vcHelpers.Selection does not have methods for returning all positions and their joint values.

There, of course, is the option to record the joint values of robot during simulation, but that is trivial. Here is a code example that records using sampling interval, but if you drive or jog a robot to a programmed point the vcDof object for each joint of robot (internal and external) can be used to get the value.

from vcScript import *

SAMPLING_INTERVAL = 0.1


def getRobotJointValues():
  joint_values = [d.VALUE for d in dofs]
  return joint_values


def stopRecordingJointValues(program_executor):
  #just an event handler to stop recording joint values
  suspendRun()


def OnRun():
  ##recorded joint values
  #while app.Simulation.IsRunning:
  #  print getRobotJointValues() #write to file, note behavior, etc.
  #  delay(SAMPLING_INTERVAL)
  pass


comp = getComponent()
app = getApplication()
robot = app.findComponent("Generic Articulated Robot")
controller = robot.findBehaviour("Controller")

joints = controller.Joints
dofs = [j.Dof for j in joints]

executor = robot.findBehaviour("Executor")
executor.OnProgramFinished = stopRecordingJointValues
recorded_jv = [[0.0, 0.0, 90.0, 0.0, 0.0, 0.0],[0.0, 2.1119999999999988, 88.0899798038463, 0.0, 4.820922531023192, 0.0],[0.0, 8.447999999999995, 82.3599192153852, 0.0, 19.283690124092768, 0.0],[0.0, 23.137002028808805, 69.07569074172633, 0.0, 52.813302263737555, 0.0],[0.0, 30.36425338657955, 62.53961306368592, 0.0, 69.31047030731943, 0.0],[0.0, 30.91558837890625, 62.65484619140625, 0.0, 69.41049194335938, 0.0],[0.0, 32.46856689453125, 64.78207397460938, 0.0, 65.73031616210938, 0.0],[0.0, 37.327117919921875, 67.9119873046875, 0.0, 57.741851806640625, 0.0],[0.0, 38.958099365234375, 68.32638549804688, 0.0, 55.696441650390625, 0.0],[0.0, 37.17315673828125, 67.860595703125, 0.0, 57.947174072265625, 0.0],[0.0, 33.78765869140625, 66.01943969726562, 0.0, 63.173828125, 0.0],[0.0, 30.873138427734375, 62.58172607421875, 0.0, 69.526123046875, 0.0],[0.5162845265931946, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[9.72522573987986, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[22.26451988207098, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[46.18529419434725, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[62.185294194347264, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[86.18529419434728, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[102.18529419434729, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[123.60580873966178, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[131.90636022294524, 30.68658447265625, 62.24810791015625, 0.0, 70.04623413085938, 0.0],[135.12451755269726, 30.643537552467265, 62.387184397011424, -0.8264927964098103, 69.86271927933883, -0.8264927964098103],[135.12451722306437, 30.116253280204358, 64.09074051295111, -10.950251959022037, 67.61483500542037, -10.950251959022037],[135.12451602531212, 28.20031588548187, 70.28077317318876, -47.73589070294041, 59.446934375792694, -47.73589070294041],[135.1245148645087, 26.34348230042353, 76.2798525626289, -83.38674738316328, 51.53100129244232, -83.38674738316328],[135.12451313316214, 23.574001754792203, 85.22752229159404, -136.5602545867535, 39.72433059708786, -136.56025458675347],[135.1245122906234, 22.226267716508236, 89.58179698620123, -162.43649542414124, 33.97875783975631, -162.43649542414124]]
1 Like

Thank you @Este and @zesty for your helpful information.
There seem to be many different options to export the joint values. In the end, I went with a different approach and thought it might be interesting for others.
First, I gather all programmed statements from the vcExecutor object and iterate over the statements and positions. Then, I use the function move_immediate to move the robot to the position of the current statement. Then I can read the current joint values of every joint and save them.

program = robotExecutor.Program
routine = program.MainRoutine
for statement in routine.Statements:
    for position in statement.Positions:
	    controller = robotExecutor.Controller
	    controller.moveImmediate(position.PositionInReference)
	    for joint in controller.Joints:
		    //save current value

Depending on your statements, you might need to check whether the current statement does have positions. Also, this not 100% tested but works fine for what I want to accomplish and does not rely on actually running a simulation.