diff --git a/404.html b/404.html index dde50a08..4a6637c7 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@ Blue - + diff --git a/assets/js/5722016a.395c229a.js b/assets/js/5722016a.395c229a.js deleted file mode 100644 index cd989da5..00000000 --- a/assets/js/5722016a.395c229a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[501],{3621:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>a});var s=i(4848),t=i(8453);const l={sidebar_position:3,title:"Teleoperation"},o=void 0,r={id:"tutorials/teleop",title:"Teleoperation",description:"This page provides a collection of tutorials that describe how to teleoperate",source:"@site/docs/tutorials/teleop.mdx",sourceDirName:"tutorials",slug:"/tutorials/teleop",permalink:"/blue/tutorials/teleop",draft:!1,unlisted:!1,editUrl:"https://github.com/Robotic-Decision-Making-Lab/blue/tree/gh-pages/docs/tutorials/teleop.mdx",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,title:"Teleoperation"},sidebar:"tutorialSidebar",previous:{title:"Integrating Custom Controllers",permalink:"/blue/tutorials/control"},next:{title:"Contributing",permalink:"/blue/contributing"}},d={},a=[{value:"Keyboard teleoperation",id:"keyboard-teleoperation",level:2},{value:"Dependencies",id:"dependencies",level:3},{value:"Tutorial steps",id:"tutorial-steps",level:3},{value:"Gamepad teleoperation",id:"gamepad-teleoperation",level:2},{value:"Dependencies",id:"dependencies-1",level:3},{value:"Tutorial steps",id:"tutorial-steps-1",level:3},{value:"USB/IP gamepad teleoperation",id:"usbip-gamepad-teleoperation",level:2},{value:"Dependencies",id:"dependencies-2",level:3},{value:"Topside configuration steps",id:"topside-configuration-steps",level:3},{value:"Vehicle configuration steps",id:"vehicle-configuration-steps",level:3},{value:"USB/IP shutdown steps",id:"usbip-shutdown-steps",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["This page provides a collection of tutorials that describe how to teleoperate\na simulated or real vehicle. Prior to starting these tutorials, you should have\ncompleted the ",(0,s.jsx)(n.a,{href:"/tutorials/simulation",children:"Running Blue in Simulation"})," tutorial and\nthe ",(0,s.jsx)(n.a,{href:"/tutorials/control",children:"Integrating Custom Controllers"})," tutorial."]}),"\n",(0,s.jsx)(n.h2,{id:"keyboard-teleoperation",children:"Keyboard teleoperation"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial describes how to teleoperate a simulated BlueROV2 using your\nkeyboard."}),"\n",(0,s.jsx)(n.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,s.jsx)(n.p,{children:"The following ROS 2 dependencies are required for this tutorial:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Gazebo Garden or newer"}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/ardusub_driver",children:"ardusub_driver"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/ros2/teleop_twist_keyboard",children:"teleop_twist_keyboard"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/mobile_to_maritime",children:"mobile_to_maritime"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["These dependencies will be met by default if you have installed Blue with\nDocker as described in the ",(0,s.jsx)(n.a,{href:"/installation",children:"installation instructions"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"tutorial-steps",children:"Tutorial steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Launch the demo Dependencies in simulation by running the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos Dependencies_demo.launch.yaml use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Once Gazebo, ArduSub, and MAVROS have fully loaded, open a new terminal and\nlaunch the demo control framework:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_controllers.launch.py use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Open a new terminal and launch the ",(0,s.jsx)(n.code,{children:"teleop_twist_keyboard"})," node:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 run teleop_twist_keyboard teleop_twist_keyboard\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"teleop_twist_keyboard"})," node will publish velocity commands according to\n",(0,s.jsx)(n.a,{href:"https://ros.org/reps/rep-0105.html",children:"REP-105"}),"; however, the launched ISMC\nadheres to the maritime conventions recorded in ",(0,s.jsx)(n.a,{href:"https://github.com/ros-infrastructure/rep/pull/398",children:"REP-156"}),".\nTo convert the velocity commands to the appropriate convention, run the\nfollowing ",(0,s.jsx)(n.code,{children:"mobile_to_maritime"})," message filter in a new terminal:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 run mobile_to_maritime mobile_twist_to_maritime_twist --ros-args in_topic:=/cmd_vel out_topic:=/integral_sliding_mode_controller/reference\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"You should now be able to teleoperate the BlueROV2 using your keyboard."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"gamepad-teleoperation",children:"Gamepad teleoperation"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial describes how to teleoperate a simulated BlueROV2 using a gamepad."}),"\n",(0,s.jsx)(n.h3,{id:"dependencies-1",children:"Dependencies"}),"\n",(0,s.jsx)(n.p,{children:"The following ROS 2 dependencies are needed for this tutorial:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Gazebo Garden or newer"}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/ardusub_driver",children:"ardusub_driver"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/mobile_to_maritime",children:"mobile_to_maritime"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/ros-teleop/teleop_tools",children:"joy_teleop"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/ros-drivers/joystick_drivers/tree/ros2",children:"joy_linux"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["These dependencies will be met by default if you have installed Blue with\nDocker as described in the ",(0,s.jsx)(n.a,{href:"/installation",children:"installation instructions"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In addition to the aforementioned requirements, you should also install the\n",(0,s.jsx)(n.code,{children:"joystick"})," apt package, which provides Linux drivers for gamepads:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install joystick\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Verify your installation with ",(0,s.jsx)(n.a,{href:"https://www.mankier.com/1/jstest-gtk",children:"jstest"})," by\nrunning the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"jstest /dev/input/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the device name of your gamepad (e.g.,\n",(0,s.jsx)(n.code,{children:"js0"}),")."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["For those using the Docker installation, the ",(0,s.jsx)(n.code,{children:"joystick"})," package should be\ninstalled on your local machine ",(0,s.jsx)(n.strong,{children:"outside"})," of the container."]})}),"\n",(0,s.jsx)(n.h3,{id:"tutorial-steps-1",children:"Tutorial steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Launch the demo BlueROV2 in simulation by running the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_demo.launch.yaml use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Once Gazebo, ArduSub, and MAVROS have fully loaded, open a new terminal and\nlaunch the demo control framework:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_controllers.launch.py use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Open a new terminal and launch the ROS 2 joystick driver using the provided\ndemo launch file:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos joy_teleop.launch.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["You should now be able to teleoperate the BlueROV2 using your gamepad. If\nthe system is not responding, ensure that the\n",(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/blue/blob/31-user-docs/blue_demos/teleoperation/config/joy_teleop.yaml",children:"teleoperation demo configuration"}),"\nreferences the correct device."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsx)(n.p,{children:"The gamepad demo uses the left trigger as a deadman switch. To enable joystick\ninputs, press and release the left trigger."})}),"\n",(0,s.jsx)(n.h2,{id:"usbip-gamepad-teleoperation",children:"USB/IP gamepad teleoperation"}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial describes how to configure ",(0,s.jsx)(n.a,{href:"https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html",children:"USB/IP"}),"\nso that you can teleoperate a remote vehicle connected to a topside computer\nvia a tether with a gamepad connected to your topside machine. In this\nconfiguration, we recommend using a ",(0,s.jsx)(n.a,{href:"https://www.logitechg.com/en-us/products/gamepads/f310-gamepad.940-000110.html",children:"Logitech F310 Gamepad"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"dependencies-2",children:"Dependencies"}),"\n",(0,s.jsx)(n.p,{children:"The following apt packages are needed for this tutorial:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"linux-tools-generic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"hwdata"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"joystick"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"which can be installed with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install linux-tools-generic hwdata joystick\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["For those using the Docker installation, the aforementioned packages should be\ninstalled on your local machine ",(0,s.jsx)(n.strong,{children:"outside"})," of the container."]})}),"\n",(0,s.jsx)(n.h3,{id:"topside-configuration-steps",children:"Topside configuration steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Enable the ",(0,s.jsx)(n.code,{children:"usbip-core"})," and ",(0,s.jsx)(n.code,{children:"usbip-host"})," kernel modules:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo modprobe usbip-core && \\\nsudo modprobe usbip-host\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start the USB/IP process as a daemon:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbipd &\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["USB/IP gets installed into directories that are not in your ",(0,s.jsx)(n.code,{children:"$PATH"}),". Because\nof this, it creates symlinks in the ",(0,s.jsx)(n.code,{children:"/usr/bin"})," directory. Sometimes you will\nget an error when using the default symlinks indicating that the installed\n",(0,s.jsx)(n.code,{children:"linux-tools-generic"})," version does not match the kernel. If this happens,\ndelete the existing symlinks and replace them with new ones."]})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"With your gamepad connected to your topside machine, verify that USB/IP is\nable to detect the gamepad device:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"usbip list -l\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should observe your gamepad in the devices listed along with its bus ID.\nFor instance, the Logitech F310 gamepad may be listed as"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"- busid 3-4 (046d:c216)\n Logitech, Inc. : F310 Gamepad [DirectInput Mode] (046d:c216)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:"3-4"})," is the bus ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Bind the gamepad device to the USB/IP process:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip bind -b \n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the bus ID of your gamepad."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify that the device has been bound by listing the exportable devices:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"usbip list -r 127.0.0.1\n"})}),"\n",(0,s.jsx)(n.p,{children:"which should show the gamepad device. For example, the Logitech F310 gamepad\ndevice may appear as"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Exportable USB devices\n======================\n- 127.0.0.1\n 3-4: Logitech, Inc. : F310 Gamepad [DirectInput Mode] (046d:c216)\n : /sys/devices/pci0000:00/0000:00:01.2/0000:20:00.0/0000:21:08.0/0000:2a:00.3/usb3/3-4\n : (Defined at Interface level) (00/00/00)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"vehicle-configuration-steps",children:"Vehicle configuration steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Load the ",(0,s.jsx)(n.code,{children:"vhci-hcd"})," kernel module on the vehicle's computer:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo modprobe vhci-hcd\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Check that the device configured on the topside machine is observable on the\nvehicle:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip list -r \n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the IP address of the\ntopside machine."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Attach the device to the vehicle:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip attach -r -b \n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["You should now be able to interact with the gamepad device as if it were\nconnected directly to the vehicle. Confirm this with ",(0,s.jsx)(n.code,{children:"jstest"})," using the\nfollowing command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"jstest /dev/input/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the device name of your gamepad on\nthe vehicle."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"usbip-shutdown-steps",children:"USB/IP shutdown steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Identify the port at which the vehicle has establishe a connection with the\ntopside machine:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip port\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Detach the device from the vehicle:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip detach -p \n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the identified port number used for\nthe connection."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Unbind the device from the USB/IP process:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip unbind -b \n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/assets/js/5722016a.c4f07e89.js b/assets/js/5722016a.c4f07e89.js new file mode 100644 index 00000000..04234051 --- /dev/null +++ b/assets/js/5722016a.c4f07e89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[501],{3621:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>a});var s=i(4848),t=i(8453);const l={sidebar_position:3,title:"Teleoperation"},o=void 0,r={id:"tutorials/teleop",title:"Teleoperation",description:"This page provides a collection of tutorials that describe how to teleoperate",source:"@site/docs/tutorials/teleop.mdx",sourceDirName:"tutorials",slug:"/tutorials/teleop",permalink:"/blue/tutorials/teleop",draft:!1,unlisted:!1,editUrl:"https://github.com/Robotic-Decision-Making-Lab/blue/tree/gh-pages/docs/tutorials/teleop.mdx",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3,title:"Teleoperation"},sidebar:"tutorialSidebar",previous:{title:"Integrating Custom Controllers",permalink:"/blue/tutorials/control"},next:{title:"Contributing",permalink:"/blue/contributing"}},d={},a=[{value:"Keyboard teleoperation",id:"keyboard-teleoperation",level:2},{value:"Dependencies",id:"dependencies",level:3},{value:"Tutorial steps",id:"tutorial-steps",level:3},{value:"Gamepad teleoperation",id:"gamepad-teleoperation",level:2},{value:"Dependencies",id:"dependencies-1",level:3},{value:"Tutorial steps",id:"tutorial-steps-1",level:3},{value:"USB/IP gamepad teleoperation",id:"usbip-gamepad-teleoperation",level:2},{value:"Dependencies",id:"dependencies-2",level:3},{value:"Topside configuration steps",id:"topside-configuration-steps",level:3},{value:"Vehicle configuration steps",id:"vehicle-configuration-steps",level:3},{value:"USB/IP shutdown steps",id:"usbip-shutdown-steps",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["This page provides a collection of tutorials that describe how to teleoperate\na simulated or real vehicle. Prior to starting these tutorials, you should have\ncompleted the ",(0,s.jsx)(n.a,{href:"/tutorials/simulation",children:"Running Blue in Simulation"})," tutorial and\nthe ",(0,s.jsx)(n.a,{href:"/tutorials/control",children:"Integrating Custom Controllers"})," tutorial."]}),"\n",(0,s.jsx)(n.h2,{id:"keyboard-teleoperation",children:"Keyboard teleoperation"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial describes how to teleoperate a simulated BlueROV2 using your\nkeyboard."}),"\n",(0,s.jsx)(n.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,s.jsx)(n.p,{children:"The following ROS 2 dependencies are required for this tutorial:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Gazebo Garden or newer"}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/ardusub_driver",children:"ardusub_driver"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/ros2/teleop_twist_keyboard",children:"teleop_twist_keyboard"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/mobile_to_maritime",children:"mobile_to_maritime"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["These dependencies will be met by default if you have installed Blue with\nDocker as described in the ",(0,s.jsx)(n.a,{href:"/installation",children:"installation instructions"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"tutorial-steps",children:"Tutorial steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Launch the demo Dependencies in simulation by running the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_demo.launch.yaml use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Once Gazebo, ArduSub, and MAVROS have fully loaded, open a new terminal and\nlaunch the demo control framework:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_controllers.launch.py use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Open a new terminal and launch the ",(0,s.jsx)(n.code,{children:"teleop_twist_keyboard"})," node:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 run teleop_twist_keyboard teleop_twist_keyboard\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"teleop_twist_keyboard"})," node will publish velocity commands according to\n",(0,s.jsx)(n.a,{href:"https://ros.org/reps/rep-0105.html",children:"REP-105"}),"; however, the launched ISMC\nadheres to the maritime conventions recorded in ",(0,s.jsx)(n.a,{href:"https://github.com/ros-infrastructure/rep/pull/398",children:"REP-156"}),".\nTo convert the velocity commands to the appropriate convention, run the\nfollowing ",(0,s.jsx)(n.code,{children:"mobile_to_maritime"})," message filter in a new terminal:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 run mobile_to_maritime mobile_twist_to_maritime_twist --ros-args -p in_topic:=/cmd_vel -p out_topic:=/integral_sliding_mode_controller/reference\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"You should now be able to teleoperate the BlueROV2 using your keyboard."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"gamepad-teleoperation",children:"Gamepad teleoperation"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial describes how to teleoperate a simulated BlueROV2 using a gamepad."}),"\n",(0,s.jsx)(n.h3,{id:"dependencies-1",children:"Dependencies"}),"\n",(0,s.jsx)(n.p,{children:"The following ROS 2 dependencies are needed for this tutorial:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Gazebo Garden or newer"}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/ardusub_driver",children:"ardusub_driver"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/mobile_to_maritime",children:"mobile_to_maritime"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/ros-teleop/teleop_tools",children:"joy_teleop"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/ros-drivers/joystick_drivers/tree/ros2",children:"joy_linux"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["These dependencies will be met by default if you have installed Blue with\nDocker as described in the ",(0,s.jsx)(n.a,{href:"/installation",children:"installation instructions"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In addition to the aforementioned requirements, you should also install the\n",(0,s.jsx)(n.code,{children:"joystick"})," apt package, which provides Linux drivers for gamepads:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install joystick\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Verify your installation with ",(0,s.jsx)(n.a,{href:"https://www.mankier.com/1/jstest-gtk",children:"jstest"})," by\nrunning the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"jstest /dev/input/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the device name of your gamepad (e.g.,\n",(0,s.jsx)(n.code,{children:"js0"}),")."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["For those using the Docker installation, the ",(0,s.jsx)(n.code,{children:"joystick"})," package should be\ninstalled on your local machine ",(0,s.jsx)(n.strong,{children:"outside"})," of the container."]})}),"\n",(0,s.jsx)(n.h3,{id:"tutorial-steps-1",children:"Tutorial steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Launch the demo BlueROV2 in simulation by running the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_demo.launch.yaml use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Once Gazebo, ArduSub, and MAVROS have fully loaded, open a new terminal and\nlaunch the demo control framework:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_controllers.launch.py use_sim:=true\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Open a new terminal and launch the ROS 2 joystick driver using the provided\ndemo launch file:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos joy_teleop.launch.yaml\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["You should now be able to teleoperate the BlueROV2 using your gamepad. If\nthe system is not responding, ensure that the\n",(0,s.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/blue/blob/31-user-docs/blue_demos/teleoperation/config/joy_teleop.yaml",children:"teleoperation demo configuration"}),"\nreferences the correct device."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsx)(n.p,{children:"The gamepad demo uses the left trigger as a deadman switch. To enable joystick\ninputs, press and release the left trigger."})}),"\n",(0,s.jsx)(n.h2,{id:"usbip-gamepad-teleoperation",children:"USB/IP gamepad teleoperation"}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial describes how to configure ",(0,s.jsx)(n.a,{href:"https://www.kernel.org/doc/html/latest/usb/usbip_protocol.html",children:"USB/IP"}),"\nso that you can teleoperate a remote vehicle connected to a topside computer\nvia a tether with a gamepad connected to your topside machine. In this\nconfiguration, we recommend using a ",(0,s.jsx)(n.a,{href:"https://www.logitechg.com/en-us/products/gamepads/f310-gamepad.940-000110.html",children:"Logitech F310 Gamepad"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"dependencies-2",children:"Dependencies"}),"\n",(0,s.jsx)(n.p,{children:"The following apt packages are needed for this tutorial:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"linux-tools-generic"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"hwdata"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"joystick"})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"which can be installed with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install linux-tools-generic hwdata joystick\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["For those using the Docker installation, the aforementioned packages should be\ninstalled on your local machine ",(0,s.jsx)(n.strong,{children:"outside"})," of the container."]})}),"\n",(0,s.jsx)(n.h3,{id:"topside-configuration-steps",children:"Topside configuration steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Enable the ",(0,s.jsx)(n.code,{children:"usbip-core"})," and ",(0,s.jsx)(n.code,{children:"usbip-host"})," kernel modules:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo modprobe usbip-core && \\\nsudo modprobe usbip-host\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Start the USB/IP process as a daemon:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbipd &\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["USB/IP gets installed into directories that are not in your ",(0,s.jsx)(n.code,{children:"$PATH"}),". Because\nof this, it creates symlinks in the ",(0,s.jsx)(n.code,{children:"/usr/bin"})," directory. Sometimes you will\nget an error when using the default symlinks indicating that the installed\n",(0,s.jsx)(n.code,{children:"linux-tools-generic"})," version does not match the kernel. If this happens,\ndelete the existing symlinks and replace them with new ones."]})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"With your gamepad connected to your topside machine, verify that USB/IP is\nable to detect the gamepad device:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"usbip list -l\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should observe your gamepad in the devices listed along with its bus ID.\nFor instance, the Logitech F310 gamepad may be listed as"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"- busid 3-4 (046d:c216)\n Logitech, Inc. : F310 Gamepad [DirectInput Mode] (046d:c216)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:"3-4"})," is the bus ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Bind the gamepad device to the USB/IP process:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip bind -b \n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the bus ID of your gamepad."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify that the device has been bound by listing the exportable devices:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"usbip list -r 127.0.0.1\n"})}),"\n",(0,s.jsx)(n.p,{children:"which should show the gamepad device. For example, the Logitech F310 gamepad\ndevice may appear as"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Exportable USB devices\n======================\n- 127.0.0.1\n 3-4: Logitech, Inc. : F310 Gamepad [DirectInput Mode] (046d:c216)\n : /sys/devices/pci0000:00/0000:00:01.2/0000:20:00.0/0000:21:08.0/0000:2a:00.3/usb3/3-4\n : (Defined at Interface level) (00/00/00)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"vehicle-configuration-steps",children:"Vehicle configuration steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Load the ",(0,s.jsx)(n.code,{children:"vhci-hcd"})," kernel module on the vehicle's computer:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo modprobe vhci-hcd\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Check that the device configured on the topside machine is observable on the\nvehicle:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip list -r \n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the IP address of the\ntopside machine."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Attach the device to the vehicle:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip attach -r -b \n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["You should now be able to interact with the gamepad device as if it were\nconnected directly to the vehicle. Confirm this with ",(0,s.jsx)(n.code,{children:"jstest"})," using the\nfollowing command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"jstest /dev/input/\n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the device name of your gamepad on\nthe vehicle."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"usbip-shutdown-steps",children:"USB/IP shutdown steps"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Identify the port at which the vehicle has establishe a connection with the\ntopside machine:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip port\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Detach the device from the vehicle:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip detach -p \n"})}),"\n",(0,s.jsxs)(n.p,{children:["where ",(0,s.jsx)(n.code,{children:""})," should be replaced with the identified port number used for\nthe connection."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Unbind the device from the USB/IP process:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo usbip unbind -b \n"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}}}]); \ No newline at end of file diff --git a/assets/js/bb30a773.921b9318.js b/assets/js/bb30a773.921b9318.js deleted file mode 100644 index 909bc6fb..00000000 --- a/assets/js/bb30a773.921b9318.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[456],{7601:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var r=t(4848),l=t(8453);const o={sidebar_position:2,title:"Integrating Custom Controllers"},i=void 0,s={id:"tutorials/control",title:"Integrating Custom Controllers",description:"Blue integrates auvcontrollers",source:"@site/docs/tutorials/control.mdx",sourceDirName:"tutorials",slug:"/tutorials/control",permalink:"/blue/tutorials/control",draft:!1,unlisted:!1,editUrl:"https://github.com/Robotic-Decision-Making-Lab/blue/tree/gh-pages/docs/tutorials/control.mdx",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,title:"Integrating Custom Controllers"},sidebar:"tutorialSidebar",previous:{title:"Running Blue in Simulation",permalink:"/blue/tutorials/simulation"},next:{title:"Teleoperation",permalink:"/blue/tutorials/teleop"}},a={},c=[{value:"Dependencies",id:"dependencies",level:2},{value:"Tutorial steps",id:"tutorial-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.p,{children:["Blue integrates ",(0,r.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"}),"\nfor vehicle control. This offers the benefit of supporting the development of\ncustom control algorithms and enabling benchmarking against existing\ncontrollers. The following tutorial describes how to use custom controllers\nwith Blue. The files used for this tutorial are available in the\n",(0,r.jsx)(n.code,{children:"blue_demos/control_integration"})," directory. Prior to starting this tutorial,\nyou should have completed the ",(0,r.jsx)(n.a,{href:"/tutorials/simulation",children:"Running Blue in Simulation"}),"\ntutorial."]}),"\n",(0,r.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsx)(n.p,{children:"The following ROS 2 dependencies are required for this tutorial:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Gazebo Garden or newer"}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/ardusub_driver",children:"ardusub_driver"}),"\n(for use with the BlueROV2 vehicle models)"]}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["These dependencies will be met by default if you have installed Blue with\nDocker as described in the ",(0,r.jsx)(n.a,{href:"/installation",children:"installation instructions"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"tutorial-steps",children:"Tutorial steps"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Launch the demo BlueROV2 in simulation by running the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_demo.launch.yaml use_sim:=true\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Wait for Gazebo, ArduSub, and MAVROS to fully load. Typically, the ",(0,r.jsx)(n.code,{children:"param"}),"\nMAVROS plugin is the last to fully load, which is indicated by the following\nmessage:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"bleh\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Open a new terminal and launch the demo control framework:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_controllers.launch.py use_sim:=true\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This should launch a set of cascading controllers, concluding with the\n",(0,r.jsx)(n.code,{children:"integral_sliding_mode_controller"})," (ISMC) controller. The control framework\nuses the ",(0,r.jsx)(n.code,{children:"thruster_hardware/ThrusterHardware"})," system interface to enable\nthruster-level control with ArduSub."]}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsx)(n.p,{children:"On occassion, the ros2_control controller manager will fail to load all of\nthe controllers. If this happens, stop the launch and try again."})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Verify that the controllers are running with the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"ros2 control list_controllers\n"})}),"\n",(0,r.jsx)(n.p,{children:"The output should resemble:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"integral_sliding_mode_controller[velocity_controllers/IntegralSlidingModeController] active\nthruster_allocation_matrix_controller[thruster_allocation_matrix_controller/ThrusterAllocationMatrixController] active\nthruster_1_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_2_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_3_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_4_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_5_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_6_controller[thruster_controllers/PolynomialThrustCurveController] active\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsxs)(n.p,{children:["Many of the controllers implemented in ",(0,r.jsx)(n.code,{children:"auv_controllers"})," support dynamically\nmodifying controller parameters and gains. We encourage you to take\nadvantage of this feature to tune the controllers to your specific vehicle.\nThis helps avoid the need to recompile and relauch the system for each\nchange that you make."]})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/assets/js/bb30a773.b8acd633.js b/assets/js/bb30a773.b8acd633.js new file mode 100644 index 00000000..62b266b0 --- /dev/null +++ b/assets/js/bb30a773.b8acd633.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocumentation=self.webpackChunkdocumentation||[]).push([[456],{7601:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var t=r(4848),l=r(8453);const o={sidebar_position:2,title:"Integrating Custom Controllers"},i=void 0,s={id:"tutorials/control",title:"Integrating Custom Controllers",description:"Blue integrates auvcontrollers",source:"@site/docs/tutorials/control.mdx",sourceDirName:"tutorials",slug:"/tutorials/control",permalink:"/blue/tutorials/control",draft:!1,unlisted:!1,editUrl:"https://github.com/Robotic-Decision-Making-Lab/blue/tree/gh-pages/docs/tutorials/control.mdx",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2,title:"Integrating Custom Controllers"},sidebar:"tutorialSidebar",previous:{title:"Running Blue in Simulation",permalink:"/blue/tutorials/simulation"},next:{title:"Teleoperation",permalink:"/blue/tutorials/teleop"}},a={},c=[{value:"Dependencies",id:"dependencies",level:2},{value:"Tutorial steps",id:"tutorial-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["Blue integrates ",(0,t.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"}),"\nfor vehicle control. This offers the benefit of supporting the development of\ncustom control algorithms and enabling benchmarking against existing\ncontrollers. The following tutorial describes how to use custom controllers\nwith Blue. The files used for this tutorial are available in the\n",(0,t.jsx)(n.code,{children:"blue_demos/control_integration"})," directory. Prior to starting this tutorial,\nyou should have completed the ",(0,t.jsx)(n.a,{href:"/tutorials/simulation",children:"Running Blue in Simulation"}),"\ntutorial."]}),"\n",(0,t.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,t.jsx)(n.p,{children:"The following ROS 2 dependencies are required for this tutorial:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Gazebo Garden or newer"}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/ardusub_driver",children:"ardusub_driver"}),"\n(for use with the BlueROV2 vehicle models)"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/Robotic-Decision-Making-Lab/auv_controllers",children:"auv_controllers"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["These dependencies will be met by default if you have installed Blue with\nDocker as described in the ",(0,t.jsx)(n.a,{href:"/installation",children:"installation instructions"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-steps",children:"Tutorial steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Launch the demo BlueROV2 in simulation by running the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_demo.launch.yaml use_sim:=true\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Wait for Gazebo, ArduSub, and MAVROS to fully load. Typically, the ",(0,t.jsx)(n.code,{children:"param"}),"\nMAVROS plugin is the last to fully load, which is indicated by the following\nmessage:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"[mavros.param]: PR: parameters list received\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Open a new terminal and launch the demo control framework:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ros2 launch blue_demos bluerov2_controllers.launch.py use_sim:=true\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This should launch a set of cascading controllers, concluding with the\n",(0,t.jsx)(n.code,{children:"integral_sliding_mode_controller"})," (ISMC) controller. The control framework\nuses the ",(0,t.jsx)(n.code,{children:"thruster_hardware/ThrusterHardware"})," system interface to enable\nthruster-level control with ArduSub."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsx)(n.p,{children:"On occassion, the ros2_control controller manager will fail to load all of\nthe controllers. If this happens, stop the launch and try again."})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Verify that the controllers are running with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ros2 control list_controllers\n"})}),"\n",(0,t.jsx)(n.p,{children:"The output should resemble:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"integral_sliding_mode_controller[velocity_controllers/IntegralSlidingModeController] active\nthruster_allocation_matrix_controller[thruster_allocation_matrix_controller/ThrusterAllocationMatrixController] active\nthruster_1_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_2_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_3_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_4_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_5_controller[thruster_controllers/PolynomialThrustCurveController] active\nthruster_6_controller[thruster_controllers/PolynomialThrustCurveController] active\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["Many of the controllers implemented in ",(0,t.jsx)(n.code,{children:"auv_controllers"})," support dynamically\nmodifying controller parameters and gains. We encourage you to take\nadvantage of this feature to tune the controllers to your specific vehicle.\nThis helps avoid the need to recompile and relauch the system for each\nchange that you make."]})}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.c516868e.js b/assets/js/runtime~main.b1379ee9.js similarity index 97% rename from assets/js/runtime~main.c516868e.js rename to assets/js/runtime~main.b1379ee9.js index c7dc6ffe..7e6a4f30 100644 --- a/assets/js/runtime~main.c516868e.js +++ b/assets/js/runtime~main.b1379ee9.js @@ -1 +1 @@ -(()=>{"use strict";var e,t,r,a,o,n={},f={};function c(e){var t=f[e];if(void 0!==t)return t.exports;var r=f[e]={exports:{}};return n[e].call(r.exports,r,r.exports,c),r.exports}c.m=n,e=[],c.O=(t,r,a,o)=>{if(!r){var n=1/0;for(u=0;u=o)&&Object.keys(c.O).every((e=>c.O[e](r[i])))?r.splice(i--,1):(f=!1,o0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[r,a,o]},c.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return c.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);c.r(o);var n={};t=t||[null,r({}),r([]),r(r)];for(var f=2&a&&e;"object"==typeof f&&!~t.indexOf(f);f=r(f))Object.getOwnPropertyNames(f).forEach((t=>n[t]=()=>e[t]));return n.default=()=>e,c.d(o,n),o},c.d=(e,t)=>{for(var r in t)c.o(t,r)&&!c.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((t,r)=>(c.f[r](e,t),t)),[])),c.u=e=>"assets/js/"+({26:"997621ba",48:"a94703ab",76:"common",98:"a7bd4aaa",235:"18891827",401:"17896441",456:"bb30a773",501:"5722016a",535:"8460f15f",581:"935f2afb",643:"72a427b3",647:"5e95c892",802:"fa4d91bf",934:"282d1385"}[e]||e)+"."+{4:"d4e84adf",26:"3eaec263",48:"49fbb7a2",63:"e2eeace6",76:"47710cf0",98:"e4961847",121:"c0d1b352",130:"fe1942d5",147:"8736d7e9",200:"e50854a9",211:"8c5458a6",216:"bd963ec8",235:"eacff8da",237:"e38219f8",292:"78518882",307:"9491a275",308:"43c50925",317:"7d26d6bb",327:"cebbe298",401:"2360cb52",432:"3b956990",440:"ff80b848",456:"921b9318",469:"8f9a24d8",501:"395c229a",506:"3036db5f",535:"7e749458",555:"606e3e3d",581:"c96ebf50",609:"0048d281",616:"1628ab38",642:"dc3ea27d",643:"67e87d1f",647:"4ca941bb",688:"923c33dc",732:"8cca20be",751:"ef6780cb",802:"b01cd35c",863:"a97bb454",934:"6bbdaad7",946:"2a39feed",947:"29042d36"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},o="documentation:",c.l=(e,t,r,n)=>{if(a[e])a[e].push(t);else{var f,i;if(void 0!==r)for(var d=document.getElementsByTagName("script"),u=0;u{f.onerror=f.onload=null,clearTimeout(s);var o=a[e];if(delete a[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(r))),t)return t(r)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),i&&document.head.appendChild(f)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/blue/",c.gca=function(e){return e={17896441:"401",18891827:"235","997621ba":"26",a94703ab:"48",common:"76",a7bd4aaa:"98",bb30a773:"456","5722016a":"501","8460f15f":"535","935f2afb":"581","72a427b3":"643","5e95c892":"647",fa4d91bf:"802","282d1385":"934"}[e]||e,c.p+c.u(e)},(()=>{var e={354:0,869:0};c.f.j=(t,r)=>{var a=c.o(e,t)?e[t]:void 0;if(0!==a)if(a)r.push(a[2]);else if(/^(354|869)$/.test(t))e[t]=0;else{var o=new Promise(((r,o)=>a=e[t]=[r,o]));r.push(a[2]=o);var n=c.p+c.u(t),f=new Error;c.l(n,(r=>{if(c.o(e,t)&&(0!==(a=e[t])&&(e[t]=void 0),a)){var o=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;f.message="Loading chunk "+t+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,a[1](f)}}),"chunk-"+t,t)}},c.O.j=t=>0===e[t];var t=(t,r)=>{var a,o,n=r[0],f=r[1],i=r[2],d=0;if(n.some((t=>0!==e[t]))){for(a in f)c.o(f,a)&&(c.m[a]=f[a]);if(i)var u=i(c)}for(t&&t(r);d{"use strict";var e,t,r,a,o,n={},f={};function c(e){var t=f[e];if(void 0!==t)return t.exports;var r=f[e]={exports:{}};return n[e].call(r.exports,r,r.exports,c),r.exports}c.m=n,e=[],c.O=(t,r,a,o)=>{if(!r){var n=1/0;for(u=0;u=o)&&Object.keys(c.O).every((e=>c.O[e](r[i])))?r.splice(i--,1):(f=!1,o0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[r,a,o]},c.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return c.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,c.t=function(e,a){if(1&a&&(e=this(e)),8&a)return e;if("object"==typeof e&&e){if(4&a&&e.__esModule)return e;if(16&a&&"function"==typeof e.then)return e}var o=Object.create(null);c.r(o);var n={};t=t||[null,r({}),r([]),r(r)];for(var f=2&a&&e;"object"==typeof f&&!~t.indexOf(f);f=r(f))Object.getOwnPropertyNames(f).forEach((t=>n[t]=()=>e[t]));return n.default=()=>e,c.d(o,n),o},c.d=(e,t)=>{for(var r in t)c.o(t,r)&&!c.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},c.f={},c.e=e=>Promise.all(Object.keys(c.f).reduce(((t,r)=>(c.f[r](e,t),t)),[])),c.u=e=>"assets/js/"+({26:"997621ba",48:"a94703ab",76:"common",98:"a7bd4aaa",235:"18891827",401:"17896441",456:"bb30a773",501:"5722016a",535:"8460f15f",581:"935f2afb",643:"72a427b3",647:"5e95c892",802:"fa4d91bf",934:"282d1385"}[e]||e)+"."+{4:"d4e84adf",26:"3eaec263",48:"49fbb7a2",63:"e2eeace6",76:"47710cf0",98:"e4961847",121:"c0d1b352",130:"fe1942d5",147:"8736d7e9",200:"e50854a9",211:"8c5458a6",216:"bd963ec8",235:"eacff8da",237:"e38219f8",292:"78518882",307:"9491a275",308:"43c50925",317:"7d26d6bb",327:"cebbe298",401:"2360cb52",432:"3b956990",440:"ff80b848",456:"b8acd633",469:"8f9a24d8",501:"c4f07e89",506:"3036db5f",535:"7e749458",555:"606e3e3d",581:"c96ebf50",609:"0048d281",616:"1628ab38",642:"dc3ea27d",643:"67e87d1f",647:"4ca941bb",688:"923c33dc",732:"8cca20be",751:"ef6780cb",802:"b01cd35c",863:"a97bb454",934:"6bbdaad7",946:"2a39feed",947:"29042d36"}[e]+".js",c.miniCssF=e=>{},c.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a={},o="documentation:",c.l=(e,t,r,n)=>{if(a[e])a[e].push(t);else{var f,i;if(void 0!==r)for(var d=document.getElementsByTagName("script"),u=0;u{f.onerror=f.onload=null,clearTimeout(s);var o=a[e];if(delete a[e],f.parentNode&&f.parentNode.removeChild(f),o&&o.forEach((e=>e(r))),t)return t(r)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=l.bind(null,f.onerror),f.onload=l.bind(null,f.onload),i&&document.head.appendChild(f)}},c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.p="/blue/",c.gca=function(e){return e={17896441:"401",18891827:"235","997621ba":"26",a94703ab:"48",common:"76",a7bd4aaa:"98",bb30a773:"456","5722016a":"501","8460f15f":"535","935f2afb":"581","72a427b3":"643","5e95c892":"647",fa4d91bf:"802","282d1385":"934"}[e]||e,c.p+c.u(e)},(()=>{var e={354:0,869:0};c.f.j=(t,r)=>{var a=c.o(e,t)?e[t]:void 0;if(0!==a)if(a)r.push(a[2]);else if(/^(354|869)$/.test(t))e[t]=0;else{var o=new Promise(((r,o)=>a=e[t]=[r,o]));r.push(a[2]=o);var n=c.p+c.u(t),f=new Error;c.l(n,(r=>{if(c.o(e,t)&&(0!==(a=e[t])&&(e[t]=void 0),a)){var o=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;f.message="Loading chunk "+t+" failed.\n("+o+": "+n+")",f.name="ChunkLoadError",f.type=o,f.request=n,a[1](f)}}),"chunk-"+t,t)}},c.O.j=t=>0===e[t];var t=(t,r)=>{var a,o,n=r[0],f=r[1],i=r[2],d=0;if(n.some((t=>0!==e[t]))){for(a in f)c.o(f,a)&&(c.m[a]=f[a]);if(i)var u=i(c)}for(t&&t(r);d Contributing | Blue - + diff --git a/index.html b/index.html index 9f84c5bc..1225d167 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ Welcome! | Blue - + diff --git a/installation/index.html b/installation/index.html index 69cd6f66..b4ccfb47 100644 --- a/installation/index.html +++ b/installation/index.html @@ -4,7 +4,7 @@ Installation | Blue - + diff --git a/overview/index.html b/overview/index.html index 4f36424c..2dbf4f58 100644 --- a/overview/index.html +++ b/overview/index.html @@ -4,7 +4,7 @@ Overview | Blue - + diff --git a/tutorials/control/index.html b/tutorials/control/index.html index d2b9b1b1..0626f1df 100644 --- a/tutorials/control/index.html +++ b/tutorials/control/index.html @@ -4,7 +4,7 @@ Integrating Custom Controllers | Blue - + @@ -36,7 +36,7 @@

Tutorial step

Wait for Gazebo, ArduSub, and MAVROS to fully load. Typically, the param MAVROS plugin is the last to fully load, which is indicated by the following message:

-
bleh
+
[mavros.param]: PR: parameters list received
  • Open a new terminal and launch the demo control framework:

    diff --git a/tutorials/simulation/index.html b/tutorials/simulation/index.html index 8ca0e83b..548a0422 100644 --- a/tutorials/simulation/index.html +++ b/tutorials/simulation/index.html @@ -4,7 +4,7 @@ Running Blue in Simulation | Blue - + diff --git a/tutorials/teleop/index.html b/tutorials/teleop/index.html index ebbb735b..7e2bc76c 100644 --- a/tutorials/teleop/index.html +++ b/tutorials/teleop/index.html @@ -4,7 +4,7 @@ Teleoperation | Blue - + @@ -30,7 +30,7 @@

    Tutorial step
    1. Launch the demo Dependencies in simulation by running the following command:

      -
      ros2 launch blue_demos Dependencies_demo.launch.yaml use_sim:=true
      +
      ros2 launch blue_demos bluerov2_demo.launch.yaml use_sim:=true
    2. Once Gazebo, ArduSub, and MAVROS have fully loaded, open a new terminal and @@ -47,7 +47,7 @@

      Tutorial step adheres to the maritime conventions recorded in REP-156. To convert the velocity commands to the appropriate convention, run the following mobile_to_maritime message filter in a new terminal:

      -
      ros2 run mobile_to_maritime mobile_twist_to_maritime_twist --ros-args in_topic:=/cmd_vel out_topic:=/integral_sliding_mode_controller/reference
      +
      ros2 run mobile_to_maritime mobile_twist_to_maritime_twist --ros-args -p in_topic:=/cmd_vel -p out_topic:=/integral_sliding_mode_controller/reference

    3. You should now be able to teleoperate the BlueROV2 using your keyboard.