Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debug broadcast enable/disable option and debug broadcast port option to config file #309

Merged
merged 9 commits into from
Oct 14, 2024
32 changes: 32 additions & 0 deletions config/motoros2_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,35 @@ publisher_qos:
#
# DEFAULT: false
#ignore_missing_calib_data: false

#-----------------------------------------------------------------------------
# Should MotoROS2 broadcast debug messages?
#
# If enabled, this will broadcast log messages on the network on port UDP 21789.
# The user can use the debug script to monitor the state of the robot, identify
# problems, and debug their code.
#
# The debug script is available under the Yaskawa-Global/motoros2 repository in
# the tools directory
# https://github.com/Yaskawa-Global/motoros2/tree/main/tools
#
# DEFAULT: true
#debug_broadcast_enabled: true

#-----------------------------------------------------------------------------
# Which network port(s) should MotoROS2 broadcast debug messages on, if
# 'debug_broadcast_enabled' is 'true'?
#
# If not specified and 'debug_broadcast_enabled' is true, MotoROS2 will
# send messages over all network ports which are active on the controller.
#
# To choose a specific port to broadcast debug messages, uncomment
# 'debug_broadcast_port' below and set it to the desired port.
#
# NOTE 1: this setting only applies to YRC1000 and YRC1000u controllers.
jimmy-mcelwain marked this conversation as resolved.
Show resolved Hide resolved
# DX200 and FS100 controllers only have a single ethernet port, and will
# always default to USER_LAN1
#
# OPTIONS: USER_LAN1, USER_LAN2
# DEFAULT: (all available network ports)
#debug_broadcast_port: USER_LAN1
37 changes: 37 additions & 0 deletions doc/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,21 @@ Save a copy of the output of the [debug-listener script](#debug-log-client) and
Open a new issue on the [Issue tracker](https://github.com/yaskawa-global/motoros2/issues), describe the problem and attach `PANELBOX.LOG` and the debug log to the issue.
Include a verbatim copy of the alarm text as seen on the teach pendant (alarm number and `[subcode]`).

### Alarm: 8011[64]

*Example:*

```text
ALARM 8011
Enable LAN port 1 for debug
[64]
```

*Solution:*
The ETHERNET function must be enabled for the LAN interface that was specified in the config file.
Either change the interface specified in the config file to a LAN interface that is enabled, or enable the corresponding LAN interface on the controller.
Please contact your local Yaskawa representative to request the ETHERNET function if it is not enabled.

### Alarm: 8012[xx]

*Example:*
Expand Down Expand Up @@ -1024,6 +1039,28 @@ In case the alarm is still raised after calibration was performed, TF broadcasti
Open a new issue on the [Issue tracker](https://github.com/yaskawa-global/motoros2/issues), describe the problem and attach `PANELBOX.LOG`, `RBCALIB.DAT` and the debug log to the issue.
Include a verbatim copy of the alarm text as seen on the teach pendant (alarm number and `[subcode]`).

### Alarm: 8013[17]

*Example:*

```text
ALARM 8013
Bad UserLan debug port in cfg
[17]
```

*Solution:*
The `debug_broadcast_port` key in the `motoros2_config.yaml` configuration file is set to an invalid value.
Debug messages will be sent over all active network ports

On YRC1000 and YRC1000u, this must be set to either `USER_LAN1` or `USER_LAN2`.

No other values are supported.

Example: `debug_broadcast_port: USER_LAN1`.

After correcting the configuration, the [changes will need to be propagated to the Yaskawa controller](../README.md#updating-the-configuration).

### Alarm: 8014[0]

*Example:*
Expand Down
68 changes: 53 additions & 15 deletions src/ConfigFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ Configuration_Item Ros_ConfigFile_Items[] =
{ "userlan_monitor_enabled", &g_nodeConfigSettings.userlan_monitor_enabled, Value_Bool },
{ "userlan_monitor_port", &g_nodeConfigSettings.userlan_monitor_port, Value_UserLanPort },
{ "ignore_missing_calib_data", &g_nodeConfigSettings.ignore_missing_calib_data, Value_Bool },
{ "debug_broadcast_enabled", &g_nodeConfigSettings.debug_broadcast_enabled, Value_Bool },
{ "debug_broadcast_port", &g_nodeConfigSettings.debug_broadcast_port, Value_UserLanPort },
};

void Ros_ConfigFile_SetAllDefaultValues()
Expand All @@ -130,6 +132,10 @@ void Ros_ConfigFile_SetAllDefaultValues()
//TODO(gavanderhoorn): make this an unsigned int
g_nodeConfigSettings.ros_domain_id = DEFAULT_ROS_DOMAIN_ID;

//userlan debug broadcast
g_nodeConfigSettings.debug_broadcast_enabled = DEFAULT_ULAN_DEBUG_BROADCAST_ENABLED;
g_nodeConfigSettings.debug_broadcast_port = DEFAULT_ULAN_DEBUG_BROADCAST_PORT;

//=========
//node_name
UCHAR macId[6];
Expand Down Expand Up @@ -327,7 +333,7 @@ void Ros_ConfigFile_CheckYamlEvent(yaml_event_t* event)
case Value_UserLanPort:
#if defined (FS100) || defined (DX200)
// single port, override whatever was configured
*(Ros_UserLan_Port_Setting*)activeItem->valueToSet = CFG_ROS_USER_LAN1;
* (Ros_UserLan_Port_Setting*)activeItem->valueToSet = CFG_ROS_USER_LAN1;
Ros_Debug_BroadcastMsg("DX200 or FS100: override to 'USER_LAN1'");

#elif defined (YRC1000) || defined (YRC1000u)
jimmy-mcelwain marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -337,20 +343,20 @@ void Ros_ConfigFile_CheckYamlEvent(yaml_event_t* event)
*(Ros_UserLan_Port_Setting*)activeItem->valueToSet = CFG_ROS_USER_LAN2;
else
{
//Note: ideally, we'd disable user lan monitoring here. However, we can't
//guarantee the 'userlan_monitor_enabled' setting won't be parsed after
//this one. If it were to be parsed after 'userlan_monitor_port', we'd
//be disabling it here, only to have it re-enabled later.
//Set the config value to the 'disabled' sentinel value and let the
//validation code below handle the fallout.
// Note: ideally, we'd disable user lan monitoring or set user lan debug
// broadcast to all here. However, we can't guarantee that the 'userlan_monitor_enabled'
// or the 'debug_broadcast_enabled' setting won't be parsed after
// this one. If it were to be parsed after the corresponding port setting, we'd
// be setting it here, only to have it re-set later. Set the config value to the
// 'malformed' sentinel value and let the validation code below handle the fallout.
Ros_Debug_BroadcastMsg(
"Unrecognised value for '%s': '%s'. Port monitoring will be disabled",
(char*)event->data.scalar.value,
(char*)activeItem->yamlKey);
*(Ros_UserLan_Port_Setting*)activeItem->valueToSet = CFG_ROS_USER_LAN_DISABLED;
"Unrecognised value for '%s': '%s'.",
(char*)activeItem->yamlKey,
(char*)event->data.scalar.value);
*(Ros_UserLan_Port_Setting*)activeItem->valueToSet = CFG_ROS_USER_LAN_MALFORMED;
}
#else
#error Unsupported platform
#error Unsupported platform
#endif
//Note: this logs whatever was in the .yaml, NOT the verified/parsed value above
Ros_Debug_BroadcastMsg("Config: %s = %s", (char*)activeItem->yamlKey,
Expand Down Expand Up @@ -690,7 +696,7 @@ void Ros_ConfigFile_ValidateNonCriticalSettings()
if (g_nodeConfigSettings.userlan_monitor_port != CFG_ROS_USER_LAN1)
#endif
{
mpSetAlarm(ALARM_CONFIGURATION_FAIL, "Invalid UserLan port in cfg",
mpSetAlarm(ALARM_CONFIGURATION_FAIL, "Bad UserLan monitor port in cfg",
Copy link
Collaborator

@gavanderhoorn gavanderhoorn Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you have a particular reason changing the phrasing here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are now 2 different UserLan ports that the user can specify (monitor and debug broadcast), so I added the word "monitor" to clarify which one this condition checked. But then that put it above 32 characters (the alarm message limit), so I chose to shorten "Invalid" to "Bad" to fit in the character limit. I think that "invalid" is a better word for that, but it's more important to be specific about which config setting needs to be changed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should we instead separate parsing and error reporting for monitoring and debug log port?

Would lead to some mild code duplication, but would also make parsing clearer and avoids this situation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe that this specific message is affected by combined parsing/error reporting for the two port config options. My preference would be to keep the parsing as combined, but I would be fine with changing it.

SUBCODE_CONFIGURATION_INVALID_USERLAN_MONITOR_PORT);
g_nodeConfigSettings.userlan_monitor_enabled = FALSE;
Ros_Debug_BroadcastMsg(
Expand All @@ -699,6 +705,28 @@ void Ros_ConfigFile_ValidateNonCriticalSettings()
}
}
}

if (g_nodeConfigSettings.debug_broadcast_enabled)
{
Ros_Debug_BroadcastMsg("UserLan debug broadcast enabled, checking port setting...");
//Check if the port setting is valid only if the debug broadcast is enabled
#if defined (YRC1000) || defined (YRC1000u)
if (g_nodeConfigSettings.debug_broadcast_port != CFG_ROS_USER_LAN1 &&
g_nodeConfigSettings.debug_broadcast_port != CFG_ROS_USER_LAN2 &&
g_nodeConfigSettings.debug_broadcast_port != CFG_ROS_USER_LAN_ALL)
#elif defined (FS100) || defined (DX200)
if (g_nodeConfigSettings.debug_broadcast_port != CFG_ROS_USER_LAN1)
#endif
{
mpSetAlarm(ALARM_CONFIGURATION_FAIL, "Bad UserLan debug port in cfg",
SUBCODE_CONFIGURATION_INVALID_DEBUG_BROADCAST_PORT);
Ros_Debug_BroadcastMsg(
"debug_broadcast_port value %d is invalid, broadcasting to all enabled ports instead",
g_nodeConfigSettings.debug_broadcast_port);
}
}


}

const char* const Ros_ConfigFile_Rmw_Qos_ProfileSetting_ToString(Ros_QoS_Profile_Setting val)
Expand Down Expand Up @@ -758,15 +786,15 @@ void Ros_ConfigFile_PrintActiveConfiguration(Ros_Configuration_Settings const* c
Ros_Debug_BroadcastMsg("Config: userlan_monitor_enabled = %d", config->userlan_monitor_enabled);
Ros_Debug_BroadcastMsg("Config: userlan_monitor_port = %d", config->userlan_monitor_port);
Ros_Debug_BroadcastMsg("Config: ignore_missing_calib_data = %d", config->ignore_missing_calib_data);
Ros_Debug_BroadcastMsg("Config: debug_broadcast_enabled = %d", config->debug_broadcast_enabled);
Ros_Debug_BroadcastMsg("Config: debug_broadcast_port = %d", config->debug_broadcast_port);
}

void Ros_ConfigFile_Parse()
{
BOOL bAlarmOnce = TRUE;
BOOL bOkToInit = TRUE;

Ros_ConfigFile_SetAllDefaultValues();

do
{
#if defined (FS100) || defined (YRC1000) || defined (YRC1000u)
Expand Down Expand Up @@ -862,6 +890,16 @@ void Ros_ConfigFile_Parse()

Ros_ConfigFile_ValidateCriticalSettings();
Ros_ConfigFile_ValidateNonCriticalSettings();
#if defined(YRC1000) || defined(YRC1000u)
// If the debug broadcast is enabled and the user chose a specific port, then
// we can no longer broadcast over ALL, we have to change it to only broadcast over one port
if (g_nodeConfigSettings.debug_broadcast_enabled &&
(g_nodeConfigSettings.debug_broadcast_port == CFG_ROS_USER_LAN1 ||
g_nodeConfigSettings.debug_broadcast_port == CFG_ROS_USER_LAN2))
{
Ros_Debug_SetFromConfig();
}
#endif
Ros_ConfigFile_PrintActiveConfiguration(&g_nodeConfigSettings);
}

Expand Down
16 changes: 12 additions & 4 deletions src/ConfigFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,20 @@ typedef enum

typedef enum
{
CFG_ROS_USER_LAN_DISABLED = -2, //sentinel
CFG_ROS_USER_LAN_MALFORMED = -3, //sentinel
CFG_ROS_USER_LAN_ALL = -2, //sentinel
CFG_ROS_USER_LAN_AUTO = -1, //sentinel
CFG_ROS_USER_LAN1 = ROS_USER_LAN1,
CFG_ROS_USER_LAN2 = ROS_USER_LAN2,
} Ros_UserLan_Port_Setting;
Comment on lines -91 to 96
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why you opted to reuse the Ros_UserLan_Port_Setting type, but it does make the parsing code a little harder to read.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I tried doing it both ways, and this had much less duplicated code and was overall cleaner in my opinion. I don't especially like it either though.


#define DEFAULT_ULAN_MON_ENABLED TRUE
#define DEFAULT_ULAN_MON_LINK CFG_ROS_USER_LAN_AUTO
#define DEFAULT_ULAN_MON_ENABLED TRUE
#define DEFAULT_ULAN_MON_LINK CFG_ROS_USER_LAN_AUTO

#define DEFAULT_IGNORE_MISSING_CALIB FALSE
#define DEFAULT_IGNORE_MISSING_CALIB FALSE

#define DEFAULT_ULAN_DEBUG_BROADCAST_ENABLED TRUE
#define DEFAULT_ULAN_DEBUG_BROADCAST_PORT CFG_ROS_USER_LAN_ALL
typedef struct
{
//TODO(gavanderhoorn): add support for unsigned types
Expand Down Expand Up @@ -141,10 +144,15 @@ typedef struct
Ros_UserLan_Port_Setting userlan_monitor_port;

BOOL ignore_missing_calib_data;

BOOL debug_broadcast_enabled;
Ros_UserLan_Port_Setting debug_broadcast_port;
} Ros_Configuration_Settings;

extern Ros_Configuration_Settings g_nodeConfigSettings;

extern void Ros_ConfigFile_SetAllDefaultValues();

extern void Ros_ConfigFile_Parse();

extern rmw_qos_profile_t const* const Ros_ConfigFile_To_Rmw_Qos_Profile(Ros_QoS_Profile_Setting val);
Expand Down
Loading