MaestroEasyExampleCpp Compiling issues

Hello I am trying to build MaestroEasyExampleCpp.vcproj, included with the “Pololu USB Software Development Kit” version 140604, in Visual Studio 2013. After migrating the solution, it seems there are some errors. All other projects in the development kit, such as the visual basic example and the C# example migrate and run fine. The cpp version is the only one that doesn’t seem to work.

Here is the Migration report for the MaestroEasyExampleCpp.vcproj :

I am relatively new to programming so I could be wrong but nothing seems drastically changed from the migration.

Here is the migrated code from the MainWindow.h header:

/*  MaestroEasyExampleCpp:
 *    Simple example GUI for the Maestro USB Servo Controller, written in
 *    Visual C++.
 *    
 *    Features:
 *       Temporary native USB connection using Usc class
 *       Button for disabling channel 0.
 *       Button for setting target of channel 0 to 1000 us.
 *       Button for setting target of channel 0 to 2000 us.
 * 
 *  NOTE: Channel 0 should be configured as a servo channel for this program
 *  to work.  You must also connect USB and servo power, and connect a servo
 *  to channel 0.  If this program does not work, use the Maestro Control
 *  Center to check what errors are occurring.
 */

#pragma once

namespace Pololu {
namespace Usc {
namespace MaestroEasyExampleCpp {

	using namespace Pololu::UsbWrapper;
	using namespace Pololu::Usc;

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Collections::Generic;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Text;

