Motor Control
the current NXC motor control function are partially uncomfortable and dysfunctional as they are based upon a (IMO) rather weird Lego firmware.
As we now will have a new firmware, the motor control functions should be revised to a more logical and more comfortable syntax and functionality.
The old NXT-Lego-FW based functions should not be necessarily provided any more, e.g., there is also no need to switch 2 or 3 or 4 motors all at once by 1 command, that simplifies the command structure respectively related to remote motors of daisy-chained EV3s).
As another example, there is no need to support the NXC-FW motor-output and motor-regulation fields any longer, and for approaching an absolute motor encoder target there should be API funtions of a completely different design.
Motor on / break / coast:
Code: Select all
OnMotor(output, pwr);
Brake(output);
Coast(output);
relative rotation:
Code: Select all
RotateMotorDegrees(output, degrees, pwr)
RotateMotorDegrees(OUT_A, 3600, 80)
Sync control: For the Synced mode it just has to be defined which is the master and which is the slave; the first which is listed should be the master, the 2nd to be slave.
All pwr or angle values passed to function are related to the master.
The Sync Ratio is based upon the percentual ratio to the master's rotation speed, e.g. 100% means equal rotation speed, 50% ==half, 0 == no slave rotation, -60%== 6/10 speed and negative direction)
Code: Select all
OnMotorSync(master_out, slave_out, master_pwr, sync_ratio)
OnMotorSync(OUT_A, OUT_D, 80, -60)
In combination to a
relative encoder target value the sync function (if provided) lets the slave approximate it's target by the fraction of the masters' rotation target. E.g.:
relative rotation target of the master: 3600
sync ratio: 50
=> synchronized rotation counts of the slave (calculated automatically): = 1800,
slave speed adjusted to the current master rotations to keep both motors synchronized in progress,
if slave is stalling, then the slave pwm power has to be increased and the master has to be slowed down.
Code: Select all
RotateMotorSyncDegrees(master_out, slave_out, master_rot_count, master_pwr, sync_ratio)
RotateMotorSyncDegrees(OUT_A, OUT_D, 3600, 80, 50)
PID control for rotation counts:
additionally p,i,d passed to the function (float values without restrictions to multiples of 32, 1, or whatever)
Absolute target approximation should be provided by functions like
Code: Select all
SetMotorTarget(output, target)
RotateToEncoderTarget(output, pwr, stop_mode) // automatic stop_mode= CONTINUE or BRAKE or COAST
Runstate(output) // IDLE or BUSY or RAMPUP or RAMPDOWN or HOLD
// stopping motors or interrupting any current motor control by:
Brake(output)
Coast(output)
PID control for target approximation:
additionally p,i,d passed to the function
All motor controlling will have to run in seperate tasks without any mutexes, in order to be possibly changed or interrupted at any time and to allow other motor tasks to be additionally started or stopped in between times.
As an enhancement, for PID control also other sensor inputs might be defined different from rotation counts, e.g., US Sensor values.
By this, the motors can be commanded to run until the sensor value has been reached and/or keep the distance in continuous mode (e.g., a distance of 50 (cm) given by the US sensor).
For this it should be possible to pass a function as a parameter to this PID control procedure:
Code: Select all
SetPIDReferenceInput(port, sensorfunction() )
SetPIDReferenceInput(OUT_A, RotationCount(OUT_A) ) // default
SetPIDReferenceInput(OUT_A, GetSensor (USSensor, S3) ) // customized