Skip to content

Commit aab17f0

Browse files
authored
Merge pull request #7 from RaspberryPiFoundation/n-rotations
Allow rotating of single or multiple motors by specifying number of rotations, rather than degrees
2 parents 01f3948 + 181a90d commit aab17f0

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

src/motor.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,66 @@ Motor_run_for_degrees(PyObject *self, PyObject *args, PyObject *kwds)
11521152
}
11531153

11541154

1155+
static PyObject *
1156+
Motor_run_for_rotations(PyObject *self, PyObject *args, PyObject *kwds)
1157+
{
1158+
MotorObject *motor = (MotorObject *)self;
1159+
static char *kwlist[] = {
1160+
"rotations", "speed", "max_power", "stop",
1161+
"acceleration", "deceleration", "stall",
1162+
"blocking", NULL
1163+
};
1164+
int32_t rotations;
1165+
int32_t speed;
1166+
uint32_t power = motor->default_max_power;
1167+
uint32_t accel = motor->default_acceleration;
1168+
uint32_t decel = motor->default_deceleration;
1169+
int stall = motor->default_stall;
1170+
uint32_t stop = MOTOR_STOP_USE_DEFAULT;
1171+
uint8_t use_profile = 0;
1172+
int parsed_stop;
1173+
int blocking = 1;
1174+
1175+
if (motor->is_detached)
1176+
{
1177+
PyErr_SetString(cmd_get_exception(), "Motor is detached");
1178+
return NULL;
1179+
}
1180+
1181+
if (PyArg_ParseTupleAndKeywords(args, kwds,
1182+
"ii|IIIIpp:run_for_rotations", kwlist,
1183+
&rotations, &speed, &power, &stop,
1184+
&accel, &decel, &stall, &blocking) == 0)
1185+
return NULL;
1186+
1187+
if (device_ensure_mode_info(motor->device) < 0)
1188+
return NULL;
1189+
1190+
speed = CLIP(speed, SPEED_MIN, SPEED_MAX);
1191+
power = CLIP(power, POWER_MIN, POWER_MAX);
1192+
accel = CLIP(accel, ACCEL_MIN, ACCEL_MAX);
1193+
decel = CLIP(decel, DECEL_MIN, DECEL_MAX);
1194+
if ((parsed_stop = parse_stop(motor, stop)) < 0)
1195+
{
1196+
PyErr_Format(PyExc_ValueError, "Invalid stop state: %d", stop);
1197+
return NULL;
1198+
}
1199+
1200+
if (set_acceleration(motor, accel, &use_profile) < 0 ||
1201+
set_deceleration(motor, decel, &use_profile) < 0 ||
1202+
set_stall(motor, stall) < 0)
1203+
return NULL;
1204+
1205+
if (cmd_start_speed_for_degrees(port_get_id(motor->port),
1206+
rotations * 360, speed, power,
1207+
(uint8_t)parsed_stop, use_profile,
1208+
blocking) < 0)
1209+
return NULL;
1210+
1211+
Py_RETURN_NONE;
1212+
}
1213+
1214+
11551215
static PyObject *
11561216
Motor_run_to_position(PyObject *self, PyObject *args, PyObject *kwds)
11571217
{
@@ -1352,6 +1412,11 @@ static PyMethodDef Motor_methods[] = {
13521412
METH_VARARGS | METH_KEYWORDS,
13531413
"Run the motor for the given angle"
13541414
},
1415+
{
1416+
"run_for_rotations", (PyCFunction)Motor_run_for_rotations,
1417+
METH_VARARGS | METH_KEYWORDS,
1418+
"Run the motor for rotations"
1419+
},
13551420
{
13561421
"run_to_position", (PyCFunction)Motor_run_to_position,
13571422
METH_VARARGS | METH_KEYWORDS,

src/pair.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,61 @@ MotorPair_run_for_degrees(PyObject *self, PyObject *args, PyObject *kwds)
903903
Py_RETURN_NONE;
904904
}
905905

906+
static PyObject *
907+
MotorPair_run_for_rotations(PyObject *self, PyObject *args, PyObject *kwds)
908+
{
909+
MotorPairObject *pair = (MotorPairObject *)self;
910+
static char *kwlist[] = {
911+
"rotations", "speed0", "speed1", "max_power", "stop",
912+
"acceleration", "deceleration", "blocking",
913+
NULL
914+
};
915+
int32_t rotations;
916+
int32_t speed0, speed1;
917+
uint32_t power = 100;
918+
uint32_t accel = pair->default_acceleration;
919+
uint32_t decel = pair->default_deceleration;
920+
uint32_t stop = MOTOR_STOP_USE_DEFAULT;
921+
uint8_t use_profile = 0;
922+
int parsed_stop;
923+
int blocking = 1;
924+
925+
if (!PyArg_ParseTupleAndKeywords(args, kwds,
926+
"iii|IIIIp:run_for_rotations", kwlist,
927+
&rotations, &speed0, &speed1,
928+
&power, &stop,
929+
&accel, &decel, &blocking))
930+
return NULL;
931+
932+
/* If the object is invalid, return False */
933+
if (pair->id == INVALID_ID)
934+
Py_RETURN_FALSE;
935+
936+
speed0 = CLIP(speed0, SPEED_MIN, SPEED_MAX);
937+
speed1 = CLIP(speed1, SPEED_MIN, SPEED_MAX);
938+
power = CLIP(power, POWER_MIN, POWER_MAX);
939+
accel = CLIP(accel, ACCEL_MIN, ACCEL_MAX);
940+
decel = CLIP(decel, DECEL_MIN, DECEL_MAX);
941+
942+
if ((parsed_stop = parse_stop(stop)) < 0)
943+
{
944+
PyErr_Format(PyExc_ValueError, "Invalid stop state: %d", stop);
945+
return NULL;
946+
}
947+
948+
if (set_acceleration(pair, accel, &use_profile) < 0 ||
949+
set_deceleration(pair, decel, &use_profile) < 0)
950+
return NULL;
951+
952+
if (cmd_start_speed_for_degrees_pair(pair->id, rotations * 360,
953+
speed0, speed1, power,
954+
(uint8_t)parsed_stop,
955+
use_profile, blocking) < 0)
956+
return NULL;
957+
958+
Py_RETURN_NONE;
959+
}
960+
906961

907962
static PyObject *
908963
MotorPair_run_to_position(PyObject *self, PyObject *args, PyObject *kwds)
@@ -1023,6 +1078,11 @@ static PyMethodDef MotorPair_methods[] = {
10231078
METH_VARARGS | METH_KEYWORDS,
10241079
"Run the motor pair for the given angle"
10251080
},
1081+
{
1082+
"run_for_rotations", (PyCFunction)MotorPair_run_for_rotations,
1083+
METH_VARARGS | METH_KEYWORDS,
1084+
"Run the motor pair for N rotations"
1085+
},
10261086
{
10271087
"run_to_position", (PyCFunction)MotorPair_run_to_position,
10281088
METH_VARARGS | METH_KEYWORDS,

0 commit comments

Comments
 (0)