Please provide some answer regards ping360

Hi @khangydt,

Did you take a look in our protocol documentation ?

From the device_data message documentation:

Type Name Description Units
u8 data 8 bit binary data array representing sonar echo strength

This array [of size N] represents the N points equally spaced between the sensor transducer and the range that the sensor is configured to scan. E.g:
For a range of 2m or 2000mm, using a scan of 200 points, each index of the vector [i] will represent i*2000/200 mm, where:

data[0]; // 0mm
data[1]; // 10mm 
...

The value of each points is normalized inside the 0-255 range, where 255 is the maximum power decoded by the A-D converter.

Following our transducer message documentation, we can write a simple request message like this:

/** This is a pseudocode example **/

// This is the default mode for now
transducer_message.set_mode(1);
// The desired gain [0-2]
transducer_message.set_gain_setting(gain);
// Set the transducer position in gradian [0-400]
transducer_message.set_angle(angle);
// Signal transmitted duration between 1-1000µS
transducer_message.set_transmit_duration(transmit_duration);
// Time interval between individual signal intensity samples in 25ns
// increments (80 to 40000 == 2 microseconds to 1000 microseconds)
transducer_message.set_sample_period(sample_period);
// Acoustic operating frequency, frequency range is 500kHz to 1000kHz,
// but 740 is a good practical frequency for different scenarios 
transducer_message.set_transmit_frequency(transmit_frequency);
// Number of samples per reflected signal [200-1200]
transducer_message.set_number_of_samples(num_points);
// Value that set the transition request [0, 1]
// if you want a profile this should be 1
transducer_message.set_transmit(transmit);

Now, different from Ping1D, Ping360 has a low abstraction level for the sensor functionality, making it super flexible if someone wants to do some specific tasks and magic tuning.
But, if you just want to do a normal scan like PingViewer, some math and knowledge of how the sonar work is necessary, E.g:

For a 30m with 1200 points, low gain and the head position at 180º | π rad |200ᵍ.

/*
From the documentation:

    _firmwareMinTransmitDuration = 5;
    _firmwareMaxTransmitDuration = 500; 
    _samplePeriodSickDuration = 25e-9;

*/


num_points = 1200;         // 1200 points
gain = 0;                  // Low gain
angle = 200;               // 200ᵍ
transmit_frequency = 740;  // Default frequency

/* Calculate the sample period and transmit duration
   for a specific range */

range = 30;          // 30m range
sample_period = calculateSamplePeriod(range);
transmit_duration = adjustTransmitDuration(range);

// Create the transducer message now with the new values
...

And here is a simple example of such functions:

/**
 * @brief Calculate the sample period based in the new range
 *
 */
float calculateSamplePeriod(distance)
{
    return 2*distance/(num_points*speed_of_sound*_samplePeriodSickDuration);
}

/**
 * @brief Adjust the transmit duration for a specific range
 * Per firmware engineer:
 * 1. Starting point is TxPulse in usec = ((one-way range in metres) * 8000) / (Velocity of sound in metres
 * per second)
 * 2. Then check that TxPulse is wide enough for currently selected sample interval in usec, i.e.,
 *    if TxPulse < (2.5 * sample interval) then TxPulse = (2.5 * sample interval)
 * 3. Perform limit checking
 *
 * @return Transmit duration
 */
float adjustTransmitDuration(distance)
{
    // 1
    transmit_duration = 8000 * distance / _speed_of_sound);
    // 2 (transmit duration is microseconds, samplePeriod() is nanoseconds)
    transmit_duration = max(2.5*samplePeriod()/1000, duration);
    // 3
    return max(_firmwareMinTransmitDuration, min(transmitDurationMax(), transmit_duration));
}

/**
 * @brief The maximum transmit duration that will be applied is limited internally by the
 * firmware to prevent damage to the hardware
 * The maximum transmit duration is equal to 64 * the sample period in microseconds
 *
 * @return The maximum transmit duration possible
 */
float transmitDurationMax()
{
    return min(_firmwareMaxTransmitDuration, samplePeriod() * 64e6);
}

/**
 * @brief Sample period in ns
 *
 * @return double
 */
float samplePeriod()
{
    return sample_period*_samplePeriodSickDuration;
}

Exactly as described in the previous example.

Note: PingViewer is open source, you can take a look in the code here:
https://github.com/bluerobotics/ping-viewer/blob/master/src/sensor/ping360.h
https://github.com/bluerobotics/ping-viewer/blob/master/src/sensor/ping360.cpp

I believe that Adam has answered that in the previous post.

If you are facing problems do understand what is the profile and how to interpret the data, this documentation can also help:

Please, let us know if you have any further question, we are always improving our documentation with examples and our libraries with higher abstraction layers. But for now, we are still working to improve Ping360 usability for people that don’t want to deal with the sonar math and logic.

2 Likes