Page 1 of 1

How to control the PWM signal of the motor directly?

Posted: Wed Oct 13, 2021 3:59 am
by DarkKnight
Hello, I am trying to find a more accurate relation between PWM and thrust, so I build a thrust stand to implement that. Right now I want to collect the datasets about different desired pwms and corresponding thrust data so that I can use polynomial fitting to find the relation, but the problem is that

Q1: how should I generate the desired pwm signals?

Q2: Is there a python interface function so that I can send the desired pwm command on the high-level computer? or I have to write the corresponding code in STM32 in low-level computer?

Q3: Another way I want to try is I want use a arduino(as micro controller) and a motor driver to generate the PWM command and drive the motor, but I don't know what kind of motor driver that I need to use?(I used the L298N a lothttps://www.amazon.com/Qunqi-Controller ... 8191&psc=1, but the drive voltage should be around 5V-35V, which is higher than rated voltage of motor in crazyflie), could you tell me what kind of motor driver that is used on crazyflie 2.1?

Re: How to control the PWM signal of the motor directly?

Posted: Wed Oct 13, 2021 9:13 am
by tobias
Q1:
You could use parameters to set these and they are called motorPowerSet.

Q2:
You can do this from python. Use the system-id branch as inspiration and this script. The dev-systemId branch has changed the code though so that if motorPowerSet.enable == 2 then motorPowerSet.m1 is set for all motors which might be desirable to have them all change value at the same time. See this file.

Q3:
You don't need to do this, it would just become messy.

Re: How to control the PWM signal of the motor directly?

Posted: Wed Oct 20, 2021 11:00 pm
by DarkKnight
Thank you so much, and your reply is very helpful!

I followed your instruction and right now I can log the pwm and battery data from crazyflie2.1 while my thrust stand can log the thrust and rpm data. The only problem is: I adjust your system_id/collect_data.py script so that it will work on my thrust stand, and in this script I set the thrust increase/decrease step to1000 from [0,65535] to motorPowerSet.m1, but the pwm data that I have collected(pwm.m1_pwm) didn't show a increase/decrease step 1000 although the overall trend is the same with my desired pwm.

Do you know why this will happen? I have attached the data and edited collect_data.py in here.

Re: How to control the PWM signal of the motor directly?

Posted: Tue Oct 26, 2021 8:39 am
by tobias
I figured out what is happening. You need to disable ENABLE_THRUST_BAT_COMPENSATED. Also then you should switch to log motorPower.m1 as pwm.m1_pwm group will not be updated.

Re: How to control the PWM signal of the motor directly?

Posted: Fri Oct 29, 2021 12:14 am
by DarkKnight
Thank you so much for your help. I tried to use

Code: Select all

self._cf.param.set_value('motor.batCompensation',0)
and

Code: Select all

self._lg_stab.add_variable('motorPower.m1','unit16_t')
then there is an error says 'motor.batCompensation' not in param TOC' and 'variable motorPower.m1 not in TOC '. Do I have to add those two parameters in the TOC firstly? are parameters in TOC are fixed or we can add parameters that we want to log? And How should we to do that?

Re: How to control the PWM signal of the motor directly?

Posted: Fri Oct 29, 2021 6:59 am
by tobias
The ENABLE_THRUST_BAT_COMPENSATED is a compile flag and the motor pwm parameter is apparently called motor.m1.

Re: How to control the PWM signal of the motor directly?

Posted: Fri Oct 29, 2021 4:44 pm
by DarkKnight
okay. Does that means I have to uncomment ENABLE_THRUST_BAT_COMPENSATED in firmware code and flash it into the Crazyflie? why your system-id branch https://github.com/bitcraze/crazyflie-f ... ta.py#L139, you can disable the battery compensation by using self._cf.param.set_value('motor.batCompensation', 0)?

Re: How to control the PWM signal of the motor directly?

Posted: Tue Nov 02, 2021 1:14 am
by DarkKnight
I have solved it. I just refer your code in here https://github.com/bitcraze/crazyflie-f ... c/motors.c,
and then change the the firmware code by myself and then flash it into crazyflie. Right now my thrust stand works! Thank you

Re: How to control the PWM signal of the motor directly?

Posted: Sat Dec 18, 2021 4:35 pm
by DarkKnight
Hello,

Here is another question. How should I keep a PWM value for a few seconds? or How should I let motor rotates at a constant PWM value for a few seconds just like what it is shown in Fig.1?

I have tried following two ways:(1)I refer to your code https://github.com/bitcraze/crazyflie-f ... ta.py#L139. I have changed the 'time_step =0.1' to 'time_step=3' (assume I want to keep the specific PWM for 3 seconds), but the result is shown in Fig.2.

Code: Select all

    def _ramp_motors(self):
        thrust_mult = 1
        thrust_step = 500
        #time_step = 0.1
        time_step = 3
        thrust = 0
        pitch = 0
        roll = 0
        yawrate = 0

        # # Unlock startup thrust protection
        # for i in range(0, 100):
        #     self._cf.commander.send_setpoint(0, 0, 0, 0)

        localization = Localization(self._cf)

        self._cf.param.set_value('motor.batCompensation', 0)
        self._cf.param.set_value('motorPowerSet.m1', 0)
        self._cf.param.set_value('motorPowerSet.enable', 2)
        self._cf.param.set_value('system.forceArm', 1)

        while self.is_connected: #thrust >= 0:
            thrust += thrust_step * thrust_mult
            if thrust >= 65536 or thrust < 0:
            # if thrust >= 20000 or thrust < 0:
                thrust_mult *= -1
                thrust += thrust_step * thrust_mult
            print(thrust)
            # self._cf.commander.send_setpoint(roll, pitch, yawrate, thrust)
            localization.send_emergency_stop_watchdog()
            self._cf.param.set_value('motorPowerSet.m1', str(thrust))
            time.sleep(time_step)
(2) For the second way that I have tried, I just update your code like the following. However, the result is still not right.

Code: Select all

    def _ramp_motors(self):
        thrust_mult = 1
        thrust_step = 1000
        time_step = 0.1
        thrust = 0
        pitch = 0
        roll = 0
        yawrate = 0

        # # Unlock startup thrust protection
        # for i in range(0, 100):
        #     self._cf.commander.send_setpoint(0, 0, 0, 0)

        localization = Localization(self._cf)

        self._cf.param.set_value('motor.batCompensation', 0)
        self._cf.param.set_value('motorPowerSet.m1', 0)
        self._cf.param.set_value('motorPowerSet.enable', 1)
        self._cf.param.set_value('system.forceArm', 1)

        while self.is_connected: #thrust >= 0:
            thrust += thrust_step * thrust_mult
            # if thrust >= 65536 or thrust < 0:
            if thrust >= 65536*0.7 or thrust < 0:
                thrust_mult *= -1
                thrust += thrust_step * thrust_mult
            print(thrust)
            # self._cf.commander.send_setpoint(roll, pitch, yawrate, thrust)
            localization.send_emergency_stop_watchdog()
            t_start = time.time()
             while(1):
                 self._cf.param.set_value('motorPowerSet.m1', str(thrust))
                 time.sleep(0.1)
                 t_end = time.time()
                 if t_end-t_start > 3:
                     break

Could you help to take a look at it and point which part that I didn't implement it correctly? any comments would be helpful! Thank you

Re: How to control the PWM signal of the motor directly?

Posted: Thu Dec 23, 2021 10:55 am
by kimberly
hi!

Sorry for the delay in answer but as you can notice we are currently close to our holidays. Tobias will answer you question again in early january so if you still have problems, give an update or start a new thread!