55#include " ocs2_quadruped_interface/SwingPlanningVisualizer.h"
66
77#include < geometry_msgs/PoseArray.h>
8+ #include < visualization_msgs/MarkerArray.h>
89
910#include < ocs2_ros_interfaces/visualization/VisualizationHelpers.h>
1011
@@ -16,11 +17,17 @@ SwingPlanningVisualizer::SwingPlanningVisualizer(const SwingTrajectoryPlanner& s
1617 nominalFootholdPublishers_[1 ] = nodeHandle.advertise <geometry_msgs::PoseArray>(" /ocs2_anymal/swing_planner/nominalFootholds_RF" , 1 );
1718 nominalFootholdPublishers_[2 ] = nodeHandle.advertise <geometry_msgs::PoseArray>(" /ocs2_anymal/swing_planner/nominalFootholds_LH" , 1 );
1819 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 );
1924}
2025
2126void SwingPlanningVisualizer::preSolverRun (scalar_t initTime, scalar_t finalTime, const vector_t & currentState,
2227 const ocs2::ReferenceManagerInterface& referenceManager) {
2328 const auto timeStamp = ros::Time::now ();
29+
30+ // Nominal footholds
2431 for (int leg = 0 ; leg < NUM_CONTACT_POINTS; leg++) {
2532 const auto nominalFootholds = swingTrajectoryPlannerPtr_->getNominalFootholds (leg);
2633
@@ -43,6 +50,35 @@ void SwingPlanningVisualizer::preSolverRun(scalar_t initTime, scalar_t finalTime
4350 poseArray.header = ocs2::getHeaderMsg (frameId_, timeStamp);
4451 nominalFootholdPublishers_[leg].publish (poseArray);
4552 }
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+ }
4682}
4783
4884} // namespace switched_model
0 commit comments