cancel
Showing results for 
Search instead for 
Did you mean: 
SOLVED

Issue with Bosch Rexroth ctrlX C++ SDK and Festo VTEM EtherCAT Communication

Issue with Bosch Rexroth ctrlX C++ SDK and Festo VTEM EtherCAT Communication

prachandabhanu
New Poster

Hello,

I am currently facing an issue while trying to control a Festo VTEM device via EtherCAT using the C++ SDK provided by Bosch Rexroth. Below is the code snippet I am using

 

#include <stdio.h>
#include <map>
#include <iostream>
#include <chrono>
#include <thread>
#include <csignal>

#include "comm/datalayer/datalayer.h"
#include "comm/datalayer/datalayer_system.h"
#include "comm/datalayer/memory_map_generated.h"

static bool g_endProcess = false;
static void signalHandler(int signal)
{
  std::cout << "signal: " << signal << std::endl;
  g_endProcess = true;
}

int main(void)
{
  comm::datalayer::DlResult result;
  comm::datalayer::Variant data;
  comm::datalayer::Variant dataIn;
  comm::datalayer::DatalayerSystem datalayer;
  datalayer.start(false);

  std::signal(SIGINT, signalHandler);

  // First we have to open the realtimememory, reading the whole outputs.
  uint8_t* outData;
  std::cout << "Opening some realtime memory" << std::endl;
  std::shared_ptr<comm::datalayer::IMemoryUser> output;
  result = datalayer.factory()->openMemory(output, "fieldbuses/ethercat/master/instances/VTEM/realtime_data/output");
  if (comm::datalayer::STATUS_FAILED(result))
  {
    std::cout << "Open the memory failed with: " << result.toString() << std::endl;
  }

  // We can read the Inputs to get a Start trigger for example
  uint8_t* inData;
  std::cout << "Opening some realtime memory" << std::endl;
  std::shared_ptr<comm::datalayer::IMemoryUser> input;
  result = datalayer.factory()->openMemory(input, "fieldbuses/ethercat/master/instances/VTEM/realtime_data/input");
  if (comm::datalayer::STATUS_FAILED(result))
  {
    std::cout << "Open the memory failed with: " << result.toString() << std::endl;
  }

  do
  {
    std::cout << "Try to get MemoryMap" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    result = output->getMemoryMap(data);
    std::cout << "Getting MemoryMap with: " << result.toString() << std::endl;
  } while (comm::datalayer::STATUS_FAILED(result) && !g_endProcess);

  return 0;
}

 

 

 

I can successfully open the memory input and output; however, when I attempt to read, get a map, or begin access, I encounter errors such as DL_RT_NOTOPEN or DL_RT_NOVALIDDATA (I will provide more details on this soon).