	/// <summary>
	/// WARNING: If you change the name of this class, you will need to change the
	///          'Resource File Name' property for the managed resource compiler tool
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public ref class MainWindow : public System::Windows::Forms::Form
	{
	public:
		MainWindow(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~MainWindow()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  Button2000;
	protected: 
	private: System::Windows::Forms::Button^  Button1000;
	private: System::Windows::Forms::Label^  ChannelLabel;
	private: System::Windows::Forms::Button^  ButtonDisable;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->Button2000 = (gcnew System::Windows::Forms::Button());
			this->Button1000 = (gcnew System::Windows::Forms::Button());
			this->ChannelLabel = (gcnew System::Windows::Forms::Label());
			this->ButtonDisable = (gcnew System::Windows::Forms::Button());
			this->SuspendLayout();
			// 
			// Button2000
			// 
			this->Button2000->Location = System::Drawing::Point(302, 25);
			this->Button2000->Name = L"Button2000";
			this->Button2000->Size = System::Drawing::Size(118, 23);
			this->Button2000->TabIndex = 7;
			this->Button2000->Text = L"Target=&2000us";
			this->Button2000->UseVisualStyleBackColor = true;
			this->Button2000->Click += gcnew System::EventHandler(this, &MainWindow::Button2000_Click);
			// 
			// Button1000
			// 
			this->Button1000->Location = System::Drawing::Point(178, 25);
			this->Button1000->Name = L"Button1000";
			this->Button1000->Size = System::Drawing::Size(118, 23);
			this->Button1000->TabIndex = 6;
			this->Button1000->Text = L"Target=&1000us";
			this->Button1000->UseVisualStyleBackColor = true;
			this->Button1000->Click += gcnew System::EventHandler(this, &MainWindow::Button1000_Click);
			// 
			// ChannelLabel
			// 
			this->ChannelLabel->AutoSize = true;
			this->ChannelLabel->Location = System::Drawing::Point(12, 30);
			this->ChannelLabel->Name = L"ChannelLabel";
			this->ChannelLabel->Size = System::Drawing::Size(58, 13);
			this->ChannelLabel->TabIndex = 5;
			this->ChannelLabel->Text = L"Channel 0:";
			// 
			// ButtonDisable
			// 
			this->ButtonDisable->Location = System::Drawing::Point(92, 25);
			this->ButtonDisable->Name = L"ButtonDisable";
			this->ButtonDisable->Size = System::Drawing::Size(80, 23);
			this->ButtonDisable->TabIndex = 4;
			this->ButtonDisable->Text = L"&Disable";
			this->ButtonDisable->UseVisualStyleBackColor = true;
			this->ButtonDisable->Click += gcnew System::EventHandler(this, &MainWindow::ButtonDisable_Click);
			// 
			// MainWindow
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(453, 75);
			this->Controls->Add(this->Button2000);
			this->Controls->Add(this->Button1000);
			this->Controls->Add(this->ChannelLabel);
			this->Controls->Add(this->ButtonDisable);
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
			this->Name = L"MainWindow";
			this->Text = L"MaestroEasyExample in C++";
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion

        /// <summary>
        /// This functions runs when the user clicks the Target=1000us button.
        /// </summary>
        Void Button1000_Click(Object^ sender, EventArgs^ e)
        {
            TrySetTarget(0, 1000 * 4);  // Set the target of channel 0 to 1000 microseconds.
        }

        /// <summary>
        /// This functions runs when the user clicks the Target=2000us button.
        /// </summary>
        Void Button2000_Click(Object^ sender, EventArgs^ e)
        {
            TrySetTarget(0, 2000 * 4);  // Set the target of channel 0 to 2000 microseconds.
        }

        /// <summary>
        /// This function runs when the user clicks the Disable button.
        /// </summary>
        Void ButtonDisable_Click(Object^ sender, EventArgs^ e)
        {
            // Set target of channel 0 to 0.  This tells the Maestro to stop
            // transmitting pulses on that channel.  Any servo connected to it
            // should stop trying to maintain its position.
            TrySetTarget(0, 0);
        }
        
        /// <summary>
        /// Attempts to set the target (width of pulses sent) of a channel.
        /// </summary>
        /// <param name="channel">Channel number from 0 to 23.</param>
        /// <param name="target">
        ///   Target, in units of quarter microseconds.  For typical servos,
        ///   6000 is neutral and the acceptable range is 4000-8000.
        /// </param>
        Void TrySetTarget(Byte channel, UInt16 target)
        {
			Usc^ device;
            try
            {
                device = connectToDevice();           // Find a device and connect.
                device->setTarget(channel, target);
            }
            catch (Exception^ exception)  // Handle exceptions by displaying them to the user.
            {
                displayException(exception);
            }
			finally  // Do this no matter what.
			{
				delete device;  // Close the connection so other processes can use the device.
			}
        }

        /// <summary>
        /// Connects to a Maestro using native USB and returns the Usc object
        /// representing that connection.  When you are done with the
        /// connection, you should delete it using the "delete" statement so
		/// that other processes or functions can connect to the device later.
        /// </summary>
        Usc^ connectToDevice()
        {
            // Get a list of all connected devices of this type.
			List<DeviceListItem^>^ connectedDevices = Usc::getConnectedDevices();

            for each (DeviceListItem^ dli in connectedDevices)
            {
                // If you have multiple devices connected and want to select a particular
                // device by serial number, you could simply add a line like this:
                //   if (dli.serialNumber != "00012345"){ continue; }

                Usc^ device = gcnew Usc(dli); // Connect to the device.
                return device;             // Return the device.
            }
            throw gcnew Exception("Could not find device.  Make sure it is plugged in to USB " +
                "and check your Device Manager (Windows) or run lsusb (Linux).");
        }

        /// <summary>
        /// Displays an exception to the user by popping up a message box.
        /// </summary>
        void displayException(Exception^ exception)
        {
            StringBuilder^ stringBuilder = gcnew StringBuilder();
            do
            {
                stringBuilder->Append(exception->Message + "  ");
                if (exception->GetType() == Win32Exception::typeid)
                {
                    stringBuilder->Append("Error code 0x" + ((Win32Exception^)exception)->NativeErrorCode.ToString("x") + ".  ");
                }
                exception = exception->InnerException;
            }
            while (exception != nullptr);
			MessageBox::Show(stringBuilder->ToString(), this->Text, MessageBoxButtons::OK, MessageBoxIcon::Error);
        }

	}; // end class

}}} // end namespaces

Some of the errors I am getting are:

using namespace Pololu::UsbWrapper; | Error: namespace “Pololu” has no member "UsbWrapper"Usc^ device; | Error: A namespace name is not allowed

and

Error: identifier “device” is undefined

There are a few more but they all seem to relate to namespace Pololu::Usc. The directions in the ReadMe simply state to open the project file and run the debugger so I don’t know where I went wrong.

I also tried to open SimpleMotorController example for cpp and the same errors seem to be occurring; it seems that something is going wrong with c++ specifically.

Any help would be appreciated! And once again sorry for my lack of knowledge.

Hello.

I just tested this with Visual Studio Express 2013 for Windows Desktop and was able to reproduce the issue you are having with MaestroEasyExampleCpp… When you build, you should be able to see warnings about missing references. These warnings can be seen in the “Error List” pane if you select the button at the top of the pane that says how many warnings there are. These warnings needs to be fixed before the project can compile.

The missing reference problem seems to be caused by an issue in Visual Studio’s conversion procedure when it converts the original Visual Studio 2008 project to Visual Studio 2013. The original project has some references that include relative paths to DLL files. For some reason, the conversion process removes the relative paths, so Visual Studio does not know where to find the DLL files when it compiles.

To fix the missing references for a Pololu USB SDK Visual C++ project in Visual Studio 2013, open the “Project” menu and select “Propeties…” to open up the project properties dialog. Under “Common Properties”, select “References”. In the list of references, select each reference to a Pololu assembly (e.g. UsbWrapper, Usc, Bytecode, Sequencer, Smc) and click “Remove Reference” for each of them. Now replace each of those references with working references by clicking “Add New Reference…” and using the “Add Reference” dialog to select the needed DLL files. Each of the projects in the Pololu USB SDK will need some subset of these files, depending on what device it uses:

