@@ -74,7 +74,37 @@ VelocitySmoother::on_configure(const rclcpp_lifecycle::State & state)
74
74
node->get_parameter (" max_accel" , max_accels_);
75
75
node->get_parameter (" max_decel" , max_decels_);
76
76
77
- for (unsigned int i = 0 ; i != 3 ; i++) {
77
+ // Get feature parameters
78
+ declare_parameter_if_not_declared (node, " odom_topic" , rclcpp::ParameterValue (" odom" ));
79
+ declare_parameter_if_not_declared (node, " odom_duration" , rclcpp::ParameterValue (0.1 ));
80
+ declare_parameter_if_not_declared (
81
+ node, " deadband_velocity" , rclcpp::ParameterValue (std::vector<double >{0.0 , 0.0 , 0.0 }));
82
+ declare_parameter_if_not_declared (node, " velocity_timeout" , rclcpp::ParameterValue (1.0 ));
83
+ node->get_parameter (" odom_topic" , odom_topic_);
84
+ node->get_parameter (" odom_duration" , odom_duration_);
85
+ node->get_parameter (" deadband_velocity" , deadband_velocities_);
86
+ node->get_parameter (" velocity_timeout" , velocity_timeout_dbl);
87
+ velocity_timeout_ = rclcpp::Duration::from_seconds (velocity_timeout_dbl);
88
+
89
+ // Check if parameters are properly set
90
+ size_t size = max_velocities_.size ();
91
+ is_6dof_ = (size == 6 );
92
+
93
+ if ((size != 3 && size != 6 ) ||
94
+ min_velocities_.size () != size ||
95
+ max_accels_.size () != size ||
96
+ max_decels_.size () != size ||
97
+ deadband_velocities_.size () != size)
98
+ {
99
+ RCLCPP_ERROR (
100
+ get_logger (),
101
+ " Invalid setting of kinematic and/or deadband limits!"
102
+ " All limits must be size of 3 (x, y, theta) or 6 (x, y, z, r, p, y)" );
103
+ on_cleanup (state);
104
+ return nav2::CallbackReturn::FAILURE;
105
+ }
106
+
107
+ for (unsigned int i = 0 ; i != size; i++) {
78
108
if (max_decels_[i] > 0.0 ) {
79
109
RCLCPP_ERROR (
80
110
get_logger (),
@@ -108,29 +138,6 @@ VelocitySmoother::on_configure(const rclcpp_lifecycle::State & state)
108
138
}
109
139
}
110
140
111
- // Get feature parameters
112
- declare_parameter_if_not_declared (node, " odom_topic" , rclcpp::ParameterValue (" odom" ));
113
- declare_parameter_if_not_declared (node, " odom_duration" , rclcpp::ParameterValue (0.1 ));
114
- declare_parameter_if_not_declared (
115
- node, " deadband_velocity" , rclcpp::ParameterValue (std::vector<double >{0.0 , 0.0 , 0.0 }));
116
- declare_parameter_if_not_declared (node, " velocity_timeout" , rclcpp::ParameterValue (1.0 ));
117
- node->get_parameter (" odom_topic" , odom_topic_);
118
- node->get_parameter (" odom_duration" , odom_duration_);
119
- node->get_parameter (" deadband_velocity" , deadband_velocities_);
120
- node->get_parameter (" velocity_timeout" , velocity_timeout_dbl);
121
- velocity_timeout_ = rclcpp::Duration::from_seconds (velocity_timeout_dbl);
122
-
123
- if (max_velocities_.size () != 3 || min_velocities_.size () != 3 ||
124
- max_accels_.size () != 3 || max_decels_.size () != 3 || deadband_velocities_.size () != 3 )
125
- {
126
- RCLCPP_ERROR (
127
- get_logger (),
128
- " Invalid setting of kinematic and/or deadband limits!"
129
- " All limits must be size of 3 representing (x, y, theta)." );
130
- on_cleanup (state);
131
- return nav2::CallbackReturn::FAILURE;
132
- }
133
-
134
141
// Get control type
135
142
if (feedback_type == " OPEN_LOOP" ) {
136
143
open_loop_ = true ;
@@ -332,15 +339,36 @@ void VelocitySmoother::smootherTimer()
332
339
}
333
340
334
341
// Apply absolute velocity restrictions to the command
335
- command_->twist .linear .x = std::clamp (
336
- command_->twist .linear .x , min_velocities_[0 ],
337
- max_velocities_[0 ]);
338
- command_->twist .linear .y = std::clamp (
339
- command_->twist .linear .y , min_velocities_[1 ],
340
- max_velocities_[1 ]);
341
- command_->twist .angular .z = std::clamp (
342
- command_->twist .angular .z , min_velocities_[2 ],
343
- max_velocities_[2 ]);
342
+ if (!is_6dof_) {
343
+ command_->twist .linear .x = std::clamp (
344
+ command_->twist .linear .x , min_velocities_[0 ],
345
+ max_velocities_[0 ]);
346
+ command_->twist .linear .y = std::clamp (
347
+ command_->twist .linear .y , min_velocities_[1 ],
348
+ max_velocities_[1 ]);
349
+ command_->twist .angular .z = std::clamp (
350
+ command_->twist .angular .z , min_velocities_[2 ],
351
+ max_velocities_[2 ]);
352
+ } else {
353
+ command_->twist .linear .x = std::clamp (
354
+ command_->twist .linear .x , min_velocities_[0 ],
355
+ max_velocities_[0 ]);
356
+ command_->twist .linear .y = std::clamp (
357
+ command_->twist .linear .y , min_velocities_[1 ],
358
+ max_velocities_[1 ]);
359
+ command_->twist .linear .z = std::clamp (
360
+ command_->twist .linear .z , min_velocities_[2 ],
361
+ max_velocities_[2 ]);
362
+ command_->twist .angular .x = std::clamp (
363
+ command_->twist .angular .x , min_velocities_[3 ],
364
+ max_velocities_[3 ]);
365
+ command_->twist .angular .y = std::clamp (
366
+ command_->twist .angular .y , min_velocities_[4 ],
367
+ max_velocities_[4 ]);
368
+ command_->twist .angular .z = std::clamp (
369
+ command_->twist .angular .z , min_velocities_[5 ],
370
+ max_velocities_[5 ]);
371
+ }
344
372
345
373
// Find if any component is not within the acceleration constraints. If so, store the most
346
374
// significant scale factor to apply to the vector <dvx, dvy, dvw>, eta, to reduce all axes
@@ -350,42 +378,113 @@ void VelocitySmoother::smootherTimer()
350
378
double eta = 1.0 ;
351
379
if (scale_velocities_) {
352
380
double curr_eta = -1.0 ;
381
+ if (!is_6dof_) {
382
+ curr_eta = findEtaConstraint (
383
+ current_.twist .linear .x , command_->twist .linear .x , max_accels_[0 ], max_decels_[0 ]);
384
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
385
+ eta = curr_eta;
386
+ }
353
387
354
- curr_eta = findEtaConstraint (
355
- current_.twist .linear .x , command_->twist .linear .x , max_accels_[0 ], max_decels_[0 ]);
356
- if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
357
- eta = curr_eta;
358
- }
388
+ curr_eta = findEtaConstraint (
389
+ current_.twist .linear .y , command_->twist .linear .y , max_accels_[1 ], max_decels_[1 ]);
390
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
391
+ eta = curr_eta;
392
+ }
359
393
360
- curr_eta = findEtaConstraint (
361
- current_.twist .linear .y , command_->twist .linear .y , max_accels_[1 ], max_decels_[1 ]);
362
- if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
363
- eta = curr_eta;
364
- }
394
+ curr_eta = findEtaConstraint (
395
+ current_.twist .angular .z , command_->twist .angular .z , max_accels_[2 ], max_decels_[2 ]);
396
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
397
+ eta = curr_eta;
398
+ }
399
+ } else {
400
+ curr_eta = findEtaConstraint (
401
+ current_.twist .linear .x , command_->twist .linear .x , max_accels_[0 ], max_decels_[0 ]);
402
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
403
+ eta = curr_eta;
404
+ }
365
405
366
- curr_eta = findEtaConstraint (
367
- current_.twist .angular .z , command_->twist .angular .z , max_accels_[2 ], max_decels_[2 ]);
368
- if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
369
- eta = curr_eta;
406
+ curr_eta = findEtaConstraint (
407
+ current_.twist .linear .y , command_->twist .linear .y , max_accels_[1 ], max_decels_[1 ]);
408
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
409
+ eta = curr_eta;
410
+ }
411
+
412
+ curr_eta = findEtaConstraint (
413
+ current_.twist .linear .z , command_->twist .linear .z , max_accels_[2 ], max_decels_[2 ]);
414
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
415
+ eta = curr_eta;
416
+ }
417
+
418
+ curr_eta = findEtaConstraint (
419
+ current_.twist .angular .x , command_->twist .angular .x , max_accels_[3 ], max_decels_[3 ]);
420
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
421
+ eta = curr_eta;
422
+ }
423
+
424
+ curr_eta = findEtaConstraint (
425
+ current_.twist .angular .y , command_->twist .angular .y , max_accels_[4 ], max_decels_[4 ]);
426
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
427
+ eta = curr_eta;
428
+ }
429
+
430
+ curr_eta = findEtaConstraint (
431
+ current_.twist .angular .z , command_->twist .angular .z , max_accels_[5 ], max_decels_[5 ]);
432
+ if (curr_eta > 0.0 && std::fabs (1.0 - curr_eta) > std::fabs (1.0 - eta)) {
433
+ eta = curr_eta;
434
+ }
370
435
}
371
436
}
372
437
373
- cmd_vel->twist .linear .x = applyConstraints (
374
- current_.twist .linear .x , command_->twist .linear .x , max_accels_[0 ], max_decels_[0 ], eta);
375
- cmd_vel->twist .linear .y = applyConstraints (
376
- current_.twist .linear .y , command_->twist .linear .y , max_accels_[1 ], max_decels_[1 ], eta);
377
- cmd_vel->twist .angular .z = applyConstraints (
378
- current_.twist .angular .z , command_->twist .angular .z , max_accels_[2 ], max_decels_[2 ], eta);
438
+ if (!is_6dof_) {
439
+ cmd_vel->twist .linear .x = applyConstraints (
440
+ current_.twist .linear .x , command_->twist .linear .x , max_accels_[0 ], max_decels_[0 ], eta);
441
+ cmd_vel->twist .linear .y = applyConstraints (
442
+ current_.twist .linear .y , command_->twist .linear .y , max_accels_[1 ], max_decels_[1 ], eta);
443
+ cmd_vel->twist .angular .z = applyConstraints (
444
+ current_.twist .angular .z , command_->twist .angular .z , max_accels_[2 ], max_decels_[2 ], eta);
445
+ } else {
446
+ cmd_vel->twist .linear .x = applyConstraints (
447
+ current_.twist .linear .x , command_->twist .linear .x , max_accels_[0 ], max_decels_[0 ], eta);
448
+ cmd_vel->twist .linear .y = applyConstraints (
449
+ current_.twist .linear .y , command_->twist .linear .y , max_accels_[1 ], max_decels_[1 ], eta);
450
+ cmd_vel->twist .linear .z = applyConstraints (
451
+ current_.twist .linear .z , command_->twist .linear .z , max_accels_[2 ], max_decels_[2 ], eta);
452
+ cmd_vel->twist .angular .x = applyConstraints (
453
+ current_.twist .angular .x , command_->twist .angular .x , max_accels_[3 ], max_decels_[3 ], eta);
454
+ cmd_vel->twist .angular .y = applyConstraints (
455
+ current_.twist .angular .y , command_->twist .angular .y , max_accels_[4 ], max_decels_[4 ], eta);
456
+ cmd_vel->twist .angular .z = applyConstraints (
457
+ current_.twist .angular .z , command_->twist .angular .z , max_accels_[5 ], max_decels_[5 ], eta);
458
+ }
459
+
379
460
last_cmd_ = *cmd_vel;
380
461
381
- // Apply deadband restrictions & publish
382
- cmd_vel->twist .linear .x =
383
- fabs (cmd_vel->twist .linear .x ) < deadband_velocities_[0 ] ? 0.0 : cmd_vel->twist .linear .x ;
384
- cmd_vel->twist .linear .y =
385
- fabs (cmd_vel->twist .linear .y ) < deadband_velocities_[1 ] ? 0.0 : cmd_vel->twist .linear .y ;
386
- cmd_vel->twist .angular .z =
387
- fabs (cmd_vel->twist .angular .z ) < deadband_velocities_[2 ] ? 0.0 : cmd_vel->twist .angular .z ;
388
462
463
+ // Apply deadband restrictions & publish
464
+ if (!is_6dof_) {
465
+ cmd_vel->twist .linear .x =
466
+ fabs (cmd_vel->twist .linear .x ) < deadband_velocities_[0 ] ? 0.0 : cmd_vel->twist .linear .x ;
467
+ cmd_vel->twist .linear .y =
468
+ fabs (cmd_vel->twist .linear .y ) < deadband_velocities_[1 ] ? 0.0 : cmd_vel->twist .linear .y ;
469
+ cmd_vel->twist .linear .z = command_->twist .linear .z ;
470
+ cmd_vel->twist .angular .x = command_->twist .angular .x ;
471
+ cmd_vel->twist .angular .y = command_->twist .angular .y ;
472
+ cmd_vel->twist .angular .z =
473
+ fabs (cmd_vel->twist .angular .z ) < deadband_velocities_[2 ] ? 0.0 : cmd_vel->twist .angular .z ;
474
+ } else {
475
+ cmd_vel->twist .linear .x =
476
+ fabs (cmd_vel->twist .linear .x ) < deadband_velocities_[0 ] ? 0.0 : cmd_vel->twist .linear .x ;
477
+ cmd_vel->twist .linear .y =
478
+ fabs (cmd_vel->twist .linear .y ) < deadband_velocities_[1 ] ? 0.0 : cmd_vel->twist .linear .y ;
479
+ cmd_vel->twist .linear .z =
480
+ fabs (cmd_vel->twist .linear .z ) < deadband_velocities_[2 ] ? 0.0 : cmd_vel->twist .linear .z ;
481
+ cmd_vel->twist .angular .x =
482
+ fabs (cmd_vel->twist .angular .x ) < deadband_velocities_[3 ] ? 0.0 : cmd_vel->twist .angular .x ;
483
+ cmd_vel->twist .angular .y =
484
+ fabs (cmd_vel->twist .angular .y ) < deadband_velocities_[4 ] ? 0.0 : cmd_vel->twist .angular .y ;
485
+ cmd_vel->twist .angular .z =
486
+ fabs (cmd_vel->twist .angular .z ) < deadband_velocities_[5 ] ? 0.0 : cmd_vel->twist .angular .z ;
487
+ }
389
488
smoothed_cmd_pub_->publish (std::move (cmd_vel));
390
489
}
391
490
@@ -423,15 +522,16 @@ VelocitySmoother::dynamicParametersCallback(std::vector<rclcpp::Parameter> param
423
522
shared_from_this (), odom_duration_, odom_topic_);
424
523
}
425
524
} else if (param_type == ParameterType::PARAMETER_DOUBLE_ARRAY) {
426
- if (parameter.as_double_array ().size () != 3 ) {
427
- RCLCPP_WARN (get_logger (), " Invalid size of parameter %s. Must be size 3" ,
428
- param_name.c_str ());
525
+ size_t size = is_6dof_ ? 6 : 3 ;
526
+ if (parameter.as_double_array ().size () != size) {
527
+ RCLCPP_WARN (get_logger (), " Invalid size of parameter %s. Must be size %ld" ,
528
+ param_name.c_str (), size);
429
529
result.successful = false ;
430
530
break ;
431
531
}
432
532
433
533
if (param_name == " max_velocity" ) {
434
- for (unsigned int i = 0 ; i != 3 ; i++) {
534
+ for (unsigned int i = 0 ; i != size ; i++) {
435
535
if (parameter.as_double_array ()[i] < 0.0 ) {
436
536
RCLCPP_WARN (
437
537
get_logger (),
@@ -443,7 +543,7 @@ VelocitySmoother::dynamicParametersCallback(std::vector<rclcpp::Parameter> param
443
543
max_velocities_ = parameter.as_double_array ();
444
544
}
445
545
} else if (param_name == " min_velocity" ) {
446
- for (unsigned int i = 0 ; i != 3 ; i++) {
546
+ for (unsigned int i = 0 ; i != size ; i++) {
447
547
if (parameter.as_double_array ()[i] > 0.0 ) {
448
548
RCLCPP_WARN (
449
549
get_logger (),
@@ -455,7 +555,7 @@ VelocitySmoother::dynamicParametersCallback(std::vector<rclcpp::Parameter> param
455
555
min_velocities_ = parameter.as_double_array ();
456
556
}
457
557
} else if (param_name == " max_accel" ) {
458
- for (unsigned int i = 0 ; i != 3 ; i++) {
558
+ for (unsigned int i = 0 ; i != size ; i++) {
459
559
if (parameter.as_double_array ()[i] < 0.0 ) {
460
560
RCLCPP_WARN (
461
561
get_logger (),
@@ -467,7 +567,7 @@ VelocitySmoother::dynamicParametersCallback(std::vector<rclcpp::Parameter> param
467
567
max_accels_ = parameter.as_double_array ();
468
568
}
469
569
} else if (param_name == " max_decel" ) {
470
- for (unsigned int i = 0 ; i != 3 ; i++) {
570
+ for (unsigned int i = 0 ; i != size ; i++) {
471
571
if (parameter.as_double_array ()[i] > 0.0 ) {
472
572
RCLCPP_WARN (
473
573
get_logger (),
0 commit comments