<jupyter_start><jupyter_text>What is a robot? The robot is a machine that, independently of its exterior, is able to modify the environment in which it operates._Robotics_ is commonly defined as the science studying the _intelligent connection between perception and action_.https://www.federica.eu/l/introduction_to_robotics    <NAME>, <NAME>, <NAME>, <NAME>, Robotics: Modelling, Planning and Control, Springer, London, 2009, ISBN 978-1-84628-642-1      Basic robot componentsMost of the industrial robots have 6 basic components: manipulatorend-effectoractuatorssensorscontrollerteach pendant  Manipulator* A collection of links (mechanical linkages) connected by joints* Generally, joints are either revolute (rotary) or prismatic (linear)* Each joint has joint axis along which the particular link either rotates or slides* Every joint axis identifies a degree of freedom (DOF) End-effector* The part that is connected to the last joint of a manipulator* The _hand_ or _tool_ which performs the required task depending on the fabrication process* If actuated (e.g. gripper gripping) the end-effector can be controlled by the robots controller via I/O. Actuators* Used to move the elements of the manipulators* Each actuator is driven by a controller* Can be electric motors (servomotor, stepper motor), pneumatic cylinders or hydraulic cylinders Sensors* Internal sensors: check joint position, temperature, force, ...* External sensors: percept environment     Controller* Brain of the robot* Receives the data from the computer, controls the motions of the actuators and coordintes the motions with the sensory feedback information. Teach pendant* A control box for programming the motions of a robot* Teach pendants are typically handheld devices and may be wired or wireless  Robot coordinate framesWorld coordinate frame (WCF)Robot coordinate frame (RCF)Tool0 coordinate frame (T0CF)Tool coordinate frame (TCF)Object coordinate frame (OCF)  Robot workspaceWorkspace is the envelope the robot can reach. anthropomorphic manipulatorSCARA manipulatorcartesian manipulator Gonzalo start  Robot programming 🤖* Offline control* Online real-time control* Online non-real-time control  Robot programming 🤖 Traditional (offline) programmingVendor-proprietary language and tools:   Vendor   Language   SoftwareABBStaubliURKUKARAPIDVAL3URScriptKRLABB RobotStudioStaubli Robotics SuiteURSimKUKA WorkVisual  Robot programming 🤖Control robots directly from within parametric design environment (Grasshopper, Dynamo, ...)HALTACOKUKA|prcScorpionvisoseMachina  Robot programming 🤖 Online programming<jupyter_code>TODO ### ROS

TODO: example online control
from IPython.display import HTML
HTML('<h2>Online non-real-time control</h2><br /><iframe src="https://player.vimeo.com/video/56125747?title=0&byline=0&portrait=0" width="700" height="394" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe><p><a href="https://vimeo.com/56125747"></p>')<jupyter_output><empty_output><jupyter_text>Forward and inverse kinematics  Robot singularitiesAn industrial robot can be controlled in two spaces: joint space and Cartesian space.* `MoveJ` – move the robot linear in joint space* `MoveL` or `MoveC` – move the robot linear/circular in cartesian space (ee-velocity)A robot singularity occurs if the robot moves in Cartesian space and the controller fails to calculate inverse kinematics (position and velocity). For `MoveL` you specify a desired pose for the end-effector AND a desired Cartesian path. To find the necessary joint positions along the desired Cartesian path, the robot controller must calculatethe inverse position and velocity kinematics of the robot. Singularities arise when this calculation fails(for example, division by zero or infinite angular velocity) and must therefore be avoided.Jogging a six-axis robotic arm in joint space, and the only time the robot will stop is when a joint hitsa limit or when there is a mechanical interference.<jupyter_code>from IPython.display import HTML
HTML('<iframe src="https://player.vimeo.com/video/20095999?title=0&byline=0&portrait=0" width="700" height="394" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe><p><a href="https://vimeo.com/20095999"></p>')
=> hint at ROS
ros uses only joint trajectories, so omitting singularities<jupyter_output><empty_output><jupyter_text>Robot characteristics* payload* reach* precision* repeatability  Robot model  Kinematic modelA robotic arm is considered as a kinematic chain of rigid bodies (or links) connected by joints to provide constrained motion.These links are constrained by their connections to other links.All rigid body movements are rotations, translations, or combinations of the two.kinematics = subdomain of mechanics, contrary to dynamics it concerns laws of motion without considering forces   Kinematic chains In the kinematic model of a robot, the connection of different manipulator joints is known as link, and the integration of two or more links is called a joint. This kinematic model can be represented as a tree structure.The tree describes the kinematic chain, i.e., the connection of robotic links with joints, and theinter-dependendencies of these links.This tree structure plus the underlying geometric information can be defined in Unified Robot Description Format (URDF),which describes any robot. If the robot is mounted on external axes, these links and jointscan be added as well.<jupyter_code>TODO:

open kinematic chain: there is only one sequence of links connecting the two ends on the chain
    Closed kinematics: when a sequence of links forms a loop<jupyter_output><empty_output><jupyter_text>Unified Robot Description Format (URDF)  Part of ur5.urdf```xml                                                                                                                                      ```  Example UR5 URDF:https://github.com/ros-industrial/universal_robot/blob/kinetic-devel/ur_description/urdf/ur5.urdf.xacro<jupyter_code>"""Example: Create robot from URDF.
"""
import compas_fab
from compas.robots import RobotModel
from compas.robots import GithubPackageMeshLoader

from viewer import RobotArtist
from viewer import ThreeJsViewer

# repo, package, branch
r = 'ros-industrial/abb'
p = 'abb_irb6600_support'
b = 'kinetic-devel'

# download urdf and meshes from github
loader = GithubPackageMeshLoader(r, p, b)
urdf = loader.load_urdf('irb6640.urdf')

# create robot model from URDF
model = RobotModel.from_urdf_file(urdf)
model.load_geometry(loader)

# create robot artist
artist = RobotArtist(model)
artist
geo = artist.draw_visual()
viewer = ThreeJsViewer()
viewer.show(geometry=geo)<jupyter_output>C:\ProgramData\Anaconda3\lib\site-packages\traittypes\traittypes.py:101: UserWarning: Given trait value dtype "int32" does not match required type "float32". A coerced copy has been created.
  np.dtype(self.dtype).name))<jupyter_text>from compas_fab.rhino import RobotArtistfrom compas_fab.blender import RobotArtist  JointsThe joints are the elements in a robot which helps the links to travel in different kind of movements.The three major types of joints are:* Revolute: A hinge joint that rotates along the axis and has a limited range specified by the upper and lower limits.* Prismatic: A sliding joint that slides along the axis, and has a limited range specified by the upper and lower limits.* Fixed: Not really a joint because it cannot move, all degrees of freedom are locked.<jupyter_code>from compas.robots import Joint

print(Joint.REVOLUTE)
print(Joint.PRISMATIC)
print(Joint.FIXED)<jupyter_output>0
2
3<jupyter_text>Configuration<jupyter_code>"""Example: create robot configuration
"""
from math import pi
from compas_fab.robots import Configuration

values = [1.5, pi]
types = [Joint.PRISMATIC, Joint.REVOLUTE]

config = Configuration(values, types)
config = Configuration.from_revolute_values([pi/2, 0., 0., pi/2, pi, 0])
config = Configuration.from_prismatic_and_revolute_values([8.312], [pi/2, 0., 0., 0., 2*pi, 0.8])<jupyter_output><empty_output><jupyter_text>Building your own robot<jupyter_code>import math
from compas.geometry import Translation, Cylinder, Circle, Plane
from compas.robots import RobotModel, Joint
from compas_fab.robots import Configuration
from compas.datastructures import Mesh
from compas.geometry import Frame

from viewer import RobotArtist
from viewer import ThreeJsViewer

# create cylinder in yz plane
radius, length = 0.3, 5
cylinder = Cylinder(Circle(Plane([0, 0, 0], [1, 0, 0]), radius), length)
cylinder.transform(Translation([length / 2., 0, 0]))

# create robot
robot = RobotModel("robot")

# add first link to robot
link0 = robot.add_link("world")

# add second link to robot
mesh = Mesh.from_shape(cylinder)
link1 = robot.add_link("link1", visual_mesh=mesh, visual_color=(0.2, 0.5, 0.6))

# add the joint between the links
axis = (0, 0, 1)
origin = Frame.worldXY()
robot.add_joint("joint1", Joint.CONTINUOUS, link0, link1, origin, axis)

# add another link
mesh = Mesh.from_shape(cylinder) # create a copy!
link2 = robot.add_link("link2", visual_mesh=mesh, visual_color=(0.5, 0.6, 0.2))

# add another joint to 'glue' the link to the chain
origin = Frame((length, 0, 0), (1, 0, 0), (0, 1, 0))
robot.add_joint("joint2", Joint.CONTINUOUS, link1, link2, origin, axis)

artist = RobotArtist(robot)
geo = artist.draw_visual()
viewer = ThreeJsViewer()
camera_position=[0.0, 10.0, 20.0]
viewer.show(camera_position=camera_position, geometry=geo)<jupyter_output><empty_output><jupyter_text>Assignment Task 2Build your own robot with a certain number of links and joints. Then create a `Configuration` with the correct joint types and values.Then use the `RobotArtist` to `update` the robot with this configuration, so that it configures into the letter of your choice.You can use the `RobotArtist` from `compas_fab.ghpython` or `compas_fab.rhino`.  Configuration space  Forward and inverse kinematics   Forward kinematicsThe forward kinematics function calculates the pose of the robot’s end-effector from a configuration (configuration space to cartesian space).The simplest way to calculate forward kinematics is based on the properties defined by the robot model:<jupyter_code>from compas_fab.robots import Configuration
from compas_fab.robots.ur5 import Robot

robot = Robot(load_geometry=True)
configuration = Configuration.from_revolute_values([-2.238, -1.153, -2.174, 0.185, 0.667, 0.])

# Use forward kinematics of robot model
frame_RCF = robot.forward_kinematics(configuration, backend='model')
frame_WCF = robot.to_world_coords(frame_RCF)

print("Frame in the robot's coordinate system")
print(frame_RCF)
print("Frame in the world coordinate system")
print(frame_WCF)
from viewer import RobotArtist
from viewer import ThreeJsViewer

artist = RobotArtist(robot.model)
robot.artist = artist
robot.update(configuration)
geo = robot.draw_visual()
viewer = ThreeJsViewer()
camera_position=[1.0, 1.0, 1.0]
viewer.show(camera_position=camera_position, geometry=geo)<jupyter_output><empty_output><jupyter_text>QuestionFor robotic arms, `inverse` is the tricky operation, do you know for which kind of robots `forward` is the tricky one?  Backends : ROSin google slides..  Inverse kinematics<jupyter_code>from compas.geometry import Frame
from compas_fab.backends import RosClient
from compas_fab.robots import Configuration

frame = Frame([0.3, 0.1, 0.5], [1, 0, 0], [0, 1, 0])
start_configuration = Configuration.from_revolute_values([0] * 6)
group = "manipulator" # or robot.main_group_name

with RosClient() as client:
    robot.client = client
    config = robot.inverse_kinematics(frame, start_configuration, group)

print(config)

frame_RCF = robot.forward_kinematics(config, backend="model")
frame_WCF = robot.represent_frame_in_WCF(frame_RCF)
print(frame_WCF)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07772151898734177, 'fraction_numerical': 0.017890295358649787, 'mean_word_length': 5.598552338530067, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 53, 'https://': 6, 'lorem ipsum': 0, 'www.': 1, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '100588', 'license': 'MIT', 'n_tokens_mistral': 3608, 'n_tokens_neox': 3336, 'n_words': 1294, 'path': 'modules/module2/Robot.ipynb', 'repo_name': 'duchaoyu/ITA19', 'size': '11869'}