How to control the PWM signal of the motor directly?

Discussions and questions about the Crazyflie Nano Quadcopter
Post Reply
DarkKnight
Member
Posts: 39
Joined: Tue Jun 15, 2021 10:19 pm

How to control the PWM signal of the motor directly?

Post 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?
tobias
Bitcraze
Posts: 2339
Joined: Mon Jan 28, 2013 7:17 pm
Location: Sweden

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

Post 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.
DarkKnight
Member
Posts: 39
Joined: Tue Jun 15, 2021 10:19 pm

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

Post 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.
Attachments
data.csv
(22.85 KiB) Downloaded 951 times
collect_data.py
(5.76 KiB) Downloaded 997 times
tobias
Bitcraze
Posts: 2339
Joined: Mon Jan 28, 2013 7:17 pm
Location: Sweden

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

Post 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.
DarkKnight
Member
Posts: 39
Joined: Tue Jun 15, 2021 10:19 pm

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

Post 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?
tobias
Bitcraze
Posts: 2339
Joined: Mon Jan 28, 2013 7:17 pm
Location: Sweden

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

Post by tobias »

The ENABLE_THRUST_BAT_COMPENSATED is a compile flag and the motor pwm parameter is apparently called motor.m1.
DarkKnight
Member
Posts: 39
Joined: Tue Jun 15, 2021 10:19 pm

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

Post 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)?
DarkKnight
Member
Posts: 39
Joined: Tue Jun 15, 2021 10:19 pm

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

Post 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
DarkKnight
Member
Posts: 39
Joined: Tue Jun 15, 2021 10:19 pm

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

Post 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
Attachments
1.jpg
2.jpg
3.jpg
kimberly
Bitcraze
Posts: 1050
Joined: Fri Jul 06, 2018 11:13 am

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

Post 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!
Post Reply