PK!]ƴsilverbullet/__init__.pyfrom .robot import Robot, Pose # noqa: F401 from .scene import Scene # noqa: F401 from .color import Color # noqa: F401 from .connection import Connection # noqa: F401 PK! silverbullet/color.pyimport dataclasses @dataclasses.dataclass class Color: r: float g: float b: float a: float = 1 def as_rgb(self): return self.as_rgba()[:3] def as_rgba(self): return dataclasses.astuple(self) @staticmethod def red(): return Color(1, 0, 0, 1) @staticmethod def green(): return Color(0, 1, 0, 1) @staticmethod def blue(): return Color(0, 0, 1, 1) PK!*Owsilverbullet/connection.pyimport pybullet from pybullet_utils.bullet_client import BulletClient import dataclasses from enum import Enum, unique @unique class Mode(Enum): DIRECT = pybullet.DIRECT GUI = pybullet.GUI SHARED_MEMORY = pybullet.SHARED_MEMORY def to_bullet(self): return self.value @dataclasses.dataclass(frozen=True) class ConnectionInfo: is_connected: bool method: Mode class Connection(object): def __init__(self, mode=Mode.DIRECT): self.client = BulletClient(connection_mode=mode.to_bullet()) def info(self) -> ConnectionInfo: result = self.client.getConnectionInfo() is_connected = bool(result['isConnected']) method = Mode(result['connectionMethod']) return ConnectionInfo(is_connected, method) def is_connected(self) -> bool: return self.info().is_connected def mode(self) -> Mode: return Mode(self.info().method) PK!Nbsilverbullet/robot.pyimport dataclasses import pybullet from pybullet_utils import bullet_client import numpy as np from .scene import Scene import functools from typing import Optional, Dict @dataclasses.dataclass class Pose: vector: np.ndarray quaternion: np.ndarray def dot(self, pose: 'Pose'): vector, quaternion = pybullet.multiplyTransforms( self.vector, self.quaternion, pose.vector, pose.quaternion) return Pose(vector, quaternion) @dataclasses.dataclass class JointState: position: float velocity: float applied_torque: float @dataclasses.dataclass class LinkState: pose: Pose linear_velocity: Optional[np.ndarray] angular_velocity: Optional[np.ndarray] @dataclasses.dataclass class ClientWithBody: client: bullet_client.BulletClient body_id: int def __getattr__(self, name: str): method = getattr(self.client, name) return functools.partial(method, bodyUniqueId=self.body_id) @dataclasses.dataclass class Robot: body_id: int scene: dataclasses.InitVar[Scene] joints: Dict[str, int] = dataclasses.field(init=False) links: Dict[str, int] = dataclasses.field(init=False) client: ClientWithBody = dataclasses.field(init=False) root_link: str = dataclasses.field(init=False) def __post_init__(self, scene: Scene): self.client = ClientWithBody(scene._conn.client, self.body_id) nr_joints = self.client.getNumJoints() self.links = {} self.joints = {} root, _ = self.client.getBodyInfo() root_name = root.decode() self.links[root_name] = -1 self.root_link = root_name for idx in range(nr_joints): result = self.client.getJointInfo(jointIndex=idx) joint_name = result[1].decode() link_name = result[12].decode() self.links[link_name] = idx self.joints[joint_name] = idx def joint_state(self, name: str) -> JointState: joint_id = self.joints[name] pos, vel, _, torque = self.client.getJointState(jointIndex=joint_id) return JointState(pos, vel, torque) def link_state(self, name: str, compute_velocity=False) -> LinkState: link_id = self.links[name] if link_id == -1: pos, ori = self.client.getBasePositionAndOrientation() if compute_velocity: a_vel, l_vel = self.client.getBaseVelocity() else: a_vel = None l_vel = None else: pos, ori, _, _, l_vel, a_vel = self.client.getLinkState( linkIndex=link_id, computeLinkVelocity=compute_velocity) pose = Pose(np.array(pos), np.array(ori)) return LinkState(pose, l_vel, a_vel) def set_joint_position(self, name: str, target: float, kp: float, kd: float, force: float): joint_id = self.joints[name] self.client.setJointMotorControl2( jointIndex=joint_id, controlMode=pybullet.POSITION_CONTROL, targetPosition=target, positionGain=kp, velocityGain=kd, force=force) def set_joint_velocity(self, name: str, target: float, force: float): joint_id = self.joints[name] self.client.setJointMotorControl2( jointIndex=joint_id, controlMode=pybullet.VELOCITY_CONTROL, targetVelocity=target, force=force) def set_joint_torque(self, name: str, force: float): joint_id = self.joints[name] self.client.setJointMotorControl2( jointIndex=joint_id, controlMode=pybullet.TORQUE_CONTROL, force=force) def bring_on_the_ground(self, padding: float = 0): h = min(self.link_state(name).pose.vector[2] for name in self.links.keys()) if h > 0: raise RuntimeError("Robot is already on the ground") self.client.resetBasePositionAndOrientation( posObj=[0, 0, -h + padding], ornObj=[0, 0, 0, 1]) @staticmethod def load_urdf(scene: Scene, path: str, flags=pybullet.URDF_USE_SELF_COLLISION): body_id = scene._conn.client.loadURDF( path, [0, 0, 0], flags=flags) return Robot(body_id, scene) PK!I,Wsilverbullet/scene.pyimport pybullet_data import pybullet import dataclasses from typing import Sequence, Optional, Union, Dict, Any from .color import Color from .connection import Connection @dataclasses.dataclass(frozen=True) class DebugBody: body_id: int def remove_from_scene(self, scene: 'Scene'): scene._conn.client.removeBody(self.body_id) @dataclasses.dataclass(frozen=True) class DebugSphere(DebugBody): pass @dataclasses.dataclass(frozen=True) class DebugItem: item_id: int def remove_from_scene(self, scene: 'Scene'): scene._conn.client.removeUserDebugItem(self.item_id) @dataclasses.dataclass(frozen=True) class DebugLine(DebugItem): pass @dataclasses.dataclass(frozen=True) class DebugText(DebugItem): pass @dataclasses.dataclass(frozen=True) class SavedState: state_id: int @dataclasses.dataclass class Scene: timestep: float frame_skip: int gravity: float = 9.8 connection: dataclasses.InitVar[Optional[Connection]] = None dt: float = dataclasses.field(init=False) ts: float = dataclasses.field(init=False) _conn: Connection = dataclasses.field(init=False) def __post_init__(self, connection: Optional[Connection]): self.dt = self.timestep * self.frame_skip self._conn = connection or Connection() self.episode_restart() def clean_everything(self): self._conn.client.resetSimulation() self.configure_simulation() def configure_simulation(self): self._conn.client.setAdditionalSearchPath( pybullet_data.getDataPath()) self._conn.client.setGravity(0, 0, -self.gravity) self._conn.client.setPhysicsEngineParameter( fixedTimeStep=self.dt, numSubSteps=self.frame_skip) def load_plane(self): self.plane_id = self._conn.client.loadURDF("plane.urdf") def episode_restart(self): self.clean_everything() self.ts = 0 self.load_plane() def step(self): self._conn.client.stepSimulation() self.ts += self.dt def draw_line(self, from_pos: Sequence[float], to_pos: Sequence[float], color: Optional[Color] = None, width: Optional[float] = None, replace: Optional[DebugItem] = None) \ -> DebugLine: args: Dict[str, Any] = { 'lineFromXYZ': from_pos, 'lineToXYZ': to_pos } if color is not None: args['lineColorRGB'] = color.as_rgb() if replace is not None: args['replaceItemUniqueId'] = replace.item_id if width is not None: args['lineWidth'] = width item_id = self._conn.client.addUserDebugLine(**args) return DebugLine(item_id) def draw_text(self, text: str, pos: Sequence[float], orientation: Optional[Sequence[float]] = None, color: Optional[Color] = None, size: Optional[float] = None, replace: Optional[DebugItem] = None) \ -> DebugText: args: Dict[str, Any] = { 'text': text, 'textPosition': pos, } if color is not None: args['textColorRGB'] = color.as_rgb() if orientation is not None: args['textOrientation'] = orientation if replace is not None: args['replaceItemUniqueId'] = replace.item_id if size is not None: args['textSize'] = size item_id = self._conn.client.addUserDebugText(**args) return DebugText(item_id) def draw_sphere(self, pos: Sequence[float], radius: Optional[float] = None, color: Optional[Color] = None) \ -> DebugSphere: args: Dict[str, Any] = { 'shapeType': pybullet.GEOM_SPHERE } if color is not None: args['rgbaColor'] = color.as_rgba() if radius is not None: args['radius'] = radius visual_id = self._conn.client.createVisualShape(**args) body_id = self._conn.client.createMultiBody( baseVisualShapeIndex=visual_id, basePosition=pos) return DebugSphere(body_id) def move_debug_body(self, body: DebugBody, position: Sequence[float], orientation: Sequence[float]): self._conn.client.resetBasePositionAndOrientation( body.body_id, position, orientation) def remove_debug_object(self, o: Union[DebugItem, DebugBody]): o.remove_from_scene(self) def save_state(self) -> SavedState: state_id = self._conn.client.saveState() return SavedState(state_id) def restore_state(self, state: SavedState): self._conn.client.restoreState(state.state_id) PK!$silverbullet-0.1.0.dist-info/LICENSECopyright 2018 Y-modify Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!HڽTU"silverbullet-0.1.0.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!H|_"%silverbullet-0.1.0.dist-info/METADATAUmo6_5jeNQ6 IW8ɀJ:KlE!);Rbo0{ywrfY;he=#t|ffj:m l}HGt5B0"dU%$m,Qr zTdR Ӳs ɵ*V yi2(*-fRDҢJ'}3 -LJS؜CW3"Wo1 xj~it:8`3/9 Ff䷻9+5=/Z ܰh0+x:};#u#TKzammNgcBoaq3# Pp+u;xM/d+gem}~=:_J2gYK>?{[Q8*:V]QPѕf9Di:O'a h'y6&iLNlj Ѧ{y|hHlts?[9oDa Ze]t&EyrLJ+f+n9^. jJUn(CէfU|0 ^V̆avÌSC,>*~0 gVrm.6 XqX㼤-vPkm/&/&]:pU7~Gثk}3?|w饮nRxn%L?^#2EXєPUδ?҈~wP~mK-p+taN?aLraqkXz$vV}{bbrƂt8x2lM>]s?.h%Y4:_LoLS>ubKH ߇K^ ̂#lHjղ" %Sz]gHԀMI^7S4z; %= zާݗ5VfHWM1RPK!H Բ#silverbullet-0.1.0.dist-info/RECORD}r0}m{P@^a$A"O7.|oi&aH+چ6