5
5
#include " ocs2_quadruped_interface/SwingPlanningVisualizer.h"
6
6
7
7
#include < geometry_msgs/PoseArray.h>
8
+ #include < visualization_msgs/MarkerArray.h>
8
9
9
10
#include < ocs2_ros_interfaces/visualization/VisualizationHelpers.h>
10
11
@@ -16,11 +17,17 @@ SwingPlanningVisualizer::SwingPlanningVisualizer(const SwingTrajectoryPlanner& s
16
17
nominalFootholdPublishers_[1 ] = nodeHandle.advertise <geometry_msgs::PoseArray>(" /ocs2_anymal/swing_planner/nominalFootholds_RF" , 1 );
17
18
nominalFootholdPublishers_[2 ] = nodeHandle.advertise <geometry_msgs::PoseArray>(" /ocs2_anymal/swing_planner/nominalFootholds_LH" , 1 );
18
19
nominalFootholdPublishers_[3 ] = nodeHandle.advertise <geometry_msgs::PoseArray>(" /ocs2_anymal/swing_planner/nominalFootholds_RH" , 1 );
20
+ swingTrajectoryPublishers_[0 ] = nodeHandle.advertise <visualization_msgs::MarkerArray>(" /ocs2_anymal/swing_planner/trajectory_LF" , 1 );
21
+ swingTrajectoryPublishers_[1 ] = nodeHandle.advertise <visualization_msgs::MarkerArray>(" /ocs2_anymal/swing_planner/trajectory_RF" , 1 );
22
+ swingTrajectoryPublishers_[2 ] = nodeHandle.advertise <visualization_msgs::MarkerArray>(" /ocs2_anymal/swing_planner/trajectory_LH" , 1 );
23
+ swingTrajectoryPublishers_[3 ] = nodeHandle.advertise <visualization_msgs::MarkerArray>(" /ocs2_anymal/swing_planner/trajectory_RH" , 1 );
19
24
}
20
25
21
26
void SwingPlanningVisualizer::preSolverRun (scalar_t initTime, scalar_t finalTime, const vector_t & currentState,
22
27
const ocs2::ReferenceManagerInterface& referenceManager) {
23
28
const auto timeStamp = ros::Time::now ();
29
+
30
+ // Nominal footholds
24
31
for (int leg = 0 ; leg < NUM_CONTACT_POINTS; leg++) {
25
32
const auto nominalFootholds = swingTrajectoryPlannerPtr_->getNominalFootholds (leg);
26
33
@@ -43,6 +50,35 @@ void SwingPlanningVisualizer::preSolverRun(scalar_t initTime, scalar_t finalTime
43
50
poseArray.header = ocs2::getHeaderMsg (frameId_, timeStamp);
44
51
nominalFootholdPublishers_[leg].publish (poseArray);
45
52
}
53
+
54
+ // Feet trajectories
55
+ visualization_msgs::Marker deleteMarker;
56
+ deleteMarker.action = visualization_msgs::Marker::DELETEALL;
57
+ for (int leg = 0 ; leg < NUM_CONTACT_POINTS; leg++) {
58
+ // Initialize and add marker that deletes old visualizations
59
+ visualization_msgs::MarkerArray swingTrajectoriesMessage;
60
+ swingTrajectoriesMessage.markers .reserve (swingTrajectoryPlannerPtr_->getTargetTrajectories ().timeTrajectory .size () + 1 ); // lower bound
61
+ swingTrajectoriesMessage.markers .push_back (deleteMarker);
62
+
63
+ for (const auto & t : swingTrajectoryPlannerPtr_->getTargetTrajectories ().timeTrajectory ) {
64
+ if (t < initTime || t > finalTime) {
65
+ continue ;
66
+ }
67
+
68
+ const auto & footPhase = swingTrajectoryPlannerPtr_->getFootPhase (leg, t);
69
+ SwingNode3d node{t, footPhase.getPositionInWorld (t), footPhase.getVelocityInWorld (t)};
70
+
71
+ swingTrajectoriesMessage.markers .push_back (ocs2::getArrowAtPointMsg (arrowScale * node.velocity , node.position , feetColorMap_[leg]));
72
+ swingTrajectoriesMessage.markers .back ().scale .x = 0.005 ; // shaft diameter
73
+ swingTrajectoriesMessage.markers .back ().scale .y = 0.01 ; // arrow-head diameter
74
+ swingTrajectoriesMessage.markers .back ().scale .z = 0.02 ; // arrow-head length
75
+ }
76
+
77
+ ocs2::assignHeader (swingTrajectoriesMessage.markers .begin (), swingTrajectoriesMessage.markers .end (),
78
+ ocs2::getHeaderMsg (frameId_, timeStamp));
79
+ ocs2::assignIncreasingId (swingTrajectoriesMessage.markers .begin (), swingTrajectoriesMessage.markers .end ());
80
+ swingTrajectoryPublishers_[leg].publish (swingTrajectoriesMessage);
81
+ }
46
82
}
47
83
48
84
} // namespace switched_model
0 commit comments