Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ It's also possible to connect via UDP server using the `--udp` option with IP:PO

## Usage

### Ping1D

The [Ping1D](https://docs.bluerobotics.com/ping-python/classPing_1_1Ping1D_1_1Ping1D.html) class provides an easy interface to configure a Ping device and retrieve data.

A Ping1D object must be initialized with the serial device path and the baudrate.
Expand Down Expand Up @@ -107,3 +109,72 @@ Use the [`set_*`](https://github.com/bluerobotics/ping-protocol#set) messages (e
```

See the [doxygen](https://docs.bluerobotics.com/ping-python/) documentation for complete API documentation.

### Ping360 Auto Scan

The `Ping360` class provides an easy interface to configure a Ping360 device
and retrieve sonar profiles.

A Ping360 object must be connected over serial or UDP.

```py
from brping import definitions
from brping import Ping360

myPing360 = Ping360()
myPing360.connect_serial("/dev/ttyUSB0", 2000000)
# For UDP
# myPing360.connect_udp("192.168.2.2", 9092)
```

Call `initialize()` to establish communications with the device.

```py
if myPing360.initialize() is False:
print("Failed to initialize Ping!")
exit(1)
```

Use `control_auto_transmit()` to start a continuous full-sector auto-scan. The
following API snippets are partial; use the [Ping360 auto-scan
example](examples/ping360AutoScan.py) for a runnable scan.

```py
myPing360.control_auto_transmit(
mode=1,
gain_setting=0,
transmit_duration=80,
sample_period=80,
transmit_frequency=750,
number_of_samples=1024,
start_angle=0,
stop_angle=399,
num_steps=1,
delay=0
)
```

The device sends a `PING360_AUTO_DEVICE_DATA` message for each angle. Each
message contains the scan angle in `angle` and raw echo-strength samples in
`data`. Use `wait_message()` to receive these messages. See the [`2301
auto_device_data` message
definition](https://docs.bluerobotics.com/ping-protocol/pingmessage-ping360/#2301-auto_device_data)
for the complete list of fields and units.

```py
message = myPing360.wait_message([definitions.PING360_AUTO_DEVICE_DATA])
if message:
angle = message.angle
data = message.data
print("Angle: %s gradians\tSample count: %s\tPreview: %s" %
(angle, len(data), list(data[:8])))
else:
print("Failed to get profile data")
```

To stop the device when using serial connections use a break and autobaud
sequence before `control_motor_off()`; in case of UDP connections call
`control_motor_off()` directly.

Auto-transmit and `PING360_AUTO_DEVICE_DATA` require Ping Protocol `v1.1.0` and
supporting Ping360 firmware.
68 changes: 41 additions & 27 deletions examples/ping360AutoScan.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

parser = argparse.ArgumentParser(description="Ping360 auto scan example")
parser.add_argument('--device', action="store", required=False, type=str, help="Ping device port. E.g: /dev/ttyUSB0")
parser.add_argument('--baudrate', action="store", type=int, default=2000000, help="Ping device baudrate. E.g: 115200")
parser.add_argument('--udp', action="store", required=False, type=str, help="Ping UDP server. E.g: 192.168.2.2:9090")
parser.add_argument('--baudrate', action="store", type=int, default=2000000, help="Ping device baudrate. E.g: 2000000")
parser.add_argument('--udp', action="store", required=False, type=str, help="Ping UDP server. E.g: 192.168.2.2:9092")
args = parser.parse_args()
if args.device is None and args.udp is None:
parser.print_help()
Expand All @@ -36,30 +36,44 @@

input("Press Enter to continue...")

myPing360.control_auto_transmit(
mode = 1,
gain_setting = 0,
transmit_duration = 80,
sample_period = 80,
transmit_frequency = 750,
number_of_samples = 1024,
start_angle = 0,
stop_angle = 399,
num_steps = 1,
delay = 0
)
try:
myPing360.control_auto_transmit(
mode = 1,
gain_setting = 0,
transmit_duration = 80,
sample_period = 80,
transmit_frequency = 750,
number_of_samples = 1024,
start_angle = 0,
stop_angle = 399,
num_steps = 1,
delay = 0
)

# Print the scanning head angle
for n in range(400):
m = myPing360.wait_message([definitions.PING360_AUTO_DEVICE_DATA])
if m:
print(m.angle)
time.sleep(0.001)
# Print a compact summary of each received profile.
for n in range(400):
message = myPing360.wait_message([definitions.PING360_AUTO_DEVICE_DATA])
if message is None:
print("Timed out waiting for a Ping360 profile.")
break

# if it is a serial device, reconnect to send a line break
# and stop auto-transmitting
if args.device is not None:
myPing360.connect_serial(args.device, args.baudrate)

# turn the motor off
myPing360.control_motor_off()
angle = message.angle
# data contains raw return-strength samples ordered nearest-to-farthest.
data = message.data
print(
f"Angle: {angle} gradians, samples: {len(data)}, "
f"preview: {list(data[:8])}"
)
time.sleep(0.001)
except KeyboardInterrupt:
print("\nScan interrupted.")
finally:
print("Stopping auto scan and disabling the motor...")
try:
if args.device is not None:
# A serial break stops auto-transmit and starts device autobaud.
myPing360.iodev.send_break()
time.sleep(0.001)
myPing360.iodev.write(b"U")
finally:
myPing360.control_motor_off()