question

Manikanta avatar image
0 Likes"
Manikanta asked Jason Lightfoot edited

Mimic a Universal Robot

I basically wanted to mimic a universal robot. I am getting the real time joint angle values of the robot into Flexsim via an emulator MODBUS connection. The values are stored in Global table. Those values are updating every 1 second through a model logic. You can see from the image

Test Robot 2.fsm1690893574605.png

I basically want the Flexsim robot to simulate the Universal robot movements real time by getting the joints angle values from the global table.

Can someone help me how to mimic the robot

FlexSim 23.0.3
robotdigital twin
1690893574605.png (762.5 KiB)
test-robot-2.fsm (73.2 KiB)
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

1 Answer

Jason Lightfoot avatar image
0 Likes"
Jason Lightfoot answered Jason Lightfoot edited

You'll find the joints under the drawsurrogate node of the robot. 1690897624701.png

You can set the rotation of each for the appropriate axis using

joint.rotation.z=<value>

where 'joint' refers to the correct joint node and you specify the axis as x,y or z.

You can either perform this when you receive the data (best), on a tick/interval or when the robot draws using onDraw.



1690897624701.png (13.6 KiB)
· 5
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Manikanta avatar image Manikanta commented ·
Dear Jason

Thank you for the information

I couldn't understand it, can you explain any one method in steps

0 Likes 0 ·
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Manikanta commented ·
Okay - I'll update your model as an example - stand by.
0 Likes 0 ·
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Manikanta commented ·

First I set up a map of the joint information by running this script with the robot in the reference position:

Object rob=Model.find("Robot1");
Object joint=drawsurrogate(rob).first.first;
Vec3 x=Vec3(1,0,0);
Vec3 y=Vec3(0,1,0);
Vec3 z=Vec3(0,0,1);


Map jointMap;
jointMap["Base"]=[joint,z,joint.rotation];   //Array of [joint node, rotation vec3, static rotation state]
joint=joint.first;
jointMap["Shoulder"]=[joint,x,joint.rotation];   
joint=joint.first;
jointMap["Elbow"]=[joint,x,joint.rotation];   
joint=joint.first;
jointMap["Wrist1"]=[joint,y,joint.rotation];   
joint=joint.first;
jointMap["Wrist2"]=[joint,x,joint.rotation];   
joint=joint.first;
jointMap["Wrist3"]=[joint,y,joint.rotation];   
rob.labels.assert("jointMap",jointMap);


Then in the onDraw trigger I placed this code:

/**Custom Code*/
Object current = ownerobject(c);
treenode view = param(1);


// If this function returns a true, the default draw code of the object will not be executed.
Map jointMap=current.jointMap;
Table jointTab=Table("GlobalTable1");
string jointName;
Object joint;
Array jointInfo;
Vec3 axisFact;
Vec3 rotReference;
double newRotation;
for (int n=jointTab.numCols;n>0;n--){
    newRotation=jointTab[1][n];
    jointName=jointTab.getColHeader(n);
    jointInfo=jointMap[jointName];
    joint=jointInfo[1];
    axisFact=jointInfo[2];
    rotReference=jointInfo[3];
    joint.rotation=(axisFact*newRotation)+rotReference;  // corrected
}

test-robot-2_jl.fsm

You could put the onDraw code in a user command and call it from there or any other event such as when you update the table.

0 Likes 0 ·
test-robot-2-jl.fsm (42.6 KiB)
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Jason Lightfoot ♦♦ commented ·

If you're unsure of the flexScript then put a breakpoint in the code and step through it - it's the easiest way to learn what's going on while looking at the local variable values.

0 Likes 0 ·
Jason Lightfoot avatar image Jason Lightfoot ♦♦ Manikanta commented ·

@Manikanta Here's an updated version with the a user command 'updateRobotJoints' to which you pass in the robot, table and row as parameters:

updateRobotJoints(current,Table("GlobalTable1"),1);

The user command code is:

Object current=param(1);
Table jointTab=param(2);
int row=param(3);

Map jointMap=current.jointMap;
Map jointInfo;
double newRotation;
for (int n=jointTab.numCols;n>0;n--){
    newRotation=jointTab[row][n];
    jointInfo=jointMap[jointTab.getColHeader(n)];
    jointInfo.joint.rotation=(jointInfo.axisMask.as(Vec3)*newRotation)+jointInfo.refRotation.as(Vec3);
}

The setup of the map has change too so that now the jointMap also contains a Map of joint information ('jointInfo') allowing dot notation to be used for the values as follows:

jointInfo.joint   // the joint object in drawsurrogates
jointInfo.axisMask // the Vec3 defining the axis to apply the rotation to
jointInfo.refRotation  // the stored rotation in the reference position

The setup script for the nested maps is then:

Object rob=Model.find("Robot1");
Object joint=drawsurrogate(rob).first.first;
Vec3 x=Vec3(1,0,0);
Vec3 y=Vec3(0,1,0);
Vec3 z=Vec3(0,0,1);
Map jointInfo;
Map jointMap;
Array jointAxes=[z,x,x,y,x,y];
Array jointNames=["Base","Shoulder","Elbow","Wrist1","Wrist2","Wrist3"];
for (int n=1;n<=jointAxes.length;n++){
    jointInfo["joint"]=joint;
    jointInfo["axisMask"]=jointAxes[n];
    jointInfo["refRotation"]=joint.rotation;
    jointMap[jointNames[n]]=jointInfo.clone();   //Map of joint node, rotation vec3, static rotation state]
    joint=joint.first;
}
rob.labels.assert("jointMap",jointMap);  // for the first time
rob.jointMap=jointMap;  // for subsequent times


test-robot-2_jl3.fsm

0 Likes 0 ·