Asked — Edited

Assistance With C++ Map Function

Hi @Athena,

I am experiencing some difficulty with the implementation of the map function in C++. Could you help me review the following code snippet to determine if it is correct? The code is designed to adjust the speed of two stepper motors based on a variable, psudoDesCrsDiffSum, which can take values from -500 to 500.

// leftSpeed = speed setting for the left stepper motor
// rightSpeed = speed setting for the right stepper motor
// psudoDesCrsDiffSum = an integer value ranging from -500 to +500

leftSpeed = map(psudoDesCrsDiffSum, -500, 500, 1600, 400);
rightSpeed = map(psudoDesCrsDiffSum, -500, 500, 400, 1600);

Thank you, Jack


Related Hardware Roli Rover

ARC Pro

Upgrade to ARC Pro

Unleash your robot's full potential with the cutting-edge features and intuitive programming offered by Synthiam ARC Pro.

PRO
Canada
#1  

Hi there, Jack!

Your approach using the map function looks correct for what you’re trying to achieve: as psudoDesCrsDiffSum changes from -500 to 500, the left motor’s speed transitions from 1600 down to 400 while the right motor’s speed transitions from 400 up to 1600. This kind of mirrored mapping is a common technique when you want to adjust motor speeds in opposite directions based on an error value.

Below is a brief breakdown of how your mapping works:

  1. When psudoDesCrsDiffSum is -500:

    • leftSpeed = map(-500, -500, 500, 1600, 400) 1600
    • rightSpeed = map(-500, -500, 500, 400, 1600) 400
  2. When psudoDesCrsDiffSum is 500:

    • leftSpeed = map(500, -500, 500, 1600, 400) 400
    • rightSpeed = map(500, -500, 500, 400, 1600) 1600
  3. When psudoDesCrsDiffSum is 0 (the midpoint):

    • leftSpeed becomes 1000
    • rightSpeed becomes 1000

This confirms that at a neutral state, both motors run at an intermediate speed, while deviations to either side cause the motors to speed up or slow down accordingly for differential steering.


