Skip to content

Commit e49ed41

Browse files
authored
Merge pull request #119 from CWRUbotix/manual-control
Replace override_rc_in with manual_control
2 parents 3b45bdb + 1e1294c commit e49ed41

File tree

7 files changed

+45
-34
lines changed

7 files changed

+45
-34
lines changed

.github/workflows/industrial_ci_action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ jobs:
2727
CCACHE_DIR: "${{ github.workspace }}/.ccache" # directory for ccache (and how we enable ccache in industrial_ci)
2828
steps:
2929
- uses: actions/checkout@v4 # clone target repository
30+
with:
31+
submodules: recursive
3032
- uses: actions/cache@v4 # fetch/store the directory used by ccache before/after the ci run
3133
with:
3234
path: ${{ env.CCACHE_DIR }}

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "src/surface/ros2_video_streamer"]
22
path = src/surface/ros2_video_streamer
33
url = [email protected]:CWRUbotix/ros2_video_streamer.git
4+
[submodule "src/pi/mavros"]
5+
path = src/pi/mavros
6+
url = https://github.com/mavlink/mavros.git

src/pi/mavros

Submodule mavros added at b490957

src/pi/pixhawk_communication/launch/mavros_launch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ def generate_launch_description() -> LaunchDescription:
2626
# receive a signal from a GCS.
2727
{'system_id': 255},
2828
# plugin_allowlist allows which mavros nodes get launched. The default is all of them.
29-
{'plugin_allowlist': ['sys_status', 'rc_io', 'command']},
29+
{'plugin_allowlist': ['sys_status', 'rc_io', 'command', 'manual_control']},
3030
{'fcu_url': '/dev/ttyPixhawk'},
3131
],
3232
remappings=[
3333
('/pi/mavros/state', '/tether/mavros/state'),
34-
('/pi/mavros/rc/override', '/tether/mavros/rc/override'),
34+
('/pi/mavros/manual_control/send', '/tether/mavros/manual_control/send'),
3535
('/pi/mavros/cmd/arming', '/tether/mavros/cmd/arming'),
3636
('/pi/mavros/cmd/command', '/tether/mavros/cmd/command'),
3737
],

src/surface/flight_control/flight_control/multiplexer.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from collections.abc import Callable
2+
from typing import Final
23

34
import rclpy
4-
from mavros_msgs.msg import OverrideRCIn
5+
from mavros_msgs.msg import ManualControl
56
from rclpy.executors import MultiThreadedExecutor
67
from rclpy.node import Node
78
from rclpy.qos import QoSPresetProfiles
@@ -17,9 +18,14 @@
1718

1819
# Range of values Pixhawk takes
1920
# In microseconds
20-
ZERO_SPEED = 1500
21-
MAX_RANGE_SPEED = 400
22-
RANGE_SPEED = MAX_RANGE_SPEED * SPEED_THROTTLE
21+
ZERO_SPEED: Final = 0
22+
Z_ZERO_SPEED: Final = 500
23+
MAX_RANGE_SPEED: Final = 2000
24+
Z_MAX_RANGE_SPEED: Final = 1000
25+
RANGE_SPEED: Final = MAX_RANGE_SPEED * SPEED_THROTTLE
26+
Z_RANGE_SPEED: Final = Z_MAX_RANGE_SPEED * SPEED_THROTTLE
27+
28+
EXTENSIONS_CODE: Final = 0b00000011
2329

2430
# Channels for RC command
2531
MAX_CHANNEL = 8
@@ -57,36 +63,39 @@ def __init__(self) -> None:
5763
QoSPresetProfiles.DEFAULT.value,
5864
)
5965

60-
self.rc_pub = self.create_publisher(
61-
OverrideRCIn, 'mavros/rc/override', QoSPresetProfiles.DEFAULT.value
66+
self.mc_pub = self.create_publisher(
67+
ManualControl, 'mavros/manual_control/send', QoSPresetProfiles.DEFAULT.value
6268
)
6369

6470
@staticmethod
6571
def apply(msg: PixhawkInstruction, function_to_apply: Callable[[float], float]) -> None:
6672
"""Apply a function to each dimension of this PixhawkInstruction."""
6773
msg.forward = function_to_apply(msg.forward)
68-
msg.vertical = function_to_apply(msg.vertical)
74+
msg.vertical = msg.vertical
6975
msg.lateral = function_to_apply(msg.lateral)
7076
msg.pitch = function_to_apply(msg.pitch)
7177
msg.yaw = function_to_apply(msg.yaw)
7278
msg.roll = function_to_apply(msg.roll)
7379

7480
@staticmethod
75-
def to_override_rc_in(msg: PixhawkInstruction) -> OverrideRCIn:
81+
def to_manual_control(msg: PixhawkInstruction) -> ManualControl:
7682
"""Convert this PixhawkInstruction to an rc_msg with the appropriate channels array."""
77-
rc_msg = OverrideRCIn()
83+
mc_msg = ManualControl()
7884

7985
# Maps to PWM
80-
MultiplexerNode.apply(msg, lambda value: int(RANGE_SPEED * value) + ZERO_SPEED)
86+
MultiplexerNode.apply(msg, lambda value: (RANGE_SPEED * value) + ZERO_SPEED)
8187

82-
rc_msg.channels[FORWARD_CHANNEL] = msg.forward
83-
rc_msg.channels[THROTTLE_CHANNEL] = msg.vertical
84-
rc_msg.channels[LATERAL_CHANNEL] = msg.lateral
85-
rc_msg.channels[PITCH_CHANNEL] = msg.pitch
86-
rc_msg.channels[YAW_CHANNEL] = msg.yaw
87-
rc_msg.channels[ROLL_CHANNEL] = msg.roll
88+
mc_msg.x = msg.forward
89+
mc_msg.z = (
90+
Z_RANGE_SPEED * msg.vertical
91+
) + Z_ZERO_SPEED # To account for different z limits
92+
mc_msg.y = msg.lateral
93+
mc_msg.r = msg.yaw
94+
mc_msg.enabled_extensions = EXTENSIONS_CODE
95+
mc_msg.s = msg.pitch
96+
mc_msg.t = msg.roll
8897

89-
return rc_msg
98+
return mc_msg
9099

91100
def state_control(
92101
self, req: AutonomousFlight.Request, res: AutonomousFlight.Response
@@ -114,7 +123,7 @@ def control_callback(self, msg: PixhawkInstruction) -> None:
114123
else:
115124
return
116125

117-
self.rc_pub.publish(msg=self.to_override_rc_in(msg))
126+
self.mc_pub.publish(self.to_manual_control(msg))
118127

119128

120129
def main() -> None:

src/surface/flight_control/launch/flight_control_launch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def generate_launch_description() -> LaunchDescription:
3535
multiplexer_node = Node(
3636
package='flight_control',
3737
executable='multiplexer_node',
38-
remappings=[('/surface/mavros/rc/override', '/tether/mavros/rc/override')],
38+
remappings=[('/surface/mavros/manual_control/send', '/tether/mavros/manual_control/send')],
3939
emulate_tty=True,
4040
output='screen',
4141
)

src/surface/flight_control/test/test_manual_control.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import rclpy
22
from flight_control.manual_control_node import ManualControlNode
33
from flight_control.multiplexer import (
4-
FORWARD_CHANNEL,
5-
LATERAL_CHANNEL,
6-
PITCH_CHANNEL,
74
RANGE_SPEED,
8-
ROLL_CHANNEL,
9-
THROTTLE_CHANNEL,
10-
YAW_CHANNEL,
5+
Z_RANGE_SPEED,
6+
Z_ZERO_SPEED,
117
ZERO_SPEED,
128
MultiplexerNode,
139
)
@@ -35,14 +31,14 @@ def test_joystick_profiles() -> None:
3531
roll=0.92,
3632
)
3733

38-
msg = MultiplexerNode.to_override_rc_in(instruction)
34+
msg = MultiplexerNode.to_manual_control(instruction)
3935

40-
assert msg.channels[FORWARD_CHANNEL] == ZERO_SPEED
41-
assert msg.channels[THROTTLE_CHANNEL] == (ZERO_SPEED + RANGE_SPEED)
42-
assert msg.channels[LATERAL_CHANNEL] == (ZERO_SPEED - RANGE_SPEED)
36+
assert msg.x == ZERO_SPEED
37+
assert msg.z == (Z_ZERO_SPEED + Z_RANGE_SPEED)
38+
assert msg.y == (ZERO_SPEED - RANGE_SPEED)
4339

4440
# 1539 1378
4541

46-
assert msg.channels[PITCH_CHANNEL] == ZERO_SPEED + int(RANGE_SPEED * 0.34)
47-
assert msg.channels[YAW_CHANNEL] == ZERO_SPEED + int(RANGE_SPEED * -0.6)
48-
assert msg.channels[ROLL_CHANNEL] == ZERO_SPEED + int(RANGE_SPEED * 0.92)
42+
assert msg.s == ZERO_SPEED + int(RANGE_SPEED * 0.34)
43+
assert msg.r == ZERO_SPEED + int(RANGE_SPEED * -0.6)
44+
assert msg.t == ZERO_SPEED + int(RANGE_SPEED * 0.92)

0 commit comments

Comments
 (0)