C++ based USB s/w to control Maestro controllers

I am trying to create an application to control maestro controllers. I have doubt regarding usage of a specific command. Can someone help me understand what is the exact output we will get when we use REQUEST_GET_VARIABLES command in libusb_control_transfer function ? It will give position,target,speed & acceleration of all the channels in Maestro or some other extra information also.

Hello.

The REQUEST_GET_VARIABLES command will return a uscVariables struct, which is defined in protocol.h. For more details about that struct, see Usc_protocol.cs in the Pololu USB SDK, where that struct is named MicroMaestroVariables. Please note that the REQUEST_GET_VARIABLES command only works on the Micro Maestro.

- Amanda

Halo Amanda, thanks for the reply. But I have maestro with 18 channels so what command should I use to get the 4 variables in the structure given.

You can use the REQUEST_GET_SERVO_SETTINGS command, which will return an array of ServoStatus structs. The ServoStatus struct represents the current status of a channel and is also defined in Usc_protocol.cs in the Pololu USB SDK.

- Amanda

Thank You Amanda for the help.

Hi Amanda, I am facing a new problem with my application. My application works well when I compile or run it from my Laptop(Ubuntu) but it is not working in UDOO board from which I want to control the Maestro. I am using libusc.h that provides simple functions to control the Maestro. I am unable to change the device & channel settings from my program and so every time I have to use your application MaestroControlCenter. I am using this function below to set up the device at StartUp but it is not working.

[code]
int set_board()
{

libusc_device_settings my_device_settings = {0,0,0,0,0,1,SERIAL_MODE_USB_DUAL_PORT,0,0,1,12,0,0,1,1};
libusc_set_device_settings(my_device, &my_device_settings);

libusc_channel_settings my_ESC_channel_settings = {0,0,0,4700,7000,5850,1150,0,0};
libusc_channel_settings my_servo_channel_settings = {0,0,0,3960,8000,5980,2020,0,0};
libusc_channel_settings my_acc_channel_settings = {3,1,0,0,1023,511,511,0,0};

libusc_set_channel_settings(my_device, my_servo, &my_servo_channel_settings);
libusc_set_channel_settings(my_device, my_ESC, &my_ESC_channel_settings);
libusc_set_channel_settings(my_device, my_acc, &my_acc_channel_settings);

return 0;

}[/code]

Hello.

There are many parameters on the Maestro that are only read from EEPROM at initialization time, which happens when the board powers up or when it receives a REQUEST_INITIALIZE command. After you change those values in EEPROM using REQUEST_SET_PARAMETER, you will need to call REQUEST_REINITIALIZE at some point in order to actually make the values have an effect. This is documented further in protocol.h in the Pololu USB SDK.

I recommend sending a REQUEST_INITIALIZE request at the end of your function. The third-party library you are using does support sending REQUEST_INITIALIZE, and their function for it is named libusc_restore_default_configuration (which is a misleading name). You could try calling that to see if it solves your problem.

I am not sure why your code would work on one system and not on another. If you still have issues, please tell us more about what you are seeing and why you think your settings were not applied.

–David

Hallo,
Thanks for your reply. I will post the results after trying out your Idea. The initialization part in my application does not work in my laptop and in UDOO. But, I face an extra problem when I try to run the application in UDOO that is the channel settings that are set using MaestroControlCenter are changed somehow when I connect the Pololu board to UDOO.

If you would like help with this extra problem, please let me know what settings you are referring to and why you think your settings are changed when you connect the Maestro to your UDOO. In case it helps, please note that anything you change in the Maestro Control Center’s “Status” tab is temporary and will not be saved when the Maestro powers off.

–David