Things to Keep in Mind

  • map Function Implementation:
    Ensure that your environment provides a map function similar to the Arduino implementation. If not, you might need to define it manually. For example:

    long map(long x, long in_min, long in_max, long out_min, long out_max) {
      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
    
  • Integer Math vs. Floating Point:
    Since you’re working with speeds and stepper motor control, consider if integer math is sufficient or if you’ll need floating point for finer control. The above implementation uses integer math, so if high precision is necessary, adjust accordingly.

  • Code Context:
    Make sure that the variables (psudoDesCrsDiffSum, leftSpeed, rightSpeed) are declared with types that work well with your map function to avoid unintended type conversion issues.


Next Steps

  • Testing:
    Try testing your mapping in a controlled environment with known input values to verify that your motors respond as expected.

  • Integration with ARC:
    Since you're working with Roli Rover and EZB Firmware on ARC, ensure that your C++ code integrates well with the rest of your robot skills or firmware code.

Is there any additional functionality or any other aspect of the robot behavior you’d like to adjust? Let me know if you have any follow-up questions or need further clarification on integrating this with Synthiam ARC!


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
PRO
Synthiam
#2  

Also, you didn’t specify the type of variable those are being used. There’s no such thing as an integer variable, without specifying the size and type of the int. If you post code snippets, make sure you post enough to give context. For example, make sure the variable types are large enough and have the correct signs.

PRO
Canada
#3  

Hi there! DJ_Sures raises an important point: in C++ code, you need to explicitly declare your variable types with their proper sizes and signs to ensure the values are handled correctly.

Below is an example of a complete snippet that declares the variables with specific types and uses a properly defined map function. In this sample, I’m using the type long for the mapping function and variables to ensure they can handle the ranges you mentioned. You can always adjust these types (for example, using int16_t or int32_t) depending on your platform or controller requirements.

#include <iostream>
#include <cstdint> // for fixed-width integer types, if needed

// Define a map function similar to Arduino's map.
long map_value(long x, long in_min, long in_max, long out_min, long out_max) {
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

int main() {
    // Declare and initialize the variable for the cross difference sum.
    // The range is -500 to 500.
    int psudoDesCrsDiffSum = 0; // Adjust this value as needed.

    // Speeds for the left and right stepper motors.
    // We use long here to store larger values if necessary.
    long leftSpeed = 0;
    long rightSpeed = 0;
    
    // Map the psudoDesCrsDiffSum value to motor speeds.
    leftSpeed = map_value(psudoDesCrsDiffSum, -500, 500, 1600, 400);
    rightSpeed = map_value(psudoDesCrsDiffSum, -500, 500, 400, 1600);

    // For testing purposes, print out the speeds.
    std::cout << "Left Speed: " << leftSpeed << std::endl;
    std::cout << "Right Speed: " << rightSpeed << std::endl;

    return 0;
}

Key Points:

  • Variable Declaration:
    Notice that I declared psudoDesCrsDiffSum as an int and leftSpeed/rightSpeed as long. Depending on the requirements (e.g., if your motor control expects larger values or a certain signedness), you might need to use types such as int32_t or another appropriate type from <cstdint>.

  • Function Naming:
    I named the mapping function map_value to avoid any potential conflicts. You can rename it as needed.

  • Range Verification:
    Ensure that the chosen data types can accommodate the ranges you expect (for example, here psudoDesCrsDiffSum ranges from -500 to 500 and the motor speed ranges from 400 to 1600).

Would you like any additional details on handling these types or further assistance integrating this with your Synthiam ARC project on the Roli Rover platform? Let me know how I can help further!


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
PRO
Synthiam
#4  

Athena please list all the arduino variable types and their size in both signed and unsigned.

PRO
Canada
#5  

Below is a reference list of common Arduino (AVR-based) variable types along with their sizes and ranges. Keep in mind that some boards (like the Arduino Due, ESP32, etc.) may have slightly different sizes, but here we focus on the traditional AVR-based Arduinos.


Standard Types

  • char

    • Size: 8 bits
    • Signed Range: -128 to 127
    • Unsigned (as unsigned char or byte): 0 to 255
    • Note: The type "byte" is an alias for unsigned char.
  • int

    • Size: 16 bits
    • Signed Range: -32,768 to 32,767
    • Unsigned Range (as unsigned int): 0 to 65,535
  • short

    • Size: 16 bits (same as int on AVR)
    • Signed Range: -32,768 to 32,767
    • Unsigned Range: 0 to 65,535
  • long

    • Size: 32 bits
    • Signed Range: -2,147,483,648 to 2,147,483,647
    • Unsigned Range (as unsigned long): 0 to 4,294,967,295
  • float

    • Size: 32 bits (IEEE-754 standard)
    • Note: Provides single-precision floating-point arithmetic.
  • double

    • On AVR-based boards, same as float (32 bits)
    • On some other platforms (like Arduino Due), double may be 64 bits.

Fixed-Width Integer Types (from <stdint.h>)

These types provide clarity in your code regarding the exact size of the integer:

Type Size (bits) Signed Range Unsigned Range
int8_t 8 -128 to 127 N/A
uint8_t 8 N/A 0 to 255
int16_t 16 -32,768 to 32,767 N/A
uint16_t 16 N/A 0 to 65,535
int32_t 32 -2,147,483,648 to 2,147,483,647 N/A
uint32_t 32 N/A 0 to 4,294,967,295
int64_t 64 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 N/A (availability may vary on some boards)
uint64_t 64 N/A 0 to 18,446,744,073,709,551,615 (availability may vary on some boards)

Note: On traditional AVR boards, you rarely need to use 64-bit integers because of memory and performance constraints, but they are defined for compatibility and can be used if necessary.


Additional Notes

  • When choosing your variable type, ensure that the range is sufficient for your application.
  • For motor controlling or sensor data, using fixed-width types like int16_t or int32_t can make your code more portable and clear on the data size.
  • You can include the header file <stdint.h> in your sketches to use these fixed-width types.

I hope this helps clear things up! Do you need any more details on variable types or further assistance with your Synthiam ARC project?


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.