11#include < dairlib/lcmt_radio_out.hpp>
2- #include < dairlib/lcmt_timestamped_saved_traj.hpp>
32#include < gflags/gflags.h>
43
4+ // Core includes for configuration, system building, and OSC
55#include " common/eigen_utils.h"
66#include " examples/plate-balancing/parameters/lcm_channel_config.h"
77#include " examples/plate-balancing/parameters/osc_controller_config.h"
@@ -44,11 +44,11 @@ using Eigen::MatrixXd;
4444using Eigen::Vector3d;
4545using Eigen::VectorXd;
4646
47+ // Command-line flags for configuration
4748DEFINE_string (plate_balancing_config,
4849 " examples/plate-balancing/config/plate_balancing_config.yaml" ,
49- " Controller settings such as channels. Attempting to minimize "
50- " number of gflags" );
51- DEFINE_bool (simulation, true , " Running in simulation or hardware" );
50+ " YAML file specifying controller and channel settings." );
51+ DEFINE_bool (simulation, true , " Run in simulation (true) or hardware (false)" );
5252
5353namespace dairlib {
5454
@@ -70,10 +70,11 @@ using systems::controllers::TransTaskSpaceTrackingData;
7070namespace examples {
7171namespace plate_balancing {
7272
73+ // Entry point for the OSC controller application
7374int DoMain (int argc, char * argv[]) {
7475 gflags::ParseCommandLineFlags (&argc, &argv, true );
7576
76- // Load parameters from YAML files
77+ // Load all configuration parameters from YAML files
7778 drake::yaml::LoadYamlOptions yaml_options;
7879 yaml_options.allow_yaml_with_no_cpp = true ;
7980 PlateBalancingConfig main_config =
@@ -94,20 +95,20 @@ int DoMain(int argc, char* argv[]) {
9495 FindResourceOrThrow (main_config.osc_osqp_setting_file ))
9596 .GetAsSolverOptions (drake::solvers::OsqpSolver::id ());
9697
97- // Build the Drake diagram
98+ // Build the system diagram for the OSC controller
9899 DiagramBuilder<double > builder;
99100
100- // Create and configure the MultibodyPlant
101+ // Construct the MultibodyPlant for the robot and parse models
101102 drake::multibody::MultibodyPlant<double > plant (0.0 );
102103 Parser parser (&plant, nullptr );
103104 parser.AddModelsFromUrl (controller_config.franka_model );
104105
105- // Weld the robot to the world frame
106+ // Weld the robot base to the world frame
106107 RigidTransform<double > X_WI = RigidTransform<double >::Identity ();
107108 plant.WeldFrames (plant.world_frame (), plant.GetFrameByName (" panda_link0" ),
108109 X_WI);
109110
110- // Add the end effector if specified in the config
111+ // Optionally add and weld the end effector, if specified in config
111112 if (!controller_config.end_effector_name .empty ()) {
112113 drake::multibody::ModelInstanceIndex end_effector_index = parser.AddModels (
113114 FindResourceOrThrow (controller_config.end_effector_model ))[0 ];
@@ -126,13 +127,13 @@ int DoMain(int argc, char* argv[]) {
126127 plant.Finalize ();
127128 auto plant_context = plant.CreateDefaultContext ();
128129
129- // Create LCM interface
130+ // Create LCM interface for communication
130131 drake::lcm::DrakeLcm lcm (" udpm://239.255.76.67:7667?ttl=0" );
131132
132- // Add LCM systems for communication
133+ // Add LCM systems for state, command, and trajectory communication
133134 auto state_receiver = builder.AddSystem <RobotOutputReceiver>(plant);
134- auto end_effector_trajectory_sub = builder. AddSystem (
135- LcmSubscriberSystem::Make<c3::lcmt_c3_trajectory>(
135+ auto end_effector_trajectory_sub =
136+ builder. AddSystem ( LcmSubscriberSystem::Make<c3::lcmt_c3_trajectory>(
136137 lcm_channel_params.c3_actor_channel , &lcm));
137138 auto end_effector_position_receiver =
138139 builder.AddSystem <LcmC3TrajectoryReceiver>(
@@ -152,6 +153,8 @@ int DoMain(int argc, char* argv[]) {
152153 TriggerTypeSet ({TriggerType::kForced })));
153154 auto franka_command_sender = builder.AddSystem <RobotCommandSender>(plant);
154155 auto osc_command_sender = builder.AddSystem <RobotCommandSender>(plant);
156+
157+ // Trajectory generators for end effector position, orientation, and force
155158 auto end_effector_trajectory =
156159 builder.AddSystem <systems::EndEffectorTrajectoryGenerator>(
157160 controller_config.neutral_position );
@@ -164,6 +167,8 @@ int DoMain(int argc, char* argv[]) {
164167 controller_config.track_end_effector_orientation );
165168 auto end_effector_force_trajectory =
166169 builder.AddSystem <systems::EndEffectorForceTrajectoryGenerator>();
170+
171+ // Radio input for remote control
167172 auto radio_sub =
168173 builder.AddSystem (LcmSubscriberSystem::Make<dairlib::lcmt_radio_out>(
169174 lcm_channel_params.radio_channel , &lcm));
@@ -173,7 +178,7 @@ int DoMain(int argc, char* argv[]) {
173178 auto osc = builder.AddSystem <OperationalSpaceControl>(
174179 plant, plant_context.get (), false );
175180
176- // Add debug publisher if specified
181+ // Optionally add debug publisher for OSC internal state
177182 if (controller_config.publish_debug_info ) {
178183 auto osc_debug_pub =
179184 builder.AddSystem (LcmPublisherSystem::Make<dairlib::lcmt_osc_output>(
@@ -183,7 +188,7 @@ int DoMain(int argc, char* argv[]) {
183188 osc_debug_pub->get_input_port ());
184189 }
185190
186- // Configure tracking data for OSC
191+ // Configure tracking data for OSC: position, orientation, force, and joint
187192 auto end_effector_position_tracking_data =
188193 std::make_unique<TransTaskSpaceTrackingData>(
189194 " end_effector_target" , controller_config.K_p_end_effector ,
@@ -195,6 +200,7 @@ int DoMain(int argc, char* argv[]) {
195200 controller_config.end_effector_acceleration * Vector3d::Ones ();
196201 end_effector_position_tracking_data->SetCmdAccelerationBounds (
197202 -end_effector_acceleration_limits, end_effector_acceleration_limits);
203+
198204 auto mid_link_position_tracking_data_for_rel =
199205 std::make_unique<JointSpaceTrackingData>(
200206 " panda_joint2_target" , controller_config.K_p_mid_link ,
@@ -216,8 +222,11 @@ int DoMain(int argc, char* argv[]) {
216222 controller_config.W_end_effector_rot , plant, plant);
217223 end_effector_orientation_tracking_data->AddFrameToTrack (
218224 controller_config.end_effector_name );
225+
219226 Eigen::VectorXd orientation_target = Eigen::VectorXd::Zero (4 );
220227 orientation_target (0 ) = 1 ;
228+
229+ // Register all tracking data with the OSC
221230 osc->AddTrackingData (std::move (end_effector_position_tracking_data));
222231 osc->AddConstTrackingData (std::move (mid_link_position_tracking_data_for_rel),
223232 1.6 * VectorXd::Ones (1 ));
@@ -232,7 +241,10 @@ int DoMain(int argc, char* argv[]) {
232241
233242 osc->Build ();
234243
235- // Connect systems in the diagram
244+ // Connect all systems in the diagram
245+
246+ // If enabled, remove gravity compensation from OSC output before sending to
247+ // robot
236248 if (controller_config.cancel_gravity_compensation ) {
237249 auto gravity_compensator =
238250 builder.AddSystem <GravityCompensationRemover>(plant, *plant_context);
@@ -251,24 +263,29 @@ int DoMain(int argc, char* argv[]) {
251263 franka_command_sender->get_input_port (0 ));
252264 }
253265
266+ // Connect radio input to trajectory generators
254267 builder.Connect (*radio_sub, *radio_to_vector);
255268 builder.Connect (radio_to_vector->get_output_port (),
256269 end_effector_trajectory->get_input_port_radio ());
257270 builder.Connect (radio_to_vector->get_output_port (),
258271 end_effector_orientation_trajectory->get_input_port_radio ());
259272 builder.Connect (radio_to_vector->get_output_port (),
260273 end_effector_force_trajectory->get_input_port_radio ());
274+
275+ // Connect command senders to LCM publishers
261276 builder.Connect (franka_command_sender->get_output_port (),
262277 franka_command_pub->get_input_port ());
263278 builder.Connect (osc_command_sender->get_output_port (),
264279 osc_command_pub->get_input_port ());
265280 builder.Connect (osc->get_output_port_osc_command (),
266281 osc_command_sender->get_input_port (0 ));
267282
283+ // Connect state and trajectory receivers to OSC and trajectory generators
268284 builder.Connect (state_receiver->get_output_port (0 ),
269285 osc->get_input_port_robot_output ());
270- builder.Connect (end_effector_trajectory_sub->get_output_port (),
271- end_effector_position_receiver->get_input_port_lcm_trajectory ());
286+ builder.Connect (
287+ end_effector_trajectory_sub->get_output_port (),
288+ end_effector_position_receiver->get_input_port_lcm_trajectory ());
272289 builder.Connect (end_effector_trajectory_sub->get_output_port (),
273290 end_effector_force_receiver->get_input_port_lcm_trajectory ());
274291 builder.Connect (
@@ -289,11 +306,11 @@ int DoMain(int argc, char* argv[]) {
289306 builder.Connect (end_effector_force_trajectory->get_output_port (0 ),
290307 osc->get_input_port_tracking_data (" end_effector_force" ));
291308
292- // Build the complete diagram
309+ // Build the complete system diagram
293310 auto owned_diagram = builder.Build ();
294311 owned_diagram->set_name ((" plate_balancing/osc_controller" ));
295312
296- // Run lcm -driven simulation
313+ // Run the LCM -driven control loop (real-time or simulation)
297314 LcmDrivenLoop<dairlib::lcmt_robot_output> loop (
298315 &lcm, std::move (owned_diagram), state_receiver,
299316 lcm_channel_params.franka_state_channel , true );
@@ -305,6 +322,7 @@ int DoMain(int argc, char* argv[]) {
305322} // namespace examples
306323} // namespace dairlib
307324
325+ // Main entry point
308326int main (int argc, char * argv[]) {
309327 return dairlib::examples::plate_balancing::DoMain (argc, argv);
310328}
0 commit comments