Skip to content

Commit 195689f

Browse files
Cleaning up errors from previous multi-task version
1 parent 5da4a77 commit 195689f

File tree

6 files changed

+122
-159
lines changed

6 files changed

+122
-159
lines changed

mm_control/scripts/generate_acados_code.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import argparse
22

3-
import mm_control.MPC as MPC
3+
from mm_control.MPC import MPC
44
from mm_utils import parsing
55

66
if __name__ == "__main__":
@@ -24,7 +24,11 @@
2424
config["controller"]["acados"]["cython"]["recompile"] = True
2525

2626
ctrl_config = config["controller"]
27-
control_class = getattr(MPC, ctrl_config["type"], None)
28-
if control_class is None:
29-
raise ValueError(f"Unknown controller type: {ctrl_config['type']}")
27+
ctrl_type = ctrl_config["type"]
28+
29+
if ctrl_type == "MPC":
30+
control_class = MPC
31+
else:
32+
raise ValueError(f"Unknown controller type: {ctrl_type}")
33+
3034
controller = control_class(ctrl_config)

mm_control/src/mm_control/MPCCostFunctions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,16 @@ def create_regularization_cost(robot_mdl, params):
506506
return RegularizationCostFunction(ss_mdl["nx"], ss_mdl["nu"])
507507

508508

509+
def create_manipulability_cost(robot_mdl, params):
510+
"""Create manipulability cost"""
511+
return ManipulabilityCostFunction(robot_mdl)
512+
513+
509514
# Register core cost functions (simplified to 6 parameterized functions)
510515
CostFunctionRegistry.register("BasePose", create_base_pose_cost)
511516
CostFunctionRegistry.register("BaseVel", create_base_vel_cost)
512517
CostFunctionRegistry.register("EEPose", create_ee_pose_cost)
513518
CostFunctionRegistry.register("EEVel", create_ee_vel_cost)
514519
CostFunctionRegistry.register("ControlEffort", ControlEffortCostFunction)
515520
CostFunctionRegistry.register("Regularization", create_regularization_cost)
521+
CostFunctionRegistry.register("Manipulability", create_manipulability_cost)

mm_plan/src/mm_plan/TaskManager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def activatePlanners(self):
2525
planner.activate()
2626

2727
def getPlanner(self):
28-
"""Get the active planners (current task and next if available).
28+
"""Get the active planner (current task).
2929
3030
Returns:
3131
Active planner

mm_run/config/test_experiments/test_position_only.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ planner:
77
tasks:
88
- name: EE Position Only
99
planner_type: WaypointPlanner
10-
base_pose: [2, 0.4, 0] # x, y, yaw in world frame
11-
ee_pose: [2.5, 0.4, 1.0, 0, 0, 0] # World frame: [x, y, z, roll, pitch, yaw]
10+
base_pose: [2, 0.4, 0.5] # x, y, yaw in world frame
11+
ee_pose: [2.5, 0.4, 1.0, 0.5, 0, 0] # World frame: [x, y, z, roll, pitch, yaw]
1212
tracking_err_tol: 0.05
1313

1414
controller:

mm_run/nodes/mpc_ros.py

Lines changed: 99 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -215,61 +215,60 @@ def _publish_cmd_vel_new(self, event):
215215

216216
self.robot_interface.publish_cmd_vel(self.cmd_vel)
217217

218-
def _publish_trajectory_tracking_pt(self, t, robot_states, planners):
218+
def _publish_trajectory_tracking_pt(self, t, robot_states, planner):
219219
msg = MultiDOFJointTrajectory()
220220
msg.header.stamp = rospy.Time.now()
221221