I have not initialized the Data Layer client as shown in the sample code provided in the SDK(https://github.com/boschrexroth/ctrlx-automation-sdk/tree/main/samples-cpp/datalayer.ecat.io). My reasons for not doing so are as follows:

  1. Since I am executing the program on the CtrlX Core, I believe it might not be necessary.
  2. Additionally, when I tried to add the client section, as shown in the sample code, I encountered the following error related to AppArmor when integrating with ROS2:
    AVC apparmor="DENIED" operation="mknod" profile="snap.ros2-vtem-datalayer-monitor.datalayerMonitor" name="/dev/shm/fastrtps_c50f8f0c6a04a86c" pid=65979 comm="datalayerMonito" requested_mask="c" denied_mask="c" fsuid=0 ouid=0

I would appreciate any guidance or suggestions on resolving these issues and whether initializing the client is necessary for my specific setup.

Thank you for your assistance, and please let me know if you require any further information to help diagnose the problem.

 

 

3 REPLIES 3

Sgilk
Frequent Contributor

Hi @prachandabhanu ,

I do believe you will need to create a client in order to utilize the memory maps. As your code is written, the application doesn't inherently know that it should open memory on the local device. Creating the client will tell the application to create an ipc connection if no other address is provided.

With regard to the AppArmor error, what does your snapcraft.yaml look like? Take a look at the datalayer.ecat.io example and make sure you have the same plugs.

EDIT: @ipa-vsp --- You actually should not need a client, my mistake. Using the shared memory requires IPC and therefore the application must run on the same device as the datalayer broker. Are you running the application locally on the CORE?

ipa-vsp
Occasional Visitor

Hi @Sgilk
Thank you for your previous assistance. I've resolved the AppArmor error and realized that I hadn't correctly initialized the snapcraft.yaml file with all the necessary plugins.
Here's an example of my current initialization:

 

comm::datalayer::IClient* client = getClient(datalayer);
  if (client == nullptr)
  {
    std::cout << "ERROR Client connected" << std::endl;
    datalayer.stop();
    return 1;
  }

  result = client->readSync("fieldbuses/ethercat/master/instances/VTEM/realtime_data/output/map", &data);
  std::cout << "Read returned: " << result.toString() << std::endl;

  result = client->readSync("fieldbuses/ethercat/master/instances/VTEM/realtime_data/input/map", &dataIn);
  std::cout << "Read returned: " << result.toString() << std::endl;

  std::signal(SIGINT, signalHandler);

  // First we have to open the realtimememory, reading the whole outputs.
  uint8_t* outData;
  std::cout << "Opening some realtime memory" << std::endl;
  std::shared_ptr<comm::datalayer::IMemoryUser> output;
  result = datalayer.factory()->openMemory(output, "fieldbuses/ethercat/master/instances/VTEM/realtime_data/output");
  std::cout << "Open the memory with: " << result.toString() << std::endl;
  if (comm::datalayer::STATUS_FAILED(result))
  {
    std::cout << "Open the memory failed with: " << result.toString() << std::endl;
  }

  // We can read the Inputs to get a Start trigger for example
  uint8_t* inData;
  std::cout << "Opening some realtime memory" << std::endl;
  std::shared_ptr<comm::datalayer::IMemoryUser> input;
  result = datalayer.factory()->openMemory(input, "fieldbuses/ethercat/master/instances/VTEM/realtime_data/input");
  std::cout << "Open the memory with: " << result.toString() << std::endl;
  if (comm::datalayer::STATUS_FAILED(result) && !g_endProcess)
  {
    std::cout << "Open the memory failed with: " << result.toString() << std::endl;
  }

 

This setup successfully opens the memory with the result DL_OK. However, I encounter an issue with the following section of the code

 

do
  {
    std::cout << "Try to get MemoryMap" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    result = output->getMemoryMap(data);
    std::cout << "Getting MemoryMap with: " << result.toString() << std::endl;
  } while (comm::datalayer::STATUS_FAILED(result));

 

In this part, I receive the error DL_RT_INVALIDMEMORYMAP when attempting to get the MemoryMap. Interestingly, if I comment out this section, I can print the memory map values without any issues. For example, I can find and print details like Name of Output and Bitoffset.

 

Name of Output we found: CPX_FB37/VTEM_8_Valves_48DI_DO_/Outputs.Valve_1_Output_5
Bitoffset: 168

 

However, when I try to begin access, I face another issue indicated by the result DL_RT_NOTOPEN.

Could you help me identify any potential mistakes that might still exist in my implementation?


Best regards,

Vishnuprasad Prachandabhanu

nickH
Community Moderator
Community Moderator

Hi Vishnuprasad Prachandabhanu,

The problem might be, that your fieldbus is not running when you are trying to access the RT-data. After you installed your snap you have to switch back into operating mode, so your fieldbus (EtherCAT) gets switched into "Running". 

Please have a look into this Post. This blog-poster had a similar problem. (Note: but you don't have to deactivate the watchdog since you don't run in sync with the scheduler)

Best regards, 

Nick

Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist