You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

interpolate_lcr_to_lcr.py 4.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. """Module for interpolating between LCR robot configurations.
  2. This module provides functionality for calculating and interpolating between
  3. different LCR robot configurations to ensure smooth transitions.
  4. """
  5. import argparse
  6. import json
  7. import os
  8. import pyarrow as pa
  9. import pyarrow.compute as pc
  10. from dora import Node
  11. from pwm_position_control.load import load_control_table_from_json_conversion_tables
  12. from pwm_position_control.transform import (
  13. logical_to_pwm_with_offset_arrow,
  14. pwm_to_logical_arrow,
  15. wrap_joints_and_values,
  16. )
  17. def main():
  18. """Initialize and run the LCR interpolation node."""
  19. parser = argparse.ArgumentParser(
  20. description="Interpolation LCR Node: This Dora node is used to calculates appropriate goal positions for the "
  21. "LCR followers knowing a Leader position and Follower position.",
  22. )
  23. parser.add_argument(
  24. "--name",
  25. type=str,
  26. required=False,
  27. help="The name of the node in the dataflow.",
  28. default="lcr-to-lcr",
  29. )
  30. parser.add_argument(
  31. "--leader-control",
  32. type=str,
  33. help="The configuration file for controlling the leader.",
  34. default=None,
  35. )
  36. parser.add_argument(
  37. "--follower-control",
  38. type=str,
  39. help="The configuration file for controlling the follower.",
  40. default=None,
  41. )
  42. args = parser.parse_args()
  43. if not os.environ.get("LEADER_CONTROL") and args.leader_control is None:
  44. raise ValueError(
  45. "The leader control is not set. Please set the configuration of the leader in the environment variables or "
  46. "as an argument.",
  47. )
  48. if not os.environ.get("FOLLOWER_CONTROL") and args.follower_control is None:
  49. raise ValueError(
  50. "The follower control is not set. Please set the configuration of the follower in the environment "
  51. "variables or as an argument.",
  52. )
  53. with open(
  54. os.environ.get("LEADER_CONTROL")
  55. if args.leader_control is None
  56. else args.leader_control,
  57. ) as file:
  58. leader_control = json.load(file)
  59. load_control_table_from_json_conversion_tables(leader_control, leader_control)
  60. with open(
  61. os.environ.get("FOLLOWER_CONTROL")
  62. if args.follower_control is None
  63. else args.follower_control,
  64. ) as file:
  65. follower_control = json.load(file)
  66. load_control_table_from_json_conversion_tables(
  67. follower_control, follower_control,
  68. )
  69. initial_mask = [
  70. True if leader_control[joint]["goal_position"] is not None else False
  71. for joint in leader_control.keys()
  72. ]
  73. logical_leader_initial_goal = wrap_joints_and_values(
  74. [
  75. joint
  76. for joint in leader_control.keys()
  77. if leader_control[joint]["goal_position"] is not None
  78. ],
  79. [
  80. leader_control[joint]["goal_position"]
  81. for joint in leader_control.keys()
  82. if leader_control[joint]["goal_position"] is not None
  83. ],
  84. )
  85. node = Node(args.name)
  86. leader_initialized = False
  87. follower_initialized = False
  88. follower_position = None
  89. for event in node:
  90. event_type = event["type"]
  91. if event_type == "INPUT":
  92. event_id = event["id"]
  93. if event_id == "leader_position":
  94. leader_position = event["value"]
  95. if not leader_initialized:
  96. leader_initialized = True
  97. pwm_goal = logical_to_pwm_with_offset_arrow(
  98. leader_position.filter(initial_mask),
  99. logical_leader_initial_goal,
  100. leader_control,
  101. )
  102. node.send_output("leader_goal", pwm_goal, event["metadata"])
  103. if not follower_initialized:
  104. continue
  105. leader_position = pwm_to_logical_arrow(leader_position, leader_control)
  106. interpolation = pa.array([1, 1, 1, 1, 1, 700 / 450], type=pa.float32())
  107. logical_goal = wrap_joints_and_values(
  108. leader_position.field("joints"),
  109. pc.multiply(leader_position.field("values"), interpolation),
  110. )
  111. pwm_goal = logical_to_pwm_with_offset_arrow(
  112. follower_position, logical_goal, follower_control,
  113. )
  114. node.send_output("follower_goal", pwm_goal, event["metadata"])
  115. elif event_id == "follower_position":
  116. follower_position = event["value"]
  117. follower_initialized = True
  118. elif event_type == "ERROR":
  119. print("[lcr-to-lcr] error: ", event["error"])
  120. break
  121. if __name__ == "__main__":
  122. main()