Skip to main content
added 176 characters in body
Source Link
G. Sliepen
  • 69.3k
  • 3
  • 75
  • 180

Since both leftTargetPWM and leftActualPWM are uint8_t values, the result will also be an uint8_t value. IfDepending on the sumtype of the two values would be larger than 255variables, the result willaddition could overflow and wrapbefore the division is performed, which would result in an unexpected result, possibly leading to badly behaving motor speed. Only after that will

While it divide by 2. A safer way wouldmight actually be safe here due to divide each value by two firstinteger promotion rules, you could explicitly convert the values to a type that you know is safe for the given operation:

leftActualPWM = (static_cast<uint16_t>(leftTargetPWM / 2) + leftActualPWM) / 2;

But that way you will lose one bit of precision. You can also cast one of the values to uint16_tOr if possible, so the result will be anas Toby Speight suggested, use C++20's uint16_t valuestd::midpoint():

leftActualPWM = (static_cast<uint16_t>std::midpoint(leftTargetPWM) +, leftActualPWM) / 2;;

IfAlternatively, if the CPU in your Arduino has hardware support for floating point operations, I would rather store most variables as float, and only convert to uint8_t PWM values right before calling analogWrite().

Since both leftTargetPWM and leftActualPWM are uint8_t values, the result will also be an uint8_t value. If the sum of the two values would be larger than 255, the result will overflow and wrap. Only after that will it divide by 2. A safer way would be to divide each value by two first:

leftActualPWM = leftTargetPWM / 2 + leftActualPWM / 2;

But that way you will lose one bit of precision. You can also cast one of the values to uint16_t, so the result will be an uint16_t value:

leftActualPWM = (static_cast<uint16_t>(leftTargetPWM) + leftActualPWM) / 2;

If the CPU in your Arduino has hardware support for floating point operations, I would rather store most variables as float, and only convert to uint8_t PWM values right before calling analogWrite().

Depending on the type of the variables, the addition could overflow before the division is performed, which would result in an unexpected result, possibly leading to badly behaving motor speed.

While it might actually be safe here due to integer promotion rules, you could explicitly convert the values to a type that you know is safe for the given operation:

leftActualPWM = (static_cast<uint16_t>(leftTargetPWM) + leftActualPWM) / 2;

Or if possible, as Toby Speight suggested, use C++20's std::midpoint():

leftActualPWM = std::midpoint(leftTargetPWM, leftActualPWM);

Alternatively, if the CPU in your Arduino has hardware support for floating point operations, I would rather store most variables as float, and only convert to uint8_t PWM values right before calling analogWrite().

added 1 character in body
Source Link
Ben A
  • 10.8k
  • 5
  • 38
  • 103

Since both leftTargetPWM and leftActualPWM are uit8_tuint8_t values, the result will also be an uint8_t value. If the sum of the two values would be larger than 255, the result will overflow and wrap. Only after that will it divide by 2. A safer way would be to divide each value by two first:

Since both leftTargetPWM and leftActualPWM are uit8_t values, the result will also be an uint8_t value. If the sum of the two values would be larger than 255, the result will overflow and wrap. Only after that will it divide by 2. A safer way would be to divide each value by two first:

Since both leftTargetPWM and leftActualPWM are uint8_t values, the result will also be an uint8_t value. If the sum of the two values would be larger than 255, the result will overflow and wrap. Only after that will it divide by 2. A safer way would be to divide each value by two first:

added 83 characters in body
Source Link
G. Sliepen
  • 69.3k
  • 3
  • 75
  • 180

You mention "feedback control" in your comments, however what you have implemented does not rely on feedback at all, instead it's simply a wayan open-loop controller to smooth the transition from one speed to another. This will indeed help smooth the motion of the robot, but the way you implemented it is very naive.

You mention "feedback control" in your comments, however what you have implemented does not rely on feedback at all, it's simply a way to smooth the transition from one speed to another. This will indeed help smooth the motion of the robot, but the way you implemented it is very naive.

You mention "feedback control" in your comments, however what you have implemented does not rely on feedback at all, instead it's an open-loop controller to smooth the transition from one speed to another. This will indeed help smooth the motion of the robot, but the way you implemented it is very naive.

Source Link
G. Sliepen
  • 69.3k
  • 3
  • 75
  • 180
Loading