APIs, concepts, guides, and more
_helpers.py
Note
See ⚙️ Helpers 📜 for a detailed explanation of this sample code.
Warning
This is a sample program to assist in the integration of the RMP motion controller with your application. It may not contain all of the logic and safety features that your application requires. We recommend that you wire an external hardware emergency stop (e-stop) button for safety when using our code sample apps. Doing so will help ensure the safety of you and those around you and will prevent potential injury or damage.

The sample apps assume that the system (network, axes, I/O) are configured prior to running the code featured in the sample app. See the Configuration page for more information.
1""" Helper functions for RapidCode Python samples.
2"""
3
4from _imports import RapidCode, RAPIDCODE_DIR, constants, platform
5
6
7def get_enum_name(prefix: str, value: int) -> str:
8 """Get enum name using reflection on SWIG-generated constants.
9
10 Args:
11 prefix: The enum prefix (e.g., "RSINetworkState_RSINetworkState")
12 value: The enum value to look up
13
14 Returns:
15 The enum name with prefix stripped, or "UNKNOWN(value)" if not found
16
17 Example:
18 get_enum_name("RSINetworkState_RSINetworkState", controller.NetworkStateGet())
19 # Returns "OPERATIONAL" for RSINetworkState_RSINetworkStateOPERATIONAL
20 """
21 for name in dir(RapidCode):
22 if name.startswith(prefix):
23 if getattr(RapidCode, name) == value:
24 return name[len(prefix):]
25 return f"UNKNOWN({value})"
26
27
28def get_creation_parameters():
29 # create a motion controller and return it.
30 # If any errors are found, raise an exception with the error log as the message.
31 creation_params: RapidCode.CreationParameters = RapidCode.CreationParameters()
32 creation_params.RmpPath = RAPIDCODE_DIR
33 creation_params.NicPrimary = constants.RMP_NIC_PRIMARY
34
35 if platform.system() == "Windows":
36 creation_params.NodeName = constants.RMP_NODE_NAME
37 elif platform.system() == "Linux":
38 creation_params.CpuAffinity = constants.RMP_CPU_AFFINITY
39 else:
40 raise Exception("Unsupported platform")
41
42 return creation_params
43
44def check_errors(rsi_object):
45 # check for errors in the given rsi_object and print any errors that are found.
46 # If the error log contains any errors (not just warnings), raises an exception with the error log as the message.
47 # returns a tuple containing a boolean indicating whether the error log contained any errors and the error log string.
48 error_string_builder = ""
49 i = rsi_object.ErrorLogCountGet()
50 while rsi_object.ErrorLogCountGet() > 0:
51 error:RapidCode.RsiError = rsi_object.ErrorLogGet()
52 error_type = "WARNING" if error.isWarning else "ERROR"
53 error_string_builder += f"{error_type}: {error.text}\n"
54 if len(error_string_builder) > 0:
55 print(error_string_builder)
56 if "ERROR" in error_string_builder:
57 raise Exception(error_string_builder)
58 return "ERROR" in error_string_builder, error_string_builder
59
60def start_the_network(controller):
61 # attempts to start the network using the given MotionController object.
62 # If the network fails to start, it reads and prints any log messages that may be helpful
63 # in determining the cause of the problem, and then raises an RsiError exception.
64 if controller.NetworkStateGet() != RapidCode.RSINetworkState_RSINetworkStateOPERATIONAL: # Check if network is started already.
65 print("Starting Network..")
66 controller.NetworkStart() # If not. Initialize The Network. (This can also be done from RapidSetup Tool)
67
68 if controller.NetworkStateGet() != RapidCode.RSINetworkState_RSINetworkStateOPERATIONAL: # Check if network is started again.
69 messages_to_read = controller.NetworkLogMessageCountGet() # Some kind of error starting the network, read the network log messages
70
71 for i in range(messages_to_read):
72 print(controller.NetworkLogMessageGet(i)) # Print all the messages to help figure out the problem
73 print("Expected OPERATIONAL state but the network did not get there.")
74 # raise Exception(Expected OPERATIONAL state but the network did not get there.) # Uncomment if you want your application to exit when the network isn't operational. (Comment when using phantom axis)
75 else: # Else, of network is operational.
76 print("Network Started")
77
78def abort_motion_object(motion_object):
79 # Aborts motion on the given motion object (Axis or MultiAxis), waits for motion to complete,
80 # clears faults, and verifies the object enters IDLE state.
81 # If the object fails to enter IDLE state, raises an exception with the error source.
82 motion_object.EStopAbort()
83 motion_object.MotionDoneWait()
84 motion_object.ClearFaults()
85
86 # check for idle state
87 verify_idle_state(motion_object)
88
89def verify_idle_state(motion_object):
90 # Verifies that the given motion object (Axis or MultiAxis) is in IDLE state.
91 # If not, raises an exception with the error source.
92 if motion_object.StateGet() != RapidCode.RSIState_RSIStateIDLE:
93 source = motion_object.SourceGet() # get state source enum
94 error_msg = f"Axis or MultiAxis {motion_object.NumberGet()} is expected to be in IDLE state, but is in state {enum_to_name(motion_object.StateGet(), 'RSIState')}. " \
95 f"\nError Source: {motion_object.SourceNameGet(source)}"
96 raise Exception(error_msg)
97
98def enum_to_name(value, prefix):
99 """Reverse lookup: int value -> enum name"""
100 for name in dir(RapidCode):
101 if name.startswith(prefix + "_" + prefix) and getattr(RapidCode, name) == value:
102 return name.split(prefix + "_" + prefix)[1]
103 return str(value)