  • UsbWrapper_Windows\UsbWrapper.dll
  • Maestro\Usc\precompiled_obj\Usc.dll
  • Maestro\Sequencer\precompiled_obj\Sequencer.dll
  • Maestro\Bytecode\Bytecode.dll
  • SimpleMotorController\Smc\precompiled_obj\Smc.dll

If you have trouble determining what references to add, you can open the original vcproj (Visual Studio 2008 project) file in Notepad and look for AssemblyReference tags to see what references the original project had.

After doing this, I was able to successfully compile and run the MaestroEasyExampleCpp project, and my vcxproj file had these references in it:

    <Reference Include="UsbWrapper">
      <HintPath>..\..\UsbWrapper_Windows\UsbWrapper.dll</HintPath>
    </Reference>
    <Reference Include="Usc">
      <HintPath>..\Usc\precompiled_obj\Usc.dll</HintPath>
    </Reference>

–David

It works perfectly now after following your instructions. Thanks a lot David!

Hi @DavidEGrayson Thanks for your reply. I went through it but unable to config it accordignly. Since i am trying to open this example on vs2019, could you please help me to configure Maestro Pololu on vs2019. Thanks.

Hello.

I just tested Visual Studio 2019 and was able to successfully compile MaestroEasyExampleCpp.

When you install Visual Studio, on the “Workloads” page, select “.NET desktop development” and “Desktop development with C++”. Also, in the “Individual Components” page, select “C++/CLI support for v142 build tools (14.27)”. If you have already installed it, you can run the installer again and click the “Modify” button to add more components.

Once you have installed the required components, follow these steps:

  1. Open Visual Studio 2019.
  2. Select File -> Open -> Project/Solution… and then browse to MaestroEasyExampleCpp.vcproj.
  3. You will see some dialogs about Visual Studio migrating the project. When Visual Studio finishes, it will create MaestroEasyExampleCpp.vcxproj.
  4. In the Solution Explorer pane, expand MaestroEasyExampleCpp, then expand References. Note that the references to UsbWrapper and Usc have yellow triangles (because Visual Studio failed to migrate those references properly).
  5. Remove the broken UsbWrapper and Usc references by right-clicking them and selecting “Remove”.
  6. Add a reference to Maestro\Usc\precompiled_obj\Usc.dll in the Pololu USB SDK by right clicking on References, selecting Add Reference -> Assemblies -> Browse… and then browsing to the DLL.
  7. Do the same thing to add a reference to UsbWrapper_Windows\precompiled_obj\UsbWrapper.dll.
  8. In the “Build” menu, select “Build MaestroEasyExampleCpp”. This should build the project and produce an executable you can run.

If you get an error that says “cannot open file ‘MSVCURTD.LIB’”, you should open the project properties and look at Configuration Properties -> General -> Platform Toolset. You might need to install a Visual Studio component corresponding to the selected toolset. In my test, it said “Visual Studio 2019 (v142)”, and I fixed the error by running the installer again and installing “C++/CLI support for v142 build tools (14.27)”.

–David