Description (API) of hMotor

Hello

I want to optimize the motor control for my robot, but I have some trouble understanding the API of hMotor, e.g.:

  • What is the usage for the breaking functions (setActiveBreaking, setPassiveBreaking)?
  • How can I limit the voltage for a 6V motor (I assume the function is setPowerLimit, but how to set the limit parameter)? Is the setPower value relative to the power input?
  • What is the slew rate for and how works it?
  • What is the queue for the motor (mentioned in waitDone) and how is it used/filled?

In general the API (not only for hMotor) seems interesting and useful, but the descriptions are very short or missing, so that the functions are at least almost unusable.That’s a pity because it prevents someone from developing things with Core2.
Is there a chance to get better API documentation?

Michael

Hi Michael,

What is the usage for the breaking functions (setActiveBreaking, setPassiveBreaking)?

Active braking gives you a better control over the motor and is preferable for small DC motors in most cases. The passive braking is safer for the motor, and if your motor is not strongly overloaded or is not overheating, you probably don’t need passive braking. This is a hardware-related thing and the topic for the article, not for a short answer :slight_smile:

How can I limit the voltage for a 6V motor (I assume the function is setPowerLimit, but how to set the limit parameter)? Is the setPower value relative to the power input?

The setPower sets the average output voltage in relation to the input voltage, so with the input voltage for CORE2 Vs = 9V and power value = 666, the output voltage for motor will be 9V*666/1000 =~ 6V.
The setPowerLimit only sets the limit, so after this line:
hMot1.setPowerLimit(500);
you will not be able to set the power for hMot1 greater that 500. When you set 400, the resulting value will be still 400. When you set 800, the resulting value will be 500 (maximum) - also relative to the input voltage Vs.

What is the slew rate for and how works it?

In many applications, when you control motor, you don’t want it to reach final speed as fast as possible. Imagine that you make an internet controlled car. If you execute setPower(1000) on it’s motors, the acceleration is so large, that the front of the car lifts up. If you specify slew rate, the final speed is the same (1000 = 100% PWM), but the acceleration is lower.

The “time” value used as an argument to setSlewRate(time) method is not straightforward.
For time=0 and time=1, the setSlewRate() has no effect on the motor power.
For 0 < time < 1, the smaller the value, the longer is the acceleration.
For example, for time=0.1 you will get about half of the maximum power after about 66ms.
When time=0.01, you will get the half of the maximum power after about 660ms.

The power is updated every 10ms and the equation is:
power(t) = slewTarget*(1-(1-time)^0.1t),
where:
t - time in [ms]
time - an argument for setSlewRate() method
slewTarget - target power value (-1000 … 1000)

What is the queue for the motor (mentioned in waitDone) and how is it used/filled?

Take a look at waitDone method:(hFramework/ports/stm32/src/hMotorPimpl.cpp at master · husarion/hFramework · GitHub).
It contains not a queue but a mutex. If you execute for example rotRel, method mutex is blocked until rotation is done, or timeout occured. Motor regulator works in the separate task. Mutex is used to communicate whether motor task has finished its work.

We are working to improve the API, but there is a lot of work to do. Updates will be appear regularly.

Radek
Husarion

Hi Radek

thanks for your detailed explanation. I’d like to see such things in the API documentation :wink:.
While looking into hMotorPimpl I found another one which is unclear to me: calibrate(). What does this function?

Michael

Hi,
Is it true that setActiveBreaking is not valid when
hFramework version in WebIDE set to “Development”:?
I got an error when changing from stable.
Regards,
Fred

Regarding to the sources in GitHub it is setActiveBraking() now…

Michael

Sorry, I am little confused.
I have the following lines in my program, while hFramework version in WebIDE set to “Development”:

hMot4.setActiveBreaking();
hMot1.setActiveBreaking();

I got the error:
MotorControl.cpp:40:8: error: ‘class hFramework::hMotor’ has no member named ‘setActiveBreaking’

It was ok in ‘stable’

Fred

It was just an assumption. If you look here https://github.com/husarion/hFramework/commit/b3be66199c728d2c742357cb3e1530c97a86ad4b, there is a change of the function names. Maybe “Development” has the changed sources.

Michael

I confirm what Michael wrote above - there was a typo in the function name :wink: and it was corrected in Development version of hFramework. Now you should write:

hMot4.setActiveBraking();
hMot1.setActiveBraking();

etc.

