├── .bazelrc ├── .gitignore ├── .travis.yml ├── BUILD ├── LICENSE ├── README.md ├── WORKSPACE ├── base ├── BUILD ├── aspect_ratio.cc ├── aspect_ratio.h ├── async_i2c.h ├── bezier.h ├── circular_buffer.h ├── common.h ├── component_archives.h ├── context.cc ├── context.h ├── context_full.h ├── error_wrap.h ├── euler.h ├── fail_functor.h ├── fit_plane.cc ├── fit_plane.h ├── format_hex.cc ├── format_hex.h ├── git_info.cc ├── git_info.h ├── git_info_linkstamp.cc ├── handler_util.h ├── interpolate.h ├── kinematic_relation.h ├── leg_force.cc ├── leg_force.h ├── linux_input.cc ├── linux_input.h ├── logging.cc ├── logging.h ├── module_main.bzl ├── module_main.h ├── named_type.h ├── point3d.h ├── quaternion.cc ├── quaternion.h ├── reservoir_sampler.h ├── runfiles.h ├── saturate.h ├── signal_result.h ├── sophus.h ├── stringify.h ├── system_fd.cc ├── system_fd.h ├── system_mmap.h ├── telemetry_log_registrar.h ├── telemetry_registry.h ├── telemetry_remote_debug_registrar.h ├── telemetry_remote_debug_server.cc ├── telemetry_remote_debug_server.h ├── test │ ├── aspect_ratio_test.cc │ ├── bezier_test.cc │ ├── fit_plane_test.cc │ ├── leg_force_test.cc │ ├── linux_input_manual_test.cc │ ├── named_type_test.cc │ ├── quaternion_test.cc │ ├── se3d_test.cc │ ├── signal_result_test.cc │ ├── sophus_test.cc │ ├── telemetry_log_registrar_test.cc │ ├── telemetry_registry_test.cc │ ├── test_main.cc │ ├── udp_manual_test.h │ └── ukf_filter_test.cc ├── timestamped_log.cc ├── timestamped_log.h ├── tokenizer.h ├── udp_data_link.cc ├── udp_data_link.h ├── udp_socket.cc ├── udp_socket.h └── ukf_filter.h ├── configs ├── BUILD ├── gimbal_config.txt ├── lizard_gimbal_config.txt ├── mech_warfare.cfg ├── moteus_gimbal_config.txt ├── quada0.cfg ├── quada1.cfg ├── quada2.cfg ├── quadruped.ini ├── quadruped_a2.ini ├── real_dynamic_high.cfg └── real_dynamic_low.cfg ├── docs ├── diagrams │ ├── 1d_swing.blend │ ├── 1d_swing.png │ ├── as5047_noise_plot.py │ ├── magnetic_saturation.odg │ ├── phase_current.py │ ├── support_line.blend │ ├── support_line.png │ └── torque_compensation.py ├── geometry.md ├── numbered-targets.odp └── quada1 │ └── README.md ├── ffmpeg ├── BUILD ├── codec.h ├── dictionary.h ├── error.h ├── ffmpeg.h ├── file.h ├── frame.h ├── input_format.h ├── packet.h ├── ref_base.h ├── stream.h ├── swscale.h └── test │ ├── codec_test.cc │ ├── data │ └── sample_log.mp4 │ ├── file_test.cc │ ├── frame_test.cc │ ├── packet_test.cc │ ├── stream_test.cc │ ├── swscale_test.cc │ └── test_main.cc ├── gl ├── BUILD ├── camera.h ├── flat_rgb_texture.h ├── framebuffer.h ├── gl_imgui.h ├── image_texture.h ├── orthographic_camera.h ├── perspective_camera.h ├── program.h ├── renderbuffer.h ├── shader.h ├── simple_line_render_list.cc ├── simple_line_render_list.h ├── simple_texture_render_list.cc ├── simple_texture_render_list.h ├── test │ ├── flat_rgb_texture_test.cc │ ├── framebuffer_test.cc │ ├── perspective_camera_test.cc │ ├── program_test.cc │ ├── shader_test.cc │ ├── simple_texture_render_list_test.cc │ ├── test_main.cc │ ├── texture_test.cc │ ├── trackball_test.cc │ ├── vertex_array_object_test.cc │ └── vertex_buffer_object_test.cc ├── texture.h ├── trackball.h ├── vertex_array_object.h └── vertex_buffer_object.h ├── hw ├── chassis │ └── 3dprint │ │ ├── 20200303-battery_stud.3mf │ │ ├── 20200415-stiffener_left.3mf │ │ ├── 20200415-stiffener_right.3mf │ │ ├── 20200415-top.3mf │ │ ├── 20200502-aligners.3mf │ │ ├── 20200504-front_plate.3mf │ │ ├── 20200506-bottom.3mf │ │ ├── 20200506-internal_cover.3mf │ │ ├── 20200708-shore_plug.3mf │ │ ├── 20201223-sides.3mf │ │ ├── 20231218-front_plate-0_6mm.3mf │ │ ├── 20231218-sides-0_6mm.3mf │ │ ├── 20231219-battery_stud-0_6.3mf │ │ ├── 20231219-bottom-0_6mm.3mf │ │ ├── 20231219-top-0_6mm.3mf │ │ ├── 20231220-internal_cover-0_6mm.3mf │ │ └── 20231220-stiffeners-0_6mm.3mf ├── chassis_a2 │ ├── battery_tray.3mf │ ├── bottom.3mf │ ├── computer_tray.3mf │ ├── front_back_plate.3mf │ ├── knee_zero.3mf │ ├── rail_carrier.3mf │ ├── shoulder_zero_left.3mf │ ├── shoulder_zero_right.3mf │ ├── side_wall.3mf │ └── top.3mf ├── leg │ └── 3dprint │ │ ├── 20200223-shoulder.3mf │ │ ├── 20200825-upper_leg.3mf │ │ ├── 20201009-lower_leg_and_bracket.3mf │ │ ├── 20201009-shoulder_conduit.3mf │ │ ├── 20210602-upper_motor_joint.3mf │ │ ├── 20210713-pulleys-tensioner.3mf │ │ ├── 20210806-lower_leg_and_bracket-left.3mf │ │ ├── 20210806-lower_leg_and_bracket-right.3mf │ │ ├── 20210806-lower_leg_and_bracket.3mf │ │ ├── 20231220-lower_leg_and_bracket-petg-0_6mm.3mf │ │ ├── 20231220-shoulder_conduit-0_6mm.3mf │ │ └── 20231220-upper_leg-0_6mm.3mf └── leg_a2 │ ├── 2x_lower_leg_base.3mf │ ├── 2x_shoulder.3mf │ ├── 2x_upper_motor.3mf │ ├── 4x_foot_axle_cap_pulley.3mf │ ├── 4x_tensioners.3mf │ ├── upper_leg_base_lower_leg_top.3mf │ ├── upper_leg_right_base_lower_leg_top.3mf │ ├── upper_leg_right_top.3mf │ └── upper_leg_top.3mf ├── install-packages ├── mech ├── BUILD ├── aruco_draw.cc ├── aruco_test.cc ├── attitude_data.h ├── camera_driver.cc ├── camera_driver.h ├── control_timing.h ├── direct_servo_latency_test.cc ├── expo_map.h ├── ik.h ├── imgui_test.cc ├── imu_client.h ├── imu_data.h ├── info-networking.txt ├── mammal_ik.cc ├── mammal_ik.h ├── mcast_telemetry_interface.h ├── mime_type.cc ├── mime_type.h ├── moteus.h ├── moteus_tool_main.cc ├── multiplex_tool_main.cc ├── nrfusb_client.cc ├── nrfusb_client.h ├── pi3hat_interface.h ├── pi3hat_wrapper.cc ├── pi3hat_wrapper.h ├── propagate_leg.h ├── qdd100_test.cc ├── quadruped.cc ├── quadruped.h ├── quadruped_command.h ├── quadruped_config.h ├── quadruped_context.h ├── quadruped_control.cc ├── quadruped_control.h ├── quadruped_state.h ├── quadruped_trot.cc ├── quadruped_trot.h ├── quadruped_util.h ├── reticle.png ├── rf_client.h ├── rf_control.cc ├── rf_control.h ├── servo_interface.h ├── swing_trajectory.cc ├── swing_trajectory.h ├── system_info.cc ├── system_info.h ├── target_tracker_data.h ├── test │ ├── expo_map_test.cc │ ├── mammal_ik_test.cc │ ├── swing_trajectory_test.cc │ ├── test_main.cc │ ├── trajectory_line_intersect_test.cc │ ├── trajectory_test.cc │ └── vertical_line_frame_test.cc ├── trajectory.cc ├── trajectory.h ├── trajectory_line_intersect.cc ├── trajectory_line_intersect.h ├── valid_leg_region.h ├── vertical_line_frame.h ├── web_control.h ├── web_control_assets │ ├── index.html │ ├── js │ │ └── app.js │ ├── mjbots.png │ └── styles.css ├── web_server.cc └── web_server.h ├── simulator ├── BUILD ├── make_robot.cc ├── make_robot.h ├── simulator.cc ├── simulator_window.cc └── simulator_window.h ├── tools ├── bazel ├── workspace │ ├── BUILD │ ├── bazel_deps │ │ ├── BUILD │ │ └── repository.bzl │ ├── default.bzl │ ├── generate_file.bzl │ ├── github_archive.bzl │ ├── gst-rpicamsrc │ │ ├── BUILD │ │ ├── package.BUILD │ │ └── repository.bzl │ ├── i2c-tools │ │ ├── BUILD │ │ ├── package.BUILD │ │ └── repository.bzl │ ├── implot │ │ ├── BUILD │ │ ├── empty-legend.diff │ │ ├── package.BUILD │ │ └── repository.bzl │ ├── mjlib │ │ ├── BUILD │ │ └── repository.bzl │ ├── moteus │ │ ├── BUILD │ │ └── repository.bzl │ ├── pi3hat │ │ ├── BUILD │ │ └── repository.bzl │ ├── raspberrypi-firmware │ │ ├── BUILD │ │ ├── package.BUILD │ │ └── repository.bzl │ ├── raspicam │ │ ├── BUILD │ │ ├── package.BUILD │ │ ├── raspicam.diff │ │ └── repository.bzl │ ├── rpi_bazel │ │ ├── BUILD │ │ └── repository.bzl │ ├── rules_pkg │ │ ├── BUILD │ │ └── repository.bzl │ ├── sophus │ │ ├── BUILD │ │ ├── package.BUILD │ │ └── repository.bzl │ └── template_file.bzl └── workspace_status.sh ├── travis-ci.py └── utils ├── BUILD ├── config_servos.py ├── imgui_tree_archive.h ├── performance_governor.sh ├── quad-start.sh ├── quad.cmd ├── quad_screen.conf ├── quadruped_tplot2.cc ├── quadruped_tplot2.h ├── rpi3 └── setup-system.py ├── ssh ├── default.ssh └── default.ssh.pub ├── start-robot.sh ├── swing_plan_test.py ├── tplot2.cc ├── trajectory_plot.py ├── tree_view.h ├── trot_timing.py ├── update_voltage.sh ├── video_aligner.py └── zero_leg.py /.bazelrc: -------------------------------------------------------------------------------- 1 | common --noenable_bzlmod 2 | build --noincompatible_enable_cc_toolchain_resolution 3 | 4 | build --crosstool_top=@rpi_bazel//tools/cc_toolchain:toolchain 5 | build --define CLANG=true 6 | 7 | # Sadly, Eigen/C++ still hasn't figured out how to reliably get 8 | # alignment correct. Lets just disable it for now. 9 | build --copt -DEIGEN_DONT_ALIGN_STATICALLY 10 | 11 | build:pi --cpu=armeabihf 12 | build:pi --define COM_GITHUB_MJBOTS_RASPBERRYPI=1 13 | 14 | build --strip=never 15 | build --compiler=clang 16 | 17 | build -c opt 18 | build --copt -D_FILE_OFFSET_BITS=64 19 | build --copt -D_LARGEFILE_SOURCE 20 | build --copt -D_LARGEFILE64_SOURCE 21 | 22 | test --test_output=errors 23 | 24 | build --workspace_status_command=tools/workspace_status.sh 25 | 26 | build --stamp 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ 3 | core 4 | *.so 5 | *.os 6 | .scons* 7 | work_plan.pdf 8 | mtool_main_window.py 9 | *.fcstd? 10 | *.blend? 11 | build-armv7l 12 | build-x86_64 13 | mjmech-data 14 | *.l#? 15 | *.s#? 16 | *.b#? 17 | *.pro 18 | logs 19 | #* 20 | .#* 21 | _bazelrc_generated 22 | /bazel-* 23 | imgui.ini 24 | tplot2.ini 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - build0 3 | - build1 4 | - build2 5 | - build3 6 | - build4 7 | - build5 8 | jobs: 9 | include: 10 | - stage: build0 11 | script: ./travis-ci.py 0 12 | - stage: build1 13 | script: ./travis-ci.py 1 14 | - stage: build2 15 | script: ./travis-ci.py 2 16 | - stage: build3 17 | script: ./travis-ci.py 3 18 | - stage: build4 19 | script: ./travis-ci.py 4 20 | - stage: build5 21 | script: ./travis-ci.py 5 && rm -rf $HOME/.cache/bazel 22 | dist: bionic 23 | language: cpp 24 | cache: 25 | directories: 26 | - $HOME/.cache/bazel/ 27 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | config_setting( 20 | name = "raspberrypi", 21 | values = { 22 | "cpu" : "armeabihf", 23 | }, 24 | ) 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015, Josh Pieper jjp@pobox.com, Mikhail Afanasyev 2 | mafanasyev@gmail.com 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mjbots quad 2 | =========== 3 | 4 | Source and design files for the mjbots quad series of robots, their 5 | controlling interfaces, and utilities for developing and operating 6 | them. 7 | 8 | * GitHub https://github.com/mjbots/mjmech 9 | * Most files are free hardware and software: Apache 2.0 License 10 | * Overall F360 assembly: https://a360.co/4bPBs6g 11 | 12 | Directory structure 13 | ------------------- 14 | 15 | * **base/** - C++ source files common to many applications. 16 | * **ffmpeg/** - C++ ffmpeg wrappers. 17 | * **gl/** - C++ GL wrappers. 18 | * **mech/** - C++ source files specific to walking robots. 19 | * **simulator/** - C++ source files for a quadruped simulator. 20 | * **utils/** - Utilities for development and data analysis. 21 | * **configs/** - Configuration files for different robots and applications. 22 | * **hw/** - Hardware design files along with firmware. 23 | * **docs/** - Documentation. 24 | 25 | 26 | First Time Setup 27 | ---------------- 28 | 29 | The following should work on Ubuntu 20.04 or 22.04. 30 | 31 | ``` 32 | ./install-packages 33 | ``` 34 | 35 | For Ubuntu 24.04, you will also need to manually download and install an appropriate libtinfo5 package from 22.04. https://packages.ubuntu.com/jammy/amd64/libtinfo5/download 36 | 37 | Building for host 38 | ----------------- 39 | 40 | ``` 41 | tools/bazel test //... 42 | ``` 43 | 44 | Running simulation 45 | ------------------ 46 | 47 | ``` 48 | ./bazel-bin/simulator/simulator -c configs/quadruped.ini 49 | ``` 50 | 51 | Then point your web browser to `http://localhost:4778` 52 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | workspace(name = "com_github_mjbots_mech") 18 | 19 | BAZEL_VERSION = "7.4.1" 20 | BAZEL_VERSION_SHA = "c97f02133adce63f0c28678ac1f21d65fa8255c80429b588aeeba8a1fac6202b" 21 | 22 | load("//tools/workspace:default.bzl", "add_default_repositories") 23 | 24 | add_default_repositories() 25 | 26 | load("@rpi_bazel//tools/workspace:default.bzl", 27 | rpi_bazel_add = "add_default_repositories") 28 | rpi_bazel_add() 29 | 30 | load("@com_github_mjbots_bazel_deps//tools/workspace:default.bzl", 31 | bazel_deps_add = "add_default_repositories") 32 | bazel_deps_add() 33 | 34 | load("@com_github_mjbots_mjlib//tools/workspace:default.bzl", 35 | mjlib_add = "add_default_repositories") 36 | mjlib_add() 37 | 38 | load("@moteus//tools/workspace:default.bzl", 39 | moteus_add = "add_default_repositories") 40 | moteus_add() 41 | -------------------------------------------------------------------------------- /base/aspect_ratio.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/aspect_ratio.h" 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | Eigen::AlignedBox2i MaintainAspectRatio(Eigen::Vector2i source, 21 | Eigen::Vector2i dest) { 22 | int x = 0; 23 | int y = 0; 24 | int display_w = dest.x(); 25 | int display_h = dest.y(); 26 | 27 | // Enforce an aspect ratio. 28 | const double desired_aspect_ratio = 29 | static_cast(std::abs(source.x())) / 30 | static_cast(std::abs(source.y())); 31 | const double actual_ratio = 32 | static_cast(display_w) / 33 | static_cast(display_h); 34 | if (actual_ratio > desired_aspect_ratio) { 35 | const int w = display_h * desired_aspect_ratio; 36 | const int remaining = display_w - w; 37 | x = remaining / 2; 38 | display_w = w; 39 | } else if (actual_ratio < desired_aspect_ratio) { 40 | const int h = display_w / desired_aspect_ratio; 41 | const int remaining = display_h - h; 42 | y = remaining / 2; 43 | display_h = h; 44 | } 45 | 46 | return { 47 | Eigen::Vector2i(x, y), 48 | Eigen::Vector2i(x + display_w, y + display_h) 49 | }; 50 | } 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /base/aspect_ratio.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace mjmech { 21 | namespace base { 22 | 23 | /// Given a source image and a destination region, return a draw 24 | /// location that maximizes the usable size while maintaining the 25 | /// aspect ratio of the source. 26 | Eigen::AlignedBox2i MaintainAspectRatio(Eigen::Vector2i source, 27 | Eigen::Vector2i dest); 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /base/async_i2c.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "mjlib/io/async_types.h" 20 | 21 | namespace mjmech { 22 | namespace base { 23 | 24 | class AsyncI2C : boost::noncopyable { 25 | public: 26 | virtual ~AsyncI2C() {} 27 | virtual boost::asio::any_io_executor get_executor() = 0; 28 | 29 | virtual void AsyncRead( 30 | uint8_t device, uint8_t address, 31 | mjlib::io::MutableBufferSequence buffers, mjlib::io::ReadHandler) = 0; 32 | 33 | virtual void AsyncWrite( 34 | uint8_t device, uint8_t address, 35 | mjlib::io::ConstBufferSequence buffers, mjlib::io::WriteHandler) = 0; 36 | }; 37 | 38 | typedef std::shared_ptr SharedI2C; 39 | typedef std::function SharedI2CHandler; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /base/bezier.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | /// Interpolate over a cubic bezier function with fixed control points 21 | /// such that velocity is 0 at start and end and the acceleration is 22 | /// continuous within that range. 23 | template 24 | class Bezier { 25 | public: 26 | Bezier(T start, T end) 27 | : start_(start), 28 | end_(end) {} 29 | 30 | T position(double phase) const { 31 | const double bezier = 32 | phase * phase * phase + 3.0 * (phase * phase * (1.0 - phase)); 33 | return start_ + bezier * delta_; 34 | } 35 | 36 | T velocity(double phase) const { 37 | const double bezier = 6 * phase * (1.0 - phase); 38 | return bezier * delta_; 39 | } 40 | 41 | T acceleration(double phase) const { 42 | const double bezier = 6 - 12 * phase; 43 | return bezier * delta_; 44 | } 45 | 46 | private: 47 | T start_; 48 | T end_; 49 | T delta_{end_ - start_}; 50 | }; 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /base/context.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "context_full.h" 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | Context::Context() 21 | : telemetry_log(std::make_unique([]() { 22 | mjlib::telemetry::FileWriter::Options options; 23 | options.blocking = false; 24 | return options; 25 | }())), 26 | remote_debug(std::make_unique(executor)), 27 | telemetry_registry(std::make_unique( 28 | context, telemetry_log.get(), remote_debug.get())), 29 | factory(std::make_unique(executor)) 30 | { 31 | } 32 | 33 | Context::~Context() {} 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /base/context.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "mjlib/io/realtime_executor.h" 24 | #include "mjlib/io/stream_factory.h" 25 | #include "mjlib/telemetry/file_writer.h" 26 | 27 | namespace mjmech { 28 | namespace base { 29 | 30 | class TelemetryRemoteDebugServer; 31 | class TelemetryRegistry; 32 | 33 | struct Context : boost::noncopyable { 34 | Context(); 35 | ~Context(); 36 | 37 | boost::asio::io_context context; 38 | mjlib::io::RealtimeExecutor rt_executor{context.get_executor()}; 39 | boost::asio::any_io_executor executor{rt_executor}; 40 | std::unique_ptr telemetry_log; 41 | std::unique_ptr remote_debug; 42 | std::unique_ptr telemetry_registry; 43 | std::unique_ptr factory; 44 | }; 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /base/context_full.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2020 Josh Pieper, jjp@pobox.com. 2 | // Copyright 2015-2016 Mikhail Afanasyev. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #pragma once 17 | 18 | #include "base/context.h" 19 | 20 | #include "mjlib/io/stream_factory.h" 21 | 22 | #include "telemetry_registry.h" 23 | #include "telemetry_remote_debug_server.h" 24 | -------------------------------------------------------------------------------- /base/error_wrap.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2018 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "stringify.h" 25 | 26 | namespace mjmech { 27 | namespace base { 28 | 29 | /// The following routine can be used to wrap coroutines such that 30 | /// boost::system_error information is captured. The default 31 | /// boost::exception_ptr ignores this exception, making it challenging 32 | /// to even report what happened. 33 | template 34 | auto ErrorWrap(Coroutine coro) { 35 | return [=](boost::asio::yield_context yield) { 36 | try { 37 | return coro(yield); 38 | } catch (boost::system::system_error& e) { 39 | std::throw_with_nested( 40 | std::runtime_error( 41 | fmt::format("system_error: {}: {}", 42 | e.what(), Stringify(e.code())))); 43 | } catch (std::runtime_error& e) { 44 | std::throw_with_nested(std::runtime_error(e.what())); 45 | } 46 | }; 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /base/euler.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2016 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/base/visitor.h" 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | /// Euler angles are in roll, pitch, then yaw. 23 | /// +roll -> right side down 24 | /// +pitch -> forward edge up 25 | /// +yaw -> clockwise looking down 26 | struct Euler { 27 | double roll = 0.0; 28 | double pitch = 0.0; 29 | double yaw = 0.0; 30 | 31 | template 32 | void Serialize(Archive* a) { 33 | a->Visit(MJ_NVP(roll)); 34 | a->Visit(MJ_NVP(pitch)); 35 | a->Visit(MJ_NVP(yaw)); 36 | } 37 | }; 38 | 39 | inline Euler operator*(const Euler& lhs, double s) { 40 | return Euler{lhs.roll * s, lhs.pitch * s, lhs.yaw * s}; 41 | } 42 | 43 | inline Euler operator*(double s, const Euler& lhs) { 44 | return Euler{lhs.roll * s, lhs.pitch * s, lhs.yaw * s}; 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /base/fail_functor.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/base/error_code.h" 18 | #include "mjlib/base/fail.h" 19 | 20 | namespace mjmech { 21 | namespace base { 22 | 23 | class FailFunctor { 24 | public: 25 | template 26 | void operator()(const mjlib::base::error_code& ec, Args...) { 27 | mjlib::base::FailIf(ec); 28 | } 29 | }; 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /base/fit_plane.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/fit_plane.h" 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | Plane FitPlane(const std::vector& points) { 23 | Eigen::MatrixXd A(points.size(), 3); 24 | Eigen::MatrixXd B(points.size(), 1); 25 | 26 | for (size_t i = 0; i < points.size(); i++) { 27 | A(i, 0) = points[i].x(); 28 | A(i, 1) = points[i].y(); 29 | A(i, 2) = 1.0; 30 | B(i) = points[i].z(); 31 | } 32 | 33 | Eigen::MatrixXd result = A.bdcSvd( 34 | Eigen::ComputeThinU | Eigen::ComputeThinV).solve(B); 35 | return Plane{result(0), result(1), result(2)}; 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /base/fit_plane.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace mjmech { 22 | namespace base { 23 | 24 | /// For a plane defined as a*x + b*y + c = z 25 | /// 26 | /// Yes, this only works for planes that are mostly level. 27 | struct Plane { 28 | double a = 0.0; 29 | double b = 0.0; 30 | double c = 0.0; 31 | }; 32 | 33 | Plane FitPlane(const std::vector& points); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /base/format_hex.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/format_hex.h" 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace mjmech { 22 | namespace base { 23 | 24 | std::string FormatHex(std::string_view data) { 25 | std::ostringstream ostr; 26 | for (char c : data) { 27 | ostr << fmt::format("{:02x}", static_cast(static_cast(c))); 28 | } 29 | return ostr.str(); 30 | } 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /base/format_hex.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace mjmech { 21 | namespace base { 22 | 23 | std::string FormatHex(std::string_view); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /base/git_info.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/git_info.h" 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | namespace { 23 | 24 | uint8_t ParseHexNibble(uint8_t c) { 25 | if (c >= '0' && c <= '9') { return c - '0'; } 26 | if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } 27 | if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } 28 | return 0; 29 | } 30 | 31 | uint8_t ParseHexByte(const char* data) { 32 | return (ParseHexNibble(data[0]) << 4) | ParseHexNibble(data[1]); 33 | } 34 | 35 | } 36 | 37 | GitInfo::GitInfo() { 38 | if (std::strlen(kGitHash) != 40) { 39 | dirty = true; 40 | } else { 41 | for (size_t i = 0; i <= 20; i++) { 42 | hash[i] = ParseHexByte(&kGitHash[i * 2]); 43 | } 44 | 45 | dirty = kGitDirty[0] != '0'; 46 | } 47 | } 48 | 49 | char kGitHash[41] __attribute__((weak)) = {}; 50 | char kGitDirty[10] __attribute__((weak)) = {}; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /base/git_info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #include "mjlib/base/visitor.h" 21 | 22 | namespace mjmech { 23 | namespace base { 24 | 25 | struct GitInfo { 26 | GitInfo(); 27 | 28 | std::array hash = {{}}; 29 | bool dirty = false; 30 | 31 | template 32 | void Serialize(Archive* a) { 33 | a->Visit(MJ_NVP(hash)); 34 | a->Visit(MJ_NVP(dirty)); 35 | } 36 | }; 37 | 38 | extern char kGitHash[41]; 39 | extern char kGitDirty[10]; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /base/git_info_linkstamp.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | namespace mjmech { 16 | namespace base { 17 | 18 | char kGitHash[41] = BUILD_SCM_REVISION; 19 | char kGitDirty[10] = BUILD_SCM_STATUS; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /base/interpolate.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | template 21 | T Interpolate(T start, T end, double scale) { 22 | return (end - start) * scale + start; 23 | } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /base/kinematic_relation.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | /// Describes the kinematic relation between two rigid body frames. 21 | struct KinematicRelation { 22 | Sophus::SE3d pose; // Absolute position and orientation 23 | base::Point3D v; // velocity 24 | base::Point3D w; // angular rate 25 | 26 | template 27 | void Serialize(Archive* a) { 28 | a->Visit(MJ_NVP(pose)); 29 | a->Visit(MJ_NVP(v)); 30 | a->Visit(MJ_NVP(w)); 31 | } 32 | }; 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /base/leg_force.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. All rights reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace mjmech { 22 | namespace base { 23 | 24 | /// Given the leg X/Y positions in the M frame, return a ratio of 25 | /// force to apply which minimizes the amount of angular acceleration 26 | /// incurred. 27 | std::vector OptimizeLegForce(const std::vector&); 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /base/module_main.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2014-2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | def module_main(name, prefix, cname, deps): 18 | native.genrule( 19 | name = "{}_main".format(name), 20 | outs = ["{}_main.cc".format(name)], 21 | cmd = """cat > $(location {name}_main.cc) << EOF 22 | #include "{prefix}/{name}.h" 23 | 24 | #include "base/module_main.h" 25 | 26 | extern "C" {{ 27 | int main(int argc, char**argv) {{ 28 | return mjmech::base::main<{cname}>(argc, argv); 29 | }} 30 | }} 31 | EOF 32 | """.format(name=name, cname=cname, prefix=prefix), 33 | ) 34 | 35 | native.cc_binary( 36 | name = "{}".format(name), 37 | srcs = [ 38 | "{}_main.cc".format(name), 39 | name + ".h", 40 | ], 41 | deps = deps + [ 42 | "@boost//:filesystem", 43 | "@boost//:date_time", 44 | "@org_llvm_libcxx//:libcxx", 45 | ], 46 | ) 47 | -------------------------------------------------------------------------------- /base/named_type.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | template 23 | class NamedType 24 | { 25 | public: 26 | explicit NamedType(T const& value) : value_(value) {} 27 | explicit NamedType(T&& value) : value_(std::move(value)) {} 28 | T& get() { return value_; } 29 | T const& get() const {return value_; } 30 | private: 31 | T value_; 32 | }; 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /base/point3d.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "mjlib/base/eigen.h" 22 | 23 | #include "base/common.h" 24 | 25 | namespace mjmech { 26 | namespace base { 27 | 28 | using Point3D = Eigen::Vector3d; 29 | 30 | inline double Point3DHeadingDeg(const Point3D& p) { 31 | return Degrees(WrapNegPiToPi(0.5 * M_PI - std::atan2(p.y(), p.x()))); 32 | } 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /base/quaternion.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2015 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "quaternion.h" 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | std::string Quaternion::str() const { 23 | return fmt::format("%f %f %f %f", w_, x_, y_, z_); 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /base/reservoir_sampler.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | /// Recursively estimate a sample of a large data set. 23 | /// 24 | /// The algorithm used here is "R" from "Random Sampling with a 25 | /// Reservoir", J. Vitter. 26 | template 27 | class ReservoirSampler { 28 | public: 29 | ReservoirSampler(std::size_t size) 30 | : size_(size) {} 31 | 32 | using Container = std::vector; 33 | using iterator = Container::iterator; 34 | using const_iterator = Container::const_iterator; 35 | 36 | void Add(T value) { 37 | count_++; 38 | 39 | if (samples_.size() < size_) { 40 | samples.push_back(std::move(value)); 41 | } else { 42 | const std::size_t M = static_cast( 43 | std::uniform_int<>(0, count_ - 1)(rng_)); 44 | if (M < size_) { 45 | samples_[M] = value; 46 | } 47 | } 48 | } 49 | 50 | iterator begin() { return samples_.begin(); } 51 | iterator end() { return samples_.end(); } 52 | 53 | const_iterator begin() const { return samples_.begin(); } 54 | const_iterator end() const { return samples_.end(); } 55 | 56 | private: 57 | Container samples_; 58 | std::size_t size_; 59 | 60 | std::mt19937 rng_; 61 | std::size_t count_ = 0; 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /base/runfiles.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include "tools/cpp/runfiles/runfiles.h" 23 | 24 | #include "mjlib/base/system_error.h" 25 | 26 | namespace mjmech { 27 | namespace base { 28 | class Runfiles { 29 | public: 30 | Runfiles() { 31 | std::string error; 32 | runfiles_.reset( 33 | bazel::tools::cpp::runfiles::Runfiles::Create( 34 | boost::filesystem::canonical("/proc/self/exe").native(), &error)); 35 | if (!runfiles_) { 36 | throw mjlib::base::system_error::einval("Error creating runfiles: " + error); 37 | } 38 | } 39 | 40 | std::string Rlocation(std::string_view path) const { 41 | return runfiles_->Rlocation("com_github_mjbots_mech/" + std::string(path)); 42 | } 43 | 44 | private: 45 | std::unique_ptr runfiles_; 46 | }; 47 | 48 | class TestRunfiles { 49 | public: 50 | TestRunfiles() { 51 | std::string error; 52 | runfiles_.reset(bazel::tools::cpp::runfiles::Runfiles::CreateForTest(&error)); 53 | if (!runfiles_) { 54 | throw mjlib::base::system_error::einval("Error creating runfiles: " + error); 55 | } 56 | } 57 | 58 | std::string Rlocation(std::string_view path) const { 59 | return runfiles_->Rlocation("com_github_mjbots_mech/" + std::string(path)); 60 | } 61 | 62 | private: 63 | std::unique_ptr runfiles_; 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /base/saturate.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | template 21 | T Saturate(InType value) { 22 | if (value >= static_cast(std::numeric_limits::max())) { 23 | return std::numeric_limits::max(); 24 | } 25 | if (value <= static_cast(std::numeric_limits::min())) { 26 | return std::numeric_limits::min(); 27 | } 28 | return static_cast(value); 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /base/stringify.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2018 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace mjmech { 21 | namespace base { 22 | 23 | template 24 | std::string Stringify(const T& rhs) { 25 | std::ostringstream ostr; 26 | ostr << rhs; 27 | return ostr.str(); 28 | } 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /base/system_fd.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/system_fd.h" 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace base { 21 | 22 | SystemFd::~SystemFd() { 23 | if (fd_ >= 0) ::close(fd_); 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /base/system_fd.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace base { 19 | 20 | /// Manages ownership of a system file descriptor. 21 | class SystemFd { 22 | public: 23 | SystemFd() : fd_(-1) {} 24 | SystemFd(int fd) : fd_(fd) {} 25 | 26 | SystemFd(SystemFd&& rhs) { 27 | fd_ = rhs.fd_; 28 | rhs.fd_ = -1; 29 | } 30 | 31 | SystemFd& operator=(SystemFd&& rhs) { 32 | fd_ = rhs.fd_; 33 | rhs.fd_ = -1; 34 | return *this; 35 | } 36 | 37 | ~SystemFd(); 38 | 39 | SystemFd(const SystemFd&) = delete; 40 | SystemFd& operator=(const SystemFd&) = delete; 41 | 42 | operator int() { return fd_; } 43 | 44 | private: 45 | int fd_ = -1; 46 | }; 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /base/system_mmap.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "mjlib/base/system_error.h" 20 | 21 | namespace mjmech { 22 | namespace base { 23 | 24 | /// Manages ownership of an mmap'ed region of a given file descriptor. 25 | class SystemMmap { 26 | public: 27 | SystemMmap() {} 28 | 29 | SystemMmap(int fd, size_t size, uint64_t offset) { 30 | ptr_ = ::mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); 31 | size_ = size; 32 | mjlib::base::system_error::throw_if(ptr_ == MAP_FAILED); 33 | } 34 | 35 | ~SystemMmap() { 36 | if (ptr_ != MAP_FAILED) { 37 | mjlib::base::system_error::throw_if(::munmap(ptr_, size_) < 0); 38 | } 39 | } 40 | 41 | SystemMmap(SystemMmap&& rhs) { 42 | std::swap(ptr_, rhs.ptr_); 43 | std::swap(size_, rhs.size_); 44 | } 45 | 46 | SystemMmap& operator=(SystemMmap&& rhs) { 47 | std::swap(ptr_, rhs.ptr_); 48 | std::swap(size_, rhs.size_); 49 | return *this; 50 | } 51 | 52 | SystemMmap(const SystemMmap&) = delete; 53 | SystemMmap& operator=(const SystemMmap&) = delete; 54 | 55 | void* ptr() { return ptr_; } 56 | 57 | // Since this is intended to be whatever, we just allow it to be 58 | // converted to any old pointer at will without extra hoops. 59 | template 60 | operator T*() { return ptr_; } 61 | 62 | template 63 | operator const T*() const { return ptr_; } 64 | 65 | private: 66 | void* ptr_ = MAP_FAILED; 67 | size_t size_ = 0; 68 | }; 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /base/telemetry_remote_debug_registrar.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "telemetry_remote_debug_server.h" 20 | 21 | namespace mjmech { 22 | namespace base { 23 | class TelemetryRemoteDebugServer; 24 | 25 | /// A registrar which supports emitting data over the network in a 26 | /// human readable format for online diagnostics and debugging. 27 | /// 28 | /// The implementation of this class is largely a pass-through, since 29 | /// tuple's can't hold noncopyable things, we delegate to a shared_ptr 30 | /// to something that is non-copyable. 31 | class TelemetryRemoteDebugRegistrar { 32 | public: 33 | TelemetryRemoteDebugRegistrar(TelemetryRemoteDebugServer* server) 34 | : server_(server) {} 35 | 36 | template 37 | void Register(const std::string& name, 38 | boost::signals2::signal* signal) { 39 | server_->Register(name, signal); 40 | } 41 | 42 | TelemetryRemoteDebugServer* const server_; 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /base/test/aspect_ratio_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/aspect_ratio.h" 16 | 17 | #include 18 | 19 | using mjmech::base::MaintainAspectRatio; 20 | 21 | BOOST_AUTO_TEST_CASE(AspectRatio) { 22 | { 23 | auto result = MaintainAspectRatio({4, 4}, {4, 4}); 24 | BOOST_TEST(result.min() == Eigen::Vector2i(0, 0)); 25 | BOOST_TEST(result.max() == Eigen::Vector2i(4, 4)); 26 | BOOST_TEST(result.sizes() == Eigen::Vector2i(4, 4)); 27 | } 28 | 29 | { 30 | auto result = MaintainAspectRatio({4, 4}, {10, 4}); 31 | BOOST_TEST(result.min() == Eigen::Vector2i(3, 0)); 32 | BOOST_TEST(result.sizes() == Eigen::Vector2i(4, 4)); 33 | } 34 | 35 | { 36 | auto result = MaintainAspectRatio({4, 4}, {20, 8}); 37 | BOOST_TEST(result.min() == Eigen::Vector2i(6, 0)); 38 | BOOST_TEST(result.sizes() == Eigen::Vector2i(8, 8)); 39 | } 40 | 41 | { 42 | auto result = MaintainAspectRatio({4, 4}, {8, 20}); 43 | BOOST_TEST(result.min() == Eigen::Vector2i(0, 6)); 44 | BOOST_TEST(result.sizes() == Eigen::Vector2i(8, 8)); 45 | } 46 | 47 | { 48 | auto result = MaintainAspectRatio({5, 4}, {10, 10}); 49 | BOOST_TEST(result.min() == Eigen::Vector2i(0, 1)); 50 | BOOST_TEST(result.sizes() == Eigen::Vector2i(10, 8)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /base/test/fit_plane_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/fit_plane.h" 16 | 17 | #include 18 | 19 | using mjmech::base::FitPlane; 20 | 21 | BOOST_AUTO_TEST_CASE(BasicFitPlane, * boost::unit_test::tolerance(1e-4)) { 22 | { 23 | std::vector points = { 24 | { -2, -2, -1 }, 25 | { -2, 2, -1 }, 26 | { 2, -2, 1 }, 27 | { 2, 2, 1 }, 28 | }; 29 | 30 | const auto result = FitPlane(points); 31 | BOOST_TEST(std::abs(result.c - 0.0) < 0.001); 32 | BOOST_TEST(result.a == 0.5); 33 | BOOST_TEST(result.b == 0.0); 34 | } 35 | 36 | { 37 | std::vector points = { 38 | { -2, -2, 0 }, 39 | { -2, 2, 2 }, 40 | { 2, -2, 0 }, 41 | { 2, 2, 2 }, 42 | }; 43 | 44 | const auto result = FitPlane(points); 45 | BOOST_TEST(result.c == 1.0); 46 | BOOST_TEST(result.a == 0.0); 47 | BOOST_TEST(result.b == 0.5); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /base/test/named_type_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/named_type.h" 16 | 17 | #include 18 | 19 | namespace { 20 | using SimpleType = mjmech::base::NamedType; 21 | 22 | int SimpleTransformer(SimpleType v) { 23 | return v.get(); 24 | } 25 | } 26 | 27 | BOOST_AUTO_TEST_CASE(NamedTypeTest) { 28 | BOOST_TEST(SimpleTransformer(SimpleType(3)) == 3); 29 | } 30 | -------------------------------------------------------------------------------- /base/test/se3d_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "sophus/se3.hpp" 16 | 17 | #include 18 | 19 | BOOST_AUTO_TEST_CASE(DoIUnderstandFrames) { 20 | // I think that this means, that point (0, 0, 0) in frame B, should 21 | // be the same as point (1, 0, 0) in frame A. 22 | Sophus::SE3d pose_AB(Sophus::SO3d(), Eigen::Vector3d(1.0, 0, 0)); 23 | 24 | const Eigen::Vector3d p_B = Eigen::Vector3d(0, 0, 0); 25 | const Eigen::Vector3d p_A = pose_AB * p_B; 26 | BOOST_TEST(p_A.x() == 1.0); 27 | } 28 | -------------------------------------------------------------------------------- /base/test/sophus_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/sophus.h" 16 | 17 | #include 18 | 19 | #include "mjlib/base/json5_write_archive.h" 20 | #include "mjlib/base/json5_read_archive.h" 21 | 22 | BOOST_AUTO_TEST_CASE(BasicSophusTest) { 23 | Sophus::SE3d zero; 24 | const auto actual = mjlib::base::Json5WriteArchive::Write(zero); 25 | const std::string expected = R"XXX({ 26 | "so3" : { 27 | "x" : 0, 28 | "y" : 0, 29 | "z" : 0, 30 | "w" : 1 31 | }, 32 | "translation" : [ 33 | 0, 34 | 0, 35 | 0 36 | ] 37 | })XXX"; 38 | BOOST_TEST(actual == expected); 39 | } 40 | -------------------------------------------------------------------------------- /base/test/telemetry_log_registrar_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/telemetry_log_registrar.h" 16 | 17 | #include 18 | 19 | #include "mjlib/base/visitor.h" 20 | 21 | #include "base/telemetry_registry.h" 22 | 23 | namespace { 24 | struct TestData { 25 | uint16_t value = 0; 26 | 27 | template 28 | void Serialize(Archive* a) { 29 | a->Visit(MJ_NVP(value)); 30 | } 31 | }; 32 | 33 | using namespace mjmech::base; 34 | } 35 | 36 | BOOST_AUTO_TEST_CASE(TelemetryLogRegistrarTest) { 37 | // TelemetryLog log; 38 | // TelemetryRegistry registry(&log); 39 | // auto callable = registry.Register("test1"); 40 | 41 | // // This should have resulted in a schema being written. 42 | 43 | } 44 | -------------------------------------------------------------------------------- /base/test/telemetry_registry_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/telemetry_registry.h" 16 | 17 | #include 18 | 19 | #include "mjlib/base/visitor.h" 20 | 21 | using namespace mjmech::base; 22 | 23 | namespace { 24 | struct TestData { 25 | int8_t foo = 0; 26 | 27 | template 28 | void Serialize(Archive* a) { 29 | a->Visit(MJ_NVP(foo)); 30 | } 31 | }; 32 | } 33 | 34 | BOOST_AUTO_TEST_CASE(TelemetryBasicTest) { 35 | } 36 | -------------------------------------------------------------------------------- /base/test/test_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #define BOOST_TEST_MODULE mech 16 | #include 17 | -------------------------------------------------------------------------------- /base/timestamped_log.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "base/timestamped_log.h" 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | 23 | namespace mjmech { 24 | namespace base { 25 | 26 | void OpenMaybeTimestampedLog(mjlib::telemetry::FileWriter* writer, 27 | std::string_view filename, 28 | TimestampMode mode) { 29 | // Make sure that the log file has a date and timestamp somewhere 30 | // in the name. 31 | namespace fs = boost::filesystem; 32 | fs::path log_file_path{std::string(filename)}; 33 | std::string extension = log_file_path.extension().native(); 34 | 35 | const auto now = boost::posix_time::microsec_clock::universal_time(); 36 | std::string datestamp = 37 | fmt::format("{}-{:02d}{:02d}{:02d}", 38 | to_iso_string(now.date()), 39 | now.time_of_day().hours(), 40 | now.time_of_day().minutes(), 41 | now.time_of_day().seconds()); 42 | 43 | const std::string stem = log_file_path.stem().native(); 44 | 45 | fs::path stamped_path = log_file_path.parent_path() / 46 | fmt::format("{}-{}{}", stem, datestamp, extension); 47 | 48 | switch (mode) { 49 | case kShort: { 50 | writer->Open(filename); 51 | break; 52 | } 53 | case kTimestamped: { 54 | writer->Open(stamped_path.native()); 55 | break; 56 | } 57 | } 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /base/timestamped_log.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "mjlib/telemetry/file_writer.h" 20 | 21 | namespace mjmech { 22 | namespace base { 23 | 24 | enum TimestampMode { 25 | kTimestamped, 26 | kShort, 27 | }; 28 | 29 | void OpenMaybeTimestampedLog(mjlib::telemetry::FileWriter* writer, 30 | std::string_view filename, 31 | TimestampMode); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /base/tokenizer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | /// A simple tokenizer. It can split on multiple delimiters, and 20 | /// reports multiple consecutive delimiters as empty tokens. 21 | class Tokenizer { 22 | public: 23 | Tokenizer(const std::string& source, const char* delimiters) 24 | : source_(source), 25 | delimiters_(delimiters), 26 | position_(source_.cbegin()) {} 27 | 28 | std::string next() { 29 | if (position_ == source_.end()) { return std::string(); } 30 | const auto start = position_; 31 | auto next = position_; 32 | bool found = false; 33 | for (; next != source_.end(); ++next) { 34 | if (std::strchr(delimiters_, *next) != nullptr) { 35 | position_ = next; 36 | ++position_; 37 | found = true; 38 | break; 39 | } 40 | } 41 | if (!found) { position_ = next; } 42 | return std::string(start, next); 43 | } 44 | 45 | std::string remaining() const { 46 | return std::string(position_, source_.end()); 47 | } 48 | 49 | private: 50 | const std::string source_; 51 | const char* const delimiters_; 52 | std::string::const_iterator position_; 53 | }; 54 | -------------------------------------------------------------------------------- /configs/BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | filegroup( 20 | name = "configs", 21 | srcs = [ 22 | "quadruped.ini", 23 | "quadruped_a2.ini", 24 | "quada0.cfg", 25 | "quada1.cfg", 26 | "quada2.cfg", 27 | ], 28 | ) 29 | -------------------------------------------------------------------------------- /configs/gimbal_config.txt: -------------------------------------------------------------------------------- 1 | pimu.address 208 2 | pimu.rate_hz 400 3 | pimu.gyro_max_dps 1000 4 | pimu.accel_max_g 4 5 | pimu.offset_deg.yaw 90.000000 6 | pimu.offset_deg.pitch 0.000000 7 | pimu.offset_deg.roll 0.000000 8 | yawenc.i2c_address 64 9 | yawblenc.sign -1 10 | yawblenc.offset_deg -108.000000 11 | yawblenc.phase_center_deg -3.000000 12 | yawblenc.poles 7 13 | pitchenc.i2c_address 128 14 | pitchblenc.sign 1 15 | pitchblenc.offset_deg 0.000000 16 | pitchblenc.phase_center_deg -6.500000 17 | pitchblenc.poles 7 18 | mahony.bias_period_s 1.000000 19 | mahony.kp 2.000000 20 | mahony.ki 0.100000 21 | gimbal.initialization_period_s 1.000000 22 | gimbal.watchdog_period_s 0.100000 23 | gimbal.boost 1 24 | gimbal.pitch.motor 2 25 | gimbal.pitch.power 1.000000 26 | gimbal.pitch.pid.kp 0.100000 27 | gimbal.pitch.pid.ki 0.050000 28 | gimbal.pitch.pid.kd 0.005000 29 | gimbal.pitch.pid.iratelimit 2.000000 30 | gimbal.pitch.pid.ilimit 0.050000 31 | gimbal.pitch.pid.kpkd_limit 0.250000 32 | gimbal.pitch.pid.sign -1 33 | gimbal.pitch.max_slew_dps 100.000000 34 | gimbal.pitch.control_derate 0.200000 35 | gimbal.pitch.mode 1 36 | gimbal.yaw.motor 1 37 | gimbal.yaw.power 1.000000 38 | gimbal.yaw.pid.kp 0.100000 39 | gimbal.yaw.pid.ki 0.050000 40 | gimbal.yaw.pid.kd 0.005000 41 | gimbal.yaw.pid.iratelimit 2.000000 42 | gimbal.yaw.pid.ilimit 0.050000 43 | gimbal.yaw.pid.kpkd_limit 0.250000 44 | gimbal.yaw.pid.sign -1 45 | gimbal.yaw.max_slew_dps 100.000000 46 | gimbal.yaw.control_derate 0.200000 47 | gimbal.yaw.mode 1 48 | gimbal.pitch_limit.min_deg -15.000000 49 | gimbal.pitch_limit.max_deg 30.000000 50 | gimbal.abs_yaw_limit.min_deg -130.000000 51 | gimbal.abs_yaw_limit.max_deg 130.000000 52 | -------------------------------------------------------------------------------- /configs/lizard_gimbal_config.txt: -------------------------------------------------------------------------------- 1 | pimu.address 208 2 | pimu.rate_hz 400 3 | pimu.gyro_max_dps 1000 4 | pimu.accel_max_g 4 5 | pimu.offset_deg.yaw 90.000000 6 | pimu.offset_deg.pitch 0.000000 7 | pimu.offset_deg.roll 0.000000 8 | yawenc.i2c_address 64 9 | yawblenc.sign -1 10 | yawblenc.offset_deg 55.000000 11 | yawblenc.phase_center_deg -20.799999 12 | yawblenc.poles 7 13 | pitchenc.i2c_address 128 14 | pitchblenc.sign 1 15 | pitchblenc.offset_deg 165.000000 16 | pitchblenc.phase_center_deg 1.500000 17 | pitchblenc.poles 7 18 | mahony.bias_period_s 1.000000 19 | mahony.kp 2.000000 20 | mahony.ki 0.100000 21 | gimbal.initialization_period_s 1.000000 22 | gimbal.watchdog_period_s 0.100000 23 | gimbal.boost 1 24 | gimbal.pitch.motor 2 25 | gimbal.pitch.power 1.000000 26 | gimbal.pitch.pid.kp 0.100000 27 | gimbal.pitch.pid.ki 0.050000 28 | gimbal.pitch.pid.kd 0.005000 29 | gimbal.pitch.pid.iratelimit 2.000000 30 | gimbal.pitch.pid.ilimit 0.050000 31 | gimbal.pitch.pid.kpkd_limit 0.250000 32 | gimbal.pitch.pid.sign -1 33 | gimbal.pitch.max_slew_dps 100.000000 34 | gimbal.pitch.control_derate 0.200000 35 | gimbal.pitch.mode 1 36 | gimbal.yaw.motor 1 37 | gimbal.yaw.power 1.000000 38 | gimbal.yaw.pid.kp 0.100000 39 | gimbal.yaw.pid.ki 0.050000 40 | gimbal.yaw.pid.kd 0.005000 41 | gimbal.yaw.pid.iratelimit 2.000000 42 | gimbal.yaw.pid.ilimit 0.050000 43 | gimbal.yaw.pid.kpkd_limit 0.250000 44 | gimbal.yaw.pid.sign -1 45 | gimbal.yaw.max_slew_dps 100.000000 46 | gimbal.yaw.control_derate 0.200000 47 | gimbal.yaw.mode 1 48 | gimbal.pitch_limit.min_deg -15.000000 49 | gimbal.pitch_limit.max_deg 30.000000 50 | gimbal.abs_yaw_limit.min_deg -130.000000 51 | gimbal.abs_yaw_limit.max_deg 130.000000 52 | -------------------------------------------------------------------------------- /configs/mech_warfare.cfg: -------------------------------------------------------------------------------- 1 | { 2 | "legs" : [ 3 | { 4 | "leg" : 0, 5 | "ik" : { 6 | "invert" : false, 7 | }, 8 | }, 9 | { 10 | "leg" : 1, 11 | "ik" : { 12 | "invert" : false, 13 | }, 14 | }, 15 | ], 16 | "mass_kg" : 10.0, 17 | } 18 | -------------------------------------------------------------------------------- /configs/moteus_gimbal_config.txt: -------------------------------------------------------------------------------- 1 | conf set motor.unwrapped_position_scale 1.000000 2 | conf set servo.i_gain 20.000000 3 | conf set servo.v_scale_V 0.008840 4 | conf set servo.pwm_min 0.009000 5 | conf set servo.pwm_min_blend 0.010000 6 | conf set servo.max_voltage 37.000000 7 | conf set servo.derate_temperature 50.000000 8 | conf set servo.fault_temperature 75.000000 9 | conf set servo.feedforward_scale 1.000000 10 | conf set servo.velocity_threshold 0.000000 11 | conf set servo.position_derate 0.020000 12 | conf set servo.adc_cur_cycles 2 13 | conf set servo.adc_aux_cycles 47 14 | conf set servo.pid_dq.kp 0.000000 15 | conf set servo.pid_dq.ki 10.000000 16 | conf set servo.pid_dq.kd 0.000000 17 | conf set servo.pid_dq.iratelimit -1.000000 18 | conf set servo.pid_dq.ilimit 20.000000 19 | conf set servo.pid_dq.kpkd_limit -1.000000 20 | conf set servo.pid_dq.max_desired_rate 30000.000000 21 | conf set servo.pid_dq.sign -1 22 | conf set servo.pid_position.kp 2.000000 23 | conf set servo.pid_position.ki 100.000000 24 | conf set servo.pid_position.kd 0.005000 25 | conf set servo.pid_position.iratelimit -1.000000 26 | conf set servo.pid_position.ilimit 0.000000 27 | conf set servo.pid_position.kpkd_limit -1.000000 28 | conf set servo.pid_position.max_desired_rate 0.000000 29 | conf set servo.pid_position.sign -1 30 | conf set servo.timeout_max_torque_Nm 0.050000 31 | conf set servo.flux_brake_min_voltage 34.500000 32 | conf set servo.flux_brake_resistance_ohm 0.100000 33 | conf set servo.max_current_A 4.000000 34 | conf set servo.velocity_filter_length 256 35 | conf set servopos.position_min -0.200000 36 | conf set servopos.position_max 0.200000 37 | conf write 38 | -------------------------------------------------------------------------------- /configs/quadruped.ini: -------------------------------------------------------------------------------- 1 | # CPUS 1, 2, and 3 are set up as isolcpu's, leaving just 0 for linux 2 | rt.cpu_affinity=2 3 | pi3hat.cpu_affinity=3 4 | 5 | [quadruped_control] 6 | 7 | config=configs/quada1.cfg 8 | 9 | [multiplex_client] 10 | -------------------------------------------------------------------------------- /configs/quadruped_a2.ini: -------------------------------------------------------------------------------- 1 | # CPUS 1, 2, and 3 are set up as isolcpu's, leaving just 0 for linux 2 | rt.cpu_affinity=2 3 | pi3hat.cpu_affinity=3 4 | 5 | [quadruped_control] 6 | 7 | config=configs/quada2.cfg 8 | 9 | [pi3hat] 10 | 11 | mounting.yaw_deg = 90 12 | mounting.pitch_deg = 0 13 | mounting.roll_deg = 180 14 | 15 | [multiplex_client] 16 | -------------------------------------------------------------------------------- /docs/diagrams/1d_swing.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/docs/diagrams/1d_swing.blend -------------------------------------------------------------------------------- /docs/diagrams/1d_swing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/docs/diagrams/1d_swing.png -------------------------------------------------------------------------------- /docs/diagrams/as5047_noise_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | import matplotlib 19 | import matplotlib.pyplot as plt 20 | import sys 21 | 22 | data = [[float(y) for y in line.strip().split(',')] 23 | for line in (open(sys.argv[1]).readlines()[1:]) 24 | if line.strip() != ''] 25 | 26 | ax = plt.subplot() 27 | ax.plot([1.0 / x[0] for x in data], [x[1]/4. for x in data]) 28 | ax.set_xlim(40000, 10) 29 | ax.set_xscale("log") 30 | ax.set_xlabel("Frequency Hz") 31 | ax.set_ylabel("LSB") 32 | ax.set_title("AS5047U Position Noise vs Frequency") 33 | 34 | plt.show() 35 | -------------------------------------------------------------------------------- /docs/diagrams/magnetic_saturation.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/docs/diagrams/magnetic_saturation.odg -------------------------------------------------------------------------------- /docs/diagrams/support_line.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/docs/diagrams/support_line.blend -------------------------------------------------------------------------------- /docs/diagrams/support_line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/docs/diagrams/support_line.png -------------------------------------------------------------------------------- /docs/diagrams/torque_compensation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import matplotlib 4 | import matplotlib.pyplot as plt 5 | 6 | 7 | DATA = [ 8 | (1.012, 1.033, 3.166), 9 | (2.496, 2.619, 7.831), 10 | (3.844, 3.698, 12.144), 11 | (4.924, 4.976, 15.53), 12 | (5.733, 5.506, 17.985), 13 | (6.812, 6.452, 20.556), 14 | (7.757, 7.425, 24.214), 15 | (8.836, 8.592, 27.998), 16 | (9.375, 9.125, 30.32), 17 | (10.455, 9.835, 35.043), 18 | (11.669, 11.417, 41.542), 19 | (12.883, 12.956, 48.286), 20 | (13.693, 13.656, 53.627), 21 | (15.311, 15.407, 65.86), 22 | (15.986, 16.071, 71.987), 23 | (16.93, 16.49, 81.1), 24 | (17.2, 16.89, 83.73), 25 | ] 26 | 27 | 28 | ax1 = plt.subplot() 29 | 30 | ax1.plot([x[0] for x in DATA], [x[1] for x in DATA], color='r', 31 | label="Measured Torque") 32 | ax1.plot([x[0] for x in DATA], [x[0] for x in DATA], color='b', 33 | linewidth=1, linestyle='dashed', 34 | label="Ideal Torque") 35 | ax1.set_ylabel("Nm") 36 | ax1.set_xlabel("Command Torque Nm") 37 | ax1.set_ylim(0, 26) 38 | ax1.grid() 39 | ax1.legend(loc='lower right') 40 | 41 | ax2 = ax1.twinx() 42 | ax2.plot([x[0] for x in DATA], [x[2] for x in DATA], color='g', 43 | label="Phase Current") 44 | ax2.set_ylabel("A") 45 | ax2.legend(loc='upper right') 46 | 47 | 48 | plt.show() 49 | -------------------------------------------------------------------------------- /docs/numbered-targets.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/docs/numbered-targets.odp -------------------------------------------------------------------------------- /ffmpeg/BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | cc_library( 20 | name = "ffmpeg", 21 | hdrs = [ 22 | "codec.h", 23 | "dictionary.h", 24 | "error.h", 25 | "file.h", 26 | "ffmpeg.h", 27 | "frame.h", 28 | "input_format.h", 29 | "packet.h", 30 | "ref_base.h", 31 | "stream.h", 32 | "swscale.h" 33 | ], 34 | deps = [ 35 | "@com_github_mjbots_mjlib//mjlib/base:fail", 36 | "@com_github_mjbots_mjlib//mjlib/base:system_error", 37 | "@eigen", 38 | "@ffmpeg", 39 | "@fmt", 40 | ], 41 | ) 42 | 43 | cc_test( 44 | name = "ffmpeg_test", 45 | srcs = ["test/" + x for x in [ 46 | "codec_test.cc", 47 | "file_test.cc", 48 | "frame_test.cc", 49 | "packet_test.cc", 50 | "stream_test.cc", 51 | "swscale_test.cc", 52 | "test_main.cc", 53 | ]], 54 | deps = [ 55 | ":ffmpeg", 56 | "//base", 57 | "@bazel_tools//tools/cpp/runfiles", 58 | "@boost//:test", 59 | "@org_llvm_libcxx//:libcxx", 60 | ], 61 | data = [ 62 | "test/data/sample_log.mp4", 63 | ], 64 | ) 65 | -------------------------------------------------------------------------------- /ffmpeg/codec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | extern "C" { 18 | #include 19 | } 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "ffmpeg/error.h" 26 | #include "ffmpeg/frame.h" 27 | #include "ffmpeg/packet.h" 28 | #include "ffmpeg/stream.h" 29 | 30 | namespace mjmech { 31 | namespace ffmpeg { 32 | 33 | class Codec { 34 | public: 35 | Codec(const Stream& stream) { 36 | const auto av_codec = stream.av_codec(); 37 | const auto p = stream.codec_parameters(); 38 | 39 | context_ = avcodec_alloc_context3(av_codec); 40 | 41 | avcodec_parameters_to_context(context_, p); 42 | 43 | ErrorCheck(avcodec_open2(context_, av_codec, nullptr)); 44 | } 45 | 46 | ~Codec() { 47 | avcodec_free_context(&context_); 48 | } 49 | 50 | void SendPacket(const Packet::Ref& packet) { 51 | ErrorCheck(avcodec_send_packet(context_, &*packet)); 52 | } 53 | 54 | std::optional GetFrame(Frame* frame) { 55 | const int ret = avcodec_receive_frame(context_, frame->get()); 56 | if (ret == AVERROR(EAGAIN)) { return {}; } 57 | ErrorCheck(ret); 58 | return Frame::Ref::MakeInternal(frame->get()); 59 | } 60 | 61 | AVPixelFormat pix_fmt() const { 62 | return context_->pix_fmt; 63 | } 64 | 65 | Eigen::Vector2i size() const { 66 | return Eigen::Vector2i(context_->width, context_->height); 67 | } 68 | 69 | private: 70 | AVCodecContext* context_; 71 | }; 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ffmpeg/dictionary.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace mjmech { 21 | namespace ffmpeg { 22 | 23 | using Dictionary = std::map; 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ffmpeg/error.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | extern "C" { 18 | #include 19 | } 20 | 21 | #include 22 | 23 | #include "mjlib/base/system_error.h" 24 | 25 | namespace mjmech { 26 | namespace ffmpeg { 27 | 28 | inline int ErrorCheck(int value) { 29 | if (value < 0) { 30 | throw mjlib::base::system_error::einval( 31 | fmt::format("ffmpeg error: {}", av_err2str(value))); 32 | } 33 | return value; 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ffmpeg/ffmpeg.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | extern "C" { 18 | #include 19 | #include 20 | #include 21 | } 22 | 23 | namespace mjmech { 24 | namespace ffmpeg { 25 | 26 | class Ffmpeg { 27 | public: 28 | static void Register() { 29 | static bool is_registered = false; 30 | if (is_registered) { return; } 31 | is_registered = true; 32 | 33 | avdevice_register_all(); 34 | avcodec_register_all(); 35 | av_register_all(); 36 | } 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ffmpeg/input_format.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace ffmpeg { 19 | 20 | class InputFormat { 21 | public: 22 | InputFormat(std::string_view name) { 23 | input_format_ = av_find_input_format(name.data()); 24 | } 25 | 26 | AVInputFormat* get() const { return input_format_; } 27 | 28 | private: 29 | AVInputFormat* input_format_ = nullptr; 30 | }; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ffmpeg/packet.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | extern "C" { 18 | #include 19 | } 20 | 21 | #include 22 | 23 | #include "ffmpeg/ref_base.h" 24 | 25 | namespace mjmech { 26 | namespace ffmpeg { 27 | 28 | class Packet { 29 | public: 30 | Packet() { 31 | av_init_packet(&packet_); 32 | } 33 | 34 | Packet(const Packet&) = delete; 35 | Packet& operator=(const Packet&) = delete; 36 | 37 | class Ref : public RefBase { 38 | public: 39 | using RefBase::RefBase; 40 | 41 | void reset() { 42 | if (value_) { 43 | av_packet_unref(value_); 44 | } 45 | value_ = nullptr; 46 | } 47 | }; 48 | 49 | AVPacket* get() { return &packet_; } 50 | 51 | private: 52 | AVPacket packet_; 53 | }; 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ffmpeg/ref_base.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace ffmpeg { 19 | 20 | template 21 | class RefBase { 22 | public: 23 | RefBase() {} 24 | RefBase(RefBase&& rhs) : value_(rhs.value_) { 25 | rhs.value_ = nullptr; 26 | } 27 | 28 | RefBase& operator=(RefBase&& rhs) { 29 | static_cast(this)->reset(); 30 | std::swap(value_, rhs.value_); 31 | return *this; 32 | } 33 | 34 | ~RefBase() { 35 | static_cast(this)->reset(); 36 | } 37 | 38 | T& operator*() { return *value_; } 39 | const T& operator*() const { return *value_; } 40 | T* operator->() { return value_; } 41 | const T* operator->() const { return value_; } 42 | 43 | static Derived MakeInternal(T* value) { 44 | return Derived(value); 45 | } 46 | 47 | protected: 48 | RefBase(T* value) : value_(value) {} 49 | 50 | T* value_ = nullptr; 51 | }; 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ffmpeg/stream.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | extern "C" { 18 | #include 19 | } 20 | 21 | namespace mjmech { 22 | namespace ffmpeg { 23 | 24 | class Stream { 25 | public: 26 | static Stream MakeInternal(AVStream* stream, AVCodec* codec) { 27 | return Stream(stream, codec); 28 | } 29 | 30 | const AVCodecParameters* codec_parameters() const { return stream_->codecpar; } 31 | const AVStream* av_stream() const { return stream_; } 32 | const AVCodec* av_codec() const { return codec_; } 33 | 34 | private: 35 | Stream(AVStream* stream, 36 | AVCodec* codec) 37 | : stream_(stream), 38 | codec_(codec) {} 39 | 40 | AVStream* stream_; 41 | AVCodec* codec_; 42 | }; 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ffmpeg/test/codec_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ffmpeg/codec.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /ffmpeg/test/data/sample_log.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/ffmpeg/test/data/sample_log.mp4 -------------------------------------------------------------------------------- /ffmpeg/test/file_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ffmpeg/file.h" 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "base/runfiles.h" 22 | #include "ffmpeg/codec.h" 23 | #include "ffmpeg/swscale.h" 24 | 25 | using namespace mjmech::ffmpeg; 26 | using bazel::tools::cpp::runfiles::Runfiles; 27 | 28 | BOOST_AUTO_TEST_CASE(FileTest) { 29 | mjmech::base::TestRunfiles runfiles; 30 | 31 | const std::string path = "ffmpeg/test/data/sample_log.mp4"; 32 | File dut{runfiles.Rlocation(path)}; 33 | 34 | auto stream = dut.FindBestStream(File::kVideo); 35 | BOOST_TEST(stream.codec_parameters()->width == 1920); 36 | 37 | auto codec = Codec(stream); 38 | std::optional swscale; 39 | 40 | Packet packet; 41 | Frame frame; 42 | Frame dest_frame; 43 | auto dest_ptr = dest_frame.Allocate(AV_PIX_FMT_RGB24, {640, 480}, 1); 44 | { 45 | auto maybe_pref = dut.Read(&packet); 46 | if (!!maybe_pref) { 47 | codec.SendPacket(*maybe_pref); 48 | auto maybe_fref = codec.GetFrame(&frame); 49 | 50 | if (!!maybe_fref) { 51 | if (!swscale) { 52 | swscale.emplace(codec, dest_frame.size(), 53 | dest_frame.format(), Swscale::kBicubic); 54 | } 55 | swscale->Scale(*maybe_fref, dest_ptr); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ffmpeg/test/frame_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ffmpeg/frame.h" 16 | 17 | #include 18 | 19 | using namespace mjmech::ffmpeg; 20 | 21 | BOOST_AUTO_TEST_CASE(FrameTest) { 22 | Frame dut; 23 | } 24 | -------------------------------------------------------------------------------- /ffmpeg/test/packet_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ffmpeg/packet.h" 16 | 17 | #include 18 | 19 | using namespace mjmech::ffmpeg; 20 | 21 | BOOST_AUTO_TEST_CASE(PacketTest) { 22 | Packet dut; 23 | } 24 | -------------------------------------------------------------------------------- /ffmpeg/test/stream_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ffmpeg/stream.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /ffmpeg/test/swscale_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "ffmpeg/swscale.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /ffmpeg/test/test_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #define BOOST_TEST_MODULE mech 16 | #include 17 | -------------------------------------------------------------------------------- /gl/camera.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace gl { 21 | 22 | class Camera { 23 | public: 24 | enum Type { 25 | kPerspective, 26 | kOrthographic, 27 | }; 28 | 29 | virtual ~Camera() {} 30 | 31 | virtual Eigen::Matrix4f matrix(double zoom = 1.0) = 0; 32 | virtual Type type() const = 0; 33 | }; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gl/flat_rgb_texture.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "gl/texture.h" 20 | 21 | namespace mjmech { 22 | namespace gl { 23 | 24 | /// A GL texture which can have RGB data sent into it. 25 | class FlatRgbTexture { 26 | public: 27 | FlatRgbTexture(Eigen::Vector2i size, GLenum format = GL_RGB) 28 | : texture_(size), 29 | size_(size), 30 | format_(format) { 31 | texture_.bind(GL_TEXTURE_2D); 32 | 33 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 34 | 35 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 36 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 37 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 38 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 39 | 40 | glTexImage2D(GL_TEXTURE_2D, 0, format_, 41 | size.x(), size.y(), 42 | 0, format_, GL_UNSIGNED_BYTE, NULL); 43 | } 44 | 45 | void Store(const void* data) { 46 | bind(); 47 | glTexSubImage2D( 48 | GL_TEXTURE_2D, 0, 0, 0, 49 | size_.x(), size_.y(), 50 | format_, GL_UNSIGNED_BYTE, 51 | data); 52 | } 53 | 54 | void bind() { 55 | texture_.bind(GL_TEXTURE_2D); 56 | } 57 | 58 | GLuint id() const { return texture_.id(); } 59 | Texture& texture() { return texture_; } 60 | 61 | private: 62 | Texture texture_; 63 | const Eigen::Vector2i size_; 64 | const GLenum format_; 65 | }; 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /gl/framebuffer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "gl/renderbuffer.h" 24 | #include "gl/texture.h" 25 | 26 | namespace mjmech { 27 | namespace gl { 28 | 29 | class Framebuffer { 30 | public: 31 | Framebuffer() { 32 | glGenFramebuffers(1, &framebuffer_); 33 | } 34 | 35 | ~Framebuffer() { 36 | glDeleteFramebuffers(1, &framebuffer_); 37 | } 38 | 39 | class Bind { 40 | public: 41 | Bind(Framebuffer& parent) { 42 | glBindFramebuffer(GL_FRAMEBUFFER, parent.id()); 43 | } 44 | 45 | ~Bind() { 46 | glBindFramebuffer(GL_FRAMEBUFFER, 0); 47 | } 48 | }; 49 | 50 | void attach(const Texture& texture, const Renderbuffer& rbo) { 51 | Bind binder(*this); 52 | 53 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.id(), 0); 54 | 55 | rbo.bind(); 56 | 57 | glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 58 | texture.size().x(), texture.size().y()); 59 | 60 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 61 | GL_RENDERBUFFER, rbo.id()); 62 | 63 | GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0 }; 64 | glDrawBuffers(1, draw_buffers); 65 | } 66 | 67 | GLuint id() const { return framebuffer_; } 68 | 69 | private: 70 | GLuint framebuffer_ = -1; 71 | }; 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /gl/gl_imgui.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /// @file 16 | /// 17 | /// This file is named gl_imgui.h just so that it will not shadow the 18 | /// official "imgui.h". 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | namespace mjmech { 25 | namespace gl { 26 | 27 | class ImGuiWindow { 28 | public: 29 | ImGuiWindow(const char* name) 30 | : open_{ImGui::Begin(name)} { 31 | } 32 | 33 | ~ImGuiWindow() { 34 | ImGui::End(); 35 | } 36 | 37 | bool open() const { 38 | return open_; 39 | } 40 | 41 | operator bool() const { 42 | return open_; 43 | } 44 | 45 | private: 46 | const bool open_; 47 | }; 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gl/image_texture.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "tools/cpp/runfiles/runfiles.h" 22 | 23 | #include "mjlib/imgui/gl.h" 24 | 25 | #include "base/runfiles.h" 26 | 27 | #include "gl/flat_rgb_texture.h" 28 | 29 | namespace mjmech { 30 | namespace gl { 31 | 32 | /// A GL texture read from a source file. 33 | class ImageTexture { 34 | public: 35 | ImageTexture(std::string_view filepath) 36 | : runfiles_(), 37 | image_{cv::imread(runfiles_.Rlocation(filepath), cv::IMREAD_UNCHANGED)}, 38 | texture_(EigenSize(image_.size()), 39 | image_.channels() == 3 ? GL_RGB : GL_RGBA) { 40 | texture_.Store(image_.data); 41 | MJ_TRACE_GL_ERROR(); 42 | } 43 | 44 | void bind() { 45 | texture_.bind(); 46 | } 47 | 48 | GLuint id() const { return texture_.id(); } 49 | Texture& texture() { return texture_.texture(); } 50 | 51 | private: 52 | template 53 | static Eigen::Vector2i EigenSize(const T& value) { 54 | return {value.width, value.height}; 55 | } 56 | 57 | base::Runfiles runfiles_; 58 | cv::Mat image_; 59 | FlatRgbTexture texture_; 60 | }; 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /gl/renderbuffer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace gl { 21 | 22 | class Renderbuffer { 23 | public: 24 | Renderbuffer() { 25 | glGenRenderbuffers(1, &rbo_); 26 | } 27 | 28 | ~Renderbuffer() { 29 | glDeleteRenderbuffers(1, &rbo_); 30 | } 31 | 32 | void bind() const { 33 | glBindRenderbuffer(GL_RENDERBUFFER, rbo_); 34 | } 35 | 36 | GLuint id() const { return rbo_; } 37 | 38 | private: 39 | GLuint rbo_ = 0; 40 | }; 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /gl/shader.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #include "mjlib/imgui/gl.h" 21 | 22 | #include "mjlib/base/fail.h" 23 | 24 | namespace mjmech { 25 | namespace gl { 26 | 27 | /// Represents a single compiled shader. 28 | class Shader { 29 | public: 30 | Shader(std::string_view source, GLenum type) 31 | : shader_(glCreateShader(type)) { 32 | MJ_TRACE_GL_ERROR(); 33 | const char* data = source.data(); 34 | GLint length = source.size(); 35 | glShaderSource(shader_, 1, static_cast(&data), &length); 36 | glCompileShader(shader_); 37 | GLint status = -1; 38 | glGetShaderiv(shader_, GL_COMPILE_STATUS, &status); 39 | if (status != GL_TRUE) { 40 | GLint log_length = 0; 41 | glGetShaderiv(shader_, GL_INFO_LOG_LENGTH, &log_length); 42 | std::vector log; 43 | log.resize(log_length); 44 | glGetShaderInfoLog(shader_, log.size(), &log_length, log.data()); 45 | 46 | mjlib::base::Fail("Error compiling shader: " + 47 | std::string(log.data(), log_length)); 48 | } 49 | MJ_TRACE_GL_ERROR(); 50 | } 51 | 52 | ~Shader() { 53 | glDeleteShader(shader_); 54 | } 55 | 56 | Shader(const Shader&) = delete; 57 | Shader& operator=(const Shader&) = delete; 58 | 59 | GLuint get() const { return shader_; } 60 | 61 | private: 62 | const GLuint shader_; 63 | }; 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /gl/simple_line_render_list.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "gl/program.h" 22 | #include "gl/shader.h" 23 | #include "gl/vertex_array_object.h" 24 | #include "gl/vertex_buffer_object.h" 25 | 26 | namespace mjmech { 27 | namespace gl { 28 | 29 | class SimpleLineRenderList { 30 | public: 31 | SimpleLineRenderList(); 32 | 33 | /// Get ready for the next rendering frame. 34 | void Reset(); 35 | 36 | /// Upload all geometry to the GPU. 37 | void Upload(); 38 | 39 | void SetProjMatrix(const Eigen::Matrix4f&); 40 | void SetViewMatrix(const Eigen::Matrix4f&); 41 | void SetModelMatrix(const Eigen::Matrix4f&); 42 | 43 | /// Draw all primitives currently uploaded to GPU. 44 | void Render(); 45 | 46 | void SetTransform(const Eigen::Matrix4f&); 47 | 48 | uint32_t AddVertex(const Eigen::Vector3f&, 49 | const Eigen::Vector4f& rgba); 50 | void AddSegment(const Eigen::Vector3f&, 51 | const Eigen::Vector3f&, 52 | const Eigen::Vector4f& rgba); 53 | 54 | private: 55 | std::vector data_; 56 | std::vector indices_; 57 | 58 | Shader vertex_shader_; 59 | Shader fragment_shader_; 60 | Program program_; 61 | 62 | VertexArrayObject vao_; 63 | VertexBufferObject vertices_; 64 | VertexBufferObject elements_; 65 | 66 | Eigen::Matrix4f transform_{Eigen::Matrix4f::Identity()}; 67 | }; 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /gl/test/flat_rgb_texture_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/flat_rgb_texture.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /gl/test/framebuffer_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/framebuffer.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /gl/test/perspective_camera_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/perspective_camera.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /gl/test/program_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/program.h" 16 | -------------------------------------------------------------------------------- /gl/test/shader_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/shader.h" 16 | 17 | #include 18 | 19 | BOOST_AUTO_TEST_CASE(ShaderIncludeTest) { 20 | } 21 | -------------------------------------------------------------------------------- /gl/test/simple_texture_render_list_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/simple_texture_render_list.h" 16 | -------------------------------------------------------------------------------- /gl/test/test_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #define BOOST_TEST_MODULE mech 16 | #include 17 | -------------------------------------------------------------------------------- /gl/test/texture_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/texture.h" 16 | -------------------------------------------------------------------------------- /gl/test/trackball_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/trackball.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /gl/test/vertex_array_object_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/vertex_array_object.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /gl/test/vertex_buffer_object_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "gl/vertex_buffer_object.h" 16 | 17 | #include 18 | -------------------------------------------------------------------------------- /gl/texture.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "mjlib/imgui/gl.h" 20 | 21 | namespace mjmech { 22 | namespace gl { 23 | 24 | class Texture { 25 | public: 26 | Texture(Eigen::Vector2i size = {}) : size_(size) { 27 | glGenTextures(1, &tex_); 28 | } 29 | 30 | ~Texture() { 31 | glDeleteTextures(1, &tex_); 32 | } 33 | 34 | Texture(const Texture&) = delete; 35 | Texture& operator=(const Texture&) = delete; 36 | 37 | void bind(GLenum target, GLenum texture = GL_TEXTURE0) { 38 | glActiveTexture(GL_TEXTURE0); 39 | glBindTexture(target, tex_); 40 | } 41 | 42 | GLuint id() const { return tex_; } 43 | 44 | Eigen::Vector2i size() const { return size_; } 45 | 46 | private: 47 | Eigen::Vector2i size_; 48 | GLuint tex_ = 0; 49 | }; 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /gl/vertex_array_object.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/imgui/gl.h" 18 | 19 | namespace mjmech { 20 | namespace gl { 21 | 22 | class VertexArrayObject { 23 | public: 24 | VertexArrayObject() { 25 | glGenVertexArrays(1, &vao_); 26 | } 27 | 28 | ~VertexArrayObject() { 29 | glDeleteVertexArrays(1, &vao_); 30 | } 31 | 32 | VertexArrayObject(const VertexArrayObject&) = delete; 33 | VertexArrayObject& operator=(const VertexArrayObject&) = delete; 34 | 35 | void bind() { 36 | glBindVertexArray(vao_); 37 | } 38 | 39 | void unbind() { 40 | glBindVertexArray(0); 41 | } 42 | 43 | private: 44 | GLuint vao_ = 0; 45 | }; 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gl/vertex_buffer_object.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/imgui/gl.h" 18 | 19 | namespace mjmech { 20 | namespace gl { 21 | 22 | class VertexBufferObject { 23 | public: 24 | VertexBufferObject() { 25 | glGenBuffers(1, &vbo_); 26 | } 27 | 28 | ~VertexBufferObject() { 29 | glDeleteBuffers(1, &vbo_); 30 | } 31 | 32 | VertexBufferObject(const VertexBufferObject&) = delete; 33 | VertexBufferObject& operator=(const VertexBufferObject&) = delete; 34 | 35 | void bind(GLenum target) { 36 | glBindBuffer(target, vbo_); 37 | } 38 | 39 | template 40 | void set_vector(GLenum target, const Vector& vector, GLenum usage) { 41 | bind(target); 42 | glBufferData(target, vector.size() * sizeof(vector[0]), &vector[0], usage); 43 | } 44 | 45 | template 46 | void set_data_array(GLenum target, const Array& array, GLenum usage) { 47 | bind(target); 48 | glBufferData(target, sizeof(array), &array[0], usage); 49 | } 50 | 51 | private: 52 | GLuint vbo_ = 0; 53 | }; 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200303-battery_stud.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200303-battery_stud.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200415-stiffener_left.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200415-stiffener_left.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200415-stiffener_right.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200415-stiffener_right.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200415-top.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200415-top.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200502-aligners.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200502-aligners.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200504-front_plate.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200504-front_plate.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200506-bottom.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200506-bottom.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200506-internal_cover.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200506-internal_cover.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20200708-shore_plug.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20200708-shore_plug.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20201223-sides.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20201223-sides.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231218-front_plate-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231218-front_plate-0_6mm.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231218-sides-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231218-sides-0_6mm.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231219-battery_stud-0_6.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231219-battery_stud-0_6.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231219-bottom-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231219-bottom-0_6mm.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231219-top-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231219-top-0_6mm.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231220-internal_cover-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231220-internal_cover-0_6mm.3mf -------------------------------------------------------------------------------- /hw/chassis/3dprint/20231220-stiffeners-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis/3dprint/20231220-stiffeners-0_6mm.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/battery_tray.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/battery_tray.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/bottom.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/bottom.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/computer_tray.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/computer_tray.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/front_back_plate.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/front_back_plate.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/knee_zero.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/knee_zero.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/rail_carrier.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/rail_carrier.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/shoulder_zero_left.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/shoulder_zero_left.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/shoulder_zero_right.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/shoulder_zero_right.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/side_wall.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/side_wall.3mf -------------------------------------------------------------------------------- /hw/chassis_a2/top.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/chassis_a2/top.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20200223-shoulder.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20200223-shoulder.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20200825-upper_leg.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20200825-upper_leg.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20201009-lower_leg_and_bracket.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20201009-lower_leg_and_bracket.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20201009-shoulder_conduit.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20201009-shoulder_conduit.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20210602-upper_motor_joint.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20210602-upper_motor_joint.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20210713-pulleys-tensioner.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20210713-pulleys-tensioner.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20210806-lower_leg_and_bracket-left.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20210806-lower_leg_and_bracket-left.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20210806-lower_leg_and_bracket-right.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20210806-lower_leg_and_bracket-right.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20210806-lower_leg_and_bracket.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20210806-lower_leg_and_bracket.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20231220-lower_leg_and_bracket-petg-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20231220-lower_leg_and_bracket-petg-0_6mm.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20231220-shoulder_conduit-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20231220-shoulder_conduit-0_6mm.3mf -------------------------------------------------------------------------------- /hw/leg/3dprint/20231220-upper_leg-0_6mm.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg/3dprint/20231220-upper_leg-0_6mm.3mf -------------------------------------------------------------------------------- /hw/leg_a2/2x_lower_leg_base.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/2x_lower_leg_base.3mf -------------------------------------------------------------------------------- /hw/leg_a2/2x_shoulder.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/2x_shoulder.3mf -------------------------------------------------------------------------------- /hw/leg_a2/2x_upper_motor.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/2x_upper_motor.3mf -------------------------------------------------------------------------------- /hw/leg_a2/4x_foot_axle_cap_pulley.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/4x_foot_axle_cap_pulley.3mf -------------------------------------------------------------------------------- /hw/leg_a2/4x_tensioners.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/4x_tensioners.3mf -------------------------------------------------------------------------------- /hw/leg_a2/upper_leg_base_lower_leg_top.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/upper_leg_base_lower_leg_top.3mf -------------------------------------------------------------------------------- /hw/leg_a2/upper_leg_right_base_lower_leg_top.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/upper_leg_right_base_lower_leg_top.3mf -------------------------------------------------------------------------------- /hw/leg_a2/upper_leg_right_top.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/upper_leg_right_top.3mf -------------------------------------------------------------------------------- /hw/leg_a2/upper_leg_top.3mf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/hw/leg_a2/upper_leg_top.3mf -------------------------------------------------------------------------------- /mech/aruco_draw.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | extern "C" { 26 | 27 | int main(int argc, char** argv) { 28 | BOOST_VERIFY(argc >= 3); 29 | 30 | cv::Mat markerImage; 31 | 32 | cv::Ptr dictionary = 33 | cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50); 34 | 35 | cv::aruco::drawMarker(dictionary, std::stoi(argv[1]), 200, markerImage, 1); 36 | 37 | cv::imwrite(argv[2], markerImage); 38 | 39 | return 0; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /mech/aruco_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2018-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | extern "C" { 27 | 28 | int main(int argc, char** argv) { 29 | BOOST_VERIFY(argc >= 2); 30 | cv::Mat input = cv::imread(argv[1]); 31 | cv::Ptr dictionary = 32 | cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50); 33 | std::vector markerIds; 34 | std::vector> markerCorners; 35 | 36 | auto parameters = cv::aruco::DetectorParameters::create(); 37 | 38 | cv::setNumThreads(1); 39 | 40 | constexpr int width = 480; 41 | constexpr int height = 480; 42 | 43 | cv::Rect crop_area(input.cols / 2 - width / 2, input.rows / 2 - height / 2, 44 | width, height); 45 | 46 | { 47 | boost::timer::auto_cpu_timer t; 48 | for (int i = 0; i < 100; i++) { 49 | cv::Mat subset = input(crop_area); 50 | cv::aruco::detectMarkers(subset, dictionary, markerCorners, markerIds, parameters); 51 | } 52 | } 53 | 54 | std::cout << markerIds.size() << "\n"; 55 | for (const auto& marker : markerCorners) { 56 | for (const auto& corner : marker) { 57 | std::cout << fmt::format("({:f},{:f}) ", corner.x, corner.y); 58 | } 59 | std::cout << "\n"; 60 | } 61 | 62 | return 0; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /mech/attitude_data.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/base/visitor.h" 18 | 19 | #include "base/euler.h" 20 | #include "base/point3d.h" 21 | #include "base/quaternion.h" 22 | 23 | namespace mjmech { 24 | namespace mech { 25 | 26 | struct AttitudeData { 27 | boost::posix_time::ptime timestamp; 28 | 29 | base::Quaternion attitude; 30 | base::Point3D rate_dps; 31 | base::Euler euler_deg; 32 | base::Point3D accel_mps2; 33 | 34 | base::Point3D bias_dps; 35 | base::Quaternion attitude_uncertainty; 36 | base::Point3D bias_uncertainty_dps; 37 | 38 | template 39 | void Serialize(Archive* a) { 40 | a->Visit(MJ_NVP(timestamp)); 41 | a->Visit(MJ_NVP(attitude)); 42 | a->Visit(MJ_NVP(rate_dps)); 43 | a->Visit(MJ_NVP(euler_deg)); 44 | a->Visit(MJ_NVP(accel_mps2)); 45 | a->Visit(MJ_NVP(bias_dps)); 46 | a->Visit(MJ_NVP(attitude_uncertainty)); 47 | a->Visit(MJ_NVP(bias_uncertainty_dps)); 48 | } 49 | }; 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /mech/camera_driver.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "mjlib/base/visitor.h" 22 | #include "mjlib/io/async_types.h" 23 | 24 | namespace mjmech { 25 | namespace mech { 26 | 27 | /// Read frames from a camera. 28 | class CameraDriver { 29 | public: 30 | struct Options { 31 | int width = 1280; 32 | int height = 720; 33 | int mode = 6; 34 | int fps = 60; 35 | int rotation = 270; 36 | 37 | std::string record_path = "/tmp/mjbots-camera"; 38 | int record_every = -1; 39 | 40 | template 41 | void Serialize(Archive* a) { 42 | a->Visit(MJ_NVP(width)); 43 | a->Visit(MJ_NVP(height)); 44 | a->Visit(MJ_NVP(mode)); 45 | a->Visit(MJ_NVP(fps)); 46 | a->Visit(MJ_NVP(rotation)); 47 | a->Visit(MJ_NVP(record_path)); 48 | a->Visit(MJ_NVP(record_every)); 49 | } 50 | }; 51 | 52 | CameraDriver(const Options& options); 53 | ~CameraDriver(); 54 | 55 | using ImageSignal = boost::signals2::signal; 56 | // This will be emitted from a background thread. 57 | ImageSignal* image_signal(); 58 | 59 | private: 60 | class Impl; 61 | std::unique_ptr impl_; 62 | }; 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /mech/expo_map.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace mech { 21 | 22 | /// A two rate piecewise linear mapping with a central deadband. 23 | /// 24 | /// For the positive side, the input-output mapping: 25 | /// 26 | /// 0 - 0.0 27 | /// 0.05 - 0.0 28 | /// 0.3 - 0.1 29 | /// 1.0 - 1.0 30 | class ExpoMap { 31 | public: 32 | struct Options { 33 | double deadband = 0.05; 34 | double slow_range = 0.30; 35 | double slow_value = 0.10; 36 | 37 | Options() {} 38 | }; 39 | 40 | ExpoMap(const Options& options = Options()) : options_(options) {} 41 | 42 | double operator()(double value) const { 43 | const auto& o = options_; 44 | 45 | if (std::abs(value) < o.deadband) { return 0.0; } 46 | const double sign = std::copysign(1.0, value); 47 | if (std::abs(value) < o.slow_range) { 48 | return o.slow_value * (value - o.deadband * sign) / 49 | (o.slow_range - o.deadband); 50 | } 51 | return (value - (sign * o.slow_range)) / 52 | (1.0 - o.slow_range) * 53 | (1.0 - o.slow_value) + sign * o.slow_value; 54 | } 55 | 56 | private: 57 | Options options_; 58 | }; 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mech/imu_client.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/io/async_types.h" 18 | 19 | #include "mech/attitude_data.h" 20 | 21 | namespace mjmech { 22 | namespace mech { 23 | 24 | class ImuClient { 25 | public: 26 | virtual ~ImuClient() {} 27 | 28 | virtual void ReadImu(AttitudeData*, mjlib::io::ErrorCallback) = 0; 29 | }; 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mech/imu_data.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "mjlib/base/visitor.h" 16 | 17 | #include "base/point3d.h" 18 | 19 | namespace mjmech { 20 | namespace mech { 21 | 22 | struct ImuData { 23 | boost::posix_time::ptime timestamp; 24 | 25 | base::Point3D rate_dps; 26 | base::Point3D accel_mps2; 27 | 28 | template 29 | void Serialize(Archive* a) { 30 | a->Visit(MJ_NVP(timestamp)); 31 | a->Visit(MJ_NVP(rate_dps)); 32 | a->Visit(MJ_NVP(accel_mps2)); 33 | } 34 | }; 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mech/mcast_telemetry_interface.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace mjmech { 22 | namespace mech { 23 | 24 | /// The multi-cast system can associate additional telemetry with 25 | /// video frames as they are sent. This interface provides a mechanism 26 | /// to provide that additional telemetry. */ 27 | class McastTelemetryInterface { 28 | public: 29 | virtual ~McastTelemetryInterface() {} 30 | 31 | /// Include @p data with @p name in packets that are sent until @p 32 | /// expiration has passed, after which no data with this name will 33 | /// be included. Any previous information associated with @p name 34 | /// is overwritten. 35 | virtual void SetTelemetry(const std::string& name, 36 | const std::string& data, 37 | boost::posix_time::ptime expiration) = 0; 38 | }; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mech/mime_type.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "mech/mime_type.h" 16 | 17 | namespace mjmech { 18 | namespace mech { 19 | 20 | std::string_view GetMimeType(std::string_view path) { 21 | const auto ext = [&]() { 22 | const auto pos = path.rfind("."); 23 | if (pos == std::string_view::npos) { return std::string_view(); } 24 | return path.substr(pos); 25 | }(); 26 | 27 | struct Mapping { 28 | std::string_view extension; 29 | std::string_view mime_type; 30 | }; 31 | constexpr Mapping mappings[] = { 32 | { ".htm", "text/html" }, 33 | { ".html", "text/html" }, 34 | { ".css", "text/css" }, 35 | { ".txt", "text/plain" }, 36 | { ".js", "application/javascript" }, 37 | { ".json", "application/json" }, 38 | { ".xml", "application/xml" }, 39 | { ".png", "image/png" }, 40 | { ".jpeg", "image/jpeg" }, 41 | { ".jpg", "image/jpg" }, 42 | { ".gif", "image/gif" }, 43 | { ".ico", "image/vnd.microsoft.icon" }, 44 | { ".svg", "image/svg+xml" }, 45 | }; 46 | for (const auto& mapping : mappings) { 47 | if (ext == mapping.extension) { 48 | return mapping.mime_type; 49 | } 50 | } 51 | return "application/text"; 52 | } 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /mech/mime_type.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace mech { 21 | 22 | std::string_view GetMimeType(std::string_view path); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /mech/moteus_tool_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "moteus/tool/moteus_tool.h" 16 | 17 | #include "mjlib/io/selector.h" 18 | #include "mjlib/multiplex/asio_client.h" 19 | 20 | #include "mech/pi3hat_wrapper.h" 21 | 22 | int main(int argc, char** argv) { 23 | boost::asio::io_context context; 24 | mjlib::io::Selector client_selector{ 25 | context.get_executor(), "client_type"}; 26 | client_selector.Register("pi3"); 27 | client_selector.set_default("pi3"); 28 | return moteus::tool::moteus_tool_main(context, argc, argv, &client_selector); 29 | } 30 | -------------------------------------------------------------------------------- /mech/multiplex_tool_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include "mjlib/io/selector.h" 18 | #include "mjlib/multiplex/multiplex_tool.h" 19 | #include "mjlib/multiplex/asio_client.h" 20 | 21 | #include "mech/pi3hat_wrapper.h" 22 | 23 | extern "C" { 24 | int main(int argc, char** argv) { 25 | boost::asio::io_context context; 26 | mjlib::io::Selector client_selector{ 27 | context.get_executor(), "client_type"}; 28 | client_selector.Register("pi3"); 29 | client_selector.set_default("pi3"); 30 | return mjlib::multiplex::multiplex_main(context, argc, argv, &client_selector); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /mech/nrfusb_client.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/io/async_stream.h" 18 | 19 | #include "mech/rf_client.h" 20 | 21 | namespace mjmech { 22 | namespace mech { 23 | 24 | /// An implementation of RfClient that uses the nrfusb. 25 | class NrfusbClient : public RfClient { 26 | public: 27 | struct Options { 28 | uint32_t id0 = 5678; 29 | uint32_t id1 = 88754; 30 | 31 | Options() {} 32 | }; 33 | NrfusbClient(mjlib::io::AsyncStream*, const Options& = Options()); 34 | ~NrfusbClient() override; 35 | 36 | void AsyncWaitForSlot( 37 | int* remote, uint16_t* bitfield, mjlib::io::ErrorCallback) override; 38 | 39 | Slot rx_slot(int remote, int slot_idx) override; 40 | void tx_slot(int remote, int slot_idx, const Slot&) override; 41 | Slot tx_slot(int remote, int slot_idx) override; 42 | 43 | private: 44 | class Impl; 45 | std::unique_ptr impl_; 46 | }; 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mech/pi3hat_interface.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/multiplex/asio_client.h" 18 | 19 | #include "mech/imu_client.h" 20 | #include "mech/rf_client.h" 21 | 22 | namespace mjmech { 23 | namespace mech { 24 | 25 | /// The pi3hat has multiple functions. This is just an interface that 26 | /// combines all of them for use in an mjlib::io::Selector. 27 | class Pi3hatInterface : public ImuClient, 28 | public RfClient, 29 | public mjlib::multiplex::AsioClient { 30 | public: 31 | ~Pi3hatInterface() override {} 32 | 33 | virtual void Cycle( 34 | AttitudeData*, 35 | const Request*, Reply*, 36 | mjlib::io::ErrorCallback callback) = 0; 37 | }; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /mech/propagate_leg.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | namespace mjmech { 18 | namespace mech { 19 | 20 | /// Propagate a leg given a linear and angular velocity of the CoM. 21 | class PropagateLeg { 22 | public: 23 | PropagateLeg(const Eigen::Vector3d& v_R, 24 | const Eigen::Vector3d& w_R, 25 | double period_s) 26 | : v_R_(v_R), 27 | w_R_(w_R), 28 | pose_T2_T1_( 29 | Sophus::SO3d( 30 | Eigen::AngleAxisd(-period_s * w_R.z(), Eigen::Vector3d::UnitZ()) 31 | .toRotationMatrix()), 32 | -v_R_ * period_s) {} 33 | 34 | struct Result { 35 | Eigen::Vector3d position; 36 | Eigen::Vector3d velocity; 37 | }; 38 | 39 | Result operator()(const Eigen::Vector3d& position_R) const { 40 | Result result; 41 | result.position = pose_T2_T1_ * position_R; 42 | result.velocity = -v_R_ - w_R_.cross(position_R); 43 | return result; 44 | } 45 | 46 | private: 47 | Eigen::Vector3d v_R_; 48 | Eigen::Vector3d w_R_; 49 | Sophus::SE3d pose_T2_T1_; 50 | }; 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /mech/quadruped_trot.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mech/quadruped_command.h" 18 | #include "mech/quadruped_context.h" 19 | 20 | namespace mjmech { 21 | namespace mech { 22 | 23 | struct TrotResult { 24 | std::vector legs_R; 25 | base::KinematicRelation desired_RB; 26 | }; 27 | 28 | /// Execute the trot gait. 29 | TrotResult QuadrupedTrot( 30 | QuadrupedContext* context, 31 | const std::vector& old_legs_R); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /mech/reticle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/mech/reticle.png -------------------------------------------------------------------------------- /mech/rf_client.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "mjlib/io/async_types.h" 20 | 21 | namespace mjmech { 22 | namespace mech { 23 | 24 | class RfClient { 25 | public: 26 | virtual ~RfClient() {} 27 | 28 | /// Wait for one or more receive slots to be updated. 29 | /// 30 | /// @param bitfield will be set with a 1 for each slot which has 31 | /// been updated. 32 | virtual void AsyncWaitForSlot( 33 | int* remote, uint16_t* bitfield, mjlib::io::ErrorCallback) = 0; 34 | 35 | struct Slot { 36 | /// The timestamp is only valid for rx, and is ignored for tx. 37 | boost::posix_time::ptime timestamp; 38 | 39 | /// The priority is only valid for tx, and will be left 40 | /// unspecified for rx. 41 | uint32_t priority = 0; 42 | 43 | uint8_t size = 0; 44 | char data[16] = {}; 45 | }; 46 | 47 | /// Return the current value of the given receive slot. 48 | virtual Slot rx_slot(int remote, int slot_idx) = 0; 49 | 50 | /// Set the given transmit slot. 51 | virtual void tx_slot(int remote, int slot_idx, const Slot&) = 0; 52 | 53 | /// Retrieve the currently selected transmit slot. 54 | virtual Slot tx_slot(int remote, int slot_idx) = 0; 55 | }; 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /mech/rf_control.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include "base/context.h" 23 | #include "mech/rf_client.h" 24 | #include "mech/quadruped_control.h" 25 | 26 | namespace mjmech { 27 | namespace mech { 28 | 29 | /// Listens to RF commands, using those to command QuadrupedControl. 30 | /// Also, exposes telemetry back out to the RF interface. 31 | class RfControl { 32 | public: 33 | // To be called at AsyncStart time. 34 | using RfGetter = std::function; 35 | 36 | RfControl(const base::Context&, QuadrupedControl* control, RfGetter); 37 | ~RfControl(); 38 | 39 | void AsyncStart(mjlib::io::ErrorCallback); 40 | 41 | clipp::group program_options(); 42 | 43 | private: 44 | class Impl; 45 | std::unique_ptr impl_; 46 | }; 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /mech/system_info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "base/context.h" 22 | 23 | namespace mjmech { 24 | namespace mech { 25 | 26 | /// Record information about the system on a periodic basis. 27 | class SystemInfo : boost::noncopyable { 28 | public: 29 | SystemInfo(base::Context&); 30 | ~SystemInfo(); 31 | 32 | void AsyncStart(mjlib::io::ErrorCallback); 33 | 34 | clipp::group program_options(); 35 | 36 | private: 37 | class Impl; 38 | std::unique_ptr impl_; 39 | }; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /mech/target_tracker_data.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016-2019 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "mjlib/base/visitor.h" 22 | 23 | #include "base/point3d.h" 24 | 25 | namespace mjmech { 26 | namespace mech { 27 | 28 | struct TargetTrackerData { 29 | boost::posix_time::ptime timestamp; 30 | 31 | struct Target { 32 | base::Point3D center; 33 | std::vector corners; 34 | 35 | template 36 | void Serialize(Archive* a) { 37 | a->Visit(MJ_NVP(center)); 38 | a->Visit(MJ_NVP(corners)); 39 | } 40 | }; 41 | 42 | std::optional target; 43 | 44 | template 45 | void Serialize(Archive* a) { 46 | a->Visit(MJ_NVP(timestamp)); 47 | a->Visit(MJ_NVP(target)); 48 | } 49 | }; 50 | 51 | typedef boost::signals2::signal< 52 | void (const TargetTrackerData*)> TargetTrackerDataSignal; 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /mech/test/expo_map_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "mech/expo_map.h" 16 | 17 | #include 18 | 19 | namespace { 20 | using Dut = mjmech::mech::ExpoMap; 21 | } 22 | 23 | BOOST_AUTO_TEST_CASE(ExpoMapTest, * boost::unit_test::tolerance(1e-5)) { 24 | Dut dut; 25 | BOOST_TEST(dut(0.0) == 0.0); 26 | BOOST_TEST(dut(0.02) == 0.0); 27 | BOOST_TEST(dut(0.05) == 0.0); 28 | BOOST_TEST(dut(0.175) == 0.05); 29 | BOOST_TEST(dut(0.30) == 0.10); 30 | BOOST_TEST(dut(0.65) == 0.55); 31 | BOOST_TEST(dut(1.00) == 1.0); 32 | BOOST_TEST(dut(-0.05) == 0.0); 33 | BOOST_TEST(dut(-0.175) == -0.05); 34 | BOOST_TEST(dut(-0.30) == -0.10); 35 | BOOST_TEST(dut(-0.65) == -0.55); 36 | BOOST_TEST(dut(-1.00) == -1.0); 37 | } 38 | -------------------------------------------------------------------------------- /mech/test/test_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2014-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #define BOOST_TEST_MODULE mech 16 | #include 17 | -------------------------------------------------------------------------------- /mech/trajectory.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "base/point3d.h" 18 | 19 | namespace mjmech { 20 | namespace mech { 21 | 22 | struct TrajectoryState { 23 | base::Point3D pose_l; 24 | base::Point3D velocity_l_s; 25 | base::Point3D acceleration_l_s2; 26 | }; 27 | 28 | TrajectoryState CalculateAccelerationLimitedTrajectory( 29 | const TrajectoryState& start, 30 | const base::Point3D& target_l, 31 | double target_velocity_l_s, 32 | double max_acceleration_l_s2, 33 | double delta_s); 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /mech/trajectory_line_intersect.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | namespace mjmech { 20 | namespace mech { 21 | 22 | /// Given a trajectory and a line segment, return the time required for 23 | /// the trajectory to intersect the line. negative may be returned if 24 | /// the trajectory would have intersected the line in the past, and 25 | /// infinity will be returned if the trajectory will never intersect 26 | /// the line. 27 | /// 28 | /// The trajectory is specified as a path starting from (0, 0) facing 29 | /// positive X. 30 | double TrajectoryLineIntersectTime( 31 | const Eigen::Vector2d& velocity, 32 | double omega, 33 | const Eigen::Vector2d& p1, 34 | const Eigen::Vector2d& p2); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /mech/vertical_line_frame.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "base/sophus.h" 20 | 21 | namespace mjmech { 22 | namespace mech { 23 | 24 | /// Find the intersection between a vertical line in frame A (the 25 | /// point through query_A along the Z axis), and the plane in frame B 26 | /// described by onplane_B and normal_B. Return the point in frame 27 | /// A. 28 | inline Eigen::Vector3d FindVerticalLinePlaneIntersect( 29 | const Sophus::SE3d& frame_AB, 30 | const Eigen::Vector3d& onplane_B, 31 | const Eigen::Vector3d& normal_B, 32 | const Eigen::Vector3d& query_A) { 33 | // The formula for a plane is 34 | // (p - onplane) * normal = 0. 35 | // 36 | // We'll first convert the B frame things into the A frame, and then 37 | // solve the equation. 38 | Eigen::Vector3d onplane_A = frame_AB * onplane_B; 39 | Eigen::Vector3d normal_A = frame_AB * (onplane_B + normal_B) - onplane_A; 40 | 41 | // The equation expanded out looks like: 42 | // (qx - ox) * nx + (qy - oy) * ny + (z - oz) * nz = 0 43 | // 44 | // Solved for Z that is: 45 | // z = oz - ((qx - ox) * nx - (qy - oy) * ny) / nz 46 | 47 | // If the normal is 0.0, then we don't have a solution. 48 | if (normal_A.z() == 0.0) { 49 | return query_A; 50 | } 51 | 52 | const double z_A = 53 | onplane_A.z() - 54 | ((query_A.head<2>() - onplane_A.head<2>()).dot( 55 | normal_A.head<2>()) / normal_A.z()); 56 | return Eigen::Vector3d(query_A.x(), query_A.y(), z_A); 57 | } 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /mech/web_control_assets/mjbots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/mech/web_control_assets/mjbots.png -------------------------------------------------------------------------------- /simulator/BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | load("//base:module_main.bzl", "module_main") 20 | 21 | cc_binary( 22 | name = "simulator", 23 | srcs = [ 24 | "make_robot.cc", 25 | "simulator_window.cc", 26 | "simulator.cc", 27 | ] + glob(["*.h"]), 28 | deps = [ 29 | "//mech", 30 | "@com_github_mjbots_mjlib//mjlib/base:limit", 31 | "@com_github_mjbots_mjlib//mjlib/base:pid", 32 | "@com_github_mjbots_mjlib//mjlib/micro:pool_ptr", 33 | "@com_github_mjbots_mjlib//mjlib/multiplex:micro_server", 34 | "@dart//:gui", 35 | "@org_llvm_libcxx//:libcxx", 36 | ], 37 | linkstatic = False, 38 | ) 39 | -------------------------------------------------------------------------------- /simulator/make_robot.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include "mech/quadruped_config.h" 20 | 21 | namespace mjmech { 22 | namespace simulator { 23 | 24 | /// Build the DART skeleton for the robot. 25 | dart::dynamics::SkeletonPtr MakeRobot(const mech::QuadrupedConfig&); 26 | 27 | /// Return a suitably large floor. 28 | dart::dynamics::SkeletonPtr MakeFloor(); 29 | 30 | /// Return a ramp to walk up and down. 31 | dart::dynamics::SkeletonPtr MakeRamp(double peak_height); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /simulator/simulator_window.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "base/context.h" 22 | 23 | namespace mjmech { 24 | namespace simulator { 25 | 26 | class SimulatorWindow { 27 | public: 28 | SimulatorWindow(base::Context&); 29 | ~SimulatorWindow(); 30 | 31 | clipp::group program_options(); 32 | 33 | void AsyncStart(mjlib::io::ErrorCallback); 34 | void InitWindow(int x, int y, const char* name); 35 | 36 | private: 37 | class Impl; 38 | std::unique_ptr impl_; 39 | }; 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tools/workspace/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/BUILD -------------------------------------------------------------------------------- /tools/workspace/bazel_deps/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/bazel_deps/BUILD -------------------------------------------------------------------------------- /tools/workspace/bazel_deps/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def bazel_deps_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "mjbots/bazel_deps", 23 | commit = "9e640212a87ccc5fa5837df35c063ba2261d4e76", 24 | sha256 = "79030e39f06961deea88e292fd2399df8a67d6376295bb3d1fc9a93f97563e07", 25 | ) 26 | -------------------------------------------------------------------------------- /tools/workspace/generate_file.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | def _generate_file_impl(ctx): 4 | out = ctx.actions.declare_file(ctx.label.name) 5 | ctx.actions.write(out, ctx.attr.content, ctx.attr.is_executable) 6 | return [DefaultInfo( 7 | files = depset([out]), 8 | data_runfiles = ctx.runfiles(files = [out]), 9 | )] 10 | 11 | generate_file = rule( 12 | attrs = { 13 | "content": attr.string(mandatory = True), 14 | "is_executable": attr.bool(default = False), 15 | }, 16 | output_to_genfiles = True, 17 | implementation = _generate_file_impl, 18 | ) 19 | 20 | """Generate a file with specified content. 21 | 22 | This creates a rule to generate a file with specified content (which is either 23 | static or has been previously computed). 24 | 25 | Args: 26 | content (:obj:`str`): Desired content of the generated file. 27 | """ 28 | -------------------------------------------------------------------------------- /tools/workspace/github_archive.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 18 | 19 | def github_archive(name, repo, commit, local_override=None, 20 | sha256=None, **kwargs): 21 | """Like 'http_archive', but for github repositories. 22 | 23 | If 'local_override' is set, then reference a local repository at 24 | the given path instead of github.com. 25 | """ 26 | 27 | if local_override: 28 | if 'build_file' in kwargs: 29 | build_file = kwargs['build_file'] 30 | build_path = build_file.package + '/' + build_file.name 31 | native.new_local_repository( 32 | name = name, 33 | build_file = build_path, 34 | path = local_override, 35 | ) 36 | else: 37 | native.local_repository( 38 | name = name, 39 | path = local_override, 40 | ) 41 | else: 42 | http_archive( 43 | name = name, 44 | url = "https://github.com/{repo}/archive/{commit}.zip".format( 45 | repo=repo, commit=commit), 46 | strip_prefix = "{}-{}".format(repo.rsplit('/', 1)[-1], commit), 47 | sha256 = sha256 or "0000000000000000000000000000000000000000000000000000000000000000", 48 | **kwargs) 49 | -------------------------------------------------------------------------------- /tools/workspace/gst-rpicamsrc/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/gst-rpicamsrc/BUILD -------------------------------------------------------------------------------- /tools/workspace/gst-rpicamsrc/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 18 | 19 | 20 | def gst_rpicamsrc_repository(name): 21 | commit = "a181cd8d4b284d09b5f0e23d9ddb4f0a94e1dc8c" 22 | http_archive( 23 | name = name, 24 | url = "https://github.com/thaytan/gst-rpicamsrc/archive/{}.zip".format(commit), 25 | sha256 = "8ebbd6736b8f396e9cef362d4e0a927f15fc97a133cadf7f8acb6cf06ad310a7", 26 | strip_prefix = "gst-rpicamsrc-{}".format(commit), 27 | build_file = Label("//tools/workspace/gst-rpicamsrc:package.BUILD"), 28 | ) 29 | -------------------------------------------------------------------------------- /tools/workspace/i2c-tools/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/i2c-tools/BUILD -------------------------------------------------------------------------------- /tools/workspace/i2c-tools/package.BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | cc_library( 20 | name = "i2c-tools", 21 | hdrs = glob(['include/**/*.h']), 22 | strip_include_prefix = "include", 23 | srcs = ["lib/smbus.c"], 24 | ) 25 | -------------------------------------------------------------------------------- /tools/workspace/i2c-tools/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 18 | 19 | 20 | def i2c_tools_repository(name): 21 | http_archive( 22 | name = name, 23 | urls = [ 24 | "https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/i2c-tools-4.0.tar.xz", 25 | ], 26 | sha256 = "d900ca1c11c51ea20caa50b096f948008b8a7ad832311b23353e21baa7af28d6", 27 | strip_prefix = "i2c-tools-4.0", 28 | build_file = Label("//tools/workspace/i2c-tools:package.BUILD"), 29 | ) 30 | -------------------------------------------------------------------------------- /tools/workspace/implot/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/implot/BUILD -------------------------------------------------------------------------------- /tools/workspace/implot/empty-legend.diff: -------------------------------------------------------------------------------- 1 | diff --git a/implot.cpp b/implot.cpp 2 | index 21bd171..c02f47f 100644 3 | --- a/implot.cpp 4 | +++ b/implot.cpp 5 | @@ -628,9 +628,11 @@ ImPlotItem* RegisterItem(const char* label_id) { 6 | item->SeenThisFrame = true; 7 | int idx = gp.CurrentPlot->Items.GetIndex(item); 8 | item->ID = id; 9 | - gp.LegendIndices.push_back(idx); 10 | - item->NameOffset = gp.LegendLabels.size(); 11 | - gp.LegendLabels.append(label_id, label_id + strlen(label_id) + 1); 12 | + if (ImGui::FindRenderedTextEnd(label_id, NULL) != label_id) { 13 | + gp.LegendIndices.push_back(idx); 14 | + item->NameOffset = gp.LegendLabels.size(); 15 | + gp.LegendLabels.append(label_id, label_id + strlen(label_id) + 1); 16 | + } 17 | if (item->Show) 18 | gp.VisibleItemCount++; 19 | return item; 20 | -------------------------------------------------------------------------------- /tools/workspace/implot/package.BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | cc_library( 20 | name = "implot", 21 | hdrs = [ 22 | "implot.h", 23 | ], 24 | srcs = [ 25 | "implot.cpp", 26 | "implot_demo.cpp", 27 | ], 28 | includes = ["."], 29 | deps = ["@imgui"], 30 | ) 31 | -------------------------------------------------------------------------------- /tools/workspace/implot/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def implot_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "epezent/implot", 23 | commit = "9894df49348a8de412fd3b52ff7bfb322dbeede2", 24 | sha256 = "f5f655ef6d6c167c978373dcd8a53f7188d99ce768a20156fc1e042167a7c296", 25 | build_file = Label("//tools/workspace/implot:package.BUILD"), 26 | patches = [Label("//tools/workspace/implot:empty-legend.diff")], 27 | patch_args = ["-p1"], 28 | ) 29 | -------------------------------------------------------------------------------- /tools/workspace/mjlib/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/mjlib/BUILD -------------------------------------------------------------------------------- /tools/workspace/mjlib/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2022 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def mjlib_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "mjbots/mjlib", 23 | commit = "c390de416689678fa5b4cbfb75544dab65cb843a", 24 | sha256 = "54c12dabe7d3045de129f6da6f87b4df267a24d27ed41a3e4a3c6b55da0dd6a1", 25 | ) 26 | -------------------------------------------------------------------------------- /tools/workspace/moteus/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/moteus/BUILD -------------------------------------------------------------------------------- /tools/workspace/moteus/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def moteus_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "mjbots/moteus", 23 | commit = "fe3a19f2c05de9aa36017f7e21f95a2bca362c75", 24 | sha256 = "361969521fc0165f78d78fb918642562b58f5b55a42fc5428aece70906e8daeb", 25 | ) 26 | -------------------------------------------------------------------------------- /tools/workspace/pi3hat/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/pi3hat/BUILD -------------------------------------------------------------------------------- /tools/workspace/pi3hat/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def pi3hat_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "mjbots/pi3hat", 23 | commit = "ab632c82bd501b9fcb6f8200df0551989292b7a1", 24 | sha256 = "45bf7f021214eb1b9390e3d06e8e0afa3d243f5b739fae776dd22c855c178a09", 25 | ) 26 | -------------------------------------------------------------------------------- /tools/workspace/raspberrypi-firmware/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/raspberrypi-firmware/BUILD -------------------------------------------------------------------------------- /tools/workspace/raspberrypi-firmware/package.BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | cc_library( 20 | name = "bcm_host", 21 | hdrs = [ 22 | "hardfp/opt/vc/include/bcm_host.h", 23 | ] + glob([ 24 | "hardfp/opt/vc/include/interface/**/*.h", 25 | "hardfp/opt/vc/include/vcinclude/**/*.h", 26 | ]), 27 | srcs = ["hardfp/opt/vc/lib/libbcm_host.so"], 28 | includes = [ 29 | "hardfp/opt/vc/include", 30 | ], 31 | ) 32 | 33 | cc_library( 34 | name = "raspberrypi-firmware", 35 | hdrs = glob(["hardfp/opt/vc/include/**/*.h"]), 36 | srcs = glob(["hardfp/opt/vc/lib/*.so"]), 37 | includes = [ 38 | "hardfp/opt/vc/include", 39 | "hardfp/opt/vc/include/interface/vcos", 40 | "hardfp/opt/vc/include/interface/mmal", 41 | ], 42 | ) 43 | -------------------------------------------------------------------------------- /tools/workspace/raspberrypi-firmware/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 18 | 19 | 20 | def raspberrypi_firmware_repository(name): 21 | http_archive( 22 | name = name, 23 | url = "https://github.com/raspberrypi/firmware/archive/1.20200601.tar.gz", 24 | sha256 = "d826cdfdcf5931b5ccdcf89b206a83983bea8c94ec349552eeccdd20666430c0", 25 | strip_prefix = "firmware-1.20200601", 26 | build_file = Label("//tools/workspace/raspberrypi-firmware:package.BUILD"), 27 | ) 28 | -------------------------------------------------------------------------------- /tools/workspace/raspicam/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/raspicam/BUILD -------------------------------------------------------------------------------- /tools/workspace/raspicam/package.BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2019 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | cc_library( 20 | name = "raspicam", 21 | hdrs = ['src/' + x for x in [ 22 | 'raspicam.h', 23 | 'raspicam_cv.h', 24 | 'raspicam_still.h', 25 | 'raspicam_still_cv.h', 26 | 'raspicamtypes.h', 27 | 'scaler.h', 28 | ]], 29 | srcs = ['src/' + x for x in [ 30 | 'raspicam.cpp', 31 | 'raspicam_cv.cpp', 32 | 'raspicam_still.cpp', 33 | 'raspicam_still_cv.cpp', 34 | 'private/exceptions.h', 35 | 'private/private_impl.cpp', 36 | 'private/private_impl.h', 37 | 'private/private_types.h', 38 | 'private/threadcondition.h', 39 | 'private/threadcondition.cpp', 40 | 'private_still/private_still_impl.cpp', 41 | 'private_still/private_still_impl.h', 42 | ]] + glob(['dependencies/**/*.h']), 43 | deps = [ 44 | "@opencv//:videoio", 45 | "@raspberrypi-firmware", 46 | ], 47 | includes = ["src", "dependencies"], 48 | copts = [ 49 | "-Wno-dynamic-exception-spec", 50 | "-Wno-unused-private-field", 51 | ], 52 | ) 53 | -------------------------------------------------------------------------------- /tools/workspace/raspicam/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2019 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def raspicam_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "cedricve/raspicam", 23 | commit = "651c56418a5a594fc12f1414eb14f2b899729cb1", 24 | sha256 = "35348ef9556aa3ebe7a5f6571fb586e9c5c1fbd1290b22245ffcee1fb2e1582c", 25 | build_file = Label("//tools/workspace/raspicam:package.BUILD"), 26 | patches = [ 27 | Label("//tools/workspace/raspicam:raspicam.diff"), 28 | ], 29 | patch_args = ["-p1"], 30 | ) 31 | -------------------------------------------------------------------------------- /tools/workspace/rpi_bazel/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/rpi_bazel/BUILD -------------------------------------------------------------------------------- /tools/workspace/rpi_bazel/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def rpi_bazel_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "mjbots/rpi_bazel", 23 | commit = "3f9e6245972dfb48dffc04d5c520b799d07ea59c", 24 | sha256 = "fbbd18a9358b67eef091ebf8fffcfc03f0c3d5b582dd5b084081ce573c2dfda0", 25 | ) 26 | -------------------------------------------------------------------------------- /tools/workspace/rules_pkg/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/rules_pkg/BUILD -------------------------------------------------------------------------------- /tools/workspace/rules_pkg/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 18 | 19 | 20 | def rules_pkg_repository(name): 21 | http_archive( 22 | name = name, 23 | urls = [ 24 | "https://github.com/bazelbuild/rules_pkg/releases/download/1.0.1/rules_pkg-1.0.1.tar.gz", 25 | ], 26 | sha256 = "d20c951960ed77cb7b341c2a59488534e494d5ad1d30c4818c736d57772a9fef", 27 | ) 28 | -------------------------------------------------------------------------------- /tools/workspace/sophus/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mjbots/quad/830b6344dc6e9646fdc80f39c2dd9f85abe1bd7e/tools/workspace/sophus/BUILD -------------------------------------------------------------------------------- /tools/workspace/sophus/package.BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2019 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | cc_library( 20 | name = "sophus", 21 | hdrs = glob(['sophus/**/*.hpp']), 22 | deps = ["@eigen"], 23 | includes = ["."], 24 | ) 25 | -------------------------------------------------------------------------------- /tools/workspace/sophus/repository.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2019 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | load("//tools/workspace:github_archive.bzl", "github_archive") 18 | 19 | def sophus_repository(name): 20 | github_archive( 21 | name = name, 22 | repo = "strasdat/Sophus", 23 | commit = "ef9551ff429899b5adae66eabd5a23f165953199", 24 | sha256 = "b5a260f5db7ace1718e9bd44c21fb1a8588e1fb05ae0da29e04bb0eca1906143", 25 | build_file = Label("//tools/workspace/sophus:package.BUILD"), 26 | ) 27 | -------------------------------------------------------------------------------- /tools/workspace/template_file.bzl: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | def _dictify(data): 18 | result = dict([x.split('=', 1) for x in data]) 19 | return result 20 | 21 | def _template_file_impl(ctx): 22 | out = ctx.actions.declare_file(ctx.label.name) 23 | 24 | substitutions = dict(ctx.attr.substitutions) 25 | substitutions.update(_dictify(ctx.attr.substitution_list)) 26 | 27 | ctx.actions.expand_template( 28 | template = ctx.files.src[0], 29 | output = out, 30 | substitutions = substitutions, 31 | is_executable = ctx.attr.is_executable) 32 | return [DefaultInfo( 33 | files = depset([out]), 34 | data_runfiles = ctx.runfiles(files = [out]), 35 | )] 36 | 37 | 38 | template_file = rule( 39 | attrs = { 40 | "src": attr.label(allow_files = True), 41 | "is_executable": attr.bool(default = False), 42 | "substitutions": attr.string_dict(), 43 | "substitution_list": attr.string_list(), 44 | }, 45 | output_to_genfiles = True, 46 | implementation = _template_file_impl, 47 | ) 48 | -------------------------------------------------------------------------------- /tools/workspace_status.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | GIT_REV=$(git rev-parse HEAD) 4 | if [[ $? != 0 ]]; 5 | then 6 | exit 1 7 | fi 8 | 9 | echo "BUILD_SCM_REVISION ${GIT_REV}" 10 | 11 | # Check whether there are any uncommitted changes. 12 | git diff-index --quiet HEAD -- 13 | if [[ $? == 0 ]]; 14 | then 15 | TREE_STATUS=0 16 | else 17 | TREE_STATUS=1 18 | fi 19 | 20 | echo "BUILD_SCM_STATUS ${TREE_STATUS}" 21 | -------------------------------------------------------------------------------- /travis-ci.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import subprocess 4 | import sys 5 | 6 | def run_all(cmds): 7 | for cmd in [x for x in cmds.split('\n') if x.strip() != '']: 8 | print(">>>", cmd) 9 | subprocess.run(cmd, shell=True) 10 | 11 | 12 | ALWAYS = """ 13 | sudo apt-get update 14 | ./install-packages --yes 15 | """ 16 | 17 | 18 | CMDS = [ 19 | "./tools/bazel test //base/...", 20 | "./tools/bazel build @ffmpeg//...", 21 | "./tools/bazel build @opencv//...", 22 | "./tools/bazel build @dart//...", 23 | "./tools/bazel build @gstreamer//... @gst-libav//... @gst-plugins-bad//... @gst-plugins-base//... @gst-plugins-ugly//... @gst-plugins-base//:plugins", 24 | "./tools/bazel test //...", 25 | ] 26 | 27 | def main(): 28 | run_all(ALWAYS) 29 | 30 | if len(sys.argv) < 2: 31 | [run_all(x) for x in CMDS] 32 | else: 33 | run_all(CMDS[int(sys.argv[1])]) 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /utils/BUILD: -------------------------------------------------------------------------------- 1 | # -*- python -*- 2 | 3 | # Copyright 2018-2020 Josh Pieper, jjp@pobox.com. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | package(default_visibility = ["//visibility:public"]) 18 | 19 | py_binary( 20 | name = "video_aligner", 21 | srcs = ["video_aligner.py"], 22 | deps = [ 23 | "@com_github_mjbots_mjlib//mjlib/telemetry:py_file_reader", 24 | ], 25 | ) 26 | 27 | cc_binary( 28 | name = "tplot2", 29 | srcs = [ 30 | "imgui_tree_archive.h", 31 | "quadruped_tplot2.h", 32 | "quadruped_tplot2.cc", 33 | "tplot2.cc", 34 | "tree_view.h", 35 | ], 36 | deps = [ 37 | "//ffmpeg", 38 | "//gl", 39 | "//mech", 40 | "@com_github_mjbots_mjlib//mjlib/base:buffer_stream", 41 | "@com_github_mjbots_mjlib//mjlib/base:clipp", 42 | "@com_github_mjbots_mjlib//mjlib/base:tokenizer", 43 | "@com_github_mjbots_mjlib//mjlib/micro:serializable_handler", 44 | "@com_github_mjbots_mjlib//mjlib/telemetry:file_reader", 45 | "@com_github_mjbots_mjlib//mjlib/telemetry:mapped_binary_reader", 46 | "@com_github_mjbots_mjlib//mjlib/imgui:imgui", 47 | "@implot", 48 | "@org_llvm_libcxx//:libcxx", 49 | ], 50 | ) 51 | 52 | exports_files([ 53 | "config_servos.py", 54 | "performance_governor.sh", 55 | "quad-start.sh", 56 | "quad_screen.conf", 57 | "quad.cmd", 58 | "start-robot.sh", 59 | "zero_leg.py", 60 | ]) 61 | -------------------------------------------------------------------------------- /utils/performance_governor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | for a in /sys/devices/system/cpu/cpu?/cpufreq/scaling_governor; do 6 | echo "performance" > $a 7 | done 8 | -------------------------------------------------------------------------------- /utils/quad-start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | screen -d -m -c /home/pi/mech/quad_screen.conf 4 | -------------------------------------------------------------------------------- /utils/quad.cmd: -------------------------------------------------------------------------------- 1 | export LD_LIBRARY_PATH=. 2 | cd /home/pi/mech; ./start-robot.sh 3 | -------------------------------------------------------------------------------- /utils/quad_screen.conf: -------------------------------------------------------------------------------- 1 | screen 1 bash --init-file /home/pi/mech/quad.cmd 2 | 3 | detach 4 | -------------------------------------------------------------------------------- /utils/quadruped_tplot2.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Josh Pieper, jjp@pobox.com. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include "mjlib/telemetry/file_reader.h" 18 | 19 | #include "utils/tree_view.h" 20 | 21 | namespace mjmech { 22 | namespace utils { 23 | 24 | void AddQuadrupedDerived(mjlib::telemetry::FileReader*, TreeView*); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/ssh/default.ssh.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDh6fNOJpuITEh3UeF5ZQNPwknV9FDRXTv1l7G2yfjrKdWELeSr+PS1tVT56z5ZHMx9/sM3Rz7iAlnQvcX9phnS5nNum7ZMIWEHOX+fhrtvH4QtviEq+CtYKqHJ/Bbu2WFKHh96afQps/riweQ4qWA6q5GRwHrXWav3gCEwFUl9u8fl8+5medoD6vZ5f0IMR7pGgsjS7XD1ts9xe7ar9yJLuKoM2AbgoJM1SLMC0ujnKHNMBep2TGc/PDdBuPA7lwW4J58XW1e4zD2evazHII39QefN51TsMBkV3KVcSYasrgvGU4QwQEQ8mJ8vTmu9nnt27me887uFQkvIgTFwSs/gDz/97nrXcRj6dCQUXWCQ65o0dC/c24OvJDj28zGo47SiAjhW0PHh0BSTsfPNJ3niFDCiPJTh08XoighIGrpDbXdZ0DvqCWphCz7dNu9QZ+c6RV6PfxKQ93zqekN08I7UgbJrxDw+R9LbtLPO1D3LVM7an5Jj31wUYv08G6XIvu3UruX6fJYgw3lumAQ+FwBSKL+1ydl5LXufYJlmZqJLR3utsjnaSbciNgB5ZFb6NvYZ8ALM87QDxf9HaEGHaflWKVW1yiLmQm76CqKGDNwZVxema+4GJuetR6bHHO8TAY7o69qV/0OYKfXxtIccxRAbZVw6Bp9MXzg+MaNoAH8xbw== info@mjbots.com 2 | -------------------------------------------------------------------------------- /utils/start-robot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ "$1" == "--help" || "$1" == "-h" ]]; then 3 | cat <