fix(robots): fix send_action in lekiwi_client
This commit is contained in:
parent
8e62c4ed02
commit
1eeeab5f4c
|
@ -131,6 +131,7 @@ class LeKiwi(Robot):
|
||||||
input("Move robot to the middle of its range of motion and press ENTER....")
|
input("Move robot to the middle of its range of motion and press ENTER....")
|
||||||
homing_offsets = self.bus.set_half_turn_homings(motors)
|
homing_offsets = self.bus.set_half_turn_homings(motors)
|
||||||
|
|
||||||
|
# TODO(Steven): Might be worth to do this also in other robots
|
||||||
full_turn_motor = [
|
full_turn_motor = [
|
||||||
motor for motor in motors if any(keyword in motor for keyword in ["wheel", "gripper"])
|
motor for motor in motors if any(keyword in motor for keyword in ["wheel", "gripper"])
|
||||||
]
|
]
|
||||||
|
|
|
@ -76,7 +76,7 @@ class LeKiwiClient(Robot):
|
||||||
]
|
]
|
||||||
self.speed_index = 0 # Start at slow
|
self.speed_index = 0 # Start at slow
|
||||||
|
|
||||||
self.is_connected = False
|
self._is_connected = False
|
||||||
self.logs = {}
|
self.logs = {}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -128,7 +128,7 @@ class LeKiwiClient(Robot):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_connected(self) -> bool:
|
def is_connected(self) -> bool:
|
||||||
pass
|
return self._is_connected
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_calibrated(self) -> bool:
|
def is_calibrated(self) -> bool:
|
||||||
|
@ -137,7 +137,7 @@ class LeKiwiClient(Robot):
|
||||||
def connect(self) -> None:
|
def connect(self) -> None:
|
||||||
"""Establishes ZMQ sockets with the remote mobile robot"""
|
"""Establishes ZMQ sockets with the remote mobile robot"""
|
||||||
|
|
||||||
if self.is_connected:
|
if self._is_connected:
|
||||||
raise DeviceAlreadyConnectedError(
|
raise DeviceAlreadyConnectedError(
|
||||||
"LeKiwi Daemon is already connected. Do not run `robot.connect()` twice."
|
"LeKiwi Daemon is already connected. Do not run `robot.connect()` twice."
|
||||||
)
|
)
|
||||||
|
@ -153,7 +153,7 @@ class LeKiwiClient(Robot):
|
||||||
self.zmq_observation_socket.connect(zmq_observations_locator)
|
self.zmq_observation_socket.connect(zmq_observations_locator)
|
||||||
self.zmq_observation_socket.setsockopt(zmq.CONFLATE, 1)
|
self.zmq_observation_socket.setsockopt(zmq.CONFLATE, 1)
|
||||||
|
|
||||||
self.is_connected = True
|
self._is_connected = True
|
||||||
|
|
||||||
def calibrate(self) -> None:
|
def calibrate(self) -> None:
|
||||||
# TODO(Steven): Nothing to calibrate.
|
# TODO(Steven): Nothing to calibrate.
|
||||||
|
@ -369,7 +369,7 @@ class LeKiwiClient(Robot):
|
||||||
present wheel speeds (converted to body-frame velocities: x, y, theta),
|
present wheel speeds (converted to body-frame velocities: x, y, theta),
|
||||||
and a camera frame. Receives over ZMQ, translate to body-frame vel
|
and a camera frame. Receives over ZMQ, translate to body-frame vel
|
||||||
"""
|
"""
|
||||||
if not self.is_connected:
|
if not self._is_connected:
|
||||||
raise DeviceNotConnectedError("LeKiwiClient is not connected. You need to run `robot.connect()`.")
|
raise DeviceNotConnectedError("LeKiwiClient is not connected. You need to run `robot.connect()`.")
|
||||||
|
|
||||||
obs_dict = {}
|
obs_dict = {}
|
||||||
|
@ -454,28 +454,38 @@ class LeKiwiClient(Robot):
|
||||||
Returns:
|
Returns:
|
||||||
np.ndarray: the action sent to the motors, potentially clipped.
|
np.ndarray: the action sent to the motors, potentially clipped.
|
||||||
"""
|
"""
|
||||||
if not self.is_connected:
|
if not self._is_connected:
|
||||||
raise DeviceNotConnectedError(
|
raise DeviceNotConnectedError(
|
||||||
"ManipulatorRobot is not connected. You need to run `robot.connect()`."
|
"ManipulatorRobot is not connected. You need to run `robot.connect()`."
|
||||||
)
|
)
|
||||||
|
|
||||||
goal_pos: np.array = np.zeros(9)
|
|
||||||
if self.robot_mode is RobotMode.AUTO:
|
if self.robot_mode is RobotMode.AUTO:
|
||||||
# TODO(Steven): Not yet implemented. The policy outputs might need a different conversion
|
# TODO(Steven): Not yet implemented. The policy outputs might need a different conversion
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
goal_pos = {}
|
||||||
# TODO(Steven): This assumes teleop mode is always used with keyboard. Tomorrow we could teleop with another device ... ?
|
# TODO(Steven): This assumes teleop mode is always used with keyboard. Tomorrow we could teleop with another device ... ?
|
||||||
if self.robot_mode is RobotMode.TELEOP:
|
if self.robot_mode is RobotMode.TELEOP:
|
||||||
if action.size < 6:
|
# TODO(Steven): I don't like this
|
||||||
logging.error("Action should include at least the 6 states of the leader arm")
|
|
||||||
|
motors_name = self.state_feature.get("names").get("motors")
|
||||||
|
|
||||||
|
common_keys = [key for key in action if any(key in motor for motor in motors_name)]
|
||||||
|
|
||||||
|
if len(common_keys) < 6:
|
||||||
|
logging.error("Action should include at least the states of the leader arm")
|
||||||
raise InvalidActionError
|
raise InvalidActionError
|
||||||
|
|
||||||
goal_pos[:6] = action[:6]
|
arm_actions = {"arm_" + arm_motor: action[arm_motor] for arm_motor in common_keys}
|
||||||
if action.size > 6:
|
goal_pos = arm_actions
|
||||||
# TODO(Steven): Assumes size and order is respected
|
if len(action) > 6:
|
||||||
wheel_actions = [v for _, v in self._from_keyboard_to_wheel_action(action[6:]).items()]
|
keyboard_keys = set(action.keys()) - set(common_keys)
|
||||||
goal_pos[6:] = wheel_actions
|
wheel_actions = {
|
||||||
self.zmq_cmd_socket.send_string(json.dumps(goal_pos.tolist())) # action is in motor space
|
"base_" + k: v for k, v in self._from_keyboard_to_wheel_action(keyboard_keys).items()
|
||||||
|
}
|
||||||
|
goal_pos = {**arm_actions, **wheel_actions}
|
||||||
|
|
||||||
|
self.zmq_cmd_socket.send_string(json.dumps(goal_pos)) # action is in motor space
|
||||||
|
|
||||||
return goal_pos
|
return goal_pos
|
||||||
|
|
||||||
|
@ -486,7 +496,7 @@ class LeKiwiClient(Robot):
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
"""Cleans ZMQ comms"""
|
"""Cleans ZMQ comms"""
|
||||||
|
|
||||||
if not self.is_connected:
|
if not self._is_connected:
|
||||||
raise DeviceNotConnectedError(
|
raise DeviceNotConnectedError(
|
||||||
"LeKiwi is not connected. You need to run `robot.connect()` before disconnecting."
|
"LeKiwi is not connected. You need to run `robot.connect()` before disconnecting."
|
||||||
)
|
)
|
||||||
|
@ -494,7 +504,7 @@ class LeKiwiClient(Robot):
|
||||||
self.zmq_observation_socket.close()
|
self.zmq_observation_socket.close()
|
||||||
self.zmq_cmd_socket.close()
|
self.zmq_cmd_socket.close()
|
||||||
self.zmq_context.term()
|
self.zmq_context.term()
|
||||||
self.is_connected = False
|
self._is_connected = False
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if getattr(self, "is_connected", False):
|
if getattr(self, "is_connected", False):
|
||||||
|
|
Loading…
Reference in New Issue