@@ -79,6 +79,7 @@ otherwise, follow the [setup instructions](#setup) first.
7979
8080Now we are already ready to go!
8181Unlock the brakes in the web interface, activate FCI, and start coding:
82+
8283``` python
8384from franky import *
8485
@@ -352,7 +353,9 @@ robot.recover_from_errors()
352353robot.relative_dynamics_factor = 0.05
353354
354355# Alternatively, you can define each constraint individually
355- robot.relative_dynamics_factor = RelativeDynamicsFactor(velocity = 0.1 , acceleration = 0.05 , jerk = 0.1 )
356+ robot.relative_dynamics_factor = RelativeDynamicsFactor(
357+ velocity = 0.1 , acceleration = 0.05 , jerk = 0.1
358+ )
356359
357360# Or, for more finegrained access, set individual limits
358361robot.translation_velocity_limit.set(3.0 )
@@ -420,7 +423,8 @@ ee_pose_kin = robot.model.pose(Frame.EndEffector, q, f_t_ee, ee_t_k)
420423# Get the jacobian of the current robot state
421424jacobian = robot.model.body_jacobian(Frame.EndEffector, state)
422425
423- # Alternatively, just get the URDF as string and do the kinematics computation yourself (only for libfranka >= 0.15.0)
426+ # Alternatively, just get the URDF as string and do the kinematics computation yourself (only
427+ # for libfranka >= 0.15.0)
424428urdf_model = robot.model_urdf
425429```
426430
@@ -448,28 +452,37 @@ from franky import *
448452# A point-to-point motion in the joint space
449453m_jp1 = JointMotion([- 0.3 , 0.1 , 0.3 , - 1.4 , 0.1 , 1.8 , 0.7 ])
450454
451- # A motion in joint space with multiple waypoints
452- m_jp2 = JointWaypointMotion([
453- JointWaypoint([- 0.3 , 0.1 , 0.3 , - 1.4 , 0.1 , 1.8 , 0.7 ]),
454- JointWaypoint([0.0 , 0.3 , 0.3 , - 1.5 , - 0.2 , 1.5 , 0.8 ]),
455- JointWaypoint([0.1 , 0.4 , 0.3 , - 1.4 , - 0.3 , 1.7 , 0.9 ])
456- ])
457-
458- # Intermediate waypoints also permit to specify target velocities. The default target velocity is 0, meaning that the
459- # robot will stop at every waypoint.
460- m_jp3 = JointWaypointMotion([
461- JointWaypoint([- 0.3 , 0.1 , 0.3 , - 1.4 , 0.1 , 1.8 , 0.7 ]),
462- JointWaypoint(
463- JointState(
464- position = [0.0 , 0.3 , 0.3 , - 1.5 , - 0.2 , 1.5 , 0.8 ],
465- velocity = [0.1 , 0.0 , 0.0 , 0.0 , - 0.0 , 0.0 , 0.0 ])),
466- JointWaypoint([0.1 , 0.4 , 0.3 , - 1.4 , - 0.3 , 1.7 , 0.9 ])
467- ])
468-
469- # Stop the robot in joint position control mode. The difference of JointStopMotion to other stop motions such as
470- # CartesianStopMotion is that # JointStopMotion # stops the robot in joint position control mode while
471- # CartesianStopMotion stops it in cartesian pose control mode. The difference becomes relevant when asynchronous move
472- # commands are being sent or reactions are being used(see below).
455+ # A motion in joint space with multiple waypoints. The robot will stop at each of these
456+ # waypoints. If you want the robot to move continuously, you have to specify a target velocity
457+ # at every waypoint as shown in the example following this one.
458+ m_jp2 = JointWaypointMotion(
459+ [
460+ JointWaypoint([- 0.3 , 0.1 , 0.3 , - 1.4 , 0.1 , 1.8 , 0.7 ]),
461+ JointWaypoint([0.0 , 0.3 , 0.3 , - 1.5 , - 0.2 , 1.5 , 0.8 ]),
462+ JointWaypoint([0.1 , 0.4 , 0.3 , - 1.4 , - 0.3 , 1.7 , 0.9 ]),
463+ ]
464+ )
465+
466+ # Intermediate waypoints also permit to specify target velocities. The default target velocity
467+ # is 0, meaning that the robot will stop at every waypoint.
468+ m_jp3 = JointWaypointMotion(
469+ [
470+ JointWaypoint([- 0.3 , 0.1 , 0.3 , - 1.4 , 0.1 , 1.8 , 0.7 ]),
471+ JointWaypoint(
472+ JointState(
473+ position = [0.0 , 0.3 , 0.3 , - 1.5 , - 0.2 , 1.5 , 0.8 ],
474+ velocity = [0.1 , 0.0 , 0.0 , 0.0 , - 0.0 , 0.0 , 0.0 ],
475+ )
476+ ),
477+ JointWaypoint([0.1 , 0.4 , 0.3 , - 1.4 , - 0.3 , 1.7 , 0.9 ]),
478+ ]
479+ )
480+
481+ # Stop the robot in joint position control mode. The difference of JointStopMotion to other
482+ # stop-motions such as CartesianStopMotion is that JointStopMotion stops the robot in joint
483+ # position control mode while CartesianStopMotion stops it in cartesian pose control mode. The
484+ # difference becomes relevant when asynchronous move commands are being sent or reactions are
485+ # being used(see below).
473486m_jp4 = JointStopMotion()
474487```
475488
@@ -479,18 +492,30 @@ m_jp4 = JointStopMotion()
479492from franky import *
480493
481494# Accelerate to the given joint velocity and hold it. After 1000ms stop the robot again.
482- m_jv1 = JointVelocityMotion([0.1 , 0.3 , - 0.1 , 0.0 , 0.1 , - 0.2 , 0.4 ], duration = Duration(1000 ))
483-
484- # Joint velocity motions also support waypoints. Unlike in joint position control, a joint velocity waypoint is a
485- # target velocity to be reached. This particular example first accelerates the joints, holds the velocity for 1s, then
486- # reverses direction for 2s, reverses direction again for 1s, and finally stops. It is important not to forget to stop
487- # the robot at the end of such a sequence, as it will otherwise throw an error.
488- m_jv2 = JointVelocityWaypointMotion([
489- JointVelocityWaypoint([0.1 , 0.3 , - 0.1 , 0.0 , 0.1 , - 0.2 , 0.4 ], hold_target_duration = Duration(1000 )),
490- JointVelocityWaypoint([- 0.1 , - 0.3 , 0.1 , - 0.0 , - 0.1 , 0.2 , - 0.4 ], hold_target_duration = Duration(2000 )),
491- JointVelocityWaypoint([0.1 , 0.3 , - 0.1 , 0.0 , 0.1 , - 0.2 , 0.4 ], hold_target_duration = Duration(1000 )),
492- JointVelocityWaypoint([0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ]),
493- ])
495+ m_jv1 = JointVelocityMotion(
496+ [0.1 , 0.3 , - 0.1 , 0.0 , 0.1 , - 0.2 , 0.4 ], duration = Duration(1000 )
497+ )
498+
499+ # Joint velocity motions also support waypoints. Unlike in joint position control, a joint
500+ # velocity waypoint is a target velocity to be reached. This particular example first
501+ # accelerates the joints, holds the velocity for 1s, then reverses direction for 2s, reverses
502+ # direction again for 1s, and finally stops. It is important not to forget to stop the robot
503+ # at the end of such a sequence, as it will otherwise throw an error.
504+ m_jv2 = JointVelocityWaypointMotion(
505+ [
506+ JointVelocityWaypoint(
507+ [0.1 , 0.3 , - 0.1 , 0.0 , 0.1 , - 0.2 , 0.4 ], hold_target_duration = Duration(1000 )
508+ ),
509+ JointVelocityWaypoint(
510+ [- 0.1 , - 0.3 , 0.1 , - 0.0 , - 0.1 , 0.2 , - 0.4 ],
511+ hold_target_duration = Duration(2000 ),
512+ ),
513+ JointVelocityWaypoint(
514+ [0.1 , 0.3 , - 0.1 , 0.0 , 0.1 , - 0.2 , 0.4 ], hold_target_duration = Duration(1000 )
515+ ),
516+ JointVelocityWaypoint([0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 ]),
517+ ]
518+ )
494519
495520# Stop the robot in joint velocity control mode.
496521m_jv3 = JointVelocityStopMotion()
@@ -508,29 +533,44 @@ quat = Rotation.from_euler("xyz", [0, 0, math.pi / 2]).as_quat()
508533m_cp1 = CartesianMotion(Affine([0.4 , - 0.2 , 0.3 ], quat))
509534
510535# With target elbow angle (otherwise, the Franka firmware will choose by itself)
511- m_cp2 = CartesianMotion(RobotPose(Affine([0.4 , - 0.2 , 0.3 ], quat), elbow_state = ElbowState(0.3 )))
536+ m_cp2 = CartesianMotion(
537+ RobotPose(Affine([0.4 , - 0.2 , 0.3 ], quat), elbow_state = ElbowState(0.3 ))
538+ )
512539
513540# A linear motion in cartesian space relative to the initial position
514- # (Note that this motion is relative both in position and orientation. Hence, when the robot's end-effector is oriented
515- # differently, it will move in a different direction)
541+ # (Note that this motion is relative both in position and orientation. Hence, when the robot's
542+ # end-effector is oriented differently, it will move in a different direction)
516543m_cp3 = CartesianMotion(Affine([0.2 , 0.0 , 0.0 ]), ReferenceType.Relative)
517544
518- # Generalization of CartesianMotion that allows for multiple waypoints
519- m_cp4 = CartesianWaypointMotion([
520- CartesianWaypoint(RobotPose(Affine([0.4 , - 0.2 , 0.3 ], quat), elbow_state = ElbowState(0.3 ))),
521- # The following waypoint is relative to the prior one and 50% slower
522- CartesianWaypoint(Affine([0.2 , 0.0 , 0.0 ]), ReferenceType.Relative, RelativeDynamicsFactor(0.5 , 1.0 , 1.0 ))
523- ])
524-
525- # Cartesian waypoints also permit to specify target velocities
526- m_cp5 = CartesianWaypointMotion([
527- CartesianWaypoint(Affine([0.5 , - 0.2 , 0.3 ], quat)),
528- CartesianWaypoint(
529- CartesianState(
530- pose = Affine([0.4 , - 0.1 , 0.3 ], quat),
531- velocity = Twist([- 0.01 , 0.01 , 0.0 ]))),
532- CartesianWaypoint(Affine([0.3 , 0.0 , 0.3 ], quat))
533- ])
545+ # Generalization of CartesianMotion that allows for multiple waypoints. The robot will stop at
546+ # each of these waypoints. If you want the robot to move continuously, you have to specify a
547+ # target velocity at every waypoint as shown in the example following this one.
548+ m_cp4 = CartesianWaypointMotion(
549+ [
550+ CartesianWaypoint(
551+ RobotPose(Affine([0.4 , - 0.2 , 0.3 ], quat), elbow_state = ElbowState(0.3 ))
552+ ),
553+ # The following waypoint is relative to the prior one and 50% slower
554+ CartesianWaypoint(
555+ Affine([0.2 , 0.0 , 0.0 ]),
556+ ReferenceType.Relative,
557+ RelativeDynamicsFactor(0.5 , 1.0 , 1.0 ),
558+ ),
559+ ]
560+ )
561+
562+ # Cartesian waypoints permit to specify target velocities
563+ m_cp5 = CartesianWaypointMotion(
564+ [
565+ CartesianWaypoint(Affine([0.5 , - 0.2 , 0.3 ], quat)),
566+ CartesianWaypoint(
567+ CartesianState(
568+ pose = Affine([0.4 , - 0.1 , 0.3 ], quat), velocity = Twist([- 0.01 , 0.01 , 0.0 ])
569+ )
570+ ),
571+ CartesianWaypoint(Affine([0.3 , 0.0 , 0.3 ], quat)),
572+ ]
573+ )
534574
535575# Stop the robot in cartesian position control mode.
536576m_cp6 = CartesianStopMotion()
@@ -541,22 +581,37 @@ m_cp6 = CartesianStopMotion()
541581``` python
542582from franky import *
543583
544- # A cartesian velocity motion with linear (first argument) and angular (second argument) components
584+ # A cartesian velocity motion with linear (first argument) and angular (second argument)
585+ # components
545586m_cv1 = CartesianVelocityMotion(Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]))
546587
547588# With target elbow velocity
548- m_cv2 = CartesianVelocityMotion(RobotVelocity(Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]), elbow_velocity = - 0.2 ))
549-
550- # Cartesian velocity motions also support multiple waypoints. Unlike in cartesian position control, a cartesian velocity
551- # waypoint is a target velocity to be reached. This particular example first accelerates the end-effector, holds the
552- # velocity for 1s, then # reverses direction for 2s, reverses direction again for 1s, and finally stops. It is important
553- # not to forget to stop # the robot at the end of such a sequence, as it will otherwise throw an error.
554- m_cv4 = CartesianVelocityWaypointMotion([
555- CartesianVelocityWaypoint(Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]), hold_target_duration = Duration(1000 )),
556- CartesianVelocityWaypoint(Twist([- 0.2 , 0.1 , - 0.1 ], [- 0.1 , 0.1 , - 0.2 ]), hold_target_duration = Duration(2000 )),
557- CartesianVelocityWaypoint(Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]), hold_target_duration = Duration(1000 )),
558- CartesianVelocityWaypoint(Twist()),
559- ])
589+ m_cv2 = CartesianVelocityMotion(
590+ RobotVelocity(Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]), elbow_velocity = - 0.2 )
591+ )
592+
593+ # Cartesian velocity motions also support multiple waypoints. Unlike in cartesian position
594+ # control, a cartesian velocity waypoint is a target velocity to be reached. This particular
595+ # example first accelerates the end-effector, holds the velocity for 1s, then reverses
596+ # direction for 2s, reverses direction again for 1s, and finally stops. It is important not to
597+ # forget to stop the robot at the end of such a sequence, as it will otherwise throw an error.
598+ m_cv4 = CartesianVelocityWaypointMotion(
599+ [
600+ CartesianVelocityWaypoint(
601+ Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]),
602+ hold_target_duration = Duration(1000 ),
603+ ),
604+ CartesianVelocityWaypoint(
605+ Twist([- 0.2 , 0.1 , - 0.1 ], [- 0.1 , 0.1 , - 0.2 ]),
606+ hold_target_duration = Duration(2000 ),
607+ ),
608+ CartesianVelocityWaypoint(
609+ Twist([0.2 , - 0.1 , 0.1 ], [0.1 , - 0.1 , 0.2 ]),
610+ hold_target_duration = Duration(1000 ),
611+ ),
612+ CartesianVelocityWaypoint(Twist()),
613+ ]
614+ )
560615
561616# Stop the robot in cartesian velocity control mode.
562617m_cv6 = CartesianVelocityStopMotion()
@@ -585,14 +640,15 @@ The real robot can be moved by applying a motion to the robot using `move`:
585640``` python
586641# Before moving the robot, set an appropriate dynamics factor. We start small:
587642robot.relative_dynamics_factor = 0.05
588- # or alternatively, to control the scaling of velocity, acceleration, and jerk limits separately:
643+ # or alternatively, to control the scaling of velocity, acceleration, and jerk limits
644+ # separately:
589645robot.relative_dynamics_factor = RelativeDynamicsFactor(0.05 , 0.1 , 0.15 )
590646# If these values are set too high, you will see discontinuity errors
591647
592648robot.move(m_jp1)
593649
594- # We can also set a relative dynamics factor in the move command. It will be multiplied with the other relative
595- # dynamics factors (robot and motion if present).
650+ # We can also set a relative dynamics factor in the move command. It will be multiplied with
651+ # the other relative dynamics factors (robot and motion if present).
596652robot.move(m_jp2, relative_dynamics_factor = 0.8 )
597653```
598654
@@ -602,7 +658,13 @@ All motions support callbacks, which will be invoked in every control step at 1k
602658Callbacks can be attached as follows:
603659
604660``` python
605- def cb (robot_state : RobotState, time_step : Duration, rel_time : Duration, abs_time : Duration, control_signal : JointPositions):
661+ def cb (
662+ robot_state : RobotState,
663+ time_step : Duration,
664+ rel_time : Duration,
665+ abs_time : Duration,
666+ control_signal : JointPositions,
667+ ):
606668 print (f " At time { abs_time} , the target joint positions were { control_signal.q} " )
607669
608670
@@ -627,9 +689,10 @@ from franky import CartesianMotion, Affine, ReferenceType, Measure, Reaction
627689
628690motion = CartesianMotion(Affine([0.0 , 0.0 , 0.1 ]), ReferenceType.Relative) # Move down 10cm
629691
630- # It is important that the reaction motion uses the same control mode as the original motion. Hence, we cannot register
631- # a JointMotion as a reaction motion to a CartesianMotion.
632- reaction_motion = CartesianMotion(Affine([0.0 , 0.0 , 0.01 ]), ReferenceType.Relative) # Move up for 1cm
692+ # It is important that the reaction motion uses the same control mode as the original motion.
693+ # Hence, we cannot register a JointMotion as a reaction motion to a CartesianMotion.
694+ # Move up for 1cm
695+ reaction_motion = CartesianMotion(Affine([0.0 , 0.0 , 0.01 ]), ReferenceType.Relative)
633696
634697# Trigger reaction if the Z force is greater than 30N
635698reaction = Reaction(Measure.FORCE_Z > 30.0 , reaction_motion)
@@ -692,7 +755,8 @@ them.
692755In C++ you can additionally use lambdas to define more complex behaviours:
693756
694757``` c++
695- auto motion = CartesianMotion(RobotPose(Affine({0.0, 0.0, 0.2}), 0.0), ReferenceType::Relative);
758+ auto motion = CartesianMotion(
759+ RobotPose (Affine({0.0, 0.0, 0.2}), 0.0), ReferenceType::Relative);
696760
697761// Stop motion if force is over 10N
698762auto stop_motion = StopMotion< franka::CartesianPose > ()
@@ -737,8 +801,8 @@ motion1 = CartesianMotion(Affine([0.2, 0.0, 0.0]), ReferenceType.Relative)
737801robot.move(motion1, asynchronous=True)
738802
739803time.sleep(0.5)
740- # Note that similar to reactions, when preempting active motions with new motions, the control mode cannot change.
741- # Hence, we cannot use, e.g., a JointMotion here.
804+ # Note that similar to reactions, when preempting active motions with new motions, the
805+ # control mode cannot change. Hence, we cannot use, e.g., a JointMotion here.
742806motion2 = CartesianMotion(Affine([0.2, 0.0, 0.0]), ReferenceType.Relative)
743807robot.move(motion2, asynchronous=True)
744808```
@@ -849,15 +913,16 @@ import franky
849913with franky.RobotWebSession(" 172.16.0.2" , " username" , " password" ) as robot_web_session:
850914 # First take control
851915 try :
852- # Try taking control. The session currently holding control has to release it in order for this session to gain
853- # control. In the web interface, a notification will show prompting the user to release control. If the other
854- # session is another franky.RobotWebSession, then the `release_control` method can be called on the other
916+ # Try taking control. The session currently holding control has to release it in order
917+ # for this session to gain control. In the web interface, a notification will show
918+ # prompting the user to release control. If the other session is another
919+ # franky.RobotWebSession, then the `release_control` method can be called on the other
855920 # session to release control.
856921 robot_web_session.take_control(wait_timeout = 10.0 )
857922 except franky.TakeControlTimeoutError:
858- # If nothing happens for 10s, we try to take control forcefully. This is particularly useful if the session
859- # holding control is dead. Taking control by force requires the user to manually push the blue button close to
860- # the robot's wrist.
923+ # If nothing happens for 10s, we try to take control forcefully. This is particularly
924+ # useful if the session holding control is dead. Taking control by force requires the
925+ # user to manually push the blue button close to the robot's wrist.
861926 robot_web_session.take_control(wait_timeout = 30.0 , force = True )
862927
863928 # Unlock the brakes
0 commit comments