Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swerve final #13

Open
wants to merge 77 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
041d6d9
test code for pi <-> pico i2c
bleubirb Aug 21, 2023
fe5794f
spi tests, have not tested them yet
bleubirb Aug 21, 2023
df0ab2d
pico spi test
bleubirb Aug 21, 2023
1856419
ishan's code
inkyant Sep 17, 2023
7807d04
NOT TESTED multicore velocity readings from encoder
inkyant Sep 18, 2023
6f9473a
comments/updates
ishanm0 Oct 5, 2023
fec2fbb
experimenting (broken)
ishanm0 Oct 5, 2023
7fe3b84
Merge remote-tracking branch 'origin/dev' into encoder
ishanm0 Oct 5, 2023
2c06b67
Merge branch 'dev' into i2c-comms
ishanm0 Oct 5, 2023
bf21984
bidirectional i2c :)
ishanm0 Oct 6, 2023
647af1b
Merge branch 'i2c-comms' into i2c-drive-one-wheel
ishanm0 Oct 6, 2023
bd4662e
renamed handler
ishanm0 Oct 6, 2023
27fe1c8
created i2c drive python & pico files, set up pico file?
ishanm0 Oct 6, 2023
52a245c
experimentation - iirc this does send data between the pi and pico (p…
ishanm0 Oct 13, 2023
2abf765
2 way pi pico i2c - python
ishanm0 Oct 14, 2023
6bde8fd
continued working on motor/pico/i2c tests
ishanm0 Oct 15, 2023
c28954e
fix prev_pos not being updated
inkyant Oct 16, 2023
16a3391
Merge branch 'encoder' of https://github.com/autoslug/modbot into enc…
inkyant Oct 16, 2023
d886c51
move multicore velocity init to constructor
inkyant Oct 16, 2023
42b473a
Update motor_test.py
ishanm0 Oct 17, 2023
c79b48a
we can get encoder velocity, but it crashes if the motor is going too…
ishanm0 Oct 17, 2023
e995e7d
Moved to quadrature_encoder project based on pico-examples code
ishanm0 Oct 17, 2023
00e0628
Created pico control test
brendanRose1 Oct 24, 2023
b0de0a1
yes
brendanRose1 Oct 27, 2023
96961a8
pico motor control works :)
ishanm0 Nov 4, 2023
07f9243
organized pico_motor_test & i2c_drive
ishanm0 Nov 4, 2023
43f15c7
comments
ishanm0 Nov 4, 2023
5073e7b
added rotation relative to a point link
ishanm0 Nov 4, 2023
6b01608
encoder works, abstracted behind a factory
ishanm0 Nov 4, 2023
38aa2d9
encoder degrees
ishanm0 Nov 4, 2023
2c3567b
more testing, wrote a byte to double function & started adapting moto…
ishanm0 Nov 5, 2023
1237bab
Merge branch 'dev' into i2c-drive-one-wheel
ishanm0 Nov 6, 2023
4d724d7
Merge branch 'dev' into encoder
ishanm0 Nov 6, 2023
7ee15fd
updated comments, ratios
ishanm0 Nov 6, 2023
78fbbe4
Merge branch 'dev' into encoder
ishanm0 Nov 7, 2023
f431f37
Renamed byte_to_motor_double & added endianess test in i2c_drive_pico.c
brendanRose1 Nov 7, 2023
1c4dc84
Read joyX and joyY bytes from pi
brendanRose1 Nov 9, 2023
f4bbc99
pico motor control w/ classes works!
ishanm0 Nov 16, 2023
42f11f1
updates to i2c_drive_pico, doesn't work yet
ishanm0 Nov 16, 2023
6c3b8cf
send data with struct
ishanm0 Nov 19, 2023
b3bd303
unsuccessful attempt to get floats out of byte data - endianness issues?
ishanm0 Dec 1, 2023
bdcb2ef
byte to float conversion isn't working
ishanm0 Dec 3, 2023
089f7e6
Update pi_i2c.py with support for multiple i2c devices
ShahVishrut Jan 14, 2024
7af874a
work
brendanRose1 Jan 21, 2024
4b61ea0
Merge I2C and PWM control
brendanRose1 Jan 21, 2024
8fe6c2e
changed x-y assignment
brendanRose1 Jan 21, 2024
d5222ff
Merge branch 'dev' into i2c-drive-one-wheel
ishanm0 Jan 21, 2024
239d34e
swerve drive math test
brendanRose1 Feb 23, 2024
ceb3bdd
Update swerve_test.py
brendanRose1 Feb 23, 2024
ae3f889
basic swerve seems to work
ishanm0 Feb 23, 2024
025d767
cleaned up
ishanm0 Feb 23, 2024
f159ef7
swerve vector control?
ishanm0 Feb 23, 2024
c51bd37
worked on steering velocity scaling
ishanm0 Mar 2, 2024
b00e2fe
testing
ishanm0 Mar 2, 2024
23489fe
Update basic_swerve_pico.c
brendanRose1 Mar 6, 2024
1052dc1
cleanup
brendanRose1 May 2, 2024
ca5f54e
Merge branch 'i2c-drive-one-wheel' into swerve-final
brendanRose1 May 2, 2024
09a8863
Merge branch 'basic-swerve' into swerve-final
brendanRose1 May 2, 2024
71c918c
Merge branch 'encoder' into swerve-final
brendanRose1 May 2, 2024
582b2f8
swerve-final
brendanRose1 May 3, 2024
96036bc
added swerve decoder and pid barebone
brendanRose1 May 4, 2024
25d027b
update pid
brendanRose1 May 6, 2024
413b657
commit
brendanRose1 May 14, 2024
023404a
small tweaks to software
brendanRose1 May 21, 2024
73f7435
restructured swerve_final branch
brendanRose1 May 21, 2024
0f0118a
merged basic-swerve
brendanRose1 May 21, 2024
6f25346
merged encoder branch into swerve-final
brendanRose1 May 21, 2024
0e51f04
Added message-library encode/decode
dojoninja1081 Jul 7, 2024
0768019
Added payload processing
dojoninja1081 Jul 9, 2024
4ad9a24
moved old swerve-decoder code
dojoninja1081 Jul 9, 2024
d1d2141
Merge branch 'message-library-test' into swerve-final
dojoninja1081 Jul 9, 2024
181c70c
made zero() public in zeroing_script
dojoninja1081 Jul 9, 2024
86976a3
Added main function
dojoninja1081 Jul 9, 2024
0f2ced2
reorganized swerve_pico code
dojoninja1081 Jul 12, 2024
0772cae
change code structure
dojoninja1081 Jul 29, 2024
42a95a4
edit cmake files added clist files
dojoninja1081 Jul 29, 2024
aff98c4
dont care
dojoninja1081 Jul 29, 2024
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
13 changes: 13 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"files.associations": {
"messaging-library.h": "c",
"stdio.h": "c",
"messaging-library-ids.h": "c",
"initializer_list": "c",
"type_traits": "c",
"xstring": "c",
"xutility": "c",
"zeroing.cpp": "c",
"stdlib.h": "c"
}
}
28 changes: 28 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc.exe build active file",
"command": "C:\\TDM-GCC-64\\bin\\gcc.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
55 changes: 55 additions & 0 deletions dev/basic_swerve/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated Cmake Pico project file

cmake_minimum_required(VERSION 3.5)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)

set(PICO_BOARD pico CACHE STRING "Board type")

# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0")
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()

project(basic_swerve_pico C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

# Add executable. Default name is the project name, version 0.1

add_executable(basic_swerve_pico basic_swerve_pico.c )

pico_set_program_name(basic_swerve_pico "basic_swerve_pico")
pico_set_program_version(basic_swerve_pico "0.1")

pico_enable_stdio_uart(basic_swerve_pico 0)
pico_enable_stdio_usb(basic_swerve_pico 1)

# Add the standard library to the build
target_link_libraries(basic_swerve_pico
pico_stdlib
pico_i2c_slave
hardware_i2c
hardware_pwm
)

# Add the standard include files to the build
target_include_directories(basic_swerve_pico PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
)

# Add any user requested libraries
target_link_libraries(basic_swerve_pico
hardware_i2c
)

pico_add_extra_outputs(basic_swerve_pico)

203 changes: 203 additions & 0 deletions dev/basic_swerve/Controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
import math
import threading

from inputs import get_gamepad # Import the get_gamepad function from the inputs module
from procon import ProCon # Import the ProCon class from the procon module


# This class represents a PS4 Controller
class PS4_Controller(object):
def __init__(self):
self.MAX_TRIG_VAL = math.pow(2, 8) # Maximum value for trigger input
self.MAX_JOY_VAL = math.pow(2, 7) # Maximum value for joystick input
self.THRESHOLD = 0.04 # Threshold for joystick deadzone
self.reset_vars() # Reset all controller variables to their initial state
self.start_thread(()) # Start a new thread to monitor the controller

# This method resets all controller variables to their initial state
def reset_vars(self):
# Initialize all controller variables to 0
self.LeftJoystickY = 0
self.LeftJoystickX = 0
self.RightJoystickY = 0
self.RightJoystickX = 0
self.LeftTrigger = 0
self.RightTrigger = 0
self.LeftBumper = 0
self.RightBumper = 0
self.A = 0
self.X = 0
self.Y = 0
self.B = 0
self.LeftThumb = 0
self.RightThumb = 0
self.Back = 0
self.Start = 0
self.LeftDPad = 0
self.RightDPad = 0
self.UpDPad = 0
self.DownDPad = 0

# This method starts a new thread to monitor the controller
def start_thread(self, thread_args=()):
self._monitor_thread = threading.Thread(
target=self._monitor_controller, args=thread_args
)
self._monitor_thread.daemon = (
True # Set the thread as a daemon so it will end when the main program ends
)
self._monitor_thread.start() # Start the thread

# This method returns the current state of all buttons/triggers
def read(self):
return [
self.LeftJoystickY,
self.LeftJoystickX,
self.RightJoystickY,
self.RightJoystickX,
self.LeftTrigger,
self.RightTrigger,
self.LeftBumper,
self.RightBumper,
self.A,
self.B,
self.X,
self.Y,
self.LeftThumb,
self.RightThumb,
self.Back,
self.Start,
self.LeftDPad,
self.RightDPad,
self.UpDPad,
self.DownDPad,
]

# This method returns the controller object itself
def read_self(self):
return self

# This method applies a threshold to a value
def threshold(self, val):
return val - 1.0 if abs(val - 1.0) > self.THRESHOLD else 0

def _monitor_controller(self):
while True:
events = get_gamepad()
for event in events:
if event.code == "ABS_Y":
self.LeftJoystickY = self.threshold(
event.state / self.MAX_JOY_VAL
) # normalize between -1 and 1
elif event.code == "ABS_X":
self.LeftJoystickX = self.threshold(
event.state / self.MAX_JOY_VAL
) # normalize between -1 and 1
elif event.code == "ABS_RY":
self.RightJoystickY = self.threshold(
event.state / self.MAX_JOY_VAL
) # normalize between -1 and 1
elif event.code == "ABS_RX":
self.RightJoystickX = self.threshold(
event.state / self.MAX_JOY_VAL
) # normalize between -1 and 1
elif event.code == "ABS_Z":
self.LeftTrigger = self.threshold(
event.state / self.MAX_TRIG_VAL
) # normalize between 0 and 1
elif event.code == "ABS_RZ":
self.RightTrigger = self.threshold(
event.state / self.MAX_TRIG_VAL
) # normalize between 0 and 1
elif event.code == "BTN_TL":
self.LeftBumper = event.state
elif event.code == "BTN_TR":
self.RightBumper = event.state
elif event.code == "BTN_SOUTH":
self.A = event.state
elif event.code == "BTN_NORTH":
self.Y = event.state # previously switched with X
elif event.code == "BTN_WEST":
self.X = event.state # previously switched with Y
elif event.code == "BTN_EAST":
self.B = event.state
elif event.code == "BTN_THUMBL":
self.LeftThumb = event.state
elif event.code == "BTN_THUMBR":
self.RightThumb = event.state
elif event.code == "BTN_SELECT":
self.Back = event.state
elif event.code == "BTN_START":
self.Start = event.state
elif event.code == "BTN_TRIGGER_HAPPY1":
self.LeftDPad = event.state
elif event.code == "BTN_TRIGGER_HAPPY2":
self.RightDPad = event.state
elif event.code == "BTN_TRIGGER_HAPPY3":
self.UpDPad = event.state
elif event.code == "BTN_TRIGGER_HAPPY4":
self.DownDPad = event.state


# This class represents the Xbox Controller in WRP used for the CPSRC GEM
class Gem_Xbox_Controller(PS4_Controller):
def __init__(self):
self.MAX_TRIG_VAL = math.pow(2, 8) # Maximum value for trigger input
self.MAX_JOY_VAL = math.pow(2, 15) # Maximum value for joystick input
self.THRESHOLD = 0.03 # Threshold for joystick deadzone

self.reset_vars() # Reset all controller variables to their initial state
self.start_thread(()) # Start a new thread to monitor the controller


# This class represents the Nintendo Pro Controller
class Nintendo_Pro_Controller(PS4_Controller):
def __init__(self):
self.MAX_TRIG_VAL = math.pow(2, 8) # Maximum value for trigger input
self.MAX_JOY_VAL = math.pow(2, 15) # Maximum value for joystick input
self.THRESHOLD = 0.1 # Threshold for joystick deadzone
self.controller = ProCon() # Initialize the ProCon controller

self.reset_vars() # Reset all controller variables to their initial state
self.start_thread(
self.procon_callback_func
) # Start a new thread to monitor the controller

# This method is called when the ProCon controller state changes
def procon_callback_func(self, buttons, l_stick, r_stick, *_):
# Update the controller variables based on the new state
# The joystick values are normalized between -1 and 1
# The threshold method is used to apply a deadband to the joystick values
# The button values are either 0 or 1
self.LeftJoystickX = self.threshold(l_stick[0] / self.MAX_JOY_VAL)
self.LeftJoystickY = self.threshold(l_stick[1] / self.MAX_JOY_VAL)
self.RightJoystickX = self.threshold(r_stick[0] / self.MAX_JOY_VAL)
self.RightJoystickY = self.threshold(r_stick[1] / self.MAX_JOY_VAL)
self.LeftTrigger = self.threshold(buttons[ProCon.Button.ZL])
self.RightTrigger = self.threshold(buttons[ProCon.Button.ZR])
self.LeftBumper = buttons[ProCon.Button.L]
self.RightBumper = buttons[ProCon.Button.R]
self.A = buttons[ProCon.Button.A]
self.B = buttons[ProCon.Button.B]
self.X = buttons[ProCon.Button.X]
self.Y = buttons[ProCon.Button.Y]
self.LeftThumb = buttons[ProCon.Button.LS]
self.RightThumb = buttons[ProCon.Button.RS]
self.Back = buttons[ProCon.Button.MINUS]
self.Start = buttons[ProCon.Button.PLUS]
self.LeftDPad = buttons[ProCon.Button.LEFT]
self.RightDPad = buttons[ProCon.Button.RIGHT]
self.UpDPad = buttons[ProCon.Button.UP]
self.DownDPad = buttons[ProCon.Button.DOWN]


if __name__ == "__main__":
joy = PS4_Controller() # Initialize a PS4 controller
# joy = Gem_Xbox_Controller() # Initialize a Gem Xbox controller
# joy = Nintendo_Pro_Controller() # Initialize a Nintendo Pro controller
while True:
try:
print(joy.read()) # Print the current state of the controller
except Exception as e:
print("error!", e) # Print any errors that occur
break # Exit the loop if an error occurs
Loading