[code]
int main()
{
startup(); // Performs the tasks that are to be done only once during the start of the program
libusc_channel_settings settings4;
//set_board();
int n = libusc_get_num_channels(my_device);
if (n==18)
{
libusc_clear_errors(my_device);

    libusc_channel_settings my_ESC_channel_settings;
    my_ESC_channel_settings.mode = 3;
    my_ESC_channel_settings.acceleration = 0;
    my_ESC_channel_settings.home = 0;
    my_ESC_channel_settings.homeMode = 1;
    my_ESC_channel_settings.speed = 0;
    my_ESC_channel_settings.maximum = 1023;
    my_ESC_channel_settings.minimum = 0;
    my_ESC_channel_settings.neutral = 0;
    my_ESC_channel_settings.range = 0;
    
    libusc_set_channel_settings(my_device, my_ESC, &my_ESC_channel_settings);
    libusc_restore_default_configuration(my_device);
    libusc_get_channel_settings(my_device, my_ESC, &settings4);
  
return 0;

}
[/code]

Hi David, In the above code I tried to set channel 0(my_ESC) as input and executed the code and the output what I got is in the first picture and then I changed channel 0 to input using MaestroControlCenter and I just used the get_channel_settings function in the above code and I got output in the second picture. I think that seetings we try to set using the function set_channel_settings is not reflecting on the device.

My understanding is that you used libusc to set channel 0 to an input, and then used libusc to read back the settings for channel 0, and the data you read back is shown in pic1.png. The settings shown in pic1.png are invalid, which means there is a problem somewhere. So then you tried setting channel 0 to be an input using the Maestro Control Center, and you used libusc to read the settings back, as shown in the pic2.png. The settings shown in pic2.png look like they are probably OK.

The invalid settings in pic1.png look like they might be uninitialized data. Maybe you never succeeded in actually reading the settings back. I looked in the source code of libusc for a bit. There is no error handling in libusc_get_raw_parameter, so if it fails to retrieve data from the device, then it will end up returning an uninitialized variable, which could explain why you are getting invalid data. You might try enabling verbose output from libusb in order to see if USB communication errors are happening.

Alternatively, it might be that libusc_get_channel_settings works fine, and there is some bug in libusc_set_channel_settings or some problem with the way you are calling it. I looked at the source code of libusc_set_channel_settings in libusc.c and I did not notice anything wrong with it. However, it too does not have any error handling.

I would recommend removing the call to libusc_restore_default_configuration (which calls REQUEST_REINITIALIZE) for now. It should not be needed in order to reproduce this issue; the only reason to call it is if you want your new settings to take effect on the Maestro. Right now, you should just try to write your settings and verify that they were written correctly, and it is OK if they do not have an effect. It takes the Maestro a while to reinitialize itself, so in our code we always sleep for 50 ms after sending that request. (I’m referring to the Usc class in the Pololu USB SDK.)

Another option is to use UscCmd (the Maestro’s command-line utility) or the Maestro Control Center to apply your settings to the Maestro instead of writing your own code to do it.

–David

Hi David, You have understood my post correctly. I am convinced that the get_channel_settings function is working properly and I think that the problem is also not with the set_channel_settings function. Its with how we use that function like whether we have to reinitialize after that function or we have to use the function with some sleep of 50ms to make our settings reflected on the Pololu. Can you please tell me how can I use that function ?
Regarding settings using USC or MaestroControlCenter, it works good when I set something and run my code in my laptop but when I connect the pololu with same settings to UDOO it does not work. So to check why it does not work I connect it back to MaestroControlCenter to check the settings and I find the settings are totally different from what I set before I connect it to UDOO.

The library you are using, libusc, is not written or tested by us, so I am not sure how to use it. The code you wrote to call libusc_set_channel_settings is OK as far as I know.

You said that some settings are being changed when you plug the Maestro into your UDOO and try to run your code there. Is there any way that you could reproduce that problem without using libusc, and without using any of your own code? For example, could you try saving a settings file using the Maestro Control Center on your laptop, then plug the Maestro into your UDOO for a few seconds, then plug it into the laptop again, and save the settings file again? I would expect the two settings files to be the same, but if they are different then it would indicate that somehow that procedure has changed the settings on your Maestro.

If you cannot reproduce the issue without running your own code, then it seems like your code and/or libusc is messing up the Maestro settings. You might consider only changing the settings with the Maestro Control Center and never using libusc to change those settings, but you could still use libusc to do things like reading the Maestro’s inputs and controlling servos.

–David

Hi David, I was not reproduce the problem without my code so there is some problem with libusc or how I am using it and they are changing the Maestro settings. But I really would like handle the settings through program because it is not always easy to change it when it the Pololu is fixed inside a RC car. Is there anyway to use Usc Cmd at the startup to set the settings in UDOO and then call my C++ code in terminal itself within a Cron Job ?

If the UDOO can run mono, then you should be able to run UscCmd on it. You can prepare a configuration file for your Maestro ahead of time using the Maestro Control Center or by running “UscCmd --getconf maestro_settings.txt”. Then you can load that configuration onto your Maestro using “UscCmd --configure maestro_settings.txt”. You could do this from a terminal or a cron job, or you could just add code to your C++ program that invokes UscCmd.

–David

Hi David, Thanks for your reply. Can you elaborate on how to invoke the UscCmd in my C++ program ?

Sorry, just now checked with UDOO it cannot run UscCmd. So, is there any other way may be a library or any other stuff tested by Pololu to set the settings before I run my C++ code.

What error did you encounter when trying to run UscCmd on the UDOO? Did you try installing the prerequisites with a command like this?

sudo apt-get install libusb-1.0-0-dev mono-runtime

Did you try running UscCmd with a command like this?

mono ./UscCmd

We do not provide any code for changing the settings on the Maestro other than the C# code in the Pololu USB SDK, so if you cannot run that code, and third-party libraries are not working for you, then I suggest that you set up the Maestro’s settings ahead of time using the Maestro Control Center on a different computer.

–David

Hi, I have a new doubt about how to use a channel as analog input. So, it can take analog inputs from 0-5V and corresponding digital values are 0-1023/1-255.75. Is that right ? If that so I have analog accelerometer that has maximum output of 3.3V and I need that to be displayed as 1023. Is there any settings I can change or it has to be managed through programming the conversions.

Hi, So I tried to convert the values in my program and I came across some anomaly. So, if 5V corresponds to 1023 then 3.3V should be 675. But, when I supplied 3.3V to analog input pin it read as 695. So,if that relation is not straightforward how can I write a code to convert the values ?