Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/Manifest.toml
/.CondaPkg
/.CondaPkg
/gen/Manifest.toml
/examples/Manifest.toml
13 changes: 3 additions & 10 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
name = "QuanserInterface"
uuid = "d7748c0a-89fb-413b-a9f0-29aba34b281f"
authors = ["Fredrik Bagge Carlson"]
version = "1.0.0-DEV"
version = "0.1.0-DEV"

[deps]
CBinding = "d43a6710-96b8-4a2d-833c-c424785e5374"
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"
Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31"
ControlSystemIdentification = "3abffc1c-5106-53b7-b354-a47bfc086282"
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
DiscretePIDs = "c1363496-6848-4723-8758-079b737f6baf"
HardwareAbstractions = "9ac91abb-62f4-42c0-88e8-83732e93d543"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LowLevelParticleFilters = "d9d29d28-c116-5dba-9239-57a5fe23875b"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
RobustAndOptimalControl = "21fd56a4-db03-40ee-82ee-a87907bee541"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"


[weakdeps]
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"

[extensions]
QuanserInterfacePythonCallExt = ["PythonCall"]


[compat]
CBinding = "1.0.10"
CEnum = "0.4.2"
Clang = "0.17.6"
CEnum = "0.4.2, 0.5"
ControlSystemIdentification = "2.6"
ControlSystemsBase = "1.7.0"
DSP = "0.7.8"
Expand All @@ -44,8 +37,8 @@ StaticArrays = "1.5"
julia = "1.9"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,19 @@ See the Youtube vidoe series [Control of a rotary pendulum using Julia](https://
## Installation

1. Install the hardware-in-the-loop (HIL) interface from here https://github.com/quanser/hil_sdk_linux_x86_64 (change linux to what's appropriate for your system)
2. To use the `PythonBackend` Install Quanser python packages as described [here](https://docs.quanser.com/quarc/documentation/python/installation.html) and manually install and load PythonCall (the python backend is an extension). Optionally, set the default backend using `QuanserInterface.set_default_backend("python")`. Install the Virtual Environment first, which will include the Python Wheels.
3. To use the C backend (default), install the sdk, and if on Linux, possibly symlink `sudo ln -s /usr/lib/x86_64-linux-gnu/libquanser_communications.so.1 /lib/libquanser_communications.so` (or wherever the library is located on your system), I had issues with the `.1` suffix causing Libdl not to find the library. The easiest way to install all the required shared libraries is to follow the python install instructions, i.e., issue the `sudo apt install python3-quanser-apis` after having added their package server.
2. To use the `CBackend` (default), install the Quanser HIL SDK ([mac], [linux], [windows])

<details>

<summary> Linux tips </summary>

If on Linux, possibly symlink `sudo ln -s /usr/lib/x86_64-linux-gnu/libquanser_communications.so.1 /lib/libquanser_communications.so` (or wherever the library is located on your system), I had issues with the `.1` suffix causing Libdl not to find the library. The easiest way to install all the required shared libraries _on linux_ is to follow the python install instructions, i.e., issue the `sudo apt install python3-quanser-apis` after having added their package server.

</details>

---

3. To use the `PythonBackend`, install Quanser python packages as described [here](https://docs.quanser.com/quarc/documentation/python/installation.html), and manually install and load `PythonCall.jl` (the python backend is an extension). Optionally, set the default backend using `QuanserInterface.set_default_backend("python")`. Install the Virtual Environment first, which will include the Python Wheels.

### Virtual environment

Expand Down
15 changes: 15 additions & 0 deletions examples/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[deps]
ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
HardwareAbstractions = "9ac91abb-62f4-42c0-88e8-83732e93d543"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LowLevelParticleFilters = "d9d29d28-c116-5dba-9239-57a5fe23875b"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
QuanserInterface = "d7748c0a-89fb-413b-a9f0-29aba34b281f"

[sources]
QuanserInterface = { path = ".." }
10 changes: 9 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# Examples
Each example has a little description at the top.
Each example has a little description at the top.

To run an example, you can do this.

```bash
QuanserInterface.jl/> julia --project=. examples/swingup.jl
```

and it will just run. The examples must be run in the `QuanserInterface.jl` project.
2 changes: 1 addition & 1 deletion examples/pendulum_identification.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This script performs maximum likelihood estimation of the parameters of the pend

The estimation uses an UnscentedKalmanFilter to perform state estimation, the system is unstable and integrates a force disturbance, and performing identification using a state estimator is a good way of handling both those problems.
=#
cd(@__DIR__)

using DelimitedFiles, Plots
N = 250
D = readdlm("swingup.csv", ',')[2:N, :] .|> identity
Expand Down
8 changes: 6 additions & 2 deletions examples/swingup.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#=
This script performs swingup of the pendulum using an energy-based controller, and stabilizes the pendulum at the top using an LQR controller. The controller gain is designed using furuta_lqg.jl
=#
cd(@__DIR__)
using Pkg; Pkg.activate("..")

if splitdir(Base.active_project())[1] != @__DIR__
@warn "Not in the QuanserInterface.jl/examples project, activating it"
using Pkg; Pkg.activate(@__DIR__)
end

using QuanserInterface
using HardwareAbstractions
using ControlSystemsBase
Expand Down
8 changes: 6 additions & 2 deletions examples/virtual_swingup.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#=
This script performs swingup of the virtual pendulum using an energy-based controller, and stabilizes the pendulum at the top using an LQR controller.
=#
cd(@__DIR__)
using Pkg; Pkg.activate("..")

if splitdir(Base.active_project())[1] != @__DIR__
@warn "Not in the `QuanserInterface.jl/examples` project, activating it"
using Pkg; Pkg.activate(@__DIR__)
end

using QuanserInterface
using HardwareAbstractions
using ControlSystemsBase
Expand Down
File renamed without changes.
2 changes: 2 additions & 0 deletions gen/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[deps]
Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31"
4 changes: 2 additions & 2 deletions src/QuanserCGenerator.jl → gen/QuanserCGenerator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Clang.Generators

LIB_PATH = "/opt/quanser/hil_sdk/include"
headers = [joinpath(LIB_PATH, header) for header in filter(x -> endswith(x, ".h"), readdir(LIB_PATH))] # include all .h files in the directory
output = "src/QuanserBindings.jl"
output = joinpath(@__DIR__, "QuanserBindings.jl")

# make sure Clang.jl can find necessary headers included by your header file
clang_args = ["-I", LIB_PATH]
Expand All @@ -20,4 +20,4 @@ ctx = create_context(headers, args, options)
# run generator
build!(ctx)

println("Bindings generated in $output")
println("Bindings generated in $output.\nPlease copy the file to src/QuanserBindings.jl")
Loading