@@ -900,3 +900,195 @@ def IsInCollision(traj, robot, selfcoll_only=False):
900
900
return True
901
901
902
902
return False
903
+
904
+
905
+ def JointStatesFromTraj (robot , traj , times , derivatives = [0 , 1 , 2 ]):
906
+ """
907
+ Helper function to extract the joint position, velocity and acceleration
908
+ from an OpenRAVE trajectory.
909
+ @param robot The OpenRAVE robot
910
+ @param traj An OpenRAVE trajectory
911
+ @param times List of times in seconds
912
+ @param derivatives list of desired derivatives defaults to [0, 1, 2]
913
+ @return pva_list List of list of derivatives at specified times.
914
+ Inserts 'None' for unavailable or undesired fields
915
+ The i-th element is the derivatives[i]-th derivative
916
+ of position of size |times| x |derivatives|
917
+
918
+ """
919
+ duration = traj .GetDuration ()
920
+
921
+ times = numpy .array (times )
922
+ if any (times > duration ):
923
+ raise ValueError ('Input times {0:} exceed duration {1:.2f}'
924
+ .format (times , duration ))
925
+
926
+ cspec = traj .GetConfigurationSpecification ()
927
+ num_dofs = robot .GetDOF ()
928
+ dof_indices = range (num_dofs )
929
+
930
+ pva_list = []
931
+ for t in times :
932
+ pva = [None ] * len (derivatives )
933
+ trajdata = traj .Sample (t )
934
+ for i , deriv in enumerate (derivatives ):
935
+ pva [i ] = cspec .ExtractJointValues (trajdata , robot , dof_indices , deriv )
936
+ pva_list .append (pva )
937
+
938
+ return pva_list
939
+
940
+
941
+ def JointStateFromTraj (robot , traj , time , derivatives = [0 , 1 , 2 ]):
942
+ """
943
+ Helper function to extract the joint position, velocity and acceleration
944
+ from an OpenRAVE trajectory.
945
+ @param robot The OpenRAVE robot
946
+ @param traj An OpenRAVE trajectory
947
+ @param time time in seconds
948
+ @param derivatives list of desired derivatives defaults to [0, 1, 2]
949
+ @return pva_list List of list of derivatives at specified times.
950
+ Inserts 'None' for unavailable or undesired fields
951
+ The i-th element is the derivatives[i]-th derivative
952
+ of position of size |times| x |derivatives|
953
+ """
954
+ return JointStatesFromTraj (robot , traj , (time ,), derivatives )[0 ]
955
+
956
+
957
+ def BodyPointsStatesFromJointStates (bodypoints ,
958
+ jointstates ,
959
+ derivatives = [0 , 1 , 2 ]):
960
+ """
961
+ Computes the derivatives body points given jointstates.
962
+ Currently only supports derivatives up to 2.
963
+ @param bodypoints List of bodypoints where each bodypoint
964
+ is a list comprising of:
965
+ (1) the OpenRAVE link the bodypoint is on
966
+ (2) position of the body point in the link frame
967
+ @param jointstates List of list of joint derivatives.
968
+ Unavailable fields are input as 'None'
969
+ @param derivatives list of desired derivatives defaults to [0, 1, 2]
970
+ @return bodypoint_list List of list of derivatives at specified times.
971
+ Inserts 'None' for unavailable or undesired fields
972
+ The i-th element is the derivatives[i]-th derivative
973
+ of position of size |times| x |derivatives|
974
+ """
975
+
976
+ # Convert derivatives to numpy array
977
+ derivatives = numpy .array (derivatives )
978
+ maxd = max (derivatives )
979
+ numd = len (derivatives )
980
+
981
+ if any (derivatives > 2 ):
982
+ raise ValueError ("Can only support derivatives up to 2." )
983
+
984
+ # Assume everything belongs to the same robot and env
985
+ robot = bodypoints [0 ][0 ].manipulator .GetRobot ()
986
+ env = robot .GetEnv ()
987
+
988
+ bpstate_list = []
989
+
990
+ with env :
991
+ with robot :
992
+ for js in jointstates :
993
+ # Make all unavailable and undesired derivatives None
994
+ q , qd , qdd = [js [x ] if x < len (js ) and x <= maxd
995
+ else None for x in range (3 )]
996
+ if q is not None :
997
+ robot .SetDOFValues (q )
998
+ else :
999
+ bpstate_list .append ([[[None ] * numd ] * len (bodypoints )])
1000
+ continue
1001
+ for bp in bodypoints :
1002
+ bp_state = [None ] * numd
1003
+ link , local_pos = bp
1004
+ link_index = link .GetIndex ()
1005
+ link_transform = link .GetTransform ()
1006
+ world_pos = (numpy .dot (link_transform [0 :3 , 0 :3 ],
1007
+ local_pos ) +
1008
+ link_transform [0 :3 , 3 ])
1009
+ bp_state [0 ] = world_pos
1010
+ if qd is not None :
1011
+ Jpos = robot .CalculateJacobian (link_index , world_pos )
1012
+ Jang = robot .CalculateAngularVelocityJacobian (
1013
+ link_index )
1014
+ vpos = numpy .dot (Jpos , qd )
1015
+ vang = numpy .dot (Jang , qd )
1016
+ bp_state [1 ] = numpy .hstack ((vpos , vang ))
1017
+ else :
1018
+ continue
1019
+ if qdd is not None :
1020
+ Hpos = robot .ComputeHessianTranslation (
1021
+ link_index , world_pos )
1022
+ Hang = robot .ComputeHessianAxisAngle (link_index )
1023
+ apos = (numpy .dot (Jpos , qdd ) +
1024
+ numpy .dot (qd , numpy .dot (Hpos , qd )))
1025
+ aang = (numpy .dot (Jang , qdd ) +
1026
+ numpy .dot (qd , numpy .dot (Hang , qd )))
1027
+ bp_state [2 ] = numpy .hstack ((apos , aang ))
1028
+ bpstate_list .append (bp_state )
1029
+ return bpstate_list
1030
+
1031
+
1032
+ def BodyPointsStatesFromJointState (bodypoints , jointstate ,
1033
+ derivatives = [0 , 1 , 2 ]):
1034
+ """
1035
+ Computes the pos, vel, acc of body points given the
1036
+ pos, vel, acc of jointstates
1037
+ @param bodypoints List of bodypoints where each bodypoint
1038
+ is a list comprising of:
1039
+ (1) the OpenRAVE link the bodypoint is on
1040
+ (2) position of the body point in the link frame
1041
+ @param jointstate List of joint position,
1042
+ velocity and acceleration.
1043
+ Unavailable fields are input as 'None'
1044
+ @param derivatives list of desired derivatives defaults to [0, 1, 2]
1045
+ @return bodypoint_list List of list of derivatives at specified times.
1046
+ Inserts 'None' for unavailable or undesired fields
1047
+ The i-th element is the derivatives[i]-th derivative
1048
+ of position of size |times| x |derivatives|
1049
+ """
1050
+ return BodyPointsStatesFromJointStates (bodypoints , (jointstate ,),
1051
+ derivatives )[0 ]
1052
+
1053
+
1054
+ def BodyPointsStatesFromTraj (bodypoints , traj , times , derivatives = [0 , 1 , 2 ]):
1055
+ """
1056
+ Computes the pos, vel, acc of body points from a joint space trajectory
1057
+ at specified times
1058
+ @param bodypoints List of bodypoints where each bodypoint
1059
+ is a list comprising of:
1060
+ (1) the OpenRAVE link the bodypoint is on
1061
+ (2) position of the body point in the link frame
1062
+ @param traj An OpenRAVE trajectory
1063
+ @param time List of times in seconds
1064
+ @param derivatives list of desired derivatives defaults to [0, 1, 2]
1065
+ @return bodypoint_list List of list of derivatives at specified times.
1066
+ Inserts 'None' for unavailable or undesired fields
1067
+ The i-th element is the derivatives[i]-th derivative
1068
+ of position of size |times| x |derivatives|
1069
+ """
1070
+ # Assume everything belongs to the same robot
1071
+ robot = bodypoints [0 ][0 ].manipulator .GetRobot ()
1072
+ jointstates = JointStatesFromTraj (robot , traj , times ,
1073
+ range (max (derivatives )))
1074
+
1075
+ return BodyPointsStatesFromJointStates (bodypoints , jointstates ,
1076
+ derivatives )
1077
+
1078
+
1079
+ def BodyPointsStateFromTraj (bodypoints , traj , time , derivatives = [0 , 1 , 2 ]):
1080
+ """
1081
+ Computes the pos, vel, acc of body points from a joint space trajectory
1082
+ at a specified time
1083
+ @param bodypoints List of bodypoints where each bodypoint
1084
+ is a list comprising of:
1085
+ (1) the OpenRAVE link the bodypoint is on
1086
+ (2) position of the body point in the link frame
1087
+ @param traj An OpenRAVE trajectory
1088
+ @param derivatives list of desired derivatives defaults to [0, 1, 2]
1089
+ @return bodypoint_list List of list of derivatives at specified times.
1090
+ Inserts 'None' for unavailable or undesired fields
1091
+ The i-th element is the derivatives[i]-th derivative
1092
+ of position of size |times| x |derivatives|
1093
+ """
1094
+ return BodyPointsStatesFromTraj (bodypoints , traj , (time ,), derivatives )[0 ]
0 commit comments