Skip to content

Commit a0aa761

Browse files
Improve portfolio presentation on docs site
Reshape the portfolio page into a web-first gallery and add a custom navy-and-gold site theme. Also surface the portfolio more clearly from the docs landing page.
1 parent efcb1fc commit a0aa761

4 files changed

Lines changed: 186 additions & 33 deletions

File tree

docs/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ the release workflow for PyPI and GitHub Pages.
1515
- Python package: importable bindings distributed as `pycddp`
1616
- Docs site: Markdown content from `docs/`, published to GitHub Pages
1717

18+
## Portfolio highlight
19+
20+
The Python portfolio page is the visual entry point for the bindings and their
21+
animation-driven demos.
22+
23+
[Open the portfolio gallery](python_portfolio.md){ .md-button .md-button--primary }
24+
[Read the Python package guide](python.md){ .md-button }
25+
1826
## Quick start
1927

2028
Install the Python package from PyPI:

docs/python_portfolio.md

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ This gallery is the Python-facing showcase for the `pycddp` bindings. Each
44
demo is solved directly from Python, then rendered as an animation with
55
Matplotlib.
66

7+
<div class="portfolio-hero">
8+
<div>
9+
<p class="portfolio-kicker">Interactive Demo Gallery</p>
10+
<h2>Solver results presented as a web-first portfolio</h2>
11+
<p>
12+
These examples are the quickest way to understand what the Python bindings
13+
actually produce: constrained solves, animated trajectories, and compact
14+
reproducible workflows.
15+
</p>
16+
<p>
17+
<a class="md-button md-button--primary" href="../python/">Python package guide</a>
18+
<a class="md-button" href="https://github.com/astomodynamics/cddp-cpp/tree/master/examples">Browse examples</a>
19+
</p>
20+
</div>
21+
<img src="../assets/cddp_in_cpp.png" alt="CDDP illustration">
22+
</div>
23+
724
## Regenerate the gallery
825

926
```bash
@@ -13,36 +30,45 @@ python examples/python_portfolio.py --demo all --output-dir docs/assets/python_p
1330

1431
## Demos
1532

16-
### Pendulum Swing-Up
17-
18-
Torque-limited `CLDDP` solve for a damped pendulum.
19-
20-
<img src="assets/python_portfolio/pendulum_swing_up.gif" width="820" alt="Pendulum swing-up animation">
21-
22-
### Cart-Pole Swing-Up
23-
24-
Bounded-force `CLDDP` solve that swings the pole upright and settles near the
25-
origin.
26-
27-
<img src="assets/python_portfolio/cartpole_swing_up.gif" width="820" alt="Cart-pole swing-up animation">
28-
29-
### Unicycle Obstacle Avoidance
30-
31-
`IPDDP` solve with a circular obstacle constraint, showing how the Python
32-
bindings can be used for constrained trajectory visualization without building
33-
the legacy C++ plotting stack.
34-
35-
<img src="assets/python_portfolio/unicycle_obstacle_avoidance.gif" width="820" alt="Unicycle obstacle avoidance animation">
36-
37-
### MPCC Racing Line
38-
39-
Full-lap receding-horizon contouring control on a compact racing circuit,
40-
solved from Python with a custom nonlinear objective and a lightweight bicycle
41-
model.
42-
43-
This is a compact kinematic MPCC-style showcase rather than a full reproduction
44-
of the autonomous-racing controller in Liniger et al. The bundled track data is
45-
derived from the [`alexliniger/MPCC`](https://github.com/alexliniger/MPCC)
46-
reference implementation.
47-
48-
<img src="assets/python_portfolio/mpcc_racing_line.gif" width="820" alt="MPCC racing line animation">
33+
<div class="portfolio-grid">
34+
<section class="portfolio-card">
35+
<h3>Pendulum Swing-Up</h3>
36+
<p>Torque-limited <code>CLDDP</code> solve for a damped pendulum.</p>
37+
<img src="assets/python_portfolio/pendulum_swing_up.gif" alt="Pendulum swing-up animation">
38+
</section>
39+
40+
<section class="portfolio-card">
41+
<h3>Cart-Pole Swing-Up</h3>
42+
<p>
43+
Bounded-force <code>CLDDP</code> solve that swings the pole upright and
44+
settles near the origin.
45+
</p>
46+
<img src="assets/python_portfolio/cartpole_swing_up.gif" alt="Cart-pole swing-up animation">
47+
</section>
48+
49+
<section class="portfolio-card">
50+
<h3>Unicycle Obstacle Avoidance</h3>
51+
<p>
52+
<code>IPDDP</code> solve with a circular obstacle constraint, showing how
53+
the Python bindings can drive constrained trajectory visualization
54+
directly from Python.
55+
</p>
56+
<img src="assets/python_portfolio/unicycle_obstacle_avoidance.gif" alt="Unicycle obstacle avoidance animation">
57+
</section>
58+
59+
<section class="portfolio-card">
60+
<h3>MPCC Racing Line</h3>
61+
<p>
62+
Full-lap contouring control on a compact circuit, solved from Python with
63+
a custom nonlinear objective and a lightweight bicycle model.
64+
</p>
65+
<p>
66+
This is a compact kinematic MPCC-style showcase rather than a full
67+
reproduction of the controller in Liniger et al. The bundled track data
68+
is derived from the
69+
<a href="https://github.com/alexliniger/MPCC"><code>alexliniger/MPCC</code></a>
70+
reference implementation.
71+
</p>
72+
<img src="assets/python_portfolio/mpcc_racing_line.gif" alt="MPCC racing line animation">
73+
</section>
74+
</div>

docs/stylesheets/extra.css

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
:root {
2+
--md-primary-fg-color: #16344f;
3+
--md-primary-fg-color--light: #325775;
4+
--md-primary-fg-color--dark: #0d2236;
5+
--md-accent-fg-color: #c89a3c;
6+
--md-accent-fg-color--transparent: rgba(200, 154, 60, 0.14);
7+
--site-navy-deep: #10273c;
8+
--site-navy-mid: #173954;
9+
--site-gold-soft: #c89a3c;
10+
--site-gold-pale: #efe1bd;
11+
--site-surface: #f6f2e8;
12+
}
13+
14+
[data-md-color-primary="custom"] {
15+
--md-typeset-a-color: var(--site-navy-mid);
16+
}
17+
18+
.md-header,
19+
.md-tabs {
20+
background: linear-gradient(90deg, var(--site-navy-deep), var(--site-navy-mid));
21+
}
22+
23+
.md-typeset .md-button--primary {
24+
background-color: var(--site-gold-soft);
25+
border-color: var(--site-gold-soft);
26+
color: #12263a;
27+
}
28+
29+
.md-typeset .md-button {
30+
border-radius: 999px;
31+
}
32+
33+
.md-typeset h1,
34+
.md-typeset h2,
35+
.md-typeset h3 {
36+
color: var(--site-navy-deep);
37+
}
38+
39+
.md-main {
40+
background:
41+
radial-gradient(circle at top right, rgba(200, 154, 60, 0.12), transparent 28rem),
42+
linear-gradient(180deg, #fcfbf7 0%, var(--site-surface) 100%);
43+
}
44+
45+
.portfolio-kicker {
46+
color: var(--site-gold-soft);
47+
font-size: 0.72rem;
48+
font-weight: 700;
49+
letter-spacing: 0.12em;
50+
margin: 0 0 0.5rem 0;
51+
text-transform: uppercase;
52+
}
53+
54+
.portfolio-hero {
55+
align-items: center;
56+
background: linear-gradient(135deg, var(--site-navy-deep), var(--site-navy-mid));
57+
border: 1px solid rgba(200, 154, 60, 0.25);
58+
border-radius: 1.2rem;
59+
box-shadow: 0 24px 60px rgba(16, 39, 60, 0.18);
60+
color: #f8f3e9;
61+
display: grid;
62+
gap: 1.5rem;
63+
grid-template-columns: 1.45fr 1fr;
64+
margin: 0 0 2rem 0;
65+
overflow: hidden;
66+
padding: 1.5rem;
67+
}
68+
69+
.portfolio-hero h2,
70+
.portfolio-hero p {
71+
color: inherit;
72+
}
73+
74+
.portfolio-hero img {
75+
border-radius: 1rem;
76+
display: block;
77+
max-width: 100%;
78+
}
79+
80+
.portfolio-grid {
81+
display: grid;
82+
gap: 1.25rem;
83+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
84+
margin-top: 1.25rem;
85+
}
86+
87+
.portfolio-card {
88+
background: rgba(255, 255, 255, 0.82);
89+
border: 1px solid rgba(16, 39, 60, 0.08);
90+
border-radius: 1rem;
91+
box-shadow: 0 14px 36px rgba(16, 39, 60, 0.08);
92+
padding: 1rem 1rem 1.15rem 1rem;
93+
}
94+
95+
.portfolio-card h3 {
96+
margin-top: 0;
97+
}
98+
99+
.portfolio-card img {
100+
border-radius: 0.85rem;
101+
display: block;
102+
margin-top: 0.8rem;
103+
width: 100%;
104+
}
105+
106+
@media (max-width: 900px) {
107+
.portfolio-hero {
108+
grid-template-columns: 1fr;
109+
}
110+
}

mkdocs.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,24 @@ theme:
1111
- navigation.sections
1212
- navigation.top
1313
- content.code.copy
14+
palette:
15+
- scheme: default
16+
primary: custom
17+
accent: custom
1418

1519
plugins:
1620
- search
1721

1822
markdown_extensions:
1923
- admonition
24+
- attr_list
25+
- md_in_html
2026
- pymdownx.highlight
2127
- pymdownx.superfences
2228

29+
extra_css:
30+
- stylesheets/extra.css
31+
2332
nav:
2433
- Overview: index.md
2534
- Installation: install.md

0 commit comments

Comments
 (0)