Skip to content
Snippets Groups Projects
Commit 253a6605 authored by Florian Beyer's avatar Florian Beyer
Browse files

added eval for the intermediate and position controller

parent 2a812498
No related branches found
No related tags found
No related merge requests found
Showing
with 272 additions and 37 deletions
import rospy
import sys
from moveit_commander import MoveGroupCommander, roscpp_initialize, roscpp_shutdown
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
def check_joint_positions_executed(target_positions):
# Initialize the MoveIt Commander
roscpp_initialize(sys.argv)
# Initialize the ROS-Node
rospy.init_node('position_controller_eval', anonymous=True)
# Initialize the MoveGroup
group = MoveGroupCommander('panda_arm')
# Check each target position
for i, target_position in enumerate(target_positions):
group.set_joint_value_target(target_position)
plan = group.go(wait=True)
group.stop()
group.clear_pose_targets()
current_joint_values = group.get_current_joint_values()
if not are_joint_positions_close(current_joint_values, target_position):
rospy.logwarn(f"Target position {i+1} not reached. Expected: {target_position}, but got: {current_joint_values}")
return False
rospy.sleep(1)
return True
def are_joint_positions_close(current, target, tolerance=0.1):
return all(abs(c - t) < tolerance for c, t in zip(current, target))
if __name__ == "__main__":
target_positions = [
[0.5, -0.5, 0.0, 0.0, 0.5, -0.5, 0.0],
[0.6, -0.6, 0.2, 0.2, 0.5, -0.5, 0.2],
[0.7, -0.2, -0.5, -0.2, -0.5, 0.7, -0.2]
]
check_joint_positions_executed(target_positions)
rospy.signal_shutdown("Evaluation completed")
roscpp_shutdown()
......@@ -4,7 +4,6 @@ import math
import rospy
from moveit_commander import MoveGroupCommander, roscpp_initialize, roscpp_shutdown
rospy.loginfo("exercise_4_1_evaluation")
roscpp_initialize(sys.argv)
......@@ -13,24 +12,29 @@ rospy.init_node('exercise_4_1_evaluation', anonymous=True)
group = MoveGroupCommander("panda_arm")
current_pose = group.get_current_pose().pose
expected_pose = [0.1, 0.1, 0.1, 0.0, 0.0, 0.0, 1.0]
error_margin = 0.01
expected_pose = [0.5, 0, 0.6, 1, 0.0, 0.0, 0.0]
error_margin = 0.1
current_values = [
current_pose.position.x,
current_pose.position.y,
current_pose.position.z,
current_pose.orientation.w,
current_pose.orientation.x,
current_pose.orientation.y,
current_pose.orientation.z,
current_pose.orientation.w
current_pose.orientation.z
]
for i, (current, expected) in enumerate(zip(current_values, expected_pose)):
if abs(current - expected) > error_margin:
roscpp_shutdown()
print("hello")
print("Orientation")
print(current_pose.orientation.x,
current_pose.orientation.y,
current_pose.orientation.z,
current_pose.orientation.w)
print("false, Pose component {} is not in the correct position".format(i+1))
sys.exit(0)
......
print("TODO: WRITE EVALUATION SCRIPT")
\ No newline at end of file
import math
import os
import importlib.util
from geometry_msgs.msg import Pose, Point, Quaternion
# Dynamically import waypoints module
waypoints_path = None
for root, dirs, files in os.walk('/'):
if 'converted.py' in files:
waypoints_path = os.path.join(root, 'converted.py')
break
if waypoints_path:
spec = importlib.util.spec_from_file_location('waypoints', waypoints_path)
waypoints_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(waypoints_module)
waypoints = waypoints_module.waypoints
else:
raise FileNotFoundError("The converted.py file was not found in the file system")
print("Waypoints:")
print(waypoints)
sol = [0.4, 0.2, 0.7, -1.0, 0.4, 0.0, 0.0]
pose1 = Pose(
position=Point(sol[0] + 0.1, sol[1], sol[2]),
orientation=Quaternion(sol[3], sol[4], sol[5], sol[6])
)
pose2 = Pose(
position=Point(sol[0] + 0.1, sol[1] + 0.2, sol[2]),
orientation=Quaternion(sol[3], sol[4], sol[5], sol[6])
)
pose3 = Pose(
position=Point(sol[0] + 0.1, sol[1] + 0.2, sol[2] + 0.1),
orientation=Quaternion(sol[3], sol[4], sol[5], sol[6])
)
target_waypoints = [pose1, pose2, pose3]
def is_close(p1, p2, tolerance=0.2):
return abs(p1.x - p2.x) <= tolerance and abs(p1.y - p2.y) <= tolerance and abs(p1.z - p2.z) <= tolerance
def quaternion_is_close(q1, q2, tolerance=0.1):
return (abs(q1.x - q2.x) <= tolerance and abs(q1.y - q2.y) <= tolerance and
abs(q1.z - q2.z) <= tolerance and abs(q1.w - q2.w) <= tolerance)
for i in range(3):
if (is_close(target_waypoints[i].position, waypoints[i].position) and
quaternion_is_close(target_waypoints[i].orientation, waypoints[i].orientation)):
print(f"Pose {i+1} matches.")
else:
print(f"Pose {i+1} does not match.")
\ No newline at end of file
%% Cell type:markdown id: tags:
# Educational Plattform Panda Robot
Author: uninh, uqwfa, ultck
%% Cell type:markdown id: tags:
## Controller_Task
### Position_Controller
In this task, you will learn...
>
> - how to work with a position controller to move the joints of a robot to specific positions.
> - how to start the position controller
> - how to create a message for the position controller
> - how to send the target position and check the movement
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
import rospy
from controller_manager_msgs.srv import LoadController, SwitchController, SwitchControllerRequest, UnloadController
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
from moveit_commander import roscpp_shutdown
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
The following code cell loads and activates a new controller in ROS after a potentially conflicting controller has been unloaded.
First, the new controller and the conflicting controller are defined.
Now the conflicting controller will load. First, the /controller_manager/switch_controller service is used to stop the controller. Then the /controller_manager service/unload_controller is used to completely unload. If any of the service calls fail, an error message is issued.
It then waits for the /controller_manager/load_controller service to load the new controller. The service is called and it checks that the controller has been loaded successfully.
Finally, wait for the /controller_manager/switch_controller service to activate the new controller. The service is called and it checks that the controller has been successfully started.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
controller_name = 'position_joint_trajectory_controller'
conflicting_controller = 'effort_joint_trajectory_controller'
# Service for unloading the conflicting controller
rospy.wait_for_service('/controller_manager/switch_controller')
try:
switch_controller = rospy.ServiceProxy('/controller_manager/switch_controller', SwitchController)
req = SwitchControllerRequest()
req.stop_controllers = [conflicting_controller]
req.strictness = SwitchControllerRequest.BEST_EFFORT
response = switch_controller(req)
assert response.ok, "Controller konnte nicht entladen werden."
except rospy.ServiceException as e:
rospy.logerr("Service call failed: %s" % e)
rospy.wait_for_service('/controller_manager/unload_controller')
try:
unload_srv = rospy.ServiceProxy('/controller_manager/unload_controller', UnloadController)
unload_resp = unload_srv(conflicting_controller)
assert unload_resp.ok, "Controller konnte nicht entladen werden."
except rospy.ServiceException as e:
rospy.logerr("Service call failed: %s" % e)
# Service for loading the controller
rospy.wait_for_service('/controller_manager/load_controller')
load_service = rospy.ServiceProxy('/controller_manager/load_controller', LoadController)
response = load_service(controller_name)
assert response.ok, "Controller konnte nicht geladen werden."
# Sevice for switching the controller
rospy.wait_for_service('/controller_manager/switch_controller')
switch_service = rospy.ServiceProxy('/controller_manager/switch_controller', SwitchController)
switch_req = SwitchControllerRequest()
switch_req.start_controllers = [controller_name]
switch_req.strictness = SwitchControllerRequest.BEST_EFFORT
response = switch_service(switch_req)
assert response.ok, "Controller konnte nicht gestartet werden."
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Now the ROS node is initialized, a publisher is created for the command topic and waited until the publisher is created.
The publisher sends messages of the type JointTrajectory to the topic /position_joint_trajectory_controller/command. The parameter queue_size=10 sets the size of the message queue. This means that up to 10 messages are held in the queue before old messages are discarded.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Initialisiere ROS
rospy.init_node('position_control', anonymous=True)
# Publisher für das Command-Topic
pub = rospy.Publisher('/position_joint_trajectory_controller/command', JointTrajectory, queue_size=10)
# Warte, bis der Publisher bereit ist
rospy.sleep(1)
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
The position controller receives messages of the type trajectory_msgs/JointTrajectory.
This message contains joint_names, a list of the joints to be controlled, and points, a list of positions to control the joints.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Erstelle die Nachricht
traj_msg = JointTrajectory()
traj_msg.joint_names = ['panda_joint1', 'panda_joint2', 'panda_joint3', 'panda_joint4', 'panda_joint5', 'panda_joint6', 'panda_joint7']
# Definiere die Zielpositionen
point = JointTrajectoryPoint()
# Hier wird die Zielpositionen (in Radiant) für jedes Gelenk als eine Liste hinzugefügt
point.positions = [0.5, -0.5, 0.0, 0.0, 0.5, -0.5, 0.0]
# Nun wird die Zeit festgelegt, bis die Bewegung abgeschlossen sein soll
point.time_from_start = rospy.Duration(2.0)
# Zuletzt wird der Punkt zur Trajektorie hinzugefügt
traj_msg.points.append(point)
# und die Nachricht wird gesendet
pub.publish(traj_msg)
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
### Task:
Now you have to define two more target positions yourself. We reach the first target position before the robot moves to the second target position.
#### What you need to do:
##### Create the message:
Start by creating a JointTrajectory message.
Next, define the joints you want to move by entering the names in the joint_names list of the JointTrajectory message.
##### Add target positions:
Create a JointTrajectoryPoint to define the target positions for each joint and complete the following fields:
- positions: The target positions in Radiant (e.g. [0.5, -0.5, 0.0])
- time_from_start: The time it takes for the robot to reach the positions
Now add the point to the trajectory and do the same for the second point as for the first.
##### Send the message:
Post the message to the topic /position_joint_trajectory_controller/command.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
# Nachricht erstellen
traj_msg = JointTrajectory()
traj_msg.joint_names = ['panda_joint1', 'panda_joint2', 'panda_joint3', 'panda_joint4', 'panda_joint5', 'panda_joint6', 'panda_joint7']
# Erste Zielposition definieren
point1 = JointTrajectoryPoint()
point1.positions = [0.6, -0.6, 0.2, 0.2, 0.5, -0.5, 0.2]
point1.time_from_start = rospy.Duration(2.0)
traj_msg.points.append(point1)
# Zweite Zielposition definieren
point2 = JointTrajectoryPoint()
point2.positions = [0.7, -0.2, -0.5, -0.2, -0.5, 0.7, -0.2]
point2.time_from_start = rospy.Duration(5.0)
traj_msg.points.append(point2)
# Nachricht senden
pub.publish(traj_msg)
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
### Cleaning up and quitting the ROS node
At the end, the ROS node is shut down and the resources are released.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Shutdown the ROS node
rospy.signal_shutdown("Task completed")
roscpp_shutdown()
##### DO NOT CHANGE #####
```
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Wechsel zurück zum effort_joint_trajectory_controller
rospy.wait_for_service('/controller_manager/switch_controller')
try:
switch_controller = rospy.ServiceProxy('/controller_manager/switch_controller', SwitchController)
req = SwitchControllerRequest()
req.stop_controllers = ['position_joint_trajectory_controller']
req.start_controllers = ['effort_joint_trajectory_controller']
req.strictness = SwitchControllerRequest.BEST_EFFORT
response = switch_controller(req)
assert response.ok, "Controller konnte nicht gewechselt werden."
except rospy.ServiceException as e:
rospy.logerr("Service call failed: %s" % e)
##### DO NOT CHANGE #####
```
......
%% Cell type:markdown id: tags:
# Educational Plattform Franka Emika Panda robot arm
Author: uninh, uqwfa, ultck
%% Cell type:markdown id: tags:
## MoveIt Basics
### Task 3
---
>
The goal of this notebook is:
- understand what planning algorithms are
- what types there are
- how to implement them in code
>
---
%% Cell type:markdown id: tags:
### Introduction planning algorithms
### Introduction planning algorithms
#### What are planning algorithms?
- Methods used to calculate a sequence of movements or actions that the robot must perform in order to reach a target (e.g. a final position)
- help solve complex problems, such as overcoming obstacles, precise reaching of endpoint
- ensure that movement is efficient, collision-free and physically possible
- Help solve complex problems, such as overcoming obstacles, precise reaching of endpoint
- Ensure that movement is efficient, collision-free, and physically possible
#### What types of planning algorithms are there ?
#### What types of planning algorithms are there?
Sampling-based algorithms
##### Sampling-based algorithms
- create random sample to find way from start to finish
- Examples: RTT, RTTConnect
- Create random samples to find a way from start to finish
- Examples: RRT, RRTConnect
##### Search-based algorithms
- use grids or graphs to calculate shortest path
- Use grids or graphs to calculate the shortest path
- Example: A*
##### Optimization based algorithms
##### Optimization-based algorithms
- improve existing paths through optimization criteria, such as efficiency
- Improve existing paths through optimization criteria, such as efficiency
- Examples: CHOMP, STOMP
Important:
When using a planning algorithm, it is important to ensure that it is defined in the MoveIt configuration file (.yaml).
%% Cell type:markdown id: tags:
First, we import all the important modules for this task. You already know Rospy and sys from previous tasks.
The MoveGroupCommander allows interaction with MoveIt! via the Python API, so you can then control the robot arm, plan and execute movements.
roscpp_initialize and roscpp_shutdown allow initialization and termination of communication with ROS from the MoveIt API.
geometry_msgs.msg is used to provide standardized message formats such as position (Point) and orientation (Quaternion) of the robotic arm.
The pose class now represents a combination of position (point) and orientation (quaternion) to describe a pose (position and orientation) in 3D space.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
import rospy
import sys
from moveit_commander import MoveGroupCommander, roscpp_initialize, roscpp_shutdown
from geometry_msgs.msg import Pose
# Initialize the MoveIt Commander
roscpp_initialize(sys.argv)
# Initialize the ROS Node
rospy.init_node('task3', anonymous=True)
# Initialize MoveGroupCommander
group = MoveGroupCommander('panda_arm')
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Next, we want to select the planning algorithm we want to use to calculate the motion. To do this, we use the set_planner_id method to select the specific planning algorithm.
Next, your task is to select the planning algorithm with the ID RRTConnectkConfigDefault for the previously defined MoveGroupCommander instance.
Next, your task is to select the planning algorithm with the ID geometric::RRTConnect for the previously defined MoveGroupCommander instance.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
# Select the desired planning algorithm
group.set_planner_id("RRTConnectkConfigDefault")
group.set_planner_id("RRTConnect")
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
Here, the current pose of the robot's end effector is retrieved and stored in the variable current_pose.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
current_pose = group.get_current_pose().pose
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Next, we define the target position of the end effector. The end effector is the part of a robot arm that is attached to the extreme end of the kinematic chain and directly interacts with the environment. It is the functional "tool holder" of the robot, whose job it is to perform specific actions. These actions depend heavily on the task of the robot.
The pose class provides a data structure that describes the spatial position and orientation of an object in 3D space. The position contains the x-, y- and z-coordinates, which in the following code defines the target position of the end effector in Cartesian space (in meters).
The orientation is represented by a quaternion, where the w component describes the rotation around the axis.
Your task now is to define a new pose, which has the point (0.1, 0.1, 0.1) and the orientation 1 (neutral).
Your task now is to define a new pose, which adds 0.2 to the current x - koordinate, and does not change the y - and z - koordinate and the orientation w 1.
Procedure:
- 1. Create a new object of type Pose
- 2. Set the variables for the position
- 3. Set the required variables for the orientation
Finally, add the target pose to the planning queue using the set_pose_target method of the MoveGroupCommander instance.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
target_pose = Pose()
target_pose.position.x = 0.1
target_pose.position.y = 0.1
target_pose.position.z = 0.1
target_pose.position.x = current_pose.position.x + 0.2
target_pose.position.y = current_pose.position.y
target_pose.position.z = current_pose.position.z
target_pose.orientation.w = 1.0
# add the target pose to the planning queue
group.set_pose_target(target_pose)
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
Now it's about planning and executing the movement of the robotic arm.
The group.go() method executes the planned movement of the robot based on the target pose that was previously set.
The wait=True argument means that further execution of the code is blocked (i.e. waits) until the movement is complete. Only after the movement is completed will the next command be executed.
The group.stop() method stops the movement of the robot immediately.
Even if the movement is already complete, this command ensures that no further movements or residual movements (e.g. by inertia or revival) take place.
The group.clear_pose_targets() method removes all pose targets previously defined for the robot.
This is very important because target positions that are not removed remain in the memory of the MoveIt object (group) and could be reused inadvertently in later move commands.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
##### YOUR CODE HERE #####
plan = group.go(wait=True)
group.stop()
group.clear_pose_targets()
##### DO NOT CHANGE #####
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
### Cleaning up and quitting the ROS node
At the end, the ROS node is shut down and the resources are released.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Shutdown the ROS node
rospy.signal_shutdown("Task completed")
roscpp_shutdown()
##### DO NOT CHANGE #####
```
......
%% Cell type:markdown id: tags:
# Educational Plattform Franka Emika Panda robot arm
Author: uninh, uqwfa, ultck
%% Cell type:markdown id: tags:
## MoveIt Intermediate
### Task 1
---
>
The goal of this notebook is :
- to move the robotic arm through a series of predetermined positions (waypoints) in Cartesian space
- how to plan movements that run along a complex trajectory
- how multiple positions can be defined, converted into a trajectory and finally executed
>
---
%% Cell type:markdown id: tags:
First, all the necessary packages and classes are imported. You already know these from the move_it_basics and move_it_objects tasks.
Then, as usual, we initialize the MoveIt Commander, create a ROS node and initialize the Move Group.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
import rospy
import sys
from moveit_commander import MoveGroupCommander, roscpp_initialize, roscpp_shutdown
from geometry_msgs.msg import Pose
# Initialize the MoveIt Commander
roscpp_initialize(sys.argv)
# Initialize the ROS-Node
rospy.init_node('move_it_intermediate', anonymous=True)
# Initialize the MoveGroup
group = MoveGroupCommander('panda_arm')
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
With group.get_current_pose() you query the current pose of the end effector in MoveIt. The method returns a PoseStamped-object, whose pose property contains the actual geometry (position and orientation).
So your task is to first create a variable current_pose and then store the current pose of the end effector in it.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
# Get the current pose of the end-effector
current_pose = group.get_current_pose().pose
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
Here a list of waypoints is initialized, in which all waypoints that the robot arm should run must be added later.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Define the waypoints the robot should move to
waypoints = []
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Now you want to define the first waypoint. So create a new object from the class pose.
For the first waypoint the robot arm should move 10 cm (0.1) along the X axis, whereby the y coordinate and z coordinate as well as the orientation should remain unchanged.
Add this waypunt at the end of the waypoints list.
Tip: Do this with the current pose
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
waypoint_1 = Pose()
waypoint_1.position.x = current_pose.position.x + 0.1
waypoint_1.position.y = current_pose.position.y
waypoint_1.position.z = current_pose.position.z
waypoint_1.orientation = current_pose.orientation
waypoints.append(waypoint_1)
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
Next, create a second waypoint, also of the pose type.
Now hold the X and Z positions from the first waypoint and shift the Y position by 0.2 (20 cm).
Again, the orientation should be taken from the current_pose.
Finally, add the new waypoint to the waypoints list.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
waypoint_2 = Pose()
waypoint_2.position.x = waypoint_1.position.x
waypoint_2.position.y = waypoint_1.position.y + 0.2
waypoint_2.position.z = waypoint_1.position.z
waypoint_2.orientation = current_pose.orientation
waypoint_2.orientation = waypoint_1.orientation
waypoints.append(waypoint_2)
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
The last waypoint should also be of the type Pose.
Hold the X and Y positions from the second waypoint and move the Z position 0.3 (30 cm) up.
Hold the X and Y positions from the second waypoint and move the Z position 0.1 (10 cm) up.
Take the orientation from the current_pose.
Add the new waypoint to the waypoints list.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
waypoint_3 = Pose()
waypoint_3.position.x = waypoint_2.position.x
waypoint_3.position.y = waypoint_2.position.y
waypoint_3.position.z = waypoint_2.position.z + 0.3
waypoint_3.position.z = waypoint_2.position.z + 0.1
waypoint_3.orientation = current_pose.orientation
waypoints.append(waypoint_3)
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
Now we define parameters that have the following meaning:
fraction = 0.0, sets the initial value of the calculated path portion to 0,
max_attempts = 100, sets the maximum number of attempts to calculate the path,
attempts = 0, counts the number of attempts.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Compute the Cartesian path
fraction = 0.0
max_attempts = 100
attempts = 0
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Create a loop that runs as long as the calculated fraction is less than 1.0 and the number of attempts is less than max_attempts.
Within the loop, calculate the Cartesian path based on the specified waypoints. Use 0.01 as the step distance of the end effector and 0.0 as the jump threshold. The method returns a plan of motion and the calculated path fraction.
Don't forget to increase the number of attempts by 1 at the end of the loop.
%% Cell type:code id: tags:
```
##### YOUR CODE HERE #####
while fraction < 1.0 and attempts < max_attempts:
(plan, fraction) = group.compute_cartesian_path(waypoints, 0.01, 0.0) # Plan the trajectory
attempts += 1
(plan, fraction) = group.compute_cartesian_path(waypoints, 0.01, 0.0) # Plan the trajectory
##### YOUR CODE HERE #####
```
%% Cell type:markdown id: tags:
The executed method now executes the created plan.
### Execute the planned path
Now we will execute the planned path.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
if fraction == 1.0:
group.execute(plan, wait=True)
else:
rospy.logwarn(f"Failed to compute a complete path after {attempts} attempts.")
# Execute the planned path
group.execute(plan, wait=True)
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
### Cleaning up and quitting the ROS node
At the end, the ROS node is shut down and the resources are released.
%% Cell type:code id: tags:
```
##### DO NOT CHANGE #####
# Shutdown the ROS node
rospy.signal_shutdown("Task completed")
roscpp_shutdown()
##### DO NOT CHANGE #####
```
......
%% Cell type:markdown id: tags:
# Educational Plattform Franka Emika Panda robot arm
Author: uninh, uqwfa, ultck
%% Cell type:markdown id: tags:
## MoveIt Basics
### Task 3
---
>
The goal of this notebook is:
- understand what planning algorithms are
- what types there are
- how to implement them in code
>
---
%% Cell type:markdown id: tags:
### Introduction planning algorithms
#### What are planning algorithms?
- Methods used to calculate a sequence of movements or actions that the robot must perform in order to reach a target (e.g. a final position)
- help solve complex problems, such as overcoming obstacles, precise reaching of endpoint
- ensure that movement is efficient, collision-free and physically possible
#### What types of planning algorithms are there ?
Sampling-based algorithms
- create random sample to find way from start to finish
- Examples: RTT, RTTConnect
##### Search-based algorithms
- use grids or graphs to calculate shortest path
- Example: A*
##### Optimization based algorithms
- improve existing paths through optimization criteria, such as efficiency
- Examples: CHOMP, STOMP
%% Cell type:markdown id: tags:
First, we import all the important modules for this task. You already know Rospy and sys from previous tasks.
The MoveGroupCommander allows interaction with MoveIt! via the Python API, so you can then control the robot arm, plan and execute movements.
roscpp_initialize and roscpp_shutdown allow initialization and termination of communication with ROS from the MoveIt API.
geometry_msgs.msg is used to provide standardized message formats such as position(pose) and orientation (point) of the robotic arm.
%% Cell type:code id: tags:task_cell_1
```
##### DO NOT CHANGE #####
import rospy
import sys
from moveit_commander import MoveGroupCommander, roscpp_initialize, roscpp_shutdown
from geometry_msgs.msg import Pose
# Initialize the MoveIt Commander
roscpp_initialize(sys.argv)
# Initialize the ROS Node
rospy.init_node('exercise_4_1', anonymous=True)
# Initialize MoveGroupCommander
group = MoveGroupCommander('panda_arm')
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Next, we want to select the planning algorithm we want to use to calculate the motion. To do this, we use the set_planner_id method to select the specific planning algorithm.
%% Cell type:code id: tags:task_cell_2,solution_removed_cell
```
##### YOUR CODE HERE #####
raise NotImplementedError()
```
%% Cell type:code id: tags:solution_cell
```
##############################################################\n#### THIS IS A SOLUTION CELL. IT WILL NOT EXECUTE. ####\n#### YOU CAN RUN THE SOLUTION DIRECTLY WITHIN THE PLUGIN. ####\n#### USE THIS CELL AS INSPIRATION FOR YOUR OWN CODE. ####\n##############################################################
## ↓↓↓↓ SOLUTION CODE HERE ↓↓↓↓ ##
# Select the desired planning algorithm
group.set_planner_id("RRTConnectkConfigDefault")
## ↑↑↑↑ SOLUTION CODE HERE ↑↑↑↑ ##
```
%% Cell type:markdown id: tags:
Next, we define the target position of the end effector. The end effector is the part of a robot arm that is attached to the extreme end of the kinematic chain and directly interacts with the environment. It is the functional "tool holder" of the robot, whose job it is to perform specific actions. These actions depend heavily on the task of the robot.
The pose class provides a data structure that describes the spatial position and orientation of an object in 3D space. The position contains the x-, y- and z-coordinates, which in the following code defines the target position of the end effector in Cartesian space (in meters).
The orientation w describes the orientation, which is used for orientation in 3D space.
A w=cos(θ/2) that is less than 1 indicates that a rotation is taking place.
The rotation angle θ can be calculated via arccos(w)⋆2.
w should always be in the range [−1.1] because it is related to cos(θ/2). Values outside this range result in invalid quaternions.
%% Cell type:code id: tags:task_cell_3,solution_removed_cell
```
##### YOUR CODE HERE #####
raise NotImplementedError()
```
%% Cell type:code id: tags:solution_cell
```
##############################################################\n#### THIS IS A SOLUTION CELL. IT WILL NOT EXECUTE. ####\n#### YOU CAN RUN THE SOLUTION DIRECTLY WITHIN THE PLUGIN. ####\n#### USE THIS CELL AS INSPIRATION FOR YOUR OWN CODE. ####\n##############################################################
## ↓↓↓↓ SOLUTION CODE HERE ↓↓↓↓ ##
target_pose = Pose()
target_pose.position.x = 0.2
target_pose.position.y = 0.25
target_pose.position.z = 0.3
target_pose.orientation.w = 1.0
## ↑↑↑↑ SOLUTION CODE HERE ↑↑↑↑ ##
```
%% Cell type:markdown id: tags:
Now it's about planning and executing the movement of the robotic arm.
The group.go() method executes the planned movement of the robot based on the target pose that was previously set.
The wait=True argument means that further execution of the code is blocked (i.e. waits) until the movement is complete. Only after the movement is completed will the next command be executed.
The group.stop() method stops the movement of the robot immediately.
Even if the movement is already complete, this command ensures that no further movements or residual movements (e.g. by inertia or revival) take place.
The group.clear_pose_targets() method removes all pose targets previously defined for the robot.
This is very important because target positions that are not removed remain in the memory of the MoveIt object (group) and could be reused inadvertently in later move commands.
%% Cell type:code id: tags:task_cell_4
```
##### DO NOT CHANGE #####
plan = group.go(wait=True)
group.stop()
group.clear_pose_targets()
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
### Cleaning up and quitting the ROS node
At the end, the ROS node is shut down and the resources are released.
%% Cell type:code id: tags:task_cell_5
```
##### DO NOT CHANGE #####
# Shutdown the ROS node
rospy.signal_shutdown("Task completed")
roscpp_shutdown()
##### DO NOT CHANGE #####
```
......
%% Cell type:markdown id: tags:
# Educational Plattform Franka Emika Panda robot arm
Author: uninh, uqwfa, ultck
%% Cell type:markdown id: tags:
## MoveIt Basics
### Task 4
---
>
The goal of this notebook is:
- query and interpret the status of the Franka Emika Panda robotic arm.
- check the current state of the robot (positions, orientations, joint angle) and understand how to access feedback during or after a movement.
>
---
%% Cell type:markdown id: tags:
First, we import all the important modules for this task. You already know Rospy and sys from previous tasks.
The MoveGroupCommander allows interaction with MoveIt! via the Python API, so you can then control the robot arm, plan and execute movements.
roscpp_initialize and roscpp_shutdown allow initialization and termination of communication with ROS from the MoveIt API.
%% Cell type:code id: tags:task_cell_1
```
##### DO NOT CHANGE #####
import rospy
import sys
from moveit_commander import MoveGroupCommander, roscpp_initialize, roscpp_shutdown
# Initialize the MoveIt Commander
roscpp_initialize(sys.argv)
# Initialize the ROS Node
rospy.init_node('exercise_4_2', anonymous=True)
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
Now the MoveGroup for the robot arm `panda_arm` is initialized.
In addition, planning parameters such as the planning algorithm and the number of planning attempts are defined.
%% Cell type:code id: tags:task_cell_2
```
##### DO NOT CHANGE #####
# Initialize the MoveGroup
group = MoveGroupCommander('panda_arm')
# Set the planner ID to 'RRTConnectkConfigDefault'
group.set_planner_id("RRTConnectkConfigDefault")
# Set the number of planning attempts to 10
group.set_num_planning_attempts(10)
##### DO NOT CHANGE #####
```
%% Cell type:markdown id: tags:
### Query of current joint angles
Next, the current joint angles of the robot arm are queried and output in the log. The MoveGroupCommander class provides the get_current_joint_values() method.
This harvests the current values of the joint angles and returns them as a list. The i-th entry in the list contains the angle of the i-th joint of the robot arm.
%% Cell type:code id: tags:task_cell_3,solution_removed_cell
```
##### YOUR CODE HERE #####
raise NotImplementedError()
```
%% Cell type:code id: tags:solution_cell
```
##############################################################\n#### THIS IS A SOLUTION CELL. IT WILL NOT EXECUTE. ####\n#### YOU CAN RUN THE SOLUTION DIRECTLY WITHIN THE PLUGIN. ####\n#### USE THIS CELL AS INSPIRATION FOR YOUR OWN CODE. ####\n##############################################################
## ↓↓↓↓ SOLUTION CODE HERE ↓↓↓↓ ##
# Query the current joint values
joint_values = group.get_current_joint_values()
rospy.loginfo("Current Joint Values: ")
for i, joint in enumerate(joint_values):
rospy.loginfo(f"Joint {i+1}: {joint:.2f} rad")
## ↑↑↑↑ SOLUTION CODE HERE ↑↑↑↑ ##
```
%% Cell type:markdown id: tags:
### Query the current end effector position
In the next step, the current pose of the end effector is queried and output in the log. The MoveGroupCommander class provides the get_current_pose() method. This method is used to determine the position and orientation of the end effector's space relative to a defined frame of reference.
The get_current_pose() method returns a message of the type PoseStamped. This contains the position as x -, y - and z - coordinates of the end effector, the orientation describes the orientation of the end effector given as quaternion (x, y, z, w) and much more information.
.pose is used to access the Pose attribute, which contains only the information about the position and orientation of the end effector. This attribute is of the Pose type.
%% Cell type:code id: tags:task_cell_4,solution_removed_cell
```
##### YOUR CODE HERE #####
raise NotImplementedError()
```
%% Cell type:code id: tags:solution_cell
```
##############################################################\n#### THIS IS A SOLUTION CELL. IT WILL NOT EXECUTE. ####\n#### YOU CAN RUN THE SOLUTION DIRECTLY WITHIN THE PLUGIN. ####\n#### USE THIS CELL AS INSPIRATION FOR YOUR OWN CODE. ####\n##############################################################
## ↓↓↓↓ SOLUTION CODE HERE ↓↓↓↓ ##
# Query the current end-effector pose
pose = group.get_current_pose().pose
rospy.loginfo(f"Endeffector Position: x={pose.position.x:.3f}, y={pose.position.y:.3f}, z={pose.position.z:.3f}")
rospy.loginfo(f"Endeffector Orientation: x={pose.orientation.x:.3f}, y={pose.orientation.y:.3f}, z={pose.orientation.z:.3f}, w={pose.orientation.w:.3f}")
## ↑↑↑↑ SOLUTION CODE HERE ↑↑↑↑ ##
```
%% Cell type:markdown id: tags:
The pose of the end effector is crucial to check the current condition of the robotic arm.
The position is needed to ensure that the end effector is in the right place in the room.
The orientation is essential when the end effector has to act in a certain orientation, e.g. to grasp an object correctly.
%% Cell type:markdown id: tags:
### Cleaning up and quitting the ROS node
At the end, the ROS node is shut down and the resources are released.
%% Cell type:code id: tags:task_cell_5
```
##### DO NOT CHANGE #####
# Shutdown the ROS node
rospy.signal_shutdown("Task completed")
roscpp_shutdown()
##### DO NOT CHANGE #####
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment