PiRacer Pro Solution to Hardware Not Working

Greetings Everyone,

Recently I purchased a PiRacer Pro by Waveshare. It was not functioning correctly. The steering and throttle would not work right from the start. I had to do a lot of digging, and the results are posted below. Several Modifications had to be made to several files to get it functionally moving. This is a generic raspberry Pi installation following the instructions on the PiRacer Pro Wiki and then modifying the contents of files. More will probably be needed but here is what I have:

In projects/donkeycar/donkeycar/parts:
actuators.py
The throttle function had to be changed to support the correct reverse sequence: (The only change is in the run>>else section

class PWMThrottle:
“”"
Wrapper over a PWM motor cotnroller to convert -1 to 1 throttle
values to PWM pulses.
“”"
MIN_THROTTLE = -1
MAX_THROTTLE = 1

def __init__(self, controller=None,
                   max_pulse=4095,
                   min_pulse=-4095,
                   zero_pulse=0):

    self.controller = controller
    self.max_pulse = max_pulse
    self.min_pulse = min_pulse
    self.zero_pulse = zero_pulse
    
    #send zero pulse to calibrate ESC
    print("Init ESC")
    self.controller.set_pulse(self.zero_pulse)
    time.sleep(1)


def run(self, throttle):
    if throttle > 0:
        pulse = dk.utils.map_range(throttle,
                                0, self.MAX_THROTTLE, 
                                self.zero_pulse, self.max_pulse)
        self.controller.pwm.set_pwm(self.controller.channel,0,pulse)
        self.controller.pwm.set_pwm(self.controller.channel+1,0,0)
        self.controller.pwm.set_pwm(self.controller.channel+2,0,4095)
        self.controller.pwm.set_pwm(self.controller.channel+3,0,0)
        self.controller.pwm.set_pwm(self.controller.channel+4,0,pulse)
        self.controller.pwm.set_pwm(self.controller.channel+7,0,pulse)
        self.controller.pwm.set_pwm(self.controller.channel+6,0,0)
        self.controller.pwm.set_pwm(self.controller.channel+5,0,4095)
    else:
        pulse = dk.utils.map_range(throttle,
                                self.MIN_THROTTLE, 0, 
                                self.min_pulse, self.zero_pulse)
        **self.controller.pwm.set_pwm(self.controller.channel,0,self.zero_pulse)**

** self.controller.pwm.set_pwm(self.controller.channel,0,pulse)**
** self.controller.pwm.set_pwm(self.controller.channel,0,self.zero_pulse)**
** self.controller.pwm.set_pwm(self.controller.channel,0,pulse)**
** ‘’’**
** self.controller.pwm.set_pwm(self.controller.channel,0,- pulse)**
** self.controller.pwm.set_pwm(self.controller.channel+2,0,0)**
** self.controller.pwm.set_pwm(self.controller.channel+1,0,4095)**
** self.controller.pwm.set_pwm(self.controller.channel+3,0,- pulse)**
** self.controller.pwm.set_pwm(self.controller.channel+4,0,0)**
** self.controller.pwm.set_pwm(self.controller.channel+7,0,- pulse)**
** self.controller.pwm.set_pwm(self.controller.channel+5,0,0)**
** self.controller.pwm.set_pwm(self.controller.channel+6,0,4095)**
** ‘’’**

def shutdown(self):
    self.run(0) #stop vehicle

In manage.py in the folder created for your car, the frequency of the throttle controller had to be changed to 60. This is because the PCA9685 supports only one frequency for all devices attached, not individual frequencies:

#Drive train setup
if cfg.DONKEY_GYM:
pass

elif cfg.DRIVE_TRAIN_TYPE == "SERVO_ESC":
    from donkeycar.parts.actuator import PCA9685, PWMSteering, PWMThrottle

    steering_controller = PCA9685(cfg.STEERING_CHANNEL, cfg.PCA9685_I2C_ADDR,**frequency=60**, busnum=cfg.PCA9685_I2C_BUSNUM)
    steering = PWMSteering(controller=steering_controller,
                                    left_pulse=cfg.STEERING_LEFT_PWM, 
                                    right_pulse=cfg.STEERING_RIGHT_PWM)
    
    throttle_controller = PCA9685(cfg.THROTTLE_CHANNEL, cfg.PCA9685_I2C_ADDR1, **frequency=60**, busnum=cfg.PCA9685_I2C_BUSNUM)
    throttle = PWMThrottle(controller=throttle_controller,
                                    max_pulse=cfg.THROTTLE_FORWARD_PWM,
                                    zero_pulse=cfg.THROTTLE_STOPPED_PWM, 
                                    min_pulse=cfg.THROTTLE_REVERSE_PWM)

    V.add(steering, inputs=['angle'])
    V.add(throttle, inputs=['throttle'])

Finally, in myconfig.py in the car directory the following things had to be changed:

PCA9685_I2C_ADDR = 0x40 #steering I2C address, use i2cdetect to validate this number
PCA9685_I2C_ADDR1 = 0x40 #throttle I2C address, use i2cdetect to validate this number

#STEERING

STEERING_CHANNEL = 0 #channel on the 9685 pwm board 0-15
STEERING_LEFT_PWM = 420 #pwm value for full left steering
STEERING_RIGHT_PWM = 290 #pwm value for full right steering

#THROTTLE

THROTTLE_CHANNEL = 1 #channel on the 9685 pwm board 0-15
THROTTLE_FORWARD_PWM = 500 #pwm value for max forward throttle
THROTTLE_STOPPED_PWM = 370 #pwm value for no movement
THROTTLE_REVERSE_PWM = 220 #pwm value for max reverse throttle

These may be changed in the future, I am working on smoothing the response out and testing all of the functions. Also I need to figure out how to mirror the camera I have. Either way this should get a lot of the PiRacer Pro folks going if they were having the same problem as me. This is tested and works with the controller that was provided.

Let me know if you have any questions. I will check back periodically and try to format it better.
I have forked the waveshare repository and will update the package so that if it is pulled from my github, following the directions provided by waveshare for installation, that it will automatically generate these files.

Regards,

Rob

Greetings,

I have modified the waveshare files and instructions and placed it on guthub at GitHub - robruzzo/PiRacerPro: Open source hardware and software platform to build a small scale self driving car.

There are instructions there on how to use the git for installing the modified files as though you were installing from scratch using waveshare’s instructions. Please let me know if you have any problems. I also added a line to the camera part to flip the picamera horizontally as was needed in my case.

Regards,

Rob