├── README.md ├── LICENSE └── Code ├── PythonTouchscreen └── interface01.py └── ArduinoRemote └── ArduinoRemote.ino /README.md: -------------------------------------------------------------------------------- 1 | # ROSremote 2 | 3 | CAD and Code for my touchscren ROS remote. 4 | 5 | YouTube video: https://www.youtube.com/watch?v=ATQblGOjMWQ 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 James Bruton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Code/PythonTouchscreen/interface01.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import pygame 3 | import sys 4 | import rospy 5 | from std_msgs.msg import String 6 | 7 | pub = rospy.Publisher('touchscreen', String, queue_size=10) 8 | rospy.init_node('screen', anonymous=True) 9 | rate = rospy.Rate(10) # 10hz 10 | 11 | # initializing the constructor 12 | pygame.init() 13 | 14 | # screen resolution 15 | res = (800,480) 16 | 17 | # opens up a window 18 | screen = pygame.display.set_mode(res) 19 | 20 | # white color 21 | color = (255,255,255) 22 | 23 | # light shade of the button 24 | color_light = (170,170,170) 25 | 26 | # dark shade of the button 27 | color_dark = (100,100,100) 28 | 29 | # stores the width of the 30 | # screen into a variable 31 | width = screen.get_width() 32 | 33 | # stores the height of the 34 | # screen into a variable 35 | height = screen.get_height() 36 | 37 | # defining a font 38 | smallfont = pygame.font.SysFont('Corbel',35) 39 | 40 | # rendering a text written in 41 | # this font 42 | text1 = smallfont.render('quit' , True , color) 43 | text2 = smallfont.render('hello' , True , color) 44 | text3 = smallfont.render('goodbye' , True , color) 45 | 46 | # fills the screen with a color 47 | screen.fill((0,0,0)) 48 | 49 | #draw buttons 50 | pygame.draw.rect(screen,color_dark,[400,300,140,50]) 51 | screen.blit(text1, (405,305)) 52 | 53 | pygame.draw.rect(screen,color_dark,[100,200,140,50]) 54 | screen.blit(text2, (105,205)) 55 | 56 | pygame.draw.rect(screen,color_dark,[100,300,140,50]) 57 | screen.blit(text3, (105,305)) 58 | 59 | hello_str = "hello" 60 | goodbye_str = "goodbye" 61 | 62 | # updates the frames of the game 63 | pygame.display.update() 64 | 65 | def hello(): 66 | print("hello") 67 | pub.publish(hello_str) 68 | 69 | def goodbye(): 70 | print("goodbye") 71 | pub.publish(goodbye_str) 72 | 73 | def quit(): 74 | pygame.quit() 75 | 76 | while True: 77 | 78 | for ev in pygame.event.get(): 79 | 80 | #checks if a mouse is clicked 81 | if ev.type == pygame.FINGERUP or ev.type == pygame.MOUSEBUTTONDOWN: 82 | 83 | #other functions 84 | if 100 <= mouse[0] <= 240 and 200 <= mouse[1] <= 250: 85 | hello() 86 | 87 | #other functions 88 | if 100 <= mouse[0] <= 240 and 300 <= mouse[1] <= 350: 89 | goodbye() 90 | 91 | if 400 <= mouse[0] <= 540 and 300 <= mouse[1] <= 350: 92 | quit() 93 | 94 | 95 | # stores the (x,y) coordinates into 96 | # the variable as a tuple 97 | mouse = pygame.mouse.get_pos() 98 | 99 | #print(mouse[0]) 100 | #print(mouse[1]) 101 | 102 | 103 | -------------------------------------------------------------------------------- /Code/ArduinoRemote/ArduinoRemote.ino: -------------------------------------------------------------------------------- 1 | //ROS 2 | #include "ros.h" 3 | #include "geometry_msgs/Twist.h" 4 | #include 5 | #include 6 | 7 | ros::NodeHandle nh; 8 | geometry_msgs::Twist twist; 9 | ros::Publisher joy_pub("cmd_vel", &twist); 10 | 11 | std_msgs::UInt16 button_msg; 12 | ros::Publisher pub_button("buttons", &button_msg); 13 | 14 | // timers for the sub-main loop 15 | unsigned long currentMillis; 16 | long previousMillis = 0; // set up timers 17 | float loopTime = 20; 18 | 19 | // values for reading sticks 20 | 21 | float stick1; 22 | float stick2; 23 | float stick3; 24 | float stick4; 25 | float stick5; 26 | float stick6; 27 | int but1; 28 | int but2; 29 | int but3; 30 | int but4; 31 | int but1out; 32 | int but2out; 33 | int but3out; 34 | int but4out; 35 | uint16_t combo = 0; 36 | 37 | void setup() { 38 | 39 | pinMode(2, INPUT_PULLUP); 40 | pinMode(3, INPUT_PULLUP); 41 | pinMode(4, INPUT_PULLUP); 42 | pinMode(5, INPUT_PULLUP); 43 | pinMode(A0, INPUT); 44 | pinMode(A1, INPUT); 45 | pinMode(A2, INPUT); 46 | pinMode(A3, INPUT); 47 | pinMode(A4, INPUT); 48 | pinMode(A5, INPUT); 49 | pinMode(A6, INPUT); 50 | 51 | nh.getHardware()->setBaud(115200); // set baud rate to 115200 52 | nh.initNode(); // init ROS 53 | nh.advertise(joy_pub); // advertise topic 54 | nh.advertise(pub_button); // advertise topic 55 | 56 | } 57 | 58 | // deadzone function for cheap joysticks 59 | 60 | float deadzone(float value) { 61 | if (value > 50) { 62 | value = value - 50; 63 | } 64 | else if (value < -50) { 65 | value = value +50; 66 | } 67 | else { 68 | value = 0; 69 | } 70 | value = value / 500; // scale so that we get 0.0 ~ 1.0 71 | return value; 72 | } 73 | 74 | int invButtons(int value) { 75 | 76 | if (value == 0) { 77 | value = 1; 78 | } 79 | else if (value == 1) { 80 | value = 0; 81 | } 82 | return value; 83 | } 84 | 85 | // ** Main loop ** 86 | 87 | void loop() { 88 | 89 | currentMillis = millis(); 90 | if (currentMillis - previousMillis >= loopTime) { // run a loop every 10ms 91 | previousMillis = currentMillis; // reset the clock to time it 92 | 93 | // read sticks and buttons 94 | 95 | but1 = digitalRead(2); 96 | but2 = digitalRead(3); 97 | but3 = digitalRead(4); 98 | but4 = digitalRead(5); 99 | 100 | // invert buttons as they are pull_ip 101 | 102 | but1out = invButtons(but1); 103 | but2out = invButtons(but2); 104 | but3out = invButtons(but3); 105 | but4out = invButtons(but4); 106 | 107 | // combine buttons into single uint16_t value 108 | 109 | combo = 0; // reset value and add buttons in this loop only 110 | 111 | if (but1out == 1) { 112 | combo = combo + 1; 113 | } 114 | else if (but2out == 1) { 115 | combo = combo + 2; 116 | } 117 | else if (but3out == 1) { 118 | combo = combo + 4; 119 | } 120 | else if (but4out == 1) { 121 | combo = combo + 8; 122 | } 123 | else { 124 | combo = 0; // of no buttons are pressed then combo is zero 125 | } 126 | 127 | stick1 = analogRead(A0); 128 | stick2 = analogRead(A1); 129 | stick3 = analogRead(A2); 130 | stick4 = analogRead(A3); 131 | stick5 = analogRead(A4); 132 | stick6 = analogRead(A5); 133 | 134 | // remove offsets 135 | 136 | stick1 = stick1 - 78 - 512; 137 | stick1 = deadzone(stick1); 138 | stick2 = stick2 - 5 - 512; 139 | stick2 = deadzone(stick2); 140 | stick3 = stick3 - 6 - 512; 141 | stick3 = deadzone(stick3); 142 | stick4 = stick4 - 4 - 512; 143 | stick4 = deadzone(stick4); 144 | stick5 = stick5 + 5 - 512; 145 | stick5 = deadzone(stick5); 146 | stick6 = stick6 - 15 - 512; 147 | stick6 = deadzone(stick6); 148 | 149 | stick5 = stick5 * -1; // invert value/direction as required based on wiring 150 | stick3 = stick3 * -1; 151 | 152 | stick3 = stick3 * 2; // extra scaling for yaw to mke driving nice 153 | 154 | // *** broadcast cmd_vel twist message ** 155 | 156 | // Update the Twist message 157 | twist.linear.x = stick5; 158 | twist.linear.y = stick4; 159 | twist.linear.z = stick6; 160 | 161 | twist.angular.x = stick2; 162 | twist.angular.y = stick1; 163 | twist.angular.z = stick3; 164 | 165 | joy_pub.publish(&twist); // make the message ready to publish 166 | 167 | // *** broadcast buttons *** 168 | 169 | button_msg.data = combo; 170 | pub_button.publish(&button_msg); 171 | 172 | nh.spinOnce(); // make sure we do ROS stuff every loop 173 | 174 | } // end of 10ms loop 175 | 176 | } // end of main loop 177 | --------------------------------------------------------------------------------