Hi Radeknh,
I disagree with you. the typo error is in DEVELOPMENT!!!
In stable

hMot4.setActiveBreaking();
hMot1.setActiveBreaking();

are ok.

I was advised by your team to go development when using:
void resetDevices()
{
sys.disable5V(); // turn off switching transistor at the hSensor 5V supply line
sys.delay(200); // wait for discharging capacitors
sys.enable5V(); // turn on switching transistor again
sys.delay(50); // wait for stable reading from sensors
}

The errors I got in stable was:
IODevices.cpp:27:7: error: ‘class hFramework::hSystem’ has no member named ‘disable5V’
sys.disable5V(); // turn off switching transistor at the hSensor 5V supply line
^
IODevices.cpp:29:7: error: ‘class hFramework::hSystem’ has no member named ‘enable5V’
sys.enable5V(); // turn on switching transistor again

I hope this info helps you to do the proper correction in sample and/or code
Regards,
Fred

Hi Fred,

it can be confusing so I will summarize the changes.

In “Stable” version (in relation to the name on “Settings” tab in Web IDE) of hFramework:

  • there is no “sys.enable5V();” and “sys.disable5V();” functions;
  • the motor behavior can be changed using “hMotX.setActiveBreaking();” function.

In “Development” version of hFramework:

  • “sys.enable5V();” and “sys.disable5V();” functions were introduced;
  • the motor behavior can be changed using “hMotX.setActiveBraking();” function.

The Development version will be moved to Stable soon.

The second change was made because even if “breaking” is a proper word without typo or spelling error, it has a different meaning than “braking”. This function changes the “slowing down” (or, braking) behavior of motors and, therefore, “braking” is the proper word for that :slight_smile:

In case of any other questions, please don’t hesitate to ask. Sorry for inconvenience.

Hi Radek

can you please still explain the calibrate() function in hMotor?

Thanks
Michael

Hi Michael,

the calibrate() function is not very important or useful one, but of course it should be documented.
I am giving a description here, but it will be also added to official API documentation with it’s next release:

bool hMotor::calibrate(int16_t power, uint32_t maxDiff, uint32_t stableTime, bool block, uint32_t timeout)

Checks if the maximum speed for a motor with encoder does not exceed the defined value.

Used to find if the motor speed, defined as encoder ticks per period (~10ms), does not exceed the “maxDiff” value, at the defined “power”. The “stableTime” value define the minimum measurement time, needed for motor to speed up.

Parameters

power - relative power value (-1000…1000) used for measurement
maxDiff - the limiting value of encoder ticks per period (~10ms)
block - determines whether the system waits for finishing this function before performing other tasks
timeout - useful when block = true, to avoid blocking the CPU forever

Returns

true, if the motor speed exceed the limiting “maxDiff” value, otherwise false

Regards,
Radek

Just another question from the API documentation I understand that the hPIDRegulator works only with the rotation functions. In the RosBot files in hFramework it looks as if it is working also with setPower().
Did I miss something?

Michael

Hi MichaelT,

You said:

I understand that the hPIDRegulator works only with the rotation functions

It’s not 100% true. Let me explain. hPIDRegulator affects motors only if you use rotation function. It means that if you don’t use any rotation function in your code but you use setPower(), hPIDRegulator doesn’t affect the operation of the program. However hPIDRegulator uses setPower() function internally to realize their own task. I will show you examples.

Look at this code:

#include "hFramework.h"

hPIDRegulator myReg;

void setupMotorPID()
{
	float kp = 5;
	float ki = 0.02;
	float kd = 100.0;

	// hPID
	myReg.setScale(1);
	myReg.setKP(kp);
	myReg.setKI(ki);
	myReg.setKD(kd);
	// hRegulator
	myReg.dtMs = 5;
	myReg.stableRange = 30;
	myReg.stableTimes = 3;

	hMotA.attachPositionRegulator(myReg);
	hMotA.resetEncoderCnt();
}

void hMain()
{
	setupMotorPID();
	
	while (1) {
		hMotA.setPower(200);
		sys.delay(1000);
	}

}

After flashed this program to you CORE2, you will see hMotA spinning forever. But if you modify hMain() like this:

void hMain()
{
	setupMotorPID();
	hMotA.rotAbs(0);

	while (1) {
		hMotA.setPower(200);
		sys.delay(1000);
	}

}

Your hMotA will be hold still with little shake every 1 second.

If you try it yourself you will understand difference very quickly.

Regards,
Hubert