A simple way to hack it might be to connect to phase A and phase B, leave phase C disconnected. Then send voltage commands along v_alpha only, leaving v_beta = 0.
Of course the proper way would be to dispense with the SVM all together. In this case, you may wish to use phase B and phase C (leaving phase A disconnected), since as mentioned this may have current measurement redundancy you could use (not required).
To do the proper way, you need to send your own modulation timings. You may have seen in enqueue_modulation_timings
the following:
next_timings_[0] = (uint16_t)(tA * (float)TIM_1_8_PERIOD_CLOCKS);
next_timings_[1] = (uint16_t)(tB * (float)TIM_1_8_PERIOD_CLOCKS);
next_timings_[2] = (uint16_t)(tC * (float)TIM_1_8_PERIOD_CLOCKS);
Here tA
, tB
and tC
is a number from 0.0f
to 1.0f
that describes “when this phase goes high”. So lets say we forget about phase A (you can hardcode it to 0.5f), and focus on the other two. Say you want to drive max power one way, then you set tB = 0.0f, tC = 1.0f
, which will raise phase B high very early in the cycle, and C very late: meaning phase B is high for all of it, and C low for all of it (they are low when they are not high). Conversely, if you send C high super early, and B high very late, it will be C that is high a lot, and B low, so you get max power the other way.
To give just a little voltage along +B, -C, you would set tB=0.45, tC=0.55
. This means both are low for a long while, which produces no voltage over the motor, then B goes high first while C is staying low for a bit, then C goes high as well so both sit high and then again there is no voltage.
To recap
-
tB = 0.0f, tC = 1.0f
- full bus voltage positive into B, negative into C
-
tB = 1.0f, tC = 0.0f
- full bus voltage negative into B, positive into C
-
tB = 0.5f, tC = 0.5f
- both phases go up and down together, giving 0 net voltage over motor.
- You should have
tB + tC = 1.0
, this means the 0-voltage-over-motor time is shared between high and low sides equally.
Since the modulation timings is just numbers 0.0 to 1.0, to get real volts you need to take your voltage setpoint and divide by your bus voltage. Then map it according to the rules above.
You can even do closed loop current control. Here you would need to bypass the clarke and park transforms in the top of FOC_Current
, the calculation of Ialpha, Ibeta, Id, Iq
. Instead just have Imotor
calculated by 0.5f * (I_B - I_C)
, essentially averaging the two, but one is negated since it is going out of the ODrive when the other is going in.
Hope that helps, thanks for volunteering for this!