Skip to content

Commit 49f153f

Browse files
authored
Merge pull request #6 from wheelos/whl_mock
Whl mock
2 parents db455a7 + 4bee23b commit 49f153f

File tree

4 files changed

+106
-9
lines changed

4 files changed

+106
-9
lines changed

cyber/setup.bash

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@ for entry in "${mainboard_path}" \
2727
done
2828
pathprepend "${HOME}/.local/bin" PATH
2929

30-
# pathprepend "${APOLLO_ROOT_DIR}" PYTHONPATH
31-
3230
# Set up the Python environment
3331
# For cyber python
32+
pathprepend "${APOLLO_ROOT_DIR}" PYTHONPATH
33+
# For common_msgs
3434
pathprepend "${bazel_bin_path}" PYTHONPATH
3535
# For cyber c++ wrap so
3636
pathprepend "${bazel_bin_path}/cyber/python/internal" PYTHONPATH
37-
# For common_msgs
38-
pathprepend "${bazel_bin_path}/modules" PYTHONPATH
37+
3938

4039
# for protobuf python
4140
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Protobuf Text Format Template for message: apollo.prediction.PredictionObstacles
2+
#
3+
# Instructions:
4+
# 1. Fill in the values for each field.
5+
# 2. For repeated fields, add multiple entries by repeating the field name.
6+
# 3. For enum fields, use defined enum names.
7+
# 4. Remove comments (#) and placeholder values before publishing.
8+
# 5. Fields not specified will use their default Protobuf values.
9+
#
10+
header {
11+
timestamp_sec: 0.0
12+
module_name: "PLACEHOLDER_STRING"
13+
sequence_num: 0
14+
lidar_timestamp: 0
15+
camera_timestamp: 0
16+
radar_timestamp: 0
17+
version: 0
18+
status {
19+
error_code: OK
20+
msg: "PLACEHOLDER_STRING"
21+
}
22+
frame_id: "PLACEHOLDER_STRING"
23+
}
24+
perception_error_code: OK
25+
start_timestamp: 0.0
26+
end_timestamp: 0.0

modules/tools/whl-mock/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# whl-mock
2+
3+
`whl-mock` is a tool for publishing arbitrary message types in Apollo. It
4+
generates message templates, lets you edit them, and publishes the customized
5+
messages. Typical use cases include sending routing or other messages by editing
6+
the corresponding template file (e.g., `RoutingRequest_template.txt`) and
7+
publishing it from the command line.
8+
9+
## Quick Start
10+
11+
### 1. Build Dependencies
12+
13+
Compile `cyber` and `common_msgs`:
14+
15+
```shell
16+
./apollo.sh build_cpu cyber common_msgs
17+
```
18+
19+
### 2. Set Up Environment
20+
21+
Source the environment variables:
22+
23+
```shell
24+
source cyber/setup.bash
25+
```
26+
27+
## Publishing Messages
28+
29+
1. Edit the desired message template file (e.g., `<your_msg_template>.txt`).
30+
2. Publish the message:
31+
32+
```shell
33+
# Example:
34+
python modules/tools/whl-mock/publisher.py --publish -i PredictionObstacles_template.txt -t /apollo/prediction
35+
# General usage:
36+
# python modules/tools/whl-mock/publisher.py --publish -i your_message_template.txt -t /your_topic -p 0.1
37+
```
38+
39+
3. In another terminal, run:
40+
41+
```shell
42+
cyber_monitor
43+
```
44+
45+
to verify the published message.
46+
47+
## Generating Message Templates
48+
49+
To publish a different message type:
50+
51+
1. Modify the message type in the code if needed.
52+
2. Generate a new template:
53+
54+
```shell
55+
python modules/tools/whl-mock/publisher.py --gen
56+
```
57+
58+
3. Edit the generated `<your_msg_template>.txt` file as needed.

modules/tools/whl-mock/publisher.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#
1818
# This affects the generated template and the message type that will be published.
1919
# Make sure it matches the actual message type you want to use.
20-
from common_msgs.control_msgs.control_cmd_pb2 import ControlCommand as MessageType
20+
21+
from cyber.proto.unit_test_pb2 import ChatterBenchmark as MessageType
2122

2223
# ========================================================
2324

@@ -28,6 +29,16 @@
2829
)
2930

3031

32+
def fill_header(msg: Message):
33+
"""
34+
Fill the header fields of the message with default values.
35+
This is a placeholder function and should be customized based on your message type.
36+
"""
37+
if hasattr(msg, "header"):
38+
msg.header.timestamp_sec = time.time()
39+
msg.header.sequence_num += 1
40+
41+
3142
class ProtoTemplateGenerator:
3243
def __init__(self, message_type: Type[Message]):
3344
self.message_type = message_type
@@ -38,7 +49,7 @@ def generate_template(self, output_filepath: str):
3849
self._fill_template_recursive(msg_instance)
3950

4051
template_str = text_format.MessageToString(
41-
msg_instance, as_utf8=True, indent=2, as_one_line=False
52+
msg_instance, as_utf8=True, indent=0, as_one_line=False
4253
)
4354

4455
preamble = f"""# Protobuf Text Format Template for message: {self.message_type.DESCRIPTOR.full_name}
@@ -93,9 +104,8 @@ def _fill_template_recursive(self, msg_instance: Message):
93104
self._get_placeholder_for_primitive(field.type)
94105
)
95106
elif field.type == descriptor.FieldDescriptor.TYPE_MESSAGE:
96-
nested_msg = field.message_type._concrete_class()
97-
self._fill_template_recursive(nested_msg)
98-
setattr(msg_instance, field.name, nested_msg)
107+
nested_instance = getattr(msg_instance, field.name)
108+
self._fill_template_recursive(nested_instance)
99109
elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
100110
enum_desc = field.enum_type
101111
first_enum_value = enum_desc.values[0].number if enum_desc.values else 0
@@ -112,6 +122,8 @@ def _get_placeholder_for_primitive(self, field_type: int) -> Any:
112122

113123
if field_type == descriptor.FieldDescriptor.TYPE_STRING:
114124
return "PLACEHOLDER_STRING"
125+
elif field_type == descriptor.FieldDescriptor.TYPE_BYTES:
126+
return b""
115127
elif field_type in (
116128
descriptor.FieldDescriptor.TYPE_INT32,
117129
descriptor.FieldDescriptor.TYPE_INT64,
@@ -187,10 +199,12 @@ def publish_message(
187199
i, _, _ = select.select([sys.stdin], [], [], None)
188200
if i:
189201
input_line = sys.stdin.readline()
202+
fill_header(msg_to_publish)
190203
writer.write(msg_to_publish)
191204
logging.info(f"Topic '{topic_name}' message published.")
192205
else:
193206
while not cyber.is_shutdown():
207+
fill_header(msg_to_publish)
194208
writer.write(msg_to_publish)
195209
if period > 0:
196210
time.sleep(period)

0 commit comments

Comments
 (0)