@@ -616,6 +616,9 @@ pbio_error_t pbio_drivebase_drive_straight(pbio_drivebase_t *db, int32_t distanc
616616/**
617617 * Starts the drivebase controllers to run by an arc of given radius and angle.
618618 *
619+ * curve() was originally used as a generalization of turn(), but is now
620+ * deprecated in favor of the arc methods, which have more practical arguments.
621+ *
619622 * This will use the default speed.
620623 *
621624 * @param [in] db The drivebase instance.
@@ -636,6 +639,74 @@ pbio_error_t pbio_drivebase_drive_curve(pbio_drivebase_t *db, int32_t radius, in
636639 return pbio_drivebase_drive_relative (db , arc_length , 0 , arc_angle , 0 , on_completion );
637640}
638641
642+ /**
643+ * Starts the drivebase controllers to run by an arc of given radius and angle.
644+ *
645+ * With a positive radius, the robot drives along a circle to its right.
646+ * With a negative radius, the robot drives along a circle to its left.
647+ *
648+ * A positive angle means driving forward along the circle, negative is reverse.
649+ *
650+ * This will use the default speed.
651+ *
652+ * @param [in] db The drivebase instance.
653+ * @param [in] radius Radius of the arc in mm.
654+ * @param [in] angle The angle to drive along the circle in degrees.
655+ * @param [in] on_completion What to do when reaching the target.
656+ * @return Error code.
657+ */
658+ pbio_error_t pbio_drivebase_drive_arc_angle (pbio_drivebase_t * db , int32_t radius , int32_t angle , pbio_control_on_completion_t on_completion ) {
659+
660+ if (pbio_int_math_abs (radius ) < 10 ) {
661+ return PBIO_ERROR_INVALID_ARG ;
662+ }
663+
664+ // Arc length is radius * angle, with the user angle parameter governing
665+ // the drive direction as positive forward.
666+ int32_t drive_distance = (10 * angle * pbio_int_math_abs (radius )) / 573 ;
667+
668+ // The user angle is positive for going forward, no matter the radius sign.
669+ // The internal functions expect positive to mean clockwise for the robot.
670+ int32_t direction = (radius > 0 ) == (angle > 0 ) ? 1 : -1 ;
671+ int32_t drive_angle = pbio_int_math_abs (angle ) * direction ;
672+
673+ // Execute the common drive command at default speed (by passing 0 speed).
674+ return pbio_drivebase_drive_relative (db , drive_distance , 0 , drive_angle , 0 , on_completion );
675+ }
676+
677+ /**
678+ * Starts the drivebase controllers to run by an arc of given radius and arc length.
679+ *
680+ * With a positive radius, the robot drives along a circle to its right.
681+ * With a negative radius, the robot drives along a circle to its left.
682+ *
683+ * A positive distance means driving forward along the circle, negative is reverse.
684+ *
685+ * This will use the default speed.
686+ *
687+ * @param [in] db The drivebase instance.
688+ * @param [in] radius Radius of the arc in mm.
689+ * @param [in] distance The distance to drive (arc length) in mm.
690+ * @param [in] on_completion What to do when reaching the target.
691+ * @return Error code.
692+ */
693+ pbio_error_t pbio_drivebase_drive_arc_distance (pbio_drivebase_t * db , int32_t radius , int32_t distance , pbio_control_on_completion_t on_completion ) {
694+
695+ if (pbio_int_math_abs (radius ) < 10 ) {
696+ return PBIO_ERROR_INVALID_ARG ;
697+ }
698+
699+ // The internal functions expect positive to mean clockwise for the robot
700+ // with respect to the ground, not in relation to any particular circle.
701+ int32_t angle = pbio_int_math_abs (distance ) * 573 / pbio_int_math_abs (radius ) / 10 ;
702+ if ((radius < 0 ) != (distance < 0 )) {
703+ angle *= -1 ;
704+ }
705+
706+ // Execute the common drive command at default speed (by passing 0 speed).
707+ return pbio_drivebase_drive_relative (db , distance , 0 , angle , 0 , on_completion );
708+ }
709+
639710/**
640711 * Starts the drivebase controllers to run for a given duration.
641712 *
0 commit comments