diff --git a/default/controllers/generic_inverse_kinematic/generic_inverse_kinematic.py b/default/controllers/generic_inverse_kinematic/generic_inverse_kinematic.py new file mode 100644 index 0000000..c31fdad --- /dev/null +++ b/default/controllers/generic_inverse_kinematic/generic_inverse_kinematic.py @@ -0,0 +1,100 @@ +# Copyright 2020 Simon Steinmann +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import numpy as np +from controller import Supervisor + +# import custom scripts. Located in the same directory as this controller +from get_relative_position import RelativePositions +from ik_module import inverseKinematics +from spawn_target import spawnTarget + +# ---------------------------------------------------------- +# CONFIGURATION +# ---------------------------------------------------------- +# how many simulationsteps before calculating the next IK solution. This +# is only relevant, if the target is constantly changing, as no new IK +# solution gets calculated, if the target did not change. +IKstepSize = 10 + +# Whether we want to want to solve for the Target rotation +useRotation = True + +# For some robots, the last link might be a motor (the last active_links value is False). +# If this is the case, you can add a translation vector, from the last motor join to the +# Toolslot. The uncommented example is for the UR10e +last_link_vector = None # [0, 0.12, 0] + + +# ---------------------------------------------------------- +# ---------------------------------------------------------- + +# Initialize the Webots Supervisor. +supervisor = Supervisor() +if not supervisor.getSupervisor(): + sys.exit('WARNING: Your robot is not a supervisor! Set the supervisor field to True and restart the controller.') + +timeStep = int(supervisor.getBasicTimeStep()) +# Initialize our inverse kinematics module +ik = inverseKinematics(supervisor, last_link_vector) + +# check if our world already has the TARGET node. If not, we spawn it. +target = supervisor.getFromDef('TARGET') +try: + target.getPosition() +except Exception as e: + print('No TARGET defined. Spawning TARGET sphere') + spawnTarget(supervisor) + +# Initialize the RelativePositions module +RelPos = RelativePositions(supervisor) + +# Initialize the arm motors and sensors. +n = supervisor.getNumberOfDevices() +motors = [] +sensors = [] +for i in range(n): + device = supervisor.getDeviceByIndex(i) + # print(device.getName(), ' - NodeType:', device.getNodeType()) + if device.getNodeType() == 54: + motors.append(device) + sensor = device.getPositionSensor() + try: + sensor.getName() + sensors.append(sensor) + sensor.enable(timeStep) + except Exception as e: + print('Rotational Motor: ' + device.getName() + ' has no Position Sensor') + + +target_pos_old = np.zeros((3)) +target_rot_old = np.zeros((3, 3)) +print('-------------------------------------------------------') +print('Move or rotate the TARGET sphere to move the arm...') +while supervisor.step(IKstepSize*timeStep) != -1: + # Get the target position relative to the arm + target_pos, target_rot = RelPos.get_pos('TARGET') + # check if our TARGET position or rotation has changed. If not, skip ik calculations (computationally intensive) + if not np.array_equal(target_pos, target_pos_old) or not np.array_equal(target_rot, target_rot_old): + # Call the ik_module to compute the inverse kinematics of the arm. + if useRotation: + ikResults = ik.get_ik(target_pos, target_rot) + else: + ikResults = ik.get_ik(target_pos) + # set the motor positions to the calculated ik solution + for i in range(len(motors)): + motors[i].setPosition(ikResults[i + 1]) + target_pos_old = target_pos + target_rot_old = target_rot diff --git a/default/controllers/generic_inverse_kinematic/get_relative_position.py b/default/controllers/generic_inverse_kinematic/get_relative_position.py new file mode 100644 index 0000000..4ee9508 --- /dev/null +++ b/default/controllers/generic_inverse_kinematic/get_relative_position.py @@ -0,0 +1,39 @@ +import numpy as np + +class RelativePositions(): + def __init__(self, Supervisor): + self.robot = Supervisor + + def get_pos(self, DEF_target, DEF_base=None): + target = self.robot.getFromDef(DEF_target) + if DEF_base is None: + base = self.robot.getSelf() + else: + base = self.robot.getFromDef(DEF_base) + + # Get the transposed rotation matrix of the base, so we can calculate poses of + # everything relative to it. + # Get orientation of the Node we want as our new reference frame and turn it into + # a numpy array. Returns 1-dim list of len=9. + rot_base = np.array(base.getOrientation()) + # reshape into a 3x3 rotation matrix + rot_base = rot_base.reshape(3, 3) + # Transpose the matrix, because we need world relative to the base, not the + # base relative to world. + rot_base = np.transpose(rot_base) + # Get the translation between the base and the world (basically where the origin + # of our new relative frame is). + # No need to use the reverse vector, as we will subtract instead of add it later. + pos_base = np.array(base.getPosition()) + + + # target position relative to world. + target_pos_world = np.array(target.getPosition()) + # Calculate the relative translation between the target and the base. + target_pos_world = np.subtract(target_pos_world, pos_base) + # Matrix multiplication with rotation matrix: target posistion relative to base. + target_pos_base = np.dot(rot_base, target_pos_world) + + # Calculate the orientation of the target, relative to the base, all in one line. + target_rot_base = np.dot(rot_base, np.array(target.getOrientation()).reshape(3, 3)) + return target_pos_base, target_rot_base \ No newline at end of file diff --git a/default/controllers/generic_inverse_kinematic/ik_module.py b/default/controllers/generic_inverse_kinematic/ik_module.py new file mode 100644 index 0000000..2c3699d --- /dev/null +++ b/default/controllers/generic_inverse_kinematic/ik_module.py @@ -0,0 +1,171 @@ +# Copyright 2020 Simon Steinmann +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import sys +import tempfile +import numpy as np + +try: + from scipy.spatial.transform import Rotation as R +except ImportError: + sys.exit('The "scipy" Python module is not installed. ' + 'To run this sample, please upgrade "pip" and install scipy with this command: "pip install scipy"') + +try: + import ikpy +except ImportError: + sys.exit('The "ikpy" Python module is not installed. ' + 'To run this sample, please upgrade "pip" and install ikpy with this command: "pip install ikpy"') + +if ikpy.__version__[0] < '3': + sys.exit('The "ikpy" Python module version is too old. ' + 'Please upgrade "ikpy" Python module to version "3.0" or newer with this command: "pip install --upgrade ikpy"') + +class inverseKinematics(): + def __init__(self, supervisor, last_link_vector=None): + # Initialize the Webots Supervisor. + self.supervisor = supervisor + self.timeStep = int(self.supervisor.getBasicTimeStep()) + + # Get names for the arm's motors and sensors. Needed for correct armChain configuration + n = self.supervisor.getNumberOfDevices() + self.motor_names = [] + self.sensor_names = [] + for i in range(n): + device = self.supervisor.getDeviceByIndex(i) + print(device.getName() , ' - NodeType = ' , device.getNodeType()) + if device.getNodeType() == 54: + sensor = device.getPositionSensor() + self.motor_names.append(device.getName()) + try: + self.sensor_names.append(sensor.getName()) + except: + print('Rotational Motor: ' + device.getName() + ' has no Position Sensor') + + + # Create the arm chain. + filename = None + # (uncomment next two lines, if you want to save a copy of the generated urdf file) + with open('filename.urdf', 'w') as file: + file.write(supervisor.getUrdf()) + with tempfile.NamedTemporaryFile(suffix='.urdf', delete=False) as file: + filename = file.name + file.write(self.supervisor.getUrdf().encode('utf-8')) + self.armChain = ikpy.chain.Chain.from_urdf_file(filename) #,last_link_vector=last_link_vector) + + + # make sure only links with a motor are active for IK calculations + active_links = [False] * len(self.armChain.links) + for i in range(len(self.armChain.links)): + link_name = self.armChain.links[i].name + active_links[i] = link_name in self.motor_names or link_name in self.sensor_names + if active_links[i]: + # ikpy includes the bounds as valid, In Webots they have to be less than the limit + new_lower = new_upper = None + if self.armChain.links[i].bounds[0] is not None: + new_lower = self.armChain.links[i].bounds[0] + 0.0000001 + if self.armChain.links[i].bounds[1] is not None: + new_upper = self.armChain.links[i].bounds[1] - 0.0000001 + self.armChain.links[i].bounds = (new_lower, new_upper) + self.last_active = i + if not any(active_links): + print('WARNING: could not identify which links are active. Setting all links to active by default.') + active_links = [True] * len(self.armChain.links) + self.armChain.active_links_mask = active_links + print(self.armChain) + + # ---------------------------------------------------------- + # Setup for correct orientation calculations + # ---------------------------------------------------------- + + # convert urdf rpy of last link into rotation matrix + try: + self.last_link_rot = R.from_euler('xyz', self.armChain.links[-1].orientation, degrees=False).as_matrix() + except: + print('Last link has no orientation. Parsing identity matrix (no rotation).') + self.last_link_rot = np.identity(3) + # get the translation vector of the last link + pos = self.armChain.links[-1].translation_vector + # calculate the final link vector using the dot product + self.final_link_vector = np.round(np.dot(self.last_link_rot,pos), 2) + print('---final vector: ',self.final_link_vector) + + # which column we have to take from the rotation matrix, for our toolSlot axis + try: + self.rot_index = self.final_link_vector.tolist().index(np.sum(self.final_link_vector)) + except: + self.rot_index=2 + print('WARNING!!!!!!!!!!!') + print('The vector of the last link is not an axis. Make sure the orientation and translation of this link are set up in a way, that either the x, y, or z axis points out of the toolSlot') + print('The IK solver will not solve correctly for orientation. The controller will now use the z-axis as the final link vector') + print('translation vector: ', pos) + print('final link vector:', self.final_link_vector) + + # define for ikpy, which axis we are using for the last link + self.toolSlot_axis = ['X', 'Y', 'Z'][self.rot_index] + self.direction = None + + + def rotateToolSlot(self, target_rot, ikResults): + # calculate the difference in Rotation around the axis between what we requested, and what we computed + fk = self.armChain.forward_kinematics(ikResults) + # rotation of the calculated ik solution + R_fk = fk[:3,:3] + # rotation to get from our ik rotation to our target rotation + R_new = np.dot(target_rot, R_fk) + # convert our rotation matrix into euler angles, so we know how much we have to change the last motor + r = R.from_matrix(R_new) + euler = r.as_euler('xyz', False) + # the first time we call this function we have to figure out in which direction we have to rotate + if self.direction is not None: + ikResults[6] = ikResults[self.last_active ] + self.direction * euler[self.rot_index] + else: + # here we test adding the delta-angle, if the resulting rotation - target rotation is not 0, we flip the direction + ikResults[6] = ikResults[self.last_active ] + 1 * euler[self.rot_index] + fk_check = self.armChain.forward_kinematics(ikResults) + if np.sum(np.abs(np.round(fk_check[:3, :3] - target_rot, 3))) == 0: + self.direction = 1 + else: + self.direction = -1 + return ikResults + + + def get_ik(self, target_pos, target_rot=None): + # check if a target_rot is requested (3x3 numpy array) + if np.sum(target_rot) == None: + # Call "ikpy" to compute the inverse kinematics of the arm WITHOUT orientation + return self.armChain.inverse_kinematics(target_pos) + else: + # get the rotation vector from the target_rot rotation matrix, depending on which axis points out of the toolSlot + rot_vector = [target_rot[0,self.rot_index],target_rot[1,self.rot_index],target_rot[2,self.rot_index]] + + # Call "ikpy" to compute the inverse kinematics of the arm WITH orientation + transMat = np.identity(4) + transMat[:3,:3] = target_rot + transMat[:3,3] = target_pos + ikResults = self.armChain.inverse_kinematics(target_pos, target_orientation=rot_vector, orientation_mode=self.toolSlot_axis) + # if ikResults is all zeros, we are dealing with a singularity + if sum(abs(ikResults)) < 0.001: + # tiny change in the orientation vector to avoid singularity + rot_vector_new = np.array(rot_vector) + np.full((1,3), 0.0000001) + ikResults = self.armChain.inverse_kinematics(target_pos, target_orientation=rot_vector_new, orientation_mode=self.toolSlot_axis) + # if the above step was not enough to avoid the singularity, we try to increase the deviation from the requested orientation step by step + n = -5 + while sum(abs(ikResults)) < 0.001: + print('Simple singulaity avoidance was not suffiecient. Trying larger deviation from requested orientation.') + print('Requested rotation vector: ' + str(rot_vector)) + rot_vector_new = np.array(rot_vector) + np.full((1,3), 1 * 10 ** n) + print('New rotation vector: ' + str(rot_vector_new)) + ikResults = self.armChain.inverse_kinematics(target_pos, target_orientation=rot_vector_new, orientation_mode=self.toolSlot_axis) + n += 1 + return self.rotateToolSlot(target_rot, ikResults) diff --git a/default/controllers/generic_inverse_kinematic/spawn_target.py b/default/controllers/generic_inverse_kinematic/spawn_target.py new file mode 100644 index 0000000..b474699 --- /dev/null +++ b/default/controllers/generic_inverse_kinematic/spawn_target.py @@ -0,0 +1,70 @@ +# Copyright 2020 Simon Steinmann +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import os +from shutil import copyfile + + +class spawnTarget(): + def __init__(self, supervisor): + targetSphereString = """ + DEF TARGET Solid { + translation 0.68 0.4 0.69 + rotation 0.5773519358512958 -0.5773469358518515 -0.5773519358512958 2.0944 + scale 0.4 0.4 0.4 + children [ + Shape { + appearance PBRAppearance { + baseColorMap ImageTexture { + url [ + "textures/target.png" + ] + } + roughnessMap ImageTexture { + url [ + "textures/target.png" + ] + } + metalnessMap ImageTexture { + url [ + "textures/target.png" + ] + } + emissiveColorMap ImageTexture { + url [ + "textures/target.png" + ] + } + textureTransform TextureTransform { + scale 2 1 + } + } + geometry Sphere { + radius 0.1 + subdivision 2 + } + } + ] + } + """ + # copy the target.png texture into our wold + controllerPath = os.path.dirname(os.path.abspath(__file__)) + worldPath = os.path.dirname(supervisor.getWorldPath()) + '/textures/' + if not os.path.exists(worldPath): + os.makedirs(worldPath) + copyfile(controllerPath + '/textures/target.png', worldPath + 'target.png') + + # spawn the TARGET node + root = supervisor.getRoot() + rootChildren = root.getField('children') + rootChildren.importMFNodeFromString(rootChildren.getCount(), targetSphereString) diff --git a/default/controllers/generic_inverse_kinematic/textures/target.png b/default/controllers/generic_inverse_kinematic/textures/target.png new file mode 100644 index 0000000..ae12666 Binary files /dev/null and b/default/controllers/generic_inverse_kinematic/textures/target.png differ diff --git a/robots/kuka/kr5/worlds/.kuka__kr5_inverse_kinematics.wbproj b/robots/kuka/kr5/worlds/.kuka__kr5_inverse_kinematics.wbproj new file mode 100644 index 0000000..0e0e0d3 --- /dev/null +++ b/robots/kuka/kr5/worlds/.kuka__kr5_inverse_kinematics.wbproj @@ -0,0 +1,9 @@ +Webots Project File version R2020b +perspectives: 000000ff00000000fd00000003000000000000021a000003d5fc0100000002fb0000001e00480074006d006c0052006f0062006f007400570069006e0064006f007700000000000000021a0000000000000000fb0000001a0044006f00630075006d0065006e0074006100740069006f006e0000000000ffffffff0000006900ffffff000000010000026b000002fafc0200000001fb0000001400540065007800740045006400690074006f00720100000016000002fa0000008900ffffff000000030000073d000000d9fc0100000001fb0000001a0043006f006e0073006f006c00650041006c006c0041006c006c01000000000000073d0000006900ffffff000004d0000002fa00000001000000020000000100000008fc00000000 +simulationViewPerspectives: 000000ff0000000100000002000001000000051f0100000002010000000100 +sceneTreePerspectives: 000000ff0000000100000002000000c0000000fa0100000002010000000200 +maximizedDockId: -1 +centralWidgetVisible: 1 +orthographicViewHeight: 1 +textFiles: 2 "../../../../webots/webots/projects/robots/abb/irb/protos/Irb4600-40.proto" "controllers/webots_IK_controller2/webots_IK_controller2.py" "../../../default/controllers/generic_inverse_kinematic/generic_inverse_kinematic.py" +consoles: Console:All:All diff --git a/robots/kuka/kr5/worlds/kuka__kr5_inverse_kinematics.wbt b/robots/kuka/kr5/worlds/kuka__kr5_inverse_kinematics.wbt new file mode 100644 index 0000000..645740e --- /dev/null +++ b/robots/kuka/kr5/worlds/kuka__kr5_inverse_kinematics.wbt @@ -0,0 +1,60 @@ +#VRML_SIM R2020b utf8 +WorldInfo { + basicTimeStep 16 + coordinateSystem "NUE" +} +Viewpoint { + orientation -0.9944585328663142 -0.10284538304268112 -0.021795724263762997 0.7597448038022628 + position -0.080546513752037 2.5616312288532073 2.6301726976621063 +} +TexturedBackground { +} +TexturedBackgroundLight { +} +RectangleArena { + floorSize 3 3 + floorTileSize 0.25 0.25 + wallHeight 0.05 +} +DEF TARGET Solid { + translation 0.26 0.4 0.42 + rotation -1 0 0 -1.5708053071795867 + scale 0.4 0.4 0.4 + children [ + Shape { + appearance PBRAppearance { + baseColorMap ImageTexture { + url [ + "textures/target.png" + ] + } + roughnessMap ImageTexture { + url [ + "textures/target.png" + ] + } + metalnessMap ImageTexture { + url [ + "textures/target.png" + ] + } + emissiveColorMap ImageTexture { + url [ + "textures/target.png" + ] + } + textureTransform TextureTransform { + scale 2 1 + } + } + geometry Sphere { + radius 0.1 + subdivision 2 + } + } + ] +} +KukaKr5Arc { + controller "generic_inverse_kinematic" + supervisor TRUE +} diff --git a/robots/kuka/kr5/worlds/textures/target.png b/robots/kuka/kr5/worlds/textures/target.png new file mode 100644 index 0000000..ae12666 Binary files /dev/null and b/robots/kuka/kr5/worlds/textures/target.png differ diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_base_link_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_base_link_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_base_link_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_base_link_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_1_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_1_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_1_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_1_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_1Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_1Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_1Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_2_1Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_1Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_1Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_1Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_1Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_2Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_2Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_2Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_3_2Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_1Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_1Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_1Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_1Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_2Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_2Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_2Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_4_2Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_1Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_1Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_1Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_1Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_2Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_2Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_2Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_5_2Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_1Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_1Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_1Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_6_1Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_0Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_0Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_0Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_0Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_1Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_1Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_1Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_1Mesh.proto diff --git a/robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_2Mesh.proto b/robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_2Mesh.proto similarity index 100% rename from robots/kuka/lrb_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_2Mesh.proto rename to robots/kuka/lbr_iiwa/protos/KukaLbrIiwa14R820_meshes/KukaLbrIiwa14R820_link_7_2Mesh.proto diff --git a/robots/kuka/lbr_iiwa/worlds/.kuka_inverse_kinematics.wbproj b/robots/kuka/lbr_iiwa/worlds/.kuka_inverse_kinematics.wbproj new file mode 100644 index 0000000..ec33ddf --- /dev/null +++ b/robots/kuka/lbr_iiwa/worlds/.kuka_inverse_kinematics.wbproj @@ -0,0 +1,9 @@ +Webots Project File version R2020b +perspectives: 000000ff00000000fd00000003000000000000021a000003d5fc0100000002fb0000001e00480074006d006c0052006f0062006f007400570069006e0064006f007700000000000000021a0000000000000000fb0000001a0044006f00630075006d0065006e0074006100740069006f006e0000000000ffffffff0000006900ffffff000000010000026b000002fafc0200000001fb0000001400540065007800740045006400690074006f00720100000016000002fa0000008900ffffff000000030000073d000000d9fc0100000001fb0000001a0043006f006e0073006f006c00650041006c006c0041006c006c01000000000000073d0000006900ffffff000004d0000002fa00000001000000020000000100000008fc00000000 +simulationViewPerspectives: 000000ff0000000100000002000001000000051f0100000002010000000100 +sceneTreePerspectives: 000000ff0000000100000002000000c0000000fa0100000002010000000200 +maximizedDockId: -1 +centralWidgetVisible: 1 +orthographicViewHeight: 1 +textFiles: 0 "../../../../webots/webots/projects/robots/abb/irb/protos/Irb4600-40.proto" +consoles: Console:All:All diff --git a/robots/kuka/lbr_iiwa/worlds/kuka_inverse_kinematics.wbt b/robots/kuka/lbr_iiwa/worlds/kuka_inverse_kinematics.wbt new file mode 100644 index 0000000..afe70c9 --- /dev/null +++ b/robots/kuka/lbr_iiwa/worlds/kuka_inverse_kinematics.wbt @@ -0,0 +1,62 @@ +#VRML_SIM R2020b utf8 +WorldInfo { + basicTimeStep 16 + coordinateSystem "NUE" +} +Viewpoint { + orientation -0.4662465401337797 0.8750484017450887 0.1300171466255336 0.4908980536393356 + position 1.3725010340850807 1.1474384464970784 3.1002260652489135 +} +TexturedBackground { +} +TexturedBackgroundLight { +} +RectangleArena { + floorSize 3 3 + floorTileSize 0.25 0.25 + wallHeight 0.05 +} +DEF TARGET Solid { + translation 0.68 0.4 0.69 + rotation 0.5773519358512958 -0.5773469358518515 -0.5773519358512958 2.0944 + scale 0.4 0.4 0.4 + children [ + Shape { + appearance PBRAppearance { + baseColorMap ImageTexture { + url [ + "textures/target.png" + ] + } + roughnessMap ImageTexture { + url [ + "textures/target.png" + ] + } + metalnessMap ImageTexture { + url [ + "textures/target.png" + ] + } + emissiveColorMap ImageTexture { + url [ + "textures/target.png" + ] + } + textureTransform TextureTransform { + scale 2 1 + } + } + geometry Sphere { + radius 0.1 + subdivision 2 + } + } + ] +} +Irb4600-40 { + rotation 1 0 0 -1.5707953071795862 + controller "generic_inverse_kinematic" + supervisor TRUE + staticBase TRUE +} diff --git a/robots/kuka/lbr_iiwa/worlds/textures/target.png b/robots/kuka/lbr_iiwa/worlds/textures/target.png new file mode 100644 index 0000000..ae12666 Binary files /dev/null and b/robots/kuka/lbr_iiwa/worlds/textures/target.png differ