View Full Version : Using PS3 controller code...

05-04-2015, 09:32 AM
I am not sure if this is the right forum for this, but as the PS3 code is part of the HR-OS1 framework, it is probably not too far out of place.

As one who prefers actually working on the code... I decided to start making a pass through the code base.

One of the things I would like to do is to eliminate most/all compile warnings as it then makes it easier to find my own mistakes later on. So over time I will try to upload these to my fork of the code base and submit pull requests.

Yesterday I started to play with some of the PS3 controller code that is part of this, as I am thinking of making a version of my Phantom Phoenix code base on Linux boards (either RPI2 or ODroid C1 mabye Xu3 lite), that can use the PS3 as the controller instead of using an XBee to talk to Commander.

So I made a copy of the code to try stuff out on, but first pass was I eliminated compile warnings (got rid of unused variables, or variables that were just set but not used, fixed potential uninitialized...)

But the more I look at this, I wonder what is planed for this code as part of HR-OS1? That is, are you planning to extend it's usage beyond what is currently done with the PS3 demo code or is it sort of functionally complete?

I am now thinking about revamping the code to strip out a bunch of unused stuff and potentially make it easier for me to use and wonder what you think.

Example: currently the demo code calls: PS3Controller_Start() to start using the controller and PS3Controller_Stop() to stop using the controller, which is fine. But the PS3Contoller_Start creates 3 threads for the controller. The main thread for handling the BT stuff, which is as I expected. But it also creates a 2nd thread (JoyMixerThread) - which more or less has all code commented except to delayms(2). So for now this thread can be purged.

It also then creates a 3rd thread PS3KeyServer, which every 1ms, checks to see if PS3KeyChanged().

The main demo code base, just simply uses the state of the PS3 object, like

if(PS3.key.PS != 0) {
while(PS2.key.PS !=0) usleep(8000);

For myself not sure the keyserver helps me or hurts me. I personally prefer to have my own code be able to check to see if anything on the controller has changed and then work off that.

Thoughts? Is discussions like this better here? Or Github issues, or email?


05-04-2015, 04:03 PM
Quick question: I have a version of the code compiling.

I find that I can run my code using the sudo command, but the PS3 device will fail without sudo.

for normal devices I would do an ls -l in the /dev directory to find the group the device is setup for and then do a
sudo addgroup <my name> <group of device>

Is there a group for the PS3 and/or Bluetooth I should make sure my user has?


05-04-2015, 04:24 PM
I know I had talked about how the PS3 controller shows up on ubuntu and how to access it in a thread not too long ago. Thinking around September? Erp, December 31 in the edison thread (http://forums.trossenrobotics.com/showthread.php?7145-Experiment-with-Intel-Edison&p=66059#post66059).

Quick check has /dev/hidraw1 as 'plugdev' when USB tethered (hidraw0 was usb mouse), /dev/usb/hiddev0 as 'root' when USB tethered, and /dev/input/js1 as 'root' either way (but supposed to be readable by anyone).

05-04-2015, 06:12 PM
Thanks Tician

I found that posting on that thread earlier as well. But it looked like it is currently only with it tethered. Also on Edison no sudo command installed.

On RPI2 or ODroid it appears like by default all commands the talk to the PS3 controller through bluetooth have to use the sudo command.
I noticed that with all of the scripts that were setup for the PS3_demo code as part of HROS1 framework.

If you try to run it without sudo command, the StartPS3Server will fail and print: Can't listen on HID control channel
Which in that function, is

nt StartPS3Server(void)
bdaddr_t bdaddr,bany={0,0,0,0,0,0};
char addr[18];
int lm = L2CAP_LM_MASTER;// was 0;
// struct timespec clock_resolution;
int rc;

ba2str(&bdaddr, addr);
if (ctl < 0) {
printf("Can't open HIDP control socket\n");
return 0;

csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, lm, 10);
if (csk < 0) {
printf("Can't listen on HID control channel\n");
return 0;

isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, lm, 10);
if (isk < 0) {
printf("Can't listen on HID interrupt channel\n");
return 0;

So the call to l2cap failed. So I was sort of hoping there was some user group I can add the user to to avoid having to do sudo, in the same way that I can have the user use an XBee connected to an FTDI device by adding the user to the dialout group.


05-04-2015, 06:36 PM
The PS3 controller code in the framework requires sudo because it attempts to write to the DS3 to set LEDs and rumble. Since it should be using '/dev/hidraw(0,1,etc.)', it might be possible by adding yourself to the 'plugdev' group since it is the group owner of the '/dev/hidraw' files and has read/write access.

You can get all the buttons and accelerometer by read-only from /dev/hidraw(0,1,etc.) and /dev/input/js(0,1,etc.). My pretty old non-dual shock PS3 controller does not want to show up as an /dev/hidraw1 when connected over bluetooth using 'sixad -s' and no bluetoothd installed on 12.04, so no gyro/accelerometer from it at the moment but can still get all the button and joystick data. Using the '/dev/input/js1' interface requires a bit more work to map the output numbers to buttons (may not be recognizing left on the D-pad from '.../js1' interface) since it does not dump the controller data in the same format as the '.../hidraw' interface.

05-05-2015, 09:24 AM
Thanks tician:

I checked and it odroid is already a member of plugdev

[email protected]:~/Raspberry_Pi/Phoenix_fixed/PhantomX_PS3$ sudo adduser odroid plugdev
[sudo] password for odroid:
The user `odroid' is already a member of `plugdev'.

[email protected]:~/Raspberry_Pi/Phoenix_fixed/PhantomX_PS3$ groups odroid
odroid : odroid adm dialout fax cdrom floppy tape sudo audio dip video plugdev netdev nopasswdlogin lpadmin scanner fuse

[email protected]:~/Raspberry_Pi/Phoenix_fixed/PhantomX_PS3$ groups
odroid adm dialout fax cdrom floppy tape sudo audio dip video plugdev netdev nopasswdlogin lpadmin scanner fuse

So it looks like, I would need to change their code more significantly to work in non root mode. Running in root mode appears to create other issues like not using the actual users settings but roots instead...

I also need to verify that the Odroid is actually getting valid PS3 data, so will add some debug support

Thanks again

05-05-2015, 02:57 PM
Real quick- what version of BlueZ is your ODROID install running? I've not yet successfully gotten the HID Daemon properly initialized in Bluez5, with Bluez4 there's a sequential process to get it working (see the start scripts in ps3_demo).

I'd love any improvements on this library honestly. Rob Farrell was kind enough to share it with the project about 2 years ago and I've barely done anything with it since as my efforts have been focused elsewhere.

05-05-2015, 04:58 PM
Thanks Andrew,

So far my main program is not talking to the PS3 controller, so need to investigate mroe.
If I look at some of the packages like: bluez-utils it looks like version 4

[email protected]:~/ROS_hexapod$ dpkg -s bluez-utils
Package: bluez-utils
Status: install ok installed
Priority: extra
Section: oldlibs
Installed-Size: 75
Maintainer: Ubuntu Developers <[email protected]>
Architecture: all
Source: bluez
Version: 4.101-0ubuntu13.1
Depends: bluetooth
Description: Transitional package
This is a transitional package to assist with moving people to the
BlueZ 4.x stack.
Homepage: http://www.bluez.org
Original-Maintainer: Debian Bluetooth Maintainers <[email protected]>

Will look more closely at your starupt script.


05-20-2015, 01:30 PM
Wrote most of this two weeks ago, but forgot to try verifying bluetooth 'hidraw' on 14.04 until today (doesn't show up as 'hidraw' with bluetooth and all /dev/hidraw(0/1/etc) are root:root 600)...

If you can get the DS3 to actually show up as /dev/hidraw0 or similar when connected over bluetooth and you do not need the vibration or LED feedback, then doing a read-only open of /dev/hidraw0 and checking that you get 49 bytes per burst will be enough to get all the control information split up as in PS3Defs.h (modified to offset by one byte). There was once a patch to the kernel driver that would permit bluetooth devices to use the hidraw interface, but there have been many, many changes since that patch was released so would have to dig deep into the driver to figure out how to re-enable that. Still, the minimal code below works fine on 12.04 with the controller connected via USB if ever needed for remote control from another PC (e.g. HR-OS1 engaged in MechWarfare).

// g++ -I. -c -o main.o main.cpp
// g++ main.o -o ps3-test

#include "PS3Defs.h" // comment out HIDA1 and decrease size to 49

#include <cstdlib>
#include <cstdio>

int main(int argc, char **argv)
_PS3 dualshock1 = {0};
int bytesRead = 0;

FILE *pFile = fopen("/dev/hidraw1", "r");
if (pFile == NULL)
fprintf(stderr, "Could not open file\n.");

while ( 1 )
bytesRead = fread(dualshock1.keys, 1, 49, pFile);
if ( bytesRead < 0 )
if ( bytesRead != 49 )
fprintf(stderr, "Unsupported report length %d."
" Wrong hidraw device or kernel<2.6.26 ?\n", bytesRead);
// printf("aX=%4d aY=%4d aZ=%4d\n", dualshock1.key.accX, dualshock1.key.accY, dualshock1.key.accZ);
printf("D-L=%4d D-U=%4d D-R=%4d D-D=%4d\n", dualshock1.key.presLeft, dualshock1.key.presUp, dualshock1.key.presRight, dualshock1.key.presDown);
return 0;

05-20-2015, 08:27 PM
Thanks I will give it a shot.

side note today I was able to bind ds4 with new odroid xu3-lite... It appears to create

05-20-2015, 08:33 PM
Quite honestly guys, not sure what we will do with the darwin-op based framework and ps3 library. The plan is to move everything HROS1/5 over to ROS, possibly by using a wrapper around the existing framework as a stepping stone, but ultimately moving over to something else entirely. ROS can handle a number of controllers, so this library wouldn't likely be useful in that implementation.

Rob Farrell wrote the ps3 library originally, and it used to have a few other features. I'm all for it being streamlined and updated, as it's great for lower-level non-ROS based control. I'll gladly merge in any updates you make!

05-31-2015, 10:10 AM
I will have to play more with this. Not sure if the devices like hidraw are setup with the bluetooth connection at lest until the connection is established..

The last couple of days, I have playing around some more with the DS4 and the XU3... I reflashed the emmc back to the original image and then started over, such that I could use the same procedures as r3n33 did setting up here XU3... Which is great.

But then the DS4 does not want to bind, which is not surprising as ODroid has bluez4... and the DS3/DS4 updates were in bluez5... So surprised it works in some cases.

I had some pretty good luck using DS4DRV, to do the binding, until I reflashed... This python program is setup to work around the binding issue, by using /dev/uinput to talk to the device and then create the /dev/input/js0 device.

And now I find myself stuck on a twig :lol:

The issue is to be able to use the ds4drv program as normal user it needs to have write access to /dev/uinput, which when I boot is setup with owner:group set to root and only root has RW access... The DS4DRV program has a udev rules file to change the mode to 0x666. The problem is this rule does not do anything now.

[email protected]:~/ds4drv/udev$ ls

[email protected]:~/ds4drv/udev$ cat *
KERNEL=="uinput", MODE="0666"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="05c4", MODE="0666"
I think the problem is, udevadm can not find this device?

I see the device /dev/uinput and I can sudo chmod 0x666 /dev/uinput
And it will update the device access where ds4drv can read and write.

but if I do something like:

[email protected]:~$ udevadm info --name=uinput
device node not found

As you can see it does not find the device. Likewise if I do: udevadm info --export-db > foo
And look at the file foo, there is no strings with uinput in the file...

So I am confused :confused:

08-13-2015, 09:21 PM
Quick update:

I have been busy having fun with Odroids and PhantomX and ROS, so my HR-OS1 has been neglected.

However over the last few days I again started playing with the idea that I should be able to use the PS3 without having to do sudo.

So I have updated my RPI2 to use the sixad code like I did earlier on NUC with Ubuntu.
One website that shows how to do this is: http://www.raspians.com/Knowledgebase/ps3-dualshock-controller-install-on-the-raspberry-pi/

A little bit ago I built a version of the PhantomX for linux (in my Raspberry Pi project), that uses the Linux joystick package.

I made a copy of this into a new branch in my HROS1 fork, and replaced the Ps3 code. I then updated a the PS3 demo code to use this.

Today I started debugging some of this, and have good news and bad news.

The good news is I think I can talk to everything without using sudo. Also the PS3 connects when I hit the PS button. Occasionally I run it and it does not want to talk to darwin, but I can quit and restart...

Bad news. The last time I tried (hit the Triangle) button, the system jerked and rebooted. I also think something may have shorted and I may have seen some magic smoke. Tomorrow I will see if everything still works. I can replace most everything as I have a spare RPI2 and some extra servos. However I don't have a spare Arbotix-pro. so i am keeping me fingers crossed.

Anyway if anyone wants to look at it, It is up in my HROS1 fork in the Use-my-joystick-controller branch.


08-18-2015, 05:32 PM
Another Quick update:

So far it looks like nothing was damaged!

In between trying to improve my makefiles, such that appropriate things are rebuilt when files change (covered in different thread), I have done some investigating into trying to figure out why maybe 1/3 to 1/2 of the time when I try to start the PS3 demo, it errors out trying to talk to the Motion Manager, with that error about sudo...

So far it looks like I am getting a timeout in the MotionManger::Initialize which calls m_CM730 Connect, which call DXLPoweron

And in the DXLPoweron, it does a WriteByte(CM730::P_DXL_POWER... My guess is maybe the Arbotix Pro may be in some unknown state from the previous run of the program... still looking.

I may also take a look at having the main program handle exceptions like hitting ctrl+c and maybe cleanup some. For example I wish it would free all of the servos, such that i don't have to use DXL_monitor program and do: free all

Another side note: I have been doing some of the debugging doing source code debugging using wingdb, which is pretty nice