-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from KazuyaOguma18/moveit
feat: moveit機能の実装
- Loading branch information
Showing
37 changed files
with
1,666 additions
and
219 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,7 +44,5 @@ | |
] | ||
} | ||
}, | ||
"runArgs": [ | ||
"--device=/dev/input/js0" | ||
] | ||
"runArgs": ["--device=/dev/input/js0"] | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import rclpy | ||
import rclpy.logging | ||
|
||
from .action import Action | ||
from ..move_group_utils import MoveGroupUtils | ||
from ..shared import Shared | ||
|
||
|
||
class MoveitNamedTarget(Action): | ||
""" | ||
Control the movement towards a named target pose stored in MoveIt. | ||
:type __moveit: MoveitPy | ||
:type __planner: PlanningComponent | ||
:type __executor: TrajectoryExecutionManager | ||
""" | ||
|
||
NAME = "moveit_named_target" | ||
|
||
def __init__(self, definition, node): | ||
super(MoveitNamedTarget, self).__init__(definition, node) | ||
Action.actions[self.__class__.NAME] = self.__class__ | ||
|
||
self.__moveit = MoveGroupUtils.moveit | ||
self.__planner = MoveGroupUtils.planner | ||
self.__executor = MoveGroupUtils.executor | ||
self.__target_name = self.get_required("target_name") | ||
|
||
def execute(self, named_joy=None): | ||
rclpy.logging.get_logger("mofpy.MoveitNamedTarget").error("Hello") | ||
if Shared.get("move_group_disabled"): | ||
msg = "move_group disabled; not executing: {0} {1}".format( | ||
self.__action, self.__target_name | ||
) | ||
rclpy.logging.get_logger("mofpy.MoveitNamedTarget").error(msg) | ||
return | ||
|
||
self.__move__() | ||
|
||
def __move__(self): | ||
rclpy.logging.get_logger("mofpy.MoveitNamedTarget").info( | ||
"Moving to {0}".format(self.__target_name) | ||
) | ||
self.__planner.set_start_state_to_current_state() | ||
|
||
if self.__target_name not in self.__planner.named_target_states: | ||
rclpy.logging.get_logger("mofpy.MoveitNamedTarget").error( | ||
"could not find the named target '{}'. Please select from the list '{}'".format( | ||
self.__target_name, self.__planner.named_target_states | ||
) | ||
) | ||
return | ||
|
||
self.__planner.set_goal_state(self.__target_name) | ||
plan = self.__planner.plan() | ||
|
||
if plan: | ||
self.__moveit.execute(plan.trajectory, controllers=[]) | ||
|
||
|
||
Action.register_preset(MoveitNamedTarget) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import threading | ||
|
||
from control_msgs.msg import JointJog | ||
from moveit_msgs.srv import ServoCommandType | ||
import rclpy | ||
from rclpy.executors import SingleThreadedExecutor | ||
from rclpy.node import Node | ||
from rclpy.qos import QoSProfile | ||
|
||
from .action import Action | ||
from ..move_group_utils import MoveGroupUtils | ||
from ..shared import Shared | ||
|
||
|
||
class MoveitServoJoint(Action): | ||
|
||
NAME = "moveit_servo_joint" | ||
|
||
def __init__(self, definition, node: Node): | ||
super(MoveitServoJoint, self).__init__(definition, node) | ||
Action.actions[self.__class__.NAME] = self.__class__ | ||
|
||
self.__frame_id = self.get("frame_id", "base_link") | ||
self.__scale = self.get("scale", 0.1) | ||
self.__quiet_on_zero = self.get("quiet_on_zero", True) | ||
self.__joint_mapping = self.__mapping__("joints") | ||
self.__axis_mapping = self.__mapping__("axes") | ||
self.__published_zero = False | ||
|
||
self.__pub = node.create_publisher( | ||
JointJog, MoveGroupUtils.servo_node_name + "/delta_joint_cmds", QoSProfile(depth=10) | ||
) | ||
client_node = Node(node.get_name() + "_moveit_servo_joint") | ||
self.__client = client_node.create_client( | ||
ServoCommandType, MoveGroupUtils.servo_node_name + "/switch_command_type" | ||
) | ||
|
||
self.executor = SingleThreadedExecutor() | ||
self.executor.add_node(client_node) | ||
self.executor_thread = threading.Thread(target=self.executor.spin, daemon=True) | ||
self.executor_thread.start() | ||
|
||
self.__moveit = MoveGroupUtils.moveit | ||
robot_model = self.__moveit.get_robot_model() | ||
group_name = MoveGroupUtils.planner.planning_group_name | ||
self.__joint_model_names = robot_model.get_joint_model_group(group_name).joint_model_names | ||
|
||
def execute(self, named_joy=None): | ||
if Shared.get("move_group_disabled"): | ||
return | ||
|
||
if Shared.get("moveit_servo_command_type") != ServoCommandType.Request.JOINT_JOG: | ||
if not self.__servo_init__(self.node): | ||
rclpy.logging.get_logger("mofpy.MoveitServoJoint").error( | ||
"Failed to initialize servo command type" | ||
) | ||
|
||
jog_joints, is_quiet = self.__get_jog_joints__(named_joy["buttons"], named_joy["axes"]) | ||
|
||
if self.__quiet_on_zero: | ||
if is_quiet: | ||
# Publish the all-zero message just once | ||
if not self.__published_zero: | ||
self.__pub.publish(jog_joints) | ||
self.__published_zero = True | ||
return | ||
|
||
self.__pub.publish(jog_joints) | ||
self.__published_zero = False | ||
|
||
def __servo_init__(self, node: Node): | ||
while not self.__client.wait_for_service(1): | ||
continue | ||
|
||
req = ServoCommandType.Request() | ||
req.command_type = ServoCommandType.Request.JOINT_JOG | ||
rclpy.logging.get_logger("moveit_servo_joint_jog").info( | ||
"call service {}".format(self.__client.service_name) | ||
) | ||
|
||
self.future = self.__client.call_async(req) | ||
self.executor.spin_until_future_complete(future=self.future, timeout_sec=1) | ||
|
||
res: ServoCommandType.Response = self.future.result() | ||
|
||
if not res: | ||
rclpy.logging.get_logger("moveit_servo_joint_jog").error( | ||
"failed to get response from {}".format(self.__client.service_name) | ||
) | ||
return False | ||
|
||
rclpy.logging.get_logger("moveit_servo_joint_jog").info( | ||
"get response from {}".format(self.__client.service_name) | ||
) | ||
if res.success: | ||
Shared.update("moveit_servo_command_type", ServoCommandType.Request.JOINT_JOG) | ||
|
||
return res.success | ||
|
||
def __get_jog_joints__(self, named_buttons, named_axes): | ||
msg = JointJog() | ||
msg.header.stamp = self.node.get_clock().now().to_msg() | ||
msg.header.frame_id = self.__frame_id | ||
for joint in self.__joint_mapping: | ||
if joint in self.__joint_model_names: | ||
v = self.__get_value__("plus", named_axes) - self.__get_value__("minus", named_axes) | ||
vel = self.__scale * self.__get_enable_joint__(joint, named_buttons) * v | ||
msg.joint_names.append(joint) | ||
msg.velocities.append(vel) | ||
|
||
is_quiet = all(val == 0 for val in msg.velocities) | ||
return msg, is_quiet | ||
|
||
def __mapping__(self, key=None): | ||
mapping_key = "mapping" + f"/{key}" if key else key | ||
params = self.get(mapping_key, {}) | ||
mapping = {} | ||
for key in params.keys(): | ||
val = params[key] | ||
mapping[key] = val | ||
|
||
return mapping | ||
|
||
def __get_enable_joint__(self, joint_name, named_buttons): | ||
if joint_name not in self.__joint_mapping: | ||
return 0 | ||
|
||
button = self.__joint_mapping[joint_name] | ||
return 1 if named_buttons[button].value else 0 | ||
|
||
def __get_value__(self, axis, named_axes): | ||
""" | ||
Extract the axis/buttons value from joy. | ||
:param axis: one of +, - to get the value of | ||
:param named_axes: the processed joy values to get the value from | ||
:return: the value | ||
""" | ||
if axis not in self.__axis_mapping: | ||
return 0 | ||
|
||
return named_axes[self.__axis_mapping[axis]].value | ||
|
||
|
||
Action.register_preset(MoveitServoJoint) |
Oops, something went wrong.