222-
for planner in planners:
223-
# Get base reference if available
224-
if planner.has_base_ref:
225-
p, v = planner.getBaseTrackingPoint(t, robot_states)
226-
if p is not None:
227-
msg.joint_names.append("base")
228-
pt_msg = MultiDOFJointTrajectoryPoint()
229-
transform = Transform()
230-
transform.translation.x = p[0]
231-
transform.translation.y = p[1]
232-
transform.translation.z = 0.25 # Display height
233-
quat = tf.quaternion_from_euler(0, 0, p[2])
234-
transform.rotation.x = quat[0]
235-
transform.rotation.y = quat[1]
236-
transform.rotation.z = quat[2]
237-
transform.rotation.w = quat[3]
238-
pt_msg.transforms.append(transform)
239-
if v is not None:
240-
velocity = Twist()
241-
velocity.linear.x = v[0]
242-
velocity.linear.y = v[1]
243-
velocity.angular.z = v[2]
244-
pt_msg.velocities.append(velocity)
245-
msg.points.append(pt_msg)
246-
247-
# Get EE reference if available
248-
if planner.has_ee_ref:
249-
p, v = planner.getEETrackingPoint(t, robot_states)
250-
if p is not None:
251-
msg.joint_names.append("EE")
252-
pt_msg = MultiDOFJointTrajectoryPoint()
253-
transform = Transform()
254-
transform.translation.x = p[0]
255-
transform.translation.y = p[1]
256-
transform.translation.z = p[2]
257-
quat = tf.quaternion_from_euler(*p[3:])
258-
transform.rotation.x = quat[0]
259-
transform.rotation.y = quat[1]
260-
transform.rotation.z = quat[2]
261-
transform.rotation.w = quat[3]
262-
pt_msg.transforms.append(transform)
263-
if v is not None:
264-
velocity = Twist()
265-
velocity.linear.x = v[0]
266-
velocity.linear.y = v[1]
267-
velocity.linear.z = v[2]
268-
velocity.angular.x = v[3] if len(v) > 3 else 0
269-
velocity.angular.y = v[4] if len(v) > 4 else 0
270-
velocity.angular.z = v[5] if len(v) > 5 else 0
271-
pt_msg.velocities.append(velocity)
272-
msg.points.append(pt_msg)
222+
# Get base reference if available
223+
if planner.has_base_ref:
224+
p, v = planner.getBaseTrackingPoint(t, robot_states)
225+
if p is not None:
226+
msg.joint_names.append("base")
227+
pt_msg = MultiDOFJointTrajectoryPoint()
228+
transform = Transform()
229+
transform.translation.x = p[0]
230+
transform.translation.y = p[1]
231+
transform.translation.z = 0.25 # Display height
232+
quat = tf.quaternion_from_euler(0, 0, p[2])
233+
transform.rotation.x = quat[0]
234+
transform.rotation.y = quat[1]
235+
transform.rotation.z = quat[2]
236+
transform.rotation.w = quat[3]
237+
pt_msg.transforms.append(transform)
238+
if v is not None:
239+
velocity = Twist()
240+
velocity.linear.x = v[0]
241+
velocity.linear.y = v[1]
242+
velocity.angular.z = v[2]
243+
pt_msg.velocities.append(velocity)
244+
msg.points.append(pt_msg)
245+
246+
# Get EE reference if available
247+
if planner.has_ee_ref:
248+
p, v = planner.getEETrackingPoint(t, robot_states)
249+
if p is not None:
250+
msg.joint_names.append("EE")
251+
pt_msg = MultiDOFJointTrajectoryPoint()
252+
transform = Transform()
253+
transform.translation.x = p[0]
254+
transform.translation.y = p[1]
255+
transform.translation.z = p[2]
256+
quat = tf.quaternion_from_euler(*p[3:])
257+
transform.rotation.x = quat[0]
258+
transform.rotation.y = quat[1]
259+
transform.rotation.z = quat[2]
260+
transform.rotation.w = quat[3]
261+
pt_msg.transforms.append(transform)
262+
if v is not None:
263+
velocity = Twist()
264+
velocity.linear.x = v[0]
265+
velocity.linear.y = v[1]
266+
velocity.linear.z = v[2]
267+
velocity.angular.x = v[3] if len(v) > 3 else 0
268+
velocity.angular.y = v[4] if len(v) > 4 else 0
269+
velocity.angular.z = v[5] if len(v) > 5 else 0
270+
pt_msg.velocities.append(velocity)
271+
msg.points.append(pt_msg)
273272

274273
if len(msg.points) > 0:
275274
self.tracking_point_pub.publish(msg)
@@ -361,51 +360,49 @@ def _publish_planner_data(self, event):
361360
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
362361
self.plan_visualization_pub.publish(marker_plan)
363362

364-
curr_planners = self.sot.getPlanners(2)
365-
colors = [[1, 0, 0], [0, 1, 0]]
366-
for pid, planner in enumerate(curr_planners):
367-
# Visualize current base waypoint/path if available
368-
if planner.has_base_ref:
369-
if planner.ref_type == RefType.WAYPOINT:
370-
quat = tf.quaternion_from_euler(0, 0, planner.base_target[2])
371-
pose_msg = PoseStamped()
372-
pose_msg.header.stamp = rospy.Time()
373-
pose_msg.pose.position = Point(*planner.base_target[:2], 0.25)
374-
pose_msg.pose.orientation = Quaternion(*list(quat))
375-
self.pose_plan_visualization_pub.publish(pose_msg)
376-
elif planner.ref_type == RefType.PATH:
377-
marker_plan = self._make_marker(
378-
Marker.POINTS,
379-
pid,
380-
rgba=colors[pid] + [1],
381-
scale=[0.1, 0.1, 0.1],
382-
)
383-
marker_plan.points = [
384-
Point(*pt[:2], 0) for pt in planner.base_plan["p"]
385-
]
386-
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
387-
self.current_plan_visualization_pub.publish(marker_plan)
388-
389-
# Visualize current EE waypoint/path if available
390-
if planner.has_ee_ref:
391-
if planner.ref_type == RefType.WAYPOINT:
392-
quat = tf.quaternion_from_euler(*planner.ee_target[3:])
393-
pose_msg = PoseStamped()
394-
pose_msg.header.frame_id = "world"
395-
pose_msg.header.stamp = rospy.Time()
396-
pose_msg.pose.position = Point(*planner.ee_target[:3])
397-
pose_msg.pose.orientation = Quaternion(*list(quat))
398-
self.pose_plan_visualization_pub.publish(pose_msg)
399-
elif planner.ref_type == RefType.PATH:
400-
marker_plan = self._make_marker(
401-
Marker.POINTS,
402-
pid + 100,
403-
rgba=colors[pid] + [1],
404-
scale=[0.1, 0.1, 0.1],
405-
)
406-
marker_plan.points = [Point(*pt[:3]) for pt in planner.ee_plan["p"]]
407-
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
408-
self.current_plan_visualization_pub.publish(marker_plan)
363+
planner = self.sot.getPlanner()
364+
# Visualize current base waypoint/path if available
365+
if planner.has_base_ref:
366+
if planner.ref_type == RefType.WAYPOINT:
367+
quat = tf.quaternion_from_euler(0, 0, planner.base_target[2])
368+
pose_msg = PoseStamped()
369+
pose_msg.header.stamp = rospy.Time()
370+
pose_msg.pose.position = Point(*planner.base_target[:2], 0.25)
371+
pose_msg.pose.orientation = Quaternion(*list(quat))
372+
self.pose_plan_visualization_pub.publish(pose_msg)
373+
elif planner.ref_type == RefType.PATH:
374+
marker_plan = self._make_marker(
375+
Marker.POINTS,
376+
0,
377+
rgba=[1, 0, 0, 1],
378+
scale=[0.1, 0.1, 0.1],
379+
)
380+
marker_plan.points = [
381+
Point(*pt[:2], 0) for pt in planner.base_plan["p"]
382+
]
383+
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
384+
self.current_plan_visualization_pub.publish(marker_plan)
385+
386+
# Visualize current EE waypoint/path if available
387+
if planner.has_ee_ref:
388+
if planner.ref_type == RefType.WAYPOINT:
389+
quat = tf.quaternion_from_euler(*planner.ee_target[3:])
390+
pose_msg = PoseStamped()
391+
pose_msg.header.frame_id = "world"
392+
pose_msg.header.stamp = rospy.Time()
393+
pose_msg.pose.position = Point(*planner.ee_target[:3])
394+
pose_msg.pose.orientation = Quaternion(*list(quat))
395+
self.pose_plan_visualization_pub.publish(pose_msg)
396+
elif planner.ref_type == RefType.PATH:
397+
marker_plan = self._make_marker(
398+
Marker.POINTS,
399+
100,
400+
rgba=[0, 1, 0, 1],
401+
scale=[0.1, 0.1, 0.1],
402+
)
403+
marker_plan.points = [Point(*pt[:3]) for pt in planner.ee_plan["p"]]
404+
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
405+
self.current_plan_visualization_pub.publish(marker_plan)
409406

410407
self.sot_lock.release()
411408

@@ -520,9 +517,6 @@ def run(self):
520517
t0 = t
521518
self.sot.started = True
522519

523-
sot_num_plans = self.ctrl_config.get("task_num", None)
524-
if sot_num_plans is None:
525-
sot_num_plans = 1 if self.ctrl_config["type"][:2] == "ST" else 2
526520
while not self.ctrl_c:
527521
t = rospy.Time.now().to_sec()
528522

@@ -558,10 +552,8 @@ def run(self):
558552
# if the robot is very close to the goal, stop the robot
559553
# Check if any active planner is close to finish
560554
self.sot_lock.acquire()
561-
active_planners = self.sot.getPlanners(num_planners=sot_num_plans)
562-
close_to_goal = False
563-
for planner in active_planners:
564-
close_to_goal = close_to_goal or planner.closeToFinish()
555+
planner = self.sot.getPlanner()
556+
close_to_goal = planner.closeToFinish()
565557
self.sot_lock.release()
566558
if close_to_goal:
567559
print("Close to goal. Braking")
@@ -597,11 +589,11 @@ def run(self):
597589

598590
# publish data
599591
self._publish_mpc_data(self.controller)
600-
# Get active planners for visualization
592+
# Get active planner for visualization
601593
self.sot_lock.acquire()
602-
active_planners = self.sot.getPlanners(num_planners=sot_num_plans)
594+
active_planner = self.sot.getPlanner()
603595
self.sot_lock.release()
604-
self._publish_trajectory_tracking_pt(t - t0, robot_states, active_planners)
596+
self._publish_trajectory_tracking_pt(t - t0, robot_states, active_planner)
605597

606598
# Update Task Manager
607599
# Convert to pose arrays in world frame

mm_run/nodes/planner_test_ros.py

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -157,42 +157,6 @@ def _publish_planner_data(self, event):
157157
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
158158
self.plan_visualization_pub.publish(marker_plan)
159159

160-
curr_planners = self.sot.getPlanners(2)
161-
colors = [[1, 0, 0], [0, 1, 0]]
162-
for pid, planner in enumerate(curr_planners):
163-
if planner.ref_type == "waypoint":
164-
if planner.ref_data_type == "Vec3":
165-
marker_plan = self._make_marker(
166-
Marker.SPHERE,
167-
pid,
168-
rgba=colors[pid] + [1],
169-
scale=[0.1, 0.1, 0.1],
170-
)
171-
marker_plan.pose.position = Point(*planner.target_pos)
172-
elif planner.ref_data_type == "Vec2":
173-
marker_plan = self._make_marker(
174-
Marker.CYLINDER,
175-
pid,
176-
rgba=colors[pid] + [1],
177-
scale=[0.1, 0.1, 0.5],
178-
)
179-
marker_plan.pose.position = Point(*planner.target_pos, 0.25)
180-
elif planner.ref_type == "trajectory":
181-
marker_plan = self._make_marker(
182-
Marker.LINE_STRIP,
183-
pid,
184-
rgba=colors[pid] + [1],
185-
scale=[0.1, 0.1, 0.1],
186-
)
187-
188-
if planner.ref_data_type == "Vec3":
189-
marker_plan.points = [Point(*pt) for pt in planner.plan["p"]]
190-
elif planner.ref_data_type == "Vec2":
191-
marker_plan.points = [Point(*pt, 0) for pt in planner.plan["p"]]
192-
193-
marker_plan.lifetime = rospy.Duration.from_sec(0.1)
194-
self.current_plan_visualization_pub.publish(marker_plan)
195-
196160
self.sot_lock.release()
197161

198162
def run(self):
@@ -215,22 +179,19 @@ def run(self):
215179
rospy.Time.now().to_sec()
216180
self.sot.started = True
217181

218-
sot_num_plans = self.ctrl_config.get("task_num", None)
219-
if sot_num_plans is None:
220-
sot_num_plans = 1 if self.ctrl_config["type"][:2] == "ST" else 2
221182
while not self.ctrl_c:
222183
rospy.Time.now().to_sec()
223184

224185
# open-loop command
225186
robot_states = (self.robot_interface.q, self.robot_interface.v)
226-
planners = self.sot.getPlanners(num_planners=sot_num_plans)
187+
planner = self.sot.getPlanner()
227188

228-
planners[0].updateRobotStates(robot_states) # need robot pose
189+
planner.updateRobotStates(robot_states) # need robot pose
229190

230-
if planners[0].plan is not None:
231-
print("plan t\n", planners[0].plan["t"].shape, planners[0].plan["t"])
232-
print("plan p\n", planners[0].plan["p"].shape, planners[0].plan["p"])
233-
print("plan v\n", planners[0].plan["v"].shape, planners[0].plan["v"])
191+
if planner.plan is not None:
192+
print("plan t\n", planner.plan["t"].shape, planner.plan["t"])
193+
print("plan p\n", planner.plan["p"].shape, planner.plan["p"])
194+
print("plan v\n", planner.plan["v"].shape, planner.plan["v"])
234195
else:
235196
print("no plan")
236197

0 commit comments

Comments
